FE: Extend Actions in Scan Execution Policy Editor to include Tags
Why are we doing this work
With https://docs.gitlab.com/ee/ci/runners/configure_runners.html#use-tags-to-control-which-jobs-a-runner-can-run you can select tags for each job in your .gitlab-ci.yml
file. These tags allows to control which jobs a runner can run.
With this feature we want to add this functionality to GitLab and extend Scan Execution Policy Editor with field to add information about tags.
You can read more about this in Allow Users to Define Tags for Scan Execution P... (&9176 - closed).
Relevant links
Non-functional requirements
- [-] Documentation:
- [-] Feature flag: No need for feature flag in this case.
- [-] Performance:
- [-] Testing:
Implementation plan
-
frontend extend ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/policy_action_builder.vue
to includegl-form-input
component for every scan type with comma separated tags,
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/constants.js b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/constants.js
index ab4756328318..c6b2d2b7d969 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/constants.js
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/constants.js
@@ -32,11 +32,11 @@ export const SCAN_EXECUTION_RULE_PERIOD_TYPE = {
export const DEFAULT_SCANNER = SCANNER_DAST;
export const SCANNER_HUMANIZED_TEMPLATE = s__(
- 'ScanExecutionPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require a %{scan} scan to run',
+ 'ScanExecutionPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require a %{scan} scan to run with tags %{tags}',
);
export const DAST_HUMANIZED_TEMPLATE = s__(
- 'ScanExecutionPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require a %{scan} scan to run with site profile %{siteProfile} and scanner profile %{scannerProfile}',
+ 'ScanExecutionPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require a %{scan} scan to run with site profile %{siteProfile} and scanner profile %{scannerProfile} with tags %{tags}',
);
export const RULE_MODE_SCANNERS = {
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/policy_action_builder.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/policy_action_builder.vue
index 6afffc4b149b..ac2aad923808 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/policy_action_builder.vue
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/policy_action_builder.vue
@@ -71,6 +71,14 @@ export default {
this.setSelectedScanner({ scannerProfile: value });
},
},
+ tags: {
+ get() {
+ return this.initAction.tags?.join('').trim() ?? '';
+ },
+ set(value) {
+ // TODO update action with new tags
+ },
+ },
},
methods: {
setSelectedScanner({
@@ -88,6 +96,7 @@ export default {
i18n: {
selectedScannerProfilePlaceholder: s__('ScanExecutionPolicy|Select scanner profile'),
selectedSiteProfilePlaceholder: s__('ScanExecutionPolicy|Select site profile'),
+ selectedTagsPlaceholder: s__('ScanExecutionPolicy|Select tags (if any)'),
},
};
</script>
@@ -142,6 +151,21 @@ export default {
/>
</gl-form-group>
</template>
+
+ <template #tags>
+ <gl-form-group
+ :label="s__('ScanExecutionPolicy|Tags')"
+ label-for="policy-tags"
+ label-sr-only
+ >
+ <gl-form-input
+ id="policy-tags"
+ v-model="tags"
+ :placeholder="$options.i18n.selectedTagsPlaceholder"
+ data-testid="policy-tags-selection"
+ />
+ </gl-form-group>
+ </template>
</gl-sprintf>
</gl-form>
<div class="gl-min-w-7">
-
frontend update DEFAULT_SCAN_EXECUTION_POLICY to include tags
by default
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/index.js b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/index.js
index 383d0fed7a71..25cdb1ddb315 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/index.js
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/index.js
@@ -17,4 +17,5 @@ actions:
- scan: dast
site_profile: ''
scanner_profile: ''
+ tags: []
`;
-
frontend update new action to include tags
by default
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/actions.js b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/actions.js
index fe45a4efd264..5312bdf66412 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/actions.js
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/actions.js
@@ -1,7 +1,7 @@
import { SCANNER_DAST } from '../constants';
export function buildScannerAction({ scanner, siteProfile = '', scannerProfile = '' }) {
- const action = { scan: scanner };
+ const action = { scan: scanner, tags: [] };
if (scanner === SCANNER_DAST) {
action.site_profile = siteProfile;
-
frontend update actionKeys to include tags
so that rule mode is not diasable whentags
is included in the yaml
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/from_yaml.js b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/from_yaml.js
index a8106430ee52..ba22b4f2b29e 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/from_yaml.js
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/from_yaml.js
@@ -35,7 +35,7 @@ export const fromYaml = ({ manifest, validateRuleMode = false }) => {
*/
const primaryKeys = ['type', 'name', 'description', 'enabled', 'rules', 'actions'];
const rulesKeys = ['type', 'agents', 'branches', 'cadence'];
- const actionsKeys = ['scan', 'site_profile', 'scanner_profile', 'variables'];
+ const actionsKeys = ['scan', 'site_profile', 'scanner_profile', 'variables', 'tags'];
return isValidPolicy({ policy, primaryKeys, rulesKeys, actionsKeys }) &&
!hasInvalidCron(policy) &&
All changes
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/constants.js b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/constants.js
index ab4756328318..c6b2d2b7d969 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/constants.js
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/constants.js
@@ -32,11 +32,11 @@ export const SCAN_EXECUTION_RULE_PERIOD_TYPE = {
export const DEFAULT_SCANNER = SCANNER_DAST;
export const SCANNER_HUMANIZED_TEMPLATE = s__(
- 'ScanExecutionPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require a %{scan} scan to run',
+ 'ScanExecutionPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require a %{scan} scan to run with tags %{tags}',
);
export const DAST_HUMANIZED_TEMPLATE = s__(
- 'ScanExecutionPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require a %{scan} scan to run with site profile %{siteProfile} and scanner profile %{scannerProfile}',
+ 'ScanExecutionPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require a %{scan} scan to run with site profile %{siteProfile} and scanner profile %{scannerProfile} with tags %{tags}',
);
export const RULE_MODE_SCANNERS = {
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/actions.js b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/actions.js
index fe45a4efd264..5312bdf66412 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/actions.js
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/actions.js
@@ -1,7 +1,7 @@
import { SCANNER_DAST } from '../constants';
export function buildScannerAction({ scanner, siteProfile = '', scannerProfile = '' }) {
- const action = { scan: scanner };
+ const action = { scan: scanner, tags: [] };
if (scanner === SCANNER_DAST) {
action.site_profile = siteProfile;
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/from_yaml.js b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/from_yaml.js
index a8106430ee52..ba22b4f2b29e 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/from_yaml.js
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/from_yaml.js
@@ -35,7 +35,7 @@ export const fromYaml = ({ manifest, validateRuleMode = false }) => {
*/
const primaryKeys = ['type', 'name', 'description', 'enabled', 'rules', 'actions'];
const rulesKeys = ['type', 'agents', 'branches', 'cadence'];
- const actionsKeys = ['scan', 'site_profile', 'scanner_profile', 'variables'];
+ const actionsKeys = ['scan', 'site_profile', 'scanner_profile', 'variables', 'tags'];
return isValidPolicy({ policy, primaryKeys, rulesKeys, actionsKeys }) &&
!hasInvalidCron(policy) &&
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/index.js b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/index.js
index 383d0fed7a71..25cdb1ddb315 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/index.js
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/lib/index.js
@@ -17,4 +17,5 @@ actions:
- scan: dast
site_profile: ''
scanner_profile: ''
+ tags: []
`;
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/policy_action_builder.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/policy_action_builder.vue
index 6afffc4b149b..ac2aad923808 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/policy_action_builder.vue
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution_policy/policy_action_builder.vue
@@ -71,6 +71,14 @@ export default {
this.setSelectedScanner({ scannerProfile: value });
},
},
+ tags: {
+ get() {
+ return this.initAction.tags?.join('').trim() ?? '';
+ },
+ set(value) {
+ // TODO update action with new tags
+ },
+ },
},
methods: {
setSelectedScanner({
@@ -88,6 +96,7 @@ export default {
i18n: {
selectedScannerProfilePlaceholder: s__('ScanExecutionPolicy|Select scanner profile'),
selectedSiteProfilePlaceholder: s__('ScanExecutionPolicy|Select site profile'),
+ selectedTagsPlaceholder: s__('ScanExecutionPolicy|Select tags (if any)'),
},
};
</script>
@@ -142,6 +151,21 @@ export default {
/>
</gl-form-group>
</template>
+
+ <template #tags>
+ <gl-form-group
+ :label="s__('ScanExecutionPolicy|Tags')"
+ label-for="policy-tags"
+ label-sr-only
+ >
+ <gl-form-input
+ id="policy-tags"
+ v-model="tags"
+ :placeholder="$options.i18n.selectedTagsPlaceholder"
+ data-testid="policy-tags-selection"
+ />
+ </gl-form-group>
+ </template>
</gl-sprintf>
</gl-form>
<div class="gl-min-w-7">
Verification steps
- Upload a GitLab Ultimate license
- Navigate to http://gdk.test:3443/flightjs/Flight/-/security/policies/new?type=scan_execution_policy
- Verify the tags at the project level
- Navigate to http://gdk.test:3443/groups/flightjs/-/security/policies/new?type=scan_execution_policy
- Verify the tags at the group level
Edited by Alexander Turinske