Skip to content

Commit c6ff8f7

Browse files
author
Jop Zitman
committed
Add inheritHookSelector to CRD and cascading scans definition
Signed-off-by: Jop Zitman <jop.zitman@secura.com>
1 parent 845b2c6 commit c6ff8f7

11 files changed

Lines changed: 202 additions & 6 deletions

hooks/cascading-scans/hook/hook.test.js

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// SPDX-License-Identifier: Apache-2.0
44

55
const { getCascadingScans } = require("./hook");
6+
const {LabelSelectorRequirementOperator} = require("./kubernetes-label-selector");
67

78
let parentScan = undefined;
89
let sslyzeCascadingRules = undefined;
@@ -104,6 +105,7 @@ test("Should create subsequent scans for open HTTPS ports (NMAP findings)", () =
104105
"spec": Object {
105106
"cascades": Object {},
106107
"env": Array [],
108+
"hookSelector": Object {},
107109
"initContainers": Array [],
108110
"parameters": Array [
109111
"--regular",
@@ -241,6 +243,7 @@ test("Should not crash when the annotations are not set", () => {
241243
"spec": Object {
242244
"cascades": Object {},
243245
"env": Array [],
246+
"hookSelector": Object {},
244247
"initContainers": Array [],
245248
"parameters": Array [
246249
"--regular",
@@ -372,6 +375,7 @@ test("Should allow wildcards in cascadingRules", () => {
372375
"spec": Object {
373376
"cascades": Object {},
374377
"env": Array [],
378+
"hookSelector": Object {},
375379
"initContainers": Array [],
376380
"parameters": Array [
377381
"--regular",
@@ -1128,6 +1132,7 @@ test("Templating should also apply to initContainer commands", () => {
11281132
"spec": Object {
11291133
"cascades": Object {},
11301134
"env": Array [],
1135+
"hookSelector": Object {},
11311136
"initContainers": Array [
11321137
Object {
11331138
"command": Array [
@@ -1260,6 +1265,7 @@ test("Templating should not break special encoding (http://...) when using tripl
12601265
"spec": Object {
12611266
"cascades": Object {},
12621267
"env": Array [],
1268+
"hookSelector": Object {},
12631269
"initContainers": Array [
12641270
Object {
12651271
"command": Array [
@@ -1301,6 +1307,145 @@ test("Templating should not break special encoding (http://...) when using tripl
13011307
`);
13021308
});
13031309

1310+
test("should merge hookSelector into cascaded scan", () => {
1311+
parentScan.spec.cascades.inheritHookSelector = true
1312+
const findings = [
1313+
{
1314+
name: "Port 443 is open",
1315+
category: "Open Port",
1316+
attributes: {
1317+
state: "open",
1318+
hostname: "foobar.com",
1319+
port: 443,
1320+
service: "https"
1321+
}
1322+
}
1323+
];
1324+
1325+
parentScan.spec.hookSelector = {}
1326+
parentScan.spec.hookSelector.matchLabels = {
1327+
"securecodebox.io/internal": "true",
1328+
}
1329+
parentScan.spec.hookSelector.matchExpressions = [
1330+
{
1331+
key: "securecodebox.io/name",
1332+
operator: LabelSelectorRequirementOperator.In,
1333+
values: ["cascading-scans"]
1334+
}
1335+
]
1336+
1337+
sslyzeCascadingRules[0].spec.scanSpec.hookSelector = {};
1338+
sslyzeCascadingRules[0].spec.scanSpec.hookSelector.matchExpressions = [
1339+
{
1340+
key: "securecodebox.io/name",
1341+
operator: LabelSelectorRequirementOperator.NotIn,
1342+
values: ["cascading-scans"]
1343+
}
1344+
]
1345+
1346+
sslyzeCascadingRules[0].spec.scanSpec.hookSelector.matchLabels = {
1347+
"securecodebox.io/internal": "false",
1348+
}
1349+
1350+
const cascadedScans = getCascadingScans(
1351+
parentScan,
1352+
findings,
1353+
sslyzeCascadingRules
1354+
);
1355+
1356+
const cascadedScan = cascadedScans[0];
1357+
1358+
expect(cascadedScan.spec.hookSelector).toMatchInlineSnapshot(`
1359+
Object {
1360+
"matchExpressions": Array [
1361+
Object {
1362+
"key": "securecodebox.io/name",
1363+
"operator": "In",
1364+
"values": Array [
1365+
"cascading-scans",
1366+
],
1367+
},
1368+
Object {
1369+
"key": "securecodebox.io/name",
1370+
"operator": "NotIn",
1371+
"values": Array [
1372+
"cascading-scans",
1373+
],
1374+
},
1375+
],
1376+
"matchLabels": Object {
1377+
"securecodebox.io/internal": "false",
1378+
},
1379+
}
1380+
`);
1381+
});
1382+
1383+
1384+
test("should not merge hookSelector into cascaded scan if inheritHookSelector is disabled", () => {
1385+
parentScan.spec.cascades.inheritHookSelector = false
1386+
const findings = [
1387+
{
1388+
name: "Port 443 is open",
1389+
category: "Open Port",
1390+
attributes: {
1391+
state: "open",
1392+
hostname: "foobar.com",
1393+
port: 443,
1394+
service: "https"
1395+
}
1396+
}
1397+
];
1398+
1399+
parentScan.spec.hookSelector = {}
1400+
parentScan.spec.hookSelector.matchLabels = {
1401+
"securecodebox.io/internal": "true",
1402+
}
1403+
parentScan.spec.hookSelector.matchExpressions = [
1404+
{
1405+
key: "securecodebox.io/name",
1406+
operator: LabelSelectorRequirementOperator.In,
1407+
values: ["cascading-scans"]
1408+
}
1409+
]
1410+
1411+
sslyzeCascadingRules[0].spec.scanSpec.hookSelector = {};
1412+
sslyzeCascadingRules[0].spec.scanSpec.hookSelector.matchExpressions = [
1413+
{
1414+
key: "securecodebox.io/name",
1415+
operator: LabelSelectorRequirementOperator.NotIn,
1416+
values: ["cascading-scans"]
1417+
}
1418+
]
1419+
1420+
sslyzeCascadingRules[0].spec.scanSpec.hookSelector.matchLabels = {
1421+
"securecodebox.io/internal": "false",
1422+
}
1423+
1424+
const cascadedScans = getCascadingScans(
1425+
parentScan,
1426+
findings,
1427+
sslyzeCascadingRules
1428+
);
1429+
1430+
const cascadedScan = cascadedScans[0];
1431+
1432+
expect(cascadedScan.spec.hookSelector).toMatchInlineSnapshot(`
1433+
Object {
1434+
"matchExpressions": Array [
1435+
Object {
1436+
"key": "securecodebox.io/name",
1437+
"operator": "NotIn",
1438+
"values": Array [
1439+
"cascading-scans",
1440+
],
1441+
},
1442+
],
1443+
"matchLabels": Object {
1444+
"securecodebox.io/internal": "false",
1445+
},
1446+
}
1447+
`);
1448+
});
13041449

13051450
test("should purge cascaded scan spec from parent scan", () => {
13061451
parentScan.spec.cascades.inheritEnv = true

hooks/cascading-scans/hook/hook.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import {
1616
getCascadedRuleForScan,
1717
purgeCascadedRuleFromScan,
1818
mergeInheritedMap,
19-
mergeInheritedArray
19+
mergeInheritedArray,
20+
mergeInheritedSelector,
2021
} from "./scan-helpers";
2122

2223
interface HandleArgs {
@@ -110,7 +111,7 @@ function getCascadingScan(
110111

111112
let { scanType, parameters } = cascadingRule.spec.scanSpec;
112113

113-
let { annotations, labels, env, volumes, volumeMounts, initContainers } = mergeCascadingRuleWithScan(parentScan, cascadingRule);
114+
let { annotations, labels, env, volumes, volumeMounts, initContainers, hookSelector } = mergeCascadingRuleWithScan(parentScan, cascadingRule);
114115

115116
let cascadingChain = getScanChain(parentScan);
116117

@@ -142,6 +143,7 @@ function getCascadingScan(
142143
]
143144
},
144145
spec: {
146+
hookSelector,
145147
scanType,
146148
parameters,
147149
cascades: parentScan.spec.cascades,
@@ -158,8 +160,8 @@ function mergeCascadingRuleWithScan(
158160
cascadingRule: CascadingRule
159161
) {
160162
const { scanAnnotations, scanLabels } = cascadingRule.spec;
161-
let { env = [], volumes = [], volumeMounts = [], initContainers = [] } = cascadingRule.spec.scanSpec;
162-
let { inheritAnnotations, inheritLabels, inheritEnv, inheritVolumes, inheritInitContainers } = scan.spec.cascades;
163+
let { env = [], volumes = [], volumeMounts = [], initContainers = [], hookSelector = {} } = cascadingRule.spec.scanSpec;
164+
let { inheritAnnotations, inheritLabels, inheritEnv, inheritVolumes, inheritInitContainers, inheritHookSelector } = scan.spec.cascades;
163165

164166
return {
165167
annotations: mergeInheritedMap(scan.metadata.annotations, scanAnnotations, inheritAnnotations),
@@ -168,6 +170,7 @@ function mergeCascadingRuleWithScan(
168170
volumes: mergeInheritedArray(scan.spec.volumes, volumes, inheritVolumes),
169171
volumeMounts: mergeInheritedArray(scan.spec.volumeMounts, volumeMounts, inheritVolumes),
170172
initContainers: mergeInheritedArray(scan.spec.initContainers, initContainers, inheritInitContainers),
173+
hookSelector: mergeInheritedSelector(scan.spec.hookSelector, hookSelector, inheritHookSelector),
171174
}
172175
}
173176

hooks/cascading-scans/hook/kubernetes-label-selector.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export interface LabelSelectorRequirement {
1919
}
2020

2121
export interface LabelSelector {
22-
matchExpressions: Array<LabelSelectorRequirement>;
23-
matchLabels: Map<string, string>;
22+
matchExpressions?: Array<LabelSelectorRequirement>;
23+
matchLabels?: Map<string, string>;
2424
}
2525

2626
// generateSelectorString transforms a kubernetes labelSelector object in to the string representation

hooks/cascading-scans/hook/scan-helpers.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export interface ScanSpec {
6262
volumes?: Array<k8s.V1Volume>;
6363
volumeMounts?: Array<k8s.V1VolumeMount>;
6464
initContainers?: Array<k8s.V1Container>;
65+
hookSelector?: LabelSelector;
6566
}
6667

6768
export interface CascadingInheritance {
@@ -70,6 +71,7 @@ export interface CascadingInheritance {
7071
inheritEnv: boolean,
7172
inheritVolumes: boolean,
7273
inheritInitContainers: boolean,
74+
inheritHookSelector: boolean,
7375
}
7476

7577
export function mergeInheritedMap(parentProps, ruleProps, inherit: boolean = true) {
@@ -89,6 +91,17 @@ export function mergeInheritedArray(parentArray, ruleArray, inherit: boolean = f
8991
return (parentArray || []).concat(ruleArray) // CascadingRule's env overwrites scan's env
9092
}
9193

94+
export function mergeInheritedSelector(parentSelector: LabelSelector = {}, ruleSelector: LabelSelector = {}, inherit: boolean = true): LabelSelector {
95+
let labelSelector: LabelSelector = {};
96+
if (parentSelector.matchExpressions || ruleSelector.matchExpressions) {
97+
labelSelector.matchExpressions = mergeInheritedArray(parentSelector.matchExpressions, ruleSelector.matchExpressions, inherit);
98+
}
99+
if (parentSelector.matchLabels || ruleSelector.matchLabels) {
100+
labelSelector.matchLabels = mergeInheritedMap(parentSelector.matchLabels, ruleSelector.matchLabels, inherit);
101+
}
102+
return labelSelector
103+
}
104+
92105
export async function startSubsequentSecureCodeBoxScan(scan: Scan) {
93106
console.log(`Starting Scan ${scan.metadata.name}`);
94107

operator/apis/execution/v1/scan_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ type CascadeSpec struct {
3939
// +kubebuilder:default=false
4040
InheritInitContainers bool `json:"inheritInitContainers"`
4141

42+
// InheritHookSelector defines whether cascading scans should inherit hookSelector from the parent scan.
43+
// +optional
44+
// +kubebuilder:default=true
45+
InheritHookSelector bool `json:"inheritHookSelector"`
46+
4247
// matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
4348
// map is equivalent to an element of matchExpressions, whose key field is "key", the
4449
// operator is "In", and the values array contains only "value". The requirements are ANDed.

operator/config/crd/bases/cascading.securecodebox.io_cascadingrules.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ spec:
114114
description: InheritEnv defines whether cascading scans should
115115
inherit environment variables from the parent scan
116116
type: boolean
117+
inheritHookSelector:
118+
default: true
119+
description: InheritHookSelector defines whether cascading
120+
scans should inherit hookSelector from the parent scan.
121+
type: boolean
117122
inheritInitContainers:
118123
default: false
119124
description: InheritInitContainers defines whether cascading

operator/config/crd/bases/execution.securecodebox.io_scans.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ spec:
7676
description: InheritEnv defines whether cascading scans should
7777
inherit environment variables from the parent scan
7878
type: boolean
79+
inheritHookSelector:
80+
default: true
81+
description: InheritHookSelector defines whether cascading scans
82+
should inherit hookSelector from the parent scan.
83+
type: boolean
7984
inheritInitContainers:
8085
default: false
8186
description: InheritInitContainers defines whether cascading scans

operator/config/crd/bases/execution.securecodebox.io_scheduledscans.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ spec:
9696
description: InheritEnv defines whether cascading scans should
9797
inherit environment variables from the parent scan
9898
type: boolean
99+
inheritHookSelector:
100+
default: true
101+
description: InheritHookSelector defines whether cascading
102+
scans should inherit hookSelector from the parent scan.
103+
type: boolean
99104
inheritInitContainers:
100105
default: false
101106
description: InheritInitContainers defines whether cascading

operator/crds/cascading.securecodebox.io_cascadingrules.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ spec:
114114
description: InheritEnv defines whether cascading scans should
115115
inherit environment variables from the parent scan
116116
type: boolean
117+
inheritHookSelector:
118+
default: true
119+
description: InheritHookSelector defines whether cascading
120+
scans should inherit hookSelector from the parent scan.
121+
type: boolean
117122
inheritInitContainers:
118123
default: false
119124
description: InheritInitContainers defines whether cascading

operator/crds/execution.securecodebox.io_scans.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ spec:
7676
description: InheritEnv defines whether cascading scans should
7777
inherit environment variables from the parent scan
7878
type: boolean
79+
inheritHookSelector:
80+
default: true
81+
description: InheritHookSelector defines whether cascading scans
82+
should inherit hookSelector from the parent scan.
83+
type: boolean
7984
inheritInitContainers:
8085
default: false
8186
description: InheritInitContainers defines whether cascading scans

0 commit comments

Comments
 (0)