Skip to content

Commit 8f537df

Browse files
authored
Merge pull request #602 from snyk/feat/podspec-from-pods
Feat/podspec from pods
2 parents 62418dd + 5e4599c commit 8f537df

File tree

6 files changed

+46
-28
lines changed

6 files changed

+46
-28
lines changed

src/supervisor/metadata-extractor.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { V1OwnerReference, V1Pod, V1Container, V1ContainerStatus } from '@kubernetes/client-node';
1+
import { V1OwnerReference, V1Pod, V1Container, V1ContainerStatus, V1PodSpec } from '@kubernetes/client-node';
22
import { IWorkload, ILocalWorkloadLocator } from '../transmitter/types';
33
import { currentClusterName } from './cluster';
44
import { IKubeObjectMetadata } from './types';
@@ -53,6 +53,7 @@ export function buildImageMetadata(
5353
}
5454

5555
async function findParentWorkload(
56+
podSpec: V1PodSpec,
5657
ownerRefs: V1OwnerReference[] | undefined,
5758
namespace: string,
5859
): Promise<IKubeObjectMetadata | undefined> {
@@ -69,9 +70,14 @@ async function findParentWorkload(
6970
}
7071

7172
const workloadReader = getWorkloadReader(supportedWorkload.kind);
72-
let nextParentMetadata: IKubeObjectMetadata | undefined;
7373
try {
74-
nextParentMetadata = await workloadReader(supportedWorkload.name, namespace);
74+
const workloadMetadata = await workloadReader(supportedWorkload.name, namespace);
75+
if (workloadMetadata === undefined) {
76+
// Could not extract data for the next parent, so return whatever we have so far.
77+
return parentMetadata;
78+
}
79+
parentMetadata = { ...workloadMetadata, podSpec };
80+
ownerReferences = parentMetadata.ownerRefs;
7581
} catch (err) {
7682
if (
7783
err &&
@@ -87,14 +93,6 @@ async function findParentWorkload(
8793
}
8894
throw err;
8995
}
90-
91-
if (nextParentMetadata === undefined) {
92-
// Could not extract data for the next parent, so return whatever we have so far.
93-
return parentMetadata;
94-
}
95-
96-
parentMetadata = nextParentMetadata;
97-
ownerReferences = parentMetadata.ownerRefs;
9896
}
9997

10098
return undefined;
@@ -151,7 +149,7 @@ export async function buildMetadataForWorkload(pod: V1Pod): Promise<IWorkload[]
151149
}
152150

153151
const podOwner: IKubeObjectMetadata | undefined = await findParentWorkload(
154-
pod.metadata.ownerReferences, pod.metadata.namespace);
152+
pod.spec, pod.metadata.ownerReferences, pod.metadata.namespace);
155153

156154
if (podOwner === undefined) {
157155
logger.info({pod}, 'pod associated with owner, but owner not found. not building metadata.');

src/supervisor/watchers/internal-namespaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export const kubernetesInternalNamespaces = [
22
'kube-node-lease',
33
'kube-public',
44
'kube-system',
5+
'local-path-storage',
56
'openshift',
67
'openshift-apiserver',
78
'openshift-apiserver-operator',

src/supervisor/workload-reader.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import { k8sApi } from './cluster';
55
import { IKubeObjectMetadata, WorkloadKind } from './types';
66
import logger = require('../common/logger');
77

8+
type IKubeObjectMetadataWithoutPodSpec = Omit<IKubeObjectMetadata, 'podSpec'>;
89
type IWorkloadReaderFunc = (
910
workloadName: string,
1011
namespace: string,
11-
) => Promise<IKubeObjectMetadata | undefined>;
12+
) => Promise<IKubeObjectMetadataWithoutPodSpec | undefined>;
1213

1314
const deploymentReader: IWorkloadReaderFunc = async (workloadName, namespace) => {
1415
const deploymentResult = await kubernetesApiWrappers.retryKubernetesApiRequest(
@@ -22,14 +23,14 @@ const deploymentReader: IWorkloadReaderFunc = async (workloadName, namespace) =>
2223
return undefined;
2324
}
2425

25-
return {
26+
const metadata: IKubeObjectMetadataWithoutPodSpec = {
2627
kind: WorkloadKind.Deployment,
2728
objectMeta: deployment.metadata,
2829
specMeta: deployment.spec.template.metadata,
2930
ownerRefs: deployment.metadata.ownerReferences,
3031
revision: deployment.status.observedGeneration,
31-
podSpec: deployment.spec.template.spec,
3232
};
33+
return metadata;
3334
};
3435

3536
const replicaSetReader: IWorkloadReaderFunc = async (workloadName, namespace) => {
@@ -44,14 +45,14 @@ const replicaSetReader: IWorkloadReaderFunc = async (workloadName, namespace) =>
4445
return undefined;
4546
}
4647

47-
return {
48+
const metadata: IKubeObjectMetadataWithoutPodSpec = {
4849
kind: WorkloadKind.ReplicaSet,
4950
objectMeta: replicaSet.metadata,
5051
specMeta: replicaSet.spec.template.metadata,
5152
ownerRefs: replicaSet.metadata.ownerReferences,
5253
revision: replicaSet.status.observedGeneration,
53-
podSpec: replicaSet.spec.template.spec,
5454
};
55+
return metadata;
5556
};
5657

5758
const statefulSetReader: IWorkloadReaderFunc = async (workloadName, namespace) => {
@@ -66,14 +67,14 @@ const statefulSetReader: IWorkloadReaderFunc = async (workloadName, namespace) =
6667
return undefined;
6768
}
6869

69-
return {
70+
const metadata: IKubeObjectMetadataWithoutPodSpec = {
7071
kind: WorkloadKind.StatefulSet,
7172
objectMeta: statefulSet.metadata,
7273
specMeta: statefulSet.spec.template.metadata,
7374
ownerRefs: statefulSet.metadata.ownerReferences,
7475
revision: statefulSet.status.observedGeneration,
75-
podSpec: statefulSet.spec.template.spec,
7676
};
77+
return metadata;
7778
};
7879

7980
const daemonSetReader: IWorkloadReaderFunc = async (workloadName, namespace) => {
@@ -88,14 +89,14 @@ const daemonSetReader: IWorkloadReaderFunc = async (workloadName, namespace) =>
8889
return undefined;
8990
}
9091

91-
return {
92+
const metadata: IKubeObjectMetadataWithoutPodSpec = {
9293
kind: WorkloadKind.DaemonSet,
9394
objectMeta: daemonSet.metadata,
9495
specMeta: daemonSet.spec.template.metadata,
9596
ownerRefs: daemonSet.metadata.ownerReferences,
9697
revision: daemonSet.status.observedGeneration,
97-
podSpec: daemonSet.spec.template.spec,
9898
};
99+
return metadata;
99100
};
100101

101102
const jobReader: IWorkloadReaderFunc = async (workloadName, namespace) => {
@@ -109,13 +110,13 @@ const jobReader: IWorkloadReaderFunc = async (workloadName, namespace) => {
109110
return undefined;
110111
}
111112

112-
return {
113+
const metadata: IKubeObjectMetadataWithoutPodSpec = {
113114
kind: WorkloadKind.Job,
114115
objectMeta: job.metadata,
115116
specMeta: job.spec.template.metadata,
116117
ownerRefs: job.metadata.ownerReferences,
117-
podSpec: job.spec.template.spec,
118118
};
119+
return metadata;
119120
};
120121

121122
// Keep an eye on this! We need v1beta1 API for CronJobs.
@@ -133,13 +134,13 @@ const cronJobReader: IWorkloadReaderFunc = async (workloadName, namespace) => {
133134
return undefined;
134135
}
135136

136-
return {
137+
const metadata: IKubeObjectMetadataWithoutPodSpec = {
137138
kind: WorkloadKind.CronJob,
138139
objectMeta: cronJob.metadata,
139140
specMeta: cronJob.spec.jobTemplate.metadata,
140141
ownerRefs: cronJob.metadata.ownerReferences,
141-
podSpec: cronJob.spec.jobTemplate.spec.template.spec,
142142
};
143+
return metadata;
143144
};
144145

145146
const replicationControllerReader: IWorkloadReaderFunc = async (workloadName, namespace) => {
@@ -155,14 +156,14 @@ const replicationControllerReader: IWorkloadReaderFunc = async (workloadName, na
155156
return undefined;
156157
}
157158

158-
return {
159+
const metadata: IKubeObjectMetadataWithoutPodSpec = {
159160
kind: WorkloadKind.ReplicationController,
160161
objectMeta: replicationController.metadata,
161162
specMeta: replicationController.spec.template.metadata,
162163
ownerRefs: replicationController.metadata.ownerReferences,
163164
revision: replicationController.status.observedGeneration,
164-
podSpec: replicationController.spec.template.spec,
165165
};
166+
return metadata;
166167
};
167168

168169
function logIncompleteWorkload(workloadName: string, namespace: string): void {

test/fixtures/java-deployment.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,12 @@ spec:
2121
name: java
2222
command: ['/bin/sleep']
2323
args: ['9999999']
24-
securityContext: {}
24+
securityContext:
25+
privileged: false
26+
capabilities:
27+
drop:
28+
- ALL
29+
resources:
30+
limits:
31+
cpu: '1'
32+
memory: '1Gi'

test/system/kind.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ tap.test('Kubernetes-Monitor with KinD', async (t) => {
105105
'all properties are present in the workload metadata',
106106
);
107107
t.ok('agentId' in requestBody, 'agent ID is present in workload payload');
108+
109+
const podSpec = requestBody.workloadMetadata.podSpec;
110+
const resources = podSpec.containers[0].resources;
111+
t.same(resources?.limits, { cpu: '1', memory: '1Gi' });
112+
113+
const securityContext = podSpec.containers[0].securityContext;
114+
t.same(securityContext?.privileged, false);
115+
t.same(securityContext?.capabilities?.drop, ['ALL']);
108116
});
109117

110118
nock('https://kubernetes-upstream.snyk.io')

test/unit/supervisor/watchers.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ tap.test('isKubernetesInternalNamespace', async (t) => {
3232
'kube-public is a k8s internal namespace');
3333
t.ok(watchers.isKubernetesInternalNamespace('kube-system'),
3434
'kube-system is a k8s internal namespace');
35+
t.ok(watchers.isKubernetesInternalNamespace('local-path-storage'),
36+
'local-path-storage is a k8s internal namespace');
3537
t.ok(watchers.isKubernetesInternalNamespace('openshift-apiserver'),
3638
'openshift-apiserver is a k8s internal namespace');
3739
t.ok(watchers.isKubernetesInternalNamespace('openshift-apiserver-operator'),

0 commit comments

Comments
 (0)