Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.

Commit 0a4881e

Browse files
committed
Add basic nmap integration test
1 parent 4edffde commit 0a4881e

File tree

5 files changed

+5177
-0
lines changed

5 files changed

+5177
-0
lines changed

.github/workflows/ci.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ jobs:
216216
- name: "Install Test Dependencies"
217217
run: |
218218
npm ci
219+
- name: "Nmap Integration Tests"
220+
run: |
221+
kubectl apply -f integrations/nmap/nmap-scan-type.yaml -f integrations/nmap/nmap-parse-definition.yaml
222+
cd tests/integration/
223+
npx jest --ci --color nmap
219224
- name: "Delete kind cluster"
220225
run: |
221226
kind delete cluster

tests/integration/helpers.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
const k8s = require("@kubernetes/client-node");
2+
3+
const kc = new k8s.KubeConfig();
4+
kc.loadFromDefault();
5+
6+
const k8sCRDApi = kc.makeApiClient(k8s.CustomObjectsApi);
7+
8+
const namespace = "integration-tests";
9+
10+
const sleep = duration =>
11+
new Promise(resolve => setTimeout(resolve, duration * 1000));
12+
13+
async function deleteScan(name) {
14+
await k8sCRDApi.deleteNamespacedCustomObject(
15+
"execution.experimental.securecodebox.io",
16+
"v1",
17+
namespace,
18+
"scans",
19+
name,
20+
{}
21+
);
22+
}
23+
24+
/**
25+
*
26+
* @param {string} name name of the scan. Actual name will be sufixed with a random number to avoid conflicts
27+
* @param {string} scanType type of the scan. Must match the name of a ScanType CRD
28+
* @param {string[]} parameters cli argument to be passed to the scanner
29+
* @param {number} timeout in seconds
30+
*/
31+
async function scan(name, scanType, parameters = [], timeout = 180) {
32+
const scanDefinition = {
33+
apiVersion: "execution.experimental.securecodebox.io/v1",
34+
kind: "Scan",
35+
metadata: {
36+
// Use `generateName` instead of name to generate a random sufix and avoid name clashes
37+
generateName: `${name}-`
38+
},
39+
spec: {
40+
scanType,
41+
parameters
42+
}
43+
};
44+
45+
const { body } = await k8sCRDApi.createNamespacedCustomObject(
46+
"execution.experimental.securecodebox.io",
47+
"v1",
48+
namespace,
49+
"scans",
50+
scanDefinition
51+
);
52+
53+
const actualName = body.metadata.name;
54+
55+
for (let i = 0; i < timeout; i++) {
56+
await sleep(1);
57+
58+
const { body } = await k8sCRDApi.getNamespacedCustomObjectStatus(
59+
"execution.experimental.securecodebox.io",
60+
"v1",
61+
namespace,
62+
"scans",
63+
actualName
64+
);
65+
66+
const scanStatus = body.status;
67+
68+
if (scanStatus && scanStatus.state === "Done") {
69+
await deleteScan(actualName);
70+
return scanStatus.findings;
71+
}
72+
}
73+
74+
throw new Error("timed out while waiting for scan results");
75+
}
76+
77+
module.exports.scan = scan;

tests/integration/nmap.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const { scan } = require('./helpers')
2+
3+
test(
4+
"localhost port scan should only find a host finding",
5+
async () => {
6+
const { categories, severities, count } = await scan(
7+
"nmap-localhost",
8+
"nmap",
9+
["localhost"]
10+
);
11+
12+
expect(count).toBe(1);
13+
expect(categories).toMatchInlineSnapshot(`
14+
Object {
15+
"Host": 1,
16+
}
17+
`);
18+
expect(severities).toMatchInlineSnapshot(`
19+
Object {
20+
"informational": 1,
21+
}
22+
`);
23+
},
24+
3 * 60 * 1000
25+
);

0 commit comments

Comments
 (0)