snyk-docker-plugin
Version:
Snyk CLI docker plugin
145 lines • 7.28 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractContent = exports.appendLatestTagIfMissing = exports.scan = exports.mergeEnvVarsIntoCredentials = void 0;
const fs = require("fs");
const path = require("path");
const image_inspector_1 = require("./analyzer/image-inspector");
const dockerfile_1 = require("./dockerfile");
const extractor_1 = require("./extractor");
const image_1 = require("./extractor/image");
const image_save_path_1 = require("./image-save-path");
const image_type_1 = require("./image-type");
const option_utils_1 = require("./option-utils");
const staticModule = require("./static");
const types_1 = require("./types");
// Registry credentials may also be provided by env vars. When both are set, flags take precedence.
function mergeEnvVarsIntoCredentials(options) {
options.username = options.username || process.env.SNYK_REGISTRY_USERNAME;
options.password = options.password || process.env.SNYK_REGISTRY_PASSWORD;
}
exports.mergeEnvVarsIntoCredentials = mergeEnvVarsIntoCredentials;
async function getAnalysisParameters(options) {
if (!options) {
throw new Error("No plugin options provided");
}
mergeEnvVarsIntoCredentials(options);
if (!options.path) {
throw new Error("No image identifier or path provided");
}
const nestedJarsDepth = options["nested-jars-depth"] || options["shaded-jars-depth"];
if (((0, option_utils_1.isTrue)(nestedJarsDepth) || (0, option_utils_1.isNumber)(nestedJarsDepth)) &&
(0, option_utils_1.isTrue)(options["exclude-app-vulns"])) {
throw new Error("To use --nested-jars-depth, you must not use --exclude-app-vulns");
}
if ((!(0, option_utils_1.isNumber)(nestedJarsDepth) &&
!(0, option_utils_1.isTrue)(nestedJarsDepth) &&
typeof nestedJarsDepth !== "undefined") ||
Number(nestedJarsDepth) < 0) {
throw new Error("--nested-jars-depth accepts only numbers bigger than or equal to 0");
}
// TODO temporary solution to avoid double results for PHP if exists in `globsToFind`
if (options.globsToFind) {
options.globsToFind.include = options.globsToFind.include.filter((glob) => !glob.includes("composer"));
}
const targetImage = appendLatestTagIfMissing(options.path);
const dockerfilePath = options.file;
const dockerfileAnalysis = await (0, dockerfile_1.readDockerfileAndAnalyse)(dockerfilePath);
const imageType = (0, image_type_1.getImageType)(targetImage);
return {
targetImage,
imageType,
dockerfileAnalysis,
options,
};
}
async function scan(options) {
const { targetImage, imageType, dockerfileAnalysis, options: updatedOptions, } = await getAnalysisParameters(options);
switch (imageType) {
case types_1.ImageType.DockerArchive:
case types_1.ImageType.OciArchive:
case types_1.ImageType.KanikoArchive:
case types_1.ImageType.UnspecifiedArchiveType:
return localArchiveAnalysis(targetImage, imageType, dockerfileAnalysis, updatedOptions);
case types_1.ImageType.Identifier:
return imageIdentifierAnalysis(targetImage, imageType, dockerfileAnalysis, updatedOptions);
default:
throw new Error("Unhandled image type for image " + targetImage);
}
}
exports.scan = scan;
function getAndValidateArchivePath(targetImage) {
const archivePath = (0, image_type_1.getArchivePath)(targetImage);
if (!fs.existsSync(archivePath)) {
throw new Error("The provided archive path does not exist on the filesystem");
}
if (!fs.lstatSync(archivePath).isFile()) {
throw new Error("The provided archive path is not a file");
}
return archivePath;
}
async function localArchiveAnalysis(targetImage, imageType, dockerfileAnalysis, options) {
var _a, _b, _c, _d, _e, _f;
const globToFind = {
include: ((_a = options.globsToFind) === null || _a === void 0 ? void 0 : _a.include) || [],
exclude: ((_b = options.globsToFind) === null || _b === void 0 ? void 0 : _b.exclude) || [],
};
const archivePath = getAndValidateArchivePath(targetImage);
const imageIdentifier = options.imageNameAndTag ||
// The target image becomes the base of the path, e.g. "archive.tar" for "/var/tmp/archive.tar"
path.basename(archivePath);
let imageName;
if ((((_c = options.digests) === null || _c === void 0 ? void 0 : _c.manifest) || ((_d = options.digests) === null || _d === void 0 ? void 0 : _d.index)) &&
options.imageNameAndTag) {
imageName = new image_1.ImageName(options.imageNameAndTag, {
manifest: (_e = options.digests) === null || _e === void 0 ? void 0 : _e.manifest,
index: (_f = options.digests) === null || _f === void 0 ? void 0 : _f.index,
});
}
return await staticModule.analyzeStatically(imageIdentifier, dockerfileAnalysis, imageType, archivePath, globToFind, options, imageName);
}
async function imageIdentifierAnalysis(targetImage, imageType, dockerfileAnalysis, options) {
var _a, _b;
const globToFind = {
include: ((_a = options.globsToFind) === null || _a === void 0 ? void 0 : _a.include) || [],
exclude: ((_b = options.globsToFind) === null || _b === void 0 ? void 0 : _b.exclude) || [],
};
const imageSavePath = (0, image_save_path_1.fullImageSavePath)(options.imageSavePath);
const archiveResult = await (0, image_inspector_1.getImageArchive)(targetImage, imageSavePath, options.username, options.password, options.platform);
const imagePath = archiveResult.path;
const imageName = archiveResult.imageName;
try {
return await staticModule.analyzeStatically(targetImage, dockerfileAnalysis, imageType, imagePath, globToFind, options, imageName);
}
finally {
archiveResult.removeArchive();
}
}
function appendLatestTagIfMissing(targetImage) {
if ((0, image_type_1.getImageType)(targetImage) === types_1.ImageType.Identifier &&
!targetImage.includes(":")) {
return `${targetImage}:latest`;
}
return targetImage;
}
exports.appendLatestTagIfMissing = appendLatestTagIfMissing;
async function extractContent(extractActions, options) {
const { targetImage, imageType, options: updatedOptions, } = await getAnalysisParameters(options);
const { username, password, platform, imageSavePath } = updatedOptions;
let imagePath;
switch (imageType) {
case types_1.ImageType.DockerArchive:
case types_1.ImageType.OciArchive:
imagePath = getAndValidateArchivePath(targetImage);
break;
case types_1.ImageType.Identifier:
const imageSavePathFull = (0, image_save_path_1.fullImageSavePath)(imageSavePath);
const archiveResult = await (0, image_inspector_1.getImageArchive)(targetImage, imageSavePathFull, username, password, platform);
imagePath = archiveResult.path;
break;
default:
throw new Error("Unhandled image type for image " + targetImage);
}
return (0, extractor_1.extractImageContent)(imageType, imagePath, extractActions, updatedOptions);
}
exports.extractContent = extractContent;
//# sourceMappingURL=scan.js.map
;