Skip to content

Commit

Permalink
feat: Extract labels from docker-archive images
Browse files Browse the repository at this point in the history
Extract all image labels from docker-archive based images from their
image config and include them in the scan result.
  • Loading branch information
hisenb3rg committed Feb 9, 2021
1 parent 727ced7 commit 5aed530
Show file tree
Hide file tree
Showing 19 changed files with 169 additions and 3 deletions.
2 changes: 2 additions & 0 deletions lib/analyzer/static-analyzer.ts
Expand Up @@ -93,6 +93,7 @@ export async function analyze(
rootFsLayers,
autoDetectedUserInstructions,
platform,
imageLabels,
} = await archiveExtractor.extractImageContent(
imageType,
imagePath,
Expand Down Expand Up @@ -175,6 +176,7 @@ export async function analyze(
applicationDependenciesScanResults,
manifestFiles,
autoDetectedUserInstructions,
imageLabels,
};
}

Expand Down
1 change: 1 addition & 0 deletions lib/analyzer/types.ts
Expand Up @@ -77,6 +77,7 @@ export interface StaticAnalysis {
autoDetectedUserInstructions?: DockerFileAnalysis;
applicationDependenciesScanResults: AppDepsScanResultWithoutTarget[];
manifestFiles: ManifestFile[];
imageLabels?: { [key: string]: string };
}

export interface ArchiveResult {
Expand Down
2 changes: 2 additions & 0 deletions lib/extractor/index.ts
Expand Up @@ -31,6 +31,7 @@ export async function extractImageContent(
imageId: ociExtractor.getImageIdFromManifest(ociArchive.manifest),
manifestLayers: ociExtractor.getManifestLayers(ociArchive.manifest),
extractedLayers: layersWithLatestFileModifications(ociArchive.layers),
imageLabels: {},
};
default:
const dockerArchive = await dockerExtractor.extractArchive(
Expand All @@ -55,6 +56,7 @@ export async function extractImageContent(
platform: dockerExtractor.getPlatformFromConfig(
dockerArchive.imageConfig,
),
imageLabels: dockerArchive.imageConfig.config.Labels,
};
}
}
Expand Down
4 changes: 4 additions & 0 deletions lib/extractor/types.ts
Expand Up @@ -18,6 +18,7 @@ export interface ExtractionResult {
rootFsLayers?: string[];
autoDetectedUserInstructions?: DockerFileAnalysis;
platform?: string;
imageLabels: { [key: string]: string };
}

export interface ExtractedLayers {
Expand All @@ -42,6 +43,9 @@ export interface DockerArchiveImageConfig {
architecture: string;
os: string;
rootfs: { diff_ids: string[] };
config: {
Labels: { [key: string]: string };
};
}

export interface OciArchiveLayer {
Expand Down
7 changes: 7 additions & 0 deletions lib/facts.ts
Expand Up @@ -60,3 +60,10 @@ export interface JarFingerprintsFact {
path: string;
};
}

export interface ImageLabels {
type: "imageLabels";
data: {
[key: string]: string;
};
}
8 changes: 8 additions & 0 deletions lib/response-builder.ts
Expand Up @@ -69,6 +69,14 @@ async function buildResponse(
additionalOsDepsFacts.push(imageLayersFact);
}

if (depsAnalysis.imageLabels) {
const imageLabels: facts.ImageLabels = {
type: "imageLabels",
data: depsAnalysis.imageLabels,
};
additionalOsDepsFacts.push(imageLabels);
}

if (
depsAnalysis.rootFsLayers &&
Array.isArray(depsAnalysis.rootFsLayers) &&
Expand Down
3 changes: 2 additions & 1 deletion lib/types.ts
Expand Up @@ -51,7 +51,8 @@ export type FactType =
| "testedFiles"
// Hashes of extracted *.jar binaries, hashed with sha1 algorithm
| "jarFingerprints"
| "autoDetectedUserInstructions";
| "autoDetectedUserInstructions"
| "imageLabels";

export interface PluginResponse {
/** The first result is guaranteed to be the OS dependencies scan result. */
Expand Down
14 changes: 12 additions & 2 deletions test/lib/extractor/extractor.spec.ts
Expand Up @@ -4,13 +4,17 @@ import { ImageType } from "../../../lib/types";
import { getFixture } from "../../util/index";

describe("extractImageContent", () => {
it("extracts red hat repositories information from layers", async () => {
const extractedContent = await extractImageContent(
let extractedContent: ExtractionResult;

beforeAll(async () => {
extractedContent = await extractImageContent(
ImageType.DockerArchive,
getFixture("docker-archives/docker-save/nginx-with-buildinfo.tar"),
[getRedHatReposContentAction],
);
});

it("extracts red hat repositories information from layers", async () => {
const numOfFoundFiles = Object.keys(extractedContent.extractedLayers)
.length;
expect(numOfFoundFiles).toBe(1);
Expand All @@ -34,4 +38,10 @@ describe("extractImageContent", () => {
image_contents: [],
});
});

it("extracts image labels", async () => {
expect(extractedContent.imageLabels).toMatchObject({
maintainer: "NGINX Docker Maintainers <docker-maint@nginx.com>",
});
});
});
Expand Up @@ -371,6 +371,12 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {
"version": "none",
},
"type": "imageLabels",
},
Object {
"data": Array [
"sha256:50644c29ef5a27c9a40c393a73ece2479de78325cae7d762ef3cdc19bf42dd0a",
Expand Down
Expand Up @@ -2520,6 +2520,20 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {
"org.label-schema.build-date": "20200504",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS",
"org.opencontainers.image.created": "2020-05-04 00:00:00+01:00",
"org.opencontainers.image.licenses": "GPL-2.0-only",
"org.opencontainers.image.title": "CentOS Base Image",
"org.opencontainers.image.vendor": "CentOS",
},
"type": "imageLabels",
},
Object {
"data": Array [
"sha256:edf3aa290fb3c255a84fe836109093fbfeef65c08544f655fad8d6afb53868ba",
Expand Down
Expand Up @@ -390,6 +390,10 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {},
"type": "imageLabels",
},
Object {
"data": "Alpine Linux v3.12",
"type": "imageOsReleasePrettyName",
Expand Down
Expand Up @@ -1760,6 +1760,12 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>",
},
"type": "imageLabels",
},
Object {
"data": Array [
"sha256:2db44bce66cde56fca25aeeb7d09dc924b748e3adfe58c9cc3eb2bd2f68a1b68",
Expand Down
Expand Up @@ -1760,6 +1760,12 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>",
},
"type": "imageLabels",
},
Object {
"data": Array [
"sha256:1c95c77433e8d7bf0f519c9d8c9ca967e2603f0defbf379130d9a841cca2e28e",
Expand Down
4 changes: 4 additions & 0 deletions test/system/image-type/__snapshots__/oci-archive.spec.ts.snap
Expand Up @@ -368,6 +368,10 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {},
"type": "imageLabels",
},
Object {
"data": "Alpine Linux v3.12",
"type": "imageOsReleasePrettyName",
Expand Down
28 changes: 28 additions & 0 deletions test/system/operating-systems/__snapshots__/centos7.spec.ts.snap
Expand Up @@ -2254,6 +2254,20 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {
"org.label-schema.build-date": "20200504",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS",
"org.opencontainers.image.created": "2020-05-04 00:00:00+01:00",
"org.opencontainers.image.licenses": "GPL-2.0-only",
"org.opencontainers.image.title": "CentOS Base Image",
"org.opencontainers.image.vendor": "CentOS",
},
"type": "imageLabels",
},
Object {
"data": Array [
"sha256:fb82b029bea0a2a3b6a62a9c1e47e57fae2a82f629b2d1a346da4fc8fb53a0b6",
Expand Down Expand Up @@ -4533,6 +4547,20 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {
"org.label-schema.build-date": "20200504",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS",
"org.opencontainers.image.created": "2020-05-04 00:00:00+01:00",
"org.opencontainers.image.licenses": "GPL-2.0-only",
"org.opencontainers.image.title": "CentOS Base Image",
"org.opencontainers.image.vendor": "CentOS",
},
"type": "imageLabels",
},
Object {
"data": Array [
"sha256:fb82b029bea0a2a3b6a62a9c1e47e57fae2a82f629b2d1a346da4fc8fb53a0b6",
Expand Down
Expand Up @@ -2779,6 +2779,17 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {
"org.opencontainers.image.authors": "Oracle Linux Product Team <ol-ovm-info_ww@oracle.com>",
"org.opencontainers.image.description": "Oracle Linux is an open-source operating system available under the GNU General Public License (GPLv2) and is suitable for both general purpose or Oracle workloads.",
"org.opencontainers.image.source": "https://github.com/oracle/container-images/tree/dist-amd64/8.2",
"org.opencontainers.image.title": "Oracle Linux 8",
"org.opencontainers.image.url": "https://github.com/oracle/container-images",
"org.opencontainers.image.vendor": "Oracle America, Inc",
},
"type": "imageLabels",
},
Object {
"data": Array [
"sha256:8f5b0a4c155316ae86167c983db7048fe2db2e9691093b35377eaf9d9b28ecc9",
Expand Down
21 changes: 21 additions & 0 deletions test/system/operating-systems/__snapshots__/sles15.spec.ts.snap
Expand Up @@ -1864,6 +1864,27 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {
"com.suse.sle.base.created": "2020-09-22T16:49:04.451343660Z",
"com.suse.sle.base.description": "Image containing a minimal environment for containers based on SUSE Linux Enterprise Server 15 SP2.",
"com.suse.sle.base.disturl": "obs://build.suse.de/SUSE:SLE-15-SP2:Update:CR/images/4a8871be8078bcef2e2417e2a98fc3a0-sles15-image",
"com.suse.sle.base.reference": "registry.suse.com/suse/sle15:15.2.8.2.751",
"com.suse.sle.base.title": "SUSE Linux Enterprise Server 15 SP2 Base Container",
"com.suse.sle.base.url": "https://www.suse.com/products/server/",
"com.suse.sle.base.vendor": "SUSE LLC",
"com.suse.sle.base.version": "15.2.8.2.751",
"org.openbuildservice.disturl": "obs://build.suse.de/SUSE:SLE-15-SP2:Update:CR/images/4a8871be8078bcef2e2417e2a98fc3a0-sles15-image",
"org.opencontainers.image.created": "2020-09-22T16:49:04.451343660Z",
"org.opencontainers.image.description": "Image containing a minimal environment for containers based on SUSE Linux Enterprise Server 15 SP2.",
"org.opencontainers.image.title": "SUSE Linux Enterprise Server 15 SP2 Base Container",
"org.opencontainers.image.url": "https://www.suse.com/products/server/",
"org.opencontainers.image.vendor": "SUSE LLC",
"org.opencontainers.image.version": "15.2.8.2.751",
"org.opensuse.reference": "registry.suse.com/suse/sle15:15.2.8.2.751",
},
"type": "imageLabels",
},
Object {
"data": Array [
"sha256:0f350a1ede685e83e2220dd2ad17b7b1247cfa80eb6a9f0bbfed83d1e544ed45",
Expand Down
25 changes: 25 additions & 0 deletions test/system/operating-systems/__snapshots__/ubi8.spec.ts.snap
Expand Up @@ -2735,6 +2735,31 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {
"architecture": "x86_64",
"build-date": "2020-09-01T19:43:46.041620",
"com.redhat.build-host": "cpt-1008.osbs.prod.upshift.rdu2.redhat.com",
"com.redhat.component": "ubi8-container",
"com.redhat.license_terms": "https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI",
"description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.",
"distribution-scope": "public",
"io.k8s.description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.",
"io.k8s.display-name": "Red Hat Universal Base Image 8",
"io.openshift.expose-services": "",
"io.openshift.tags": "base rhel8",
"maintainer": "Red Hat, Inc.",
"name": "ubi8",
"release": "347",
"summary": "Provides the latest release of Red Hat Universal Base Image 8.",
"url": "https://access.redhat.com/containers/#/registry.access.redhat.com/ubi8/images/8.2-347",
"vcs-ref": "663db861f0ff7a9c526c1c169a62c14c01a32dcc",
"vcs-type": "git",
"vendor": "Red Hat, Inc.",
"version": "8.2",
},
"type": "imageLabels",
},
Object {
"data": Array [
"sha256:ccf04fbd6e1943f648d1c2980e96038edc02b543c597556098ab2bcaa4fd1fa8",
Expand Down
6 changes: 6 additions & 0 deletions test/system/platforms/__snapshots__/arm.spec.ts.snap
Expand Up @@ -963,6 +963,12 @@ Object {
],
"type": "imageLayers",
},
Object {
"data": Object {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>",
},
"type": "imageLabels",
},
Object {
"data": Array [
"sha256:e2f13739ad415e6f8d9f73253910e4984563a1ec98bd0e0af715fc2c74dfe84b",
Expand Down

0 comments on commit 5aed530

Please sign in to comment.