Skip to content

Commit b1dc1c4

Browse files
authored
Merge pull request #1174 from snyk/fix/return-pod-image-metadata-for-unsupported-workload-kind
fix: return pod image metadata for unsupported workload
2 parents 27e446b + 9d31fca commit b1dc1c4

File tree

7 files changed

+406
-12
lines changed

7 files changed

+406
-12
lines changed

src/scanner/images/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,30 @@ const statAsync = promisify(stat);
2323
*/
2424
async function pullImageBySkopeoRepo(
2525
imageToPull: IPullableImage,
26+
workloadName: string,
2627
): Promise<IPullableImage> {
2728
// Scan image by digest if exists, other way fallback tag
2829
const scanId = imageToPull.imageWithDigest ?? imageToPull.imageName;
2930
await skopeoCopy(
3031
scanId,
3132
imageToPull.fileSystemPath,
3233
imageToPull.skopeoRepoType,
34+
workloadName,
3335
);
3436
return imageToPull;
3537
}
3638

3739
export async function pullImages(
3840
images: IPullableImage[],
41+
workloadName: string,
3942
): Promise<IPullableImage[]> {
4043
const pulledImages: IPullableImage[] = [];
4144
for (const image of images) {
4245
if (!image.fileSystemPath) {
4346
continue;
4447
}
4548
try {
46-
const pulledImage = await pullImageBySkopeoRepo(image);
49+
const pulledImage = await pullImageBySkopeoRepo(image, workloadName);
4750
pulledImages.push(pulledImage);
4851
} catch (error) {
4952
logger.error(

src/scanner/images/skopeo.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export async function pull(
3636
image: string,
3737
destination: string,
3838
skopeoRepoType: SkopeoRepositoryType,
39+
workloadName: string,
3940
): Promise<void> {
4041
const creds = await credentials.getSourceCredentials(image);
4142
const credentialsParameters = getCredentialParameters(creds);
@@ -56,12 +57,13 @@ export async function pull(
5657
sanitise: false,
5758
});
5859

59-
await pullWithRetry(args, destination);
60+
await pullWithRetry(args, destination, workloadName);
6061
}
6162

6263
async function pullWithRetry(
6364
args: Array<processWrapper.IProcessArgument>,
6465
destination: string,
66+
workloadName: string,
6567
): Promise<void> {
6668
const MAX_ATTEMPTS = 10;
6769
const RETRY_INTERVAL_SEC = 0.2;
@@ -77,7 +79,7 @@ async function pullWithRetry(
7779
}
7880
} catch (deleteErr) {
7981
logger.warn(
80-
{ error: deleteErr, destination },
82+
{ workloadName, error: deleteErr, destination },
8183
'could not clean up the Skopeo-copy archive',
8284
);
8385
}

src/scanner/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export async function processWorkload(
4141
);
4242
const imagesWithFileSystemPath = getImagesWithFileSystemPath(uniqueImages);
4343
const imagePullStartTimestampMs = Date.now();
44-
const pulledImages = await pullImages(imagesWithFileSystemPath);
44+
const pulledImages = await pullImages(imagesWithFileSystemPath, workloadName);
4545
const imagePullDurationMs = Date.now() - imagePullStartTimestampMs;
4646
if (pulledImages.length === 0) {
4747
logger.info(

src/supervisor/metadata-extractor.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ export function buildImageMetadata(
2626
const { name, namespace, labels, annotations, uid } = objectMeta;
2727

2828
const containerNameToSpec: { [key: string]: V1Container } = {};
29-
for (const container of podSpec.containers) {
30-
delete container.args;
31-
delete container.env;
32-
delete container.command;
33-
//! would container.envFrom also include sensitive data?
34-
containerNameToSpec[container.name] = container;
29+
if (podSpec.containers) {
30+
for (const container of podSpec.containers) {
31+
delete container.args;
32+
delete container.env;
33+
delete container.command;
34+
//! would container.envFrom also include sensitive data?
35+
containerNameToSpec[container.name] = container;
36+
}
3537
}
3638

3739
const containerNameToStatus: { [key: string]: V1ContainerStatus } = {};
@@ -212,6 +214,29 @@ export async function buildMetadataForWorkload(
212214
pod.metadata.namespace,
213215
);
214216

217+
const hasNodeOwnerRef = pod.metadata?.ownerReferences?.find(
218+
(owner) => owner.kind === 'Node',
219+
);
220+
221+
if (hasNodeOwnerRef && podOwner === undefined) {
222+
logger.info(
223+
{ podMetadata: pod.metadata },
224+
'pod associated with owner, but owner not found. returning pod metadata.',
225+
);
226+
return buildImageMetadata(
227+
{
228+
kind: 'Pod', // Reading pod.kind may be undefined, so use this
229+
objectMeta: pod.metadata,
230+
// Notice the pod.metadata repeats; this is because pods
231+
// do not have the "template" property.
232+
specMeta: pod.metadata,
233+
ownerRefs: [],
234+
podSpec: pod.spec,
235+
},
236+
pod.status.containerStatuses,
237+
);
238+
}
239+
215240
if (podOwner === undefined) {
216241
logger.info(
217242
{ podMetadata: pod.metadata },

0 commit comments

Comments
 (0)