UNCLASSIFIED

Commit 10bdd738 authored by Zachary Sanders's avatar Zachary Sanders
Browse files

fix pypi regex parse error

parent e0620029
Pipeline #375450 passed with stages
in 15 minutes and 52 seconds
......@@ -73,7 +73,7 @@ function parseUrl(urlString) {
return null;
}
function extractPackageFile(content) {
var _a, _b;
var _a, _b, _c, _d, _e;
const deps = [];
let hasBase = false;
let hasResource = false;
......@@ -100,7 +100,6 @@ function extractPackageFile(content) {
const baseDep = { managerData: { baseResource } };
baseDep.depType = 'ironbank-base';
baseDep.depName = `registry1.dso.mil/ironbank/${String(manifest.args.BASE_IMAGE)}`;
// baseDep.depName = 'registry1.dso.mil/ironbank/' + manifest.args.BASE_IMAGE;
baseDep.datasource = datasourceDocker.id;
baseDep.versioning = dockerVersioning.id;
baseDep.lookupName = `registry1.dso.mil/ironbank/${String(manifest.args.BASE_IMAGE)}`;
......@@ -150,8 +149,8 @@ function extractPackageFile(content) {
// helm
else if (item.url.startsWith('helm://')) {
const regex = new RegExp('helm://(?<registryUrl>.*/)(?<lookupName>.*?)-(?<currentValue>.*?).tgz');
const groups = regex.exec(item.url).groups;
if ((groups === null || groups === void 0 ? void 0 : groups.registryUrl) && groups.lookupName && groups.currentValue) {
const groups = (_c = regex.exec(item.url)) === null || _c === void 0 ? void 0 : _c.groups;
if ((groups === null || groups === void 0 ? void 0 : groups.registryUrl) && (groups === null || groups === void 0 ? void 0 : groups.lookupName) && (groups === null || groups === void 0 ? void 0 : groups.currentValue)) {
logger_1.logger.info(groups.registryUrl);
dep.depType = 'ironbank-helm';
dep.depName = item.name;
......@@ -167,8 +166,8 @@ function extractPackageFile(content) {
// rubygems
else if (item.url.startsWith('https://rubygems.org')) {
const regex = new RegExp('https://(?<registryUrl>.*)/(.*/)(?<lookupName>.*-?)-(?<currentValue>.*?).gem');
const groups = regex.exec(item.url).groups;
if ((groups === null || groups === void 0 ? void 0 : groups.registryUrl) && groups.lookupName && groups.currentValue) {
const groups = (_d = regex.exec(item.url)) === null || _d === void 0 ? void 0 : _d.groups;
if ((groups === null || groups === void 0 ? void 0 : groups.registryUrl) && (groups === null || groups === void 0 ? void 0 : groups.lookupName) && (groups === null || groups === void 0 ? void 0 : groups.currentValue)) {
dep.depType = 'ironbank-rubygems';
dep.depName = groups.lookupName;
dep.lookupName = groups.lookupName;
......@@ -181,9 +180,9 @@ function extractPackageFile(content) {
}
}
else if (item.url.startsWith('https://files.pythonhosted.org')) {
const regex = new RegExp('https://(.*)/(.*)/(.*)/(.*)/(.*)/(?<lookupName>.*?)-(?<version>.*?)-(.*)');
const group = regex.exec(item.url).groups;
if (group.lookupName && group.version) {
const regex = new RegExp('https://(.*)/(.*)/(.*)/(.*)/(.*)/(?<lookupName>.*?)-(?<version>([0-9]+).([0-9]+).([0-9]+))[-|.](.*)');
const group = (_e = regex.exec(item.url)) === null || _e === void 0 ? void 0 : _e.groups;
if ((group === null || group === void 0 ? void 0 : group.lookupName) && (group === null || group === void 0 ? void 0 : group.version)) {
dep.depType = 'ironbank-pypi';
dep.currentDigest = item.validation.value;
dep.currentValue = group.version;
......
This diff is collapsed.
args:
BASE_IMAGE: "opensource/nodejs/nodejs14"
BASE_TAG: "14.16.1"
resources:
- url: "docker://docker.io/jboss/keycloak@sha256:3720b5ace316b5790a58ce838f46e8cd44cedbdb7e35d3866311ddc5a5e71466"
tag: "jboss/keycloak:12.0.3"
- url: "https://github.com/etcd-io/etcd/releases/download/v3.4.8/etcd-v3.4.8-linux-amd64.tar.gz"
filename: etcd.tar.gz
validation:
type: sha256
value: a3a332a68fe8dedf20149c1a4b8746fe8061b72d75d3a5850b17e04de9ed7942
- url: "https://github.com/fluent/fluentd/archive/v1.10.3.tar.gz"
filename: fluentd.tar.gz
validation:
type: sha256
value: c2b5bbb6c2236f73310b22c748e32a88f25288f3e6e1bd272f3dccc6a2322160
- filename: urllib3-1.25.10-py2.py3-none-any.whl
url: https://files.pythonhosted.org/packages/9f/f0/a391d1463ebb1b233795cabfc0ef38d3db4442339de68f847026199e69d7/urllib3-1.25.10-py2.py3-none-any.whl
validation:
type: sha256
value: e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461
- filename: gitlab-triage-1.15.0.gem
url: https://rubygems.org/downloads/gitlab-triage-1.15.0.gem
validation:
type: sha256
value: e516d720a67c9e3447db858775b48f44aae210b184dd96f7a20fe4fbb4022834
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`lib/manager/ironbank/extract extractPackageFile() extracts single image lines 1`] = `
Array [
Object {
"currentValue": "14.16.1",
"datasource": "docker",
"depName": "registry1.dso.mil/ironbank/opensource/nodejs/nodejs14",
"depType": "ironbank-base",
"lookupName": "registry1.dso.mil/ironbank/opensource/nodejs/nodejs14",
"managerData": Object {
"baseResource": Object {
"tag": "14.16.1",
"url": "opensource/nodejs/nodejs14",
},
},
"versioning": "docker",
},
Object {
"currentDigest": "sha256:3720b5ace316b5790a58ce838f46e8cd44cedbdb7e35d3866311ddc5a5e71466",
"currentValue": "12.0.3",
"datasource": "docker",
"depName": "jboss/keycloak",
"depType": "ironbank-docker",
"lookupName": "jboss/keycloak",
"managerData": Object {
"item": Object {
"tag": "jboss/keycloak:12.0.3",
"url": "docker://docker.io/jboss/keycloak@sha256:3720b5ace316b5790a58ce838f46e8cd44cedbdb7e35d3866311ddc5a5e71466",
},
},
"versioning": "docker",
},
Object {
"currentValue": "v3.4.8",
"datasource": "github-releases",
"depName": "etcd-io/etcd",
"depType": "ironbank-github",
"lookupName": "etcd-io/etcd",
"managerData": Object {
"item": Object {
"filename": "etcd.tar.gz",
"url": "https://github.com/etcd-io/etcd/releases/download/v3.4.8/etcd-v3.4.8-linux-amd64.tar.gz",
"validation": Object {
"type": "sha256",
"value": "a3a332a68fe8dedf20149c1a4b8746fe8061b72d75d3a5850b17e04de9ed7942",
},
},
},
"repo": "etcd-io/etcd",
},
Object {
"currentValue": "v1.10.3",
"datasource": "github-tags",
"depName": "fluent/fluentd",
"depType": "ironbank-github",
"lookupName": "fluent/fluentd",
"managerData": Object {
"item": Object {
"filename": "fluentd.tar.gz",
"url": "https://github.com/fluent/fluentd/archive/v1.10.3.tar.gz",
"validation": Object {
"type": "sha256",
"value": "c2b5bbb6c2236f73310b22c748e32a88f25288f3e6e1bd272f3dccc6a2322160",
},
},
},
"repo": "fluent/fluentd",
},
Object {
"currentDigest": "e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461",
"currentValue": "1.25.10",
"datasource": "pypi",
"depName": "urllib3",
"depType": "ironbank-pypi",
"lookupName": "urllib3",
"managerData": Object {
"item": Object {
"filename": "urllib3-1.25.10-py2.py3-none-any.whl",
"url": "https://files.pythonhosted.org/packages/9f/f0/a391d1463ebb1b233795cabfc0ef38d3db4442339de68f847026199e69d7/urllib3-1.25.10-py2.py3-none-any.whl",
"validation": Object {
"type": "sha256",
"value": "e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461",
},
},
},
},
Object {
"currentValue": "1.15.0",
"datasource": "rubygems",
"depName": "gitlab-triage",
"depType": "ironbank-rubygems",
"lookupName": "gitlab-triage",
"managerData": Object {
"item": Object {
"filename": "gitlab-triage-1.15.0.gem",
"url": "https://rubygems.org/downloads/gitlab-triage-1.15.0.gem",
"validation": Object {
"type": "sha256",
"value": "e516d720a67c9e3447db858775b48f44aae210b184dd96f7a20fe4fbb4022834",
},
},
},
"registryUrls": Array [
"https://rubygems.org",
],
},
]
`;
import { UpdateArtifact, UpdateArtifactsResult } from '../types';
export declare function updateArtifacts({ packageFileName, updatedDeps, newPackageFileContent, config, }: UpdateArtifact): Promise<UpdateArtifactsResult[] | null>;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateArtifacts = void 0;
const is_1 = __importDefault(require("@sindresorhus/is"));
const js_yaml_1 = __importDefault(require("js-yaml"));
const upath_1 = require("upath");
const admin_1 = require("../../config/admin");
const logger_1 = require("../../logger");
const exec_1 = require("../../util/exec");
const fs_1 = require("../../util/fs");
const git_1 = require("../../util/git");
async function postUpgrade(url, path) {
logger_1.logger.debug(`ironbank.postUpgrade(${url}, ${path})`);
try {
const cmd = 'ironbank-helm.sh';
const args = '--directory ' + path + ' --url ' + url;
await exec_1.exec(`${cmd} ${args}`);
}
catch (err) {
logger_1.logger.error(err);
return false;
}
return true;
}
async function updateArtifacts({ packageFileName, updatedDeps, newPackageFileContent, config, }) {
var _a, _b;
logger_1.logger.debug(`ironbank.updateArtifacts(${packageFileName})`);
if (!is_1.default.nonEmptyArray(updatedDeps)) {
return null;
}
let manifest;
try {
manifest = js_yaml_1.default.load(newPackageFileContent, {
json: true,
});
}
catch (err) {
logger_1.logger.error('Failed to parse hardening_manifest.yaml');
return null;
}
if (!(manifest && is_1.default.array(manifest.resources))) {
return null;
}
if (!((_a = manifest.resources[0].url) === null || _a === void 0 ? void 0 : _a.startsWith('helm://'))) {
return null;
}
const charts = new Map();
for (const item of manifest.resources) {
if ((_b = item.url) === null || _b === void 0 ? void 0 : _b.startsWith('helm://')) {
charts.set(item.name, `${String('https://')}${String(item.url.substring(7))}`);
}
}
for (const dep of updatedDeps) {
logger_1.logger.debug(`updatedDep(${dep})`);
if (charts.has(dep)) {
const result = await postUpgrade(charts.get(dep), upath_1.join(admin_1.getAdminConfig(), dep));
if (!result) {
return null;
}
}
}
const res = [];
const status = await git_1.getRepoStatus();
for (const f of status.modified.concat(status.not_added)) {
res.push({
file: {
name: f,
contents: await fs_1.readLocalFile(f),
},
});
}
for (const f of status.deleted || []) {
res.push({
file: {
name: '|delete|',
contents: f,
},
});
}
return res;
}
exports.updateArtifacts = updateArtifacts;
//# sourceMappingURL=artifacts.js.map
\ No newline at end of file
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../../lib/manager/ironbank/artifacts.ts"],"names":[],"mappings":"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","sourcesContent":["import is from '@sindresorhus/is';\nimport yaml from 'js-yaml';\nimport { join } from 'upath';\nimport { getAdminConfig } from '../../config/admin';\nimport { logger } from '../../logger';\nimport { exec } from '../../util/exec';\nimport { readLocalFile } from '../../util/fs';\nimport { getRepoStatus } from '../../util/git';\nimport { UpdateArtifact, UpdateArtifactsResult } from '../types';\nimport { HardeningManifest } from './extract';\n\nasync function postUpgrade(url: string, path: string): Promise<boolean> {\n logger.debug(`ironbank.postUpgrade(${url}, ${path})`);\n try {\n const cmd = 'ironbank-helm.sh';\n const args = '--directory ' + path + ' --url ' + url;\n await exec(`${cmd} ${args}`);\n } catch (err) {\n logger.error(err);\n return false;\n }\n return true;\n}\n\nexport async function updateArtifacts({\n packageFileName,\n updatedDeps,\n newPackageFileContent,\n config,\n}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {\n logger.debug(`ironbank.updateArtifacts(${packageFileName})`);\n if (!is.nonEmptyArray(updatedDeps)) {\n return null;\n }\n\n let manifest: HardeningManifest;\n try {\n manifest = yaml.load(newPackageFileContent, {\n json: true,\n }) as HardeningManifest;\n } catch (err) {\n logger.error('Failed to parse hardening_manifest.yaml');\n return null;\n }\n\n if (!(manifest && is.array(manifest.resources))) {\n return null;\n }\n\n if (!manifest.resources[0].url?.startsWith('helm://')) {\n return null;\n }\n\n const charts = new Map();\n for (const item of manifest.resources) {\n if (item.url?.startsWith('helm://')) {\n charts.set(\n item.name,\n `${String('https://')}${String(item.url.substring(7))}`\n );\n }\n }\n\n for (const dep of updatedDeps) {\n logger.debug(`updatedDep(${dep})`);\n if (charts.has(dep)) {\n const result = await postUpgrade(\n charts.get(dep),\n join(getAdminConfig(), dep)\n );\n if (!result) {\n return null;\n }\n }\n }\n\n const res = [];\n const status = await getRepoStatus();\n\n for (const f of status.modified.concat(status.not_added)) {\n res.push({\n file: {\n name: f,\n contents: await readLocalFile(f),\n },\n });\n }\n\n for (const f of status.deleted || []) {\n res.push({\n file: {\n name: '|delete|',\n contents: f,\n },\n });\n }\n\n return res;\n}\n"]}
\ No newline at end of file
import is from '@sindresorhus/is';
import yaml from 'js-yaml';
import { join } from 'upath';
import { getAdminConfig } from '../../config/admin';
import { logger } from '../../logger';
import { exec } from '../../util/exec';
import { readLocalFile } from '../../util/fs';
import { getRepoStatus } from '../../util/git';
import { UpdateArtifact, UpdateArtifactsResult } from '../types';
import { HardeningManifest } from './extract';
async function postUpgrade(url: string, path: string): Promise<boolean> {
logger.debug(`ironbank.postUpgrade(${url}, ${path})`);
try {
const cmd = 'ironbank-helm.sh';
const args = '--directory ' + path + ' --url ' + url;
await exec(`${cmd} ${args}`);
} catch (err) {
logger.error(err);
return false;
}
return true;
}
export async function updateArtifacts({
packageFileName,
updatedDeps,
newPackageFileContent,
config,
}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {
logger.debug(`ironbank.updateArtifacts(${packageFileName})`);
if (!is.nonEmptyArray(updatedDeps)) {
return null;
}
let manifest: HardeningManifest;
try {
manifest = yaml.load(newPackageFileContent, {
json: true,
}) as HardeningManifest;
} catch (err) {
logger.error('Failed to parse hardening_manifest.yaml');
return null;
}
if (!(manifest && is.array(manifest.resources))) {
return null;
}
if (!manifest.resources[0].url?.startsWith('helm://')) {
return null;
}
const charts = new Map();
for (const item of manifest.resources) {
if (item.url?.startsWith('helm://')) {
charts.set(
item.name,
`${String('https://')}${String(item.url.substring(7))}`
);
}
}
for (const dep of updatedDeps) {
logger.debug(`updatedDep(${dep})`);
if (charts.has(dep)) {
const result = await postUpgrade(
charts.get(dep),
join(getAdminConfig(), dep)
);
if (!result) {
return null;
}
}
}
const res = [];
const status = await getRepoStatus();
for (const f of status.modified.concat(status.not_added)) {
res.push({
file: {
name: f,
contents: await readLocalFile(f),
},
});
}
for (const f of status.deleted || []) {
res.push({
file: {
name: '|delete|',
contents: f,
},
});
}
return res;
}
import { PackageFile } from '../types';
export interface HardeningManifest {
apiVersion: string;
name: string;
tags: string[];
args: Args;
labels: Labels;
resources: Resource[];
maintainers: Maintainer[];
}
export interface Args {
BASE_IMAGE: string;
BASE_TAG: string;
}
export interface Labels {
'org.opencontainers.image.title': string;
'org.opencontainers.image.description': string;
'org.opencontainers.image.licenses': string;
'org.opencontainers.image.url': string;
'org.opencontainers.image.vendor': string;
'org.opencontainers.image.version': string;
'mil.dso.ironbank.image.keywords': string;
'mil.dso.ironbank.image.type': string;
'mil.dso.ironbank.product.name': string;
}
export interface Maintainer {
name: string;
username: string;
email: string;
cht_member: boolean;
}
export interface Resource {
tag?: string;
url: string;
name?: string;
filename?: string;
validation?: Validation;
}
export interface Validation {
type: string;
value: string;
}
export declare function extractPackageFile(content: string): PackageFile;
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractPackageFile = void 0;
const url_1 = require("url");
const is_1 = __importDefault(require("@sindresorhus/is"));
const js_yaml_1 = __importDefault(require("js-yaml"));
const datasourceDocker = __importStar(require("../../datasource/docker"));
const datasourceGithubReleases = __importStar(require("../../datasource/github-releases"));
const datasourceGithubTags = __importStar(require("../../datasource/github-tags"));
const datasourceHelm = __importStar(require("../../datasource/helm"));
const datasourcePypi = __importStar(require("../../datasource/pypi"));
const datasourceRubyGems = __importStar(require("../../datasource/rubygems"));
const logger_1 = require("../../logger");
const dockerVersioning = __importStar(require("../../versioning/docker"));
function getDatasourceId(lookupName, url) {
if (lookupName === 'antirez/redis') {
return datasourceGithubTags.id;
}
if (url.includes('archive')) {
return datasourceGithubTags.id;
}
return datasourceGithubReleases.id;
}
function parseUrl(urlString) {
// istanbul ignore if
if (!urlString) {
return null;
}
const url = url_1.parse(urlString);
if (url.host !== 'github.com') {
return null;
}
const path = url.path.split('/').slice(1);
const repo = path[0] + '/' + path[1];
let currentValue = null;
if (path[2] === 'releases' && path[3] === 'download') {
currentValue = path[4];
}
if (path[2] === 'archive') {
if (path[3] === 'refs') {
currentValue = path[5].replace(/\.tar\.gz$/, '');
}
else {
currentValue = path[3].replace(/\.tar\.gz$/, '');
}
}
if (currentValue) {
return { repo, currentValue };
}
// istanbul ignore next
return null;
}
function extractPackageFile(content) {
var _a, _b;
const deps = [];
let hasBase = false;
let hasResource = false;
let manifest;
try {
manifest = js_yaml_1.default.load(content, { json: true });
}
catch (err) {
logger_1.logger.debug('Failed to parse hardening_manifest.yaml');
return null;
}
if (!((_a = manifest.args) === null || _a === void 0 ? void 0 : _a.BASE_TAG) || !((_b = manifest.args) === null || _b === void 0 ? void 0 : _b.BASE_IMAGE) || !manifest) {
return null;
}
// extract base image
if (!(manifest === null) &&
'BASE_TAG' in manifest.args &&
'BASE_IMAGE' in manifest.args) {
hasBase = true;
const baseResource = {
url: manifest.args.BASE_IMAGE,
tag: manifest.args.BASE_TAG,
};
const baseDep = { managerData: { baseResource } };
baseDep.depType = 'ironbank-base';
baseDep.depName = `registry1.dso.mil/ironbank/${String(manifest.args.BASE_IMAGE)}`;
// baseDep.depName = 'registry1.dso.mil/ironbank/' + manifest.args.BASE_IMAGE;
baseDep.datasource = datasourceDocker.id;
baseDep.versioning = dockerVersioning.id;
baseDep.lookupName = `registry1.dso.mil/ironbank/${String(manifest.args.BASE_IMAGE)}`;
baseDep.currentValue = manifest.args.BASE_TAG;
deps.push(baseDep);
}
// check if there are resource in the HM resource block
if (is_1.default.array(manifest.resources)) {
hasResource = true;
}
// no base or resources, return null
if (!hasBase && !hasResource) {
return null;
}
// has base but no resources
if (!hasResource) {
return { deps };
}
// extract resources list in manifest resource block
for (const item of manifest.resources) {
const dep = { managerData: { item } };
if (item.url) {
// docker
if (item.url.startsWith('docker://')) {
const currentDigest = item.url.split('@')[1];
const [lookupName, currentValue] = item.tag.split(':');
dep.depType = 'ironbank-docker';
dep.depName = lookupName;
dep.datasource = datasourceDocker.id;
dep.versioning = dockerVersioning.id;
dep.lookupName = lookupName;
dep.currentDigest = currentDigest;
dep.currentValue = currentValue;
deps.push(dep);
}
// github-releases
else if (item.url.startsWith('https://github.com')) {
const parsedUrl = parseUrl(item.url);
dep.depType = 'ironbank-github';
dep.depName = parsedUrl.repo;
dep.repo = parsedUrl.repo;
dep.currentValue = parsedUrl.currentValue;
dep.datasource = getDatasourceId(dep.repo, item.url);
dep.lookupName = dep.repo;
deps.push(dep);
}
// helm
else if (item.url.startsWith('helm://')) {
const regex = new RegExp('helm://(?<registryUrl>.*/)(?<lookupName>.*?)-(?<currentValue>.*?).tgz');
const groups = regex.exec(item.url).groups;
if ((groups === null || groups === void 0 ? void 0 : groups.registryUrl) && groups.lookupName && groups.currentValue) {
logger_1.logger.info(groups.registryUrl);
dep.depType = 'ironbank-helm';
dep.depName = item.name;
dep.datasource = datasourceHelm.HelmDatasource.id;
dep.registryUrls = [
`${String('https://')}${String(groups.registryUrl)}`,
];
dep.lookupName = groups.lookupName;
dep.currentValue = groups.currentValue;
deps.push(dep);
}
}
// rubygems
else if (item.url.startsWith('https://rubygems.org')) {
const regex = new RegExp('https://(?<registryUrl>.*)/(.*/)(?<lookupName>.*-?)-(?<currentValue>.*?).gem');
const groups = regex.exec(item.url).groups;
if ((groups === null || groups === void 0 ? void 0 : groups.registryUrl) && groups.lookupName && groups.currentValue) {
dep.depType = 'ironbank-rubygems';
dep.depName = groups.lookupName;
dep.lookupName = groups.lookupName;
dep.datasource = datasourceRubyGems.id;
dep.currentValue = groups.currentValue;
dep.registryUrls = [
`${String('https://')}${String(groups.registryUrl)}`,
];
deps.push(dep);
}
}
else if (item.url.startsWith('https://files.pythonhosted.org')) {
const regex = new RegExp('https://(.*)/(.*)/(.*)/(.*)/(.*)/(?<lookupName>.*?)-(?<version>.*?)-(.*)');
const group = regex.exec(item.url).groups;
if (group.lookupName && group.version) {
dep.depType = 'ironbank-pypi';
dep.currentDigest = item.validation.value;
dep.currentValue = group.version;
dep.depName = group.lookupName;
dep.datasource = datasourcePypi.id;
dep.lookupName = group.lookupName;
deps.push(dep);
}
}
}
}
if (!deps.length) {
return null;
}
return { deps };
}
exports.extractPackageFile = extractPackageFile;
//# sourceMappingURL=extract.js.map
\ No newline at end of file
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../../lib/manager/ironbank/extract.ts"],"names":[],"mappings":"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","sourcesContent":["import { parse as _parse } from 'url';\nimport is from '@sindresorhus/is';\nimport yaml from 'js-yaml';\nimport * as datasourceDocker from '../../datasource/docker';\nimport * as datasourceGithubReleases from '../../datasource/github-releases';\nimport * as datasourceGithubTags from '../../datasource/github-tags';\nimport * as datasourceHelm from '../../datasource/helm';\nimport * as datasourcePypi from '../../datasource/pypi';\nimport * as datasourceRubyGems from '../../datasource/rubygems';\nimport { logger } from '../../logger';\nimport * as dockerVersioning from '../../versioning/docker';\nimport { PackageDependency, PackageFile } from '../types';\n\nexport interface HardeningManifest {\n apiVersion: string;\n name: string;\n tags: string[];\n args: Args;\n labels: Labels;\n resources: Resource[];\n maintainers: Maintainer[];\n}\n\nexport interface Args {\n BASE_IMAGE: string;\n BASE_TAG: string;\n}\n\nexport interface Labels {\n 'org.opencontainers.image.title': string;\n 'org.opencontainers.image.description': string;\n 'org.opencontainers.image.licenses': string;\n 'org.opencontainers.image.url': string;\n 'org.opencontainers.image.vendor': string;\n 'org.opencontainers.image.version': string;\n 'mil.dso.ironbank.image.keywords': string;\n 'mil.dso.ironbank.image.type': string;\n 'mil.dso.ironbank.product.name': string;\n}\n\nexport interface Maintainer {\n name: string;\n username: string;\n email: string;\n cht_member: boolean;\n}\n\nexport interface Resource {\n tag?: string;\n url: string;\n name?: string;\n filename?: string;\n validation?: Validation;\n}\n\nexport interface Validation {\n type: string;\n value: string;\n}\n\ninterface UrlParsedResult {\n repo: string;\n currentValue: string;\n}\n\nfunction getDatasourceId(lookupName: string, url: string): string {\n if (lookupName === 'antirez/redis') {\n return datasourceGithubTags.id;\n }\n if (url.includes('archive')) {\n return datasourceGithubTags.id;\n }\n\n return datasourceGithubReleases.id;\n}\n\nfunction parseUrl(urlString: string): UrlParsedResult | null {\n // istanbul ignore if\n if (!urlString) {\n return null;\n }\n const url = _parse(urlString);\n if (url.host !== 'github.com') {\n return null;\n }\n const path = url.path.split('/').slice(1);\n const repo = path[0] + '/' + path[1];\n let currentValue: string = null;\n if (path[2] === 'releases' && path[3] === 'download') {\n currentValue = path[4];\n }\n if (path[2] === 'archive') {\n if (path[3] === 'refs') {\n currentValue = path[5].replace(/\\.tar\\.gz$/, '');\n } else {\n currentValue = path[3].replace(/\\.tar\\.gz$/, '');\n }\n }\n if (currentValue) {\n return { repo, currentValue };\n }\n // istanbul ignore next\n return null;\n}\n\nexport function extractPackageFile(content: string): PackageFile {\n const deps: PackageDependency[] = [];\n let hasBase = false;\n let hasResource = false;\n\n let manifest: HardeningManifest;\n\n try {\n manifest = yaml.load(content, { json: true }) as HardeningManifest;\n } catch (err) {\n logger.debug('Failed to parse hardening_manifest.yaml');\n return null;\n }\n\n if (!manifest.args?.BASE_TAG || !manifest.args?.BASE_IMAGE || !manifest) {\n return null;\n }\n\n // extract base image\n if (\n !(manifest === null) &&\n 'BASE_TAG' in manifest.args &&\n 'BASE_IMAGE' in manifest.args\n ) {\n hasBase = true;\n const baseResource: Resource = {\n url: manifest.args.BASE_IMAGE,\n tag: manifest.args.BASE_TAG,\n };\n const baseDep: PackageDependency = { managerData: { baseResource } };\n baseDep.depType = 'ironbank-base';\n baseDep.depName = `registry1.dso.mil/ironbank/${String(\n manifest.args.BASE_IMAGE\n )}`;\n // baseDep.depName = 'registry1.dso.mil/ironbank/' + manifest.args.BASE_IMAGE;\n baseDep.datasource = datasourceDocker.id;\n baseDep.versioning = dockerVersioning.id;\n baseDep.lookupName = `registry1.dso.mil/ironbank/${String(\n manifest.args.BASE_IMAGE\n )}`;\n baseDep.currentValue = manifest.args.BASE_TAG;\n deps.push(baseDep);\n }\n\n // check if there are resource in the HM resource block\n if (is.array(manifest.resources)) {\n hasResource = true;\n }\n\n // no base or resources, return null\n if (!hasBase && !hasResource) {\n return null;\n }\n\n // has base but no resources\n if (!hasResource) {\n return { deps };\n }\n\n // extract resources list in manifest resource block\n for (const item of manifest.resources) {\n const dep: PackageDependency = { managerData: { item } };\n if (item.url) {\n // docker\n if (item.url.startsWith('docker://')) {\n const currentDigest = item.url.split('@')[1];\n const [lookupName, currentValue] = item.tag.split(':');\n dep.depType = 'ironbank-docker';\n dep.depName = lookupName;\n dep.datasource = datasourceDocker.id;\n dep.versioning = dockerVersioning.id;\n dep.lookupName = lookupName;\n dep.currentDigest = currentDigest;\n dep.currentValue = currentValue;\n deps.push(dep);\n }\n // github-releases\n else if (item.url.startsWith('https://github.com')) {\n const parsedUrl = parseUrl(item.url);\n dep.depType = 'ironbank-github';\n dep.depName = parsedUrl.repo;\n dep.repo = parsedUrl.repo;\n dep.currentValue = parsedUrl.currentValue;\n dep.datasource = getDatasourceId(dep.repo, item.url);\n dep.lookupName = dep.repo;\n deps.push(dep);\n }\n // helm\n else if (item.url.startsWith('helm://')) {\n const regex = new RegExp(\n 'helm://(?<registryUrl>.*/)(?<lookupName>.*?)-(?<currentValue>.*?).tgz'\n );\n const groups = regex.exec(item.url).groups;\n if (groups?.registryUrl && groups.lookupName && groups.currentValue) {\n logger.info(groups.registryUrl);\n dep.depType = 'ironbank-helm';\n dep.depName = item.name;\n dep.datasource = datasourceHelm.HelmDatasource.id;\n dep.registryUrls = [\n `${String('https://')}${String(groups.registryUrl)}`,\n ];\n dep.lookupName = groups.lookupName;\n dep.currentValue = groups.currentValue;\n deps.push(dep);\n }\n }\n // rubygems\n else if (item.url.startsWith('https://rubygems.org')) {\n const regex = new RegExp(\n 'https://(?<registryUrl>.*)/(.*/)(?<lookupName>.*-?)-(?<currentValue>.*?).gem'\n );\n const groups = regex.exec(item.url).groups;\n if (groups?.registryUrl && groups.lookupName && groups.currentValue) {\n dep.depType = 'ironbank-rubygems';\n dep.depName = groups.lookupName;\n dep.lookupName = groups.lookupName;\n dep.datasource = datasourceRubyGems.id;\n dep.currentValue = groups.currentValue;\n dep.registryUrls = [\n `${String('https://')}${String(groups.registryUrl)}`,\n ];\n deps.push(dep);\n }\n } else if (item.url.startsWith('https://files.pythonhosted.org')) {\n const regex = new RegExp(\n 'https://(.*)/(.*)/(.*)/(.*)/(.*)/(?<lookupName>.*?)-(?<version>.*?)-(.*)'\n );\n const group = regex.exec(item.url).groups;\n\n if (group.lookupName && group.version) {\n dep.depType = 'ironbank-pypi';\n dep.currentDigest = item.validation.value;\n dep.currentValue = group.version;\n dep.depName = group.lookupName;\n dep.datasource = datasourcePypi.id;\n dep.lookupName = group.lookupName;\n\n deps.push(dep);\n }\n }\n }\n }\n\n if (!deps.length) {\n return null;\n }\n return { deps };\n}\n"]}
\ No newline at end of file
import { readFileSync } from 'fs';
import { extractPackageFile } from './extract';
const yamlFile = readFileSync(
'lib/manager/ironbank/__fixtures__/hardening_manifest.yaml',
'utf8'
);
describe('lib/manager/ironbank/extract', () => {
describe('extractPackageFile()', () => {
it('returns null for empty', () => {
expect(extractPackageFile('nothing here')).toBeNull();
});
it('extracts single image lines', () => {
const res = extractPackageFile(yamlFile);
expect(res.deps).toMatchSnapshot();
expect(res.deps).toHaveLength(6);
});
});
});
import { parse as _parse } from 'url';
import is from '@sindresorhus/is';
import yaml from 'js-yaml';
import * as datasourceDocker from '../../datasource/docker';
import * as datasourceGithubReleases from '../../datasource/github-releases';
import * as datasourceGithubTags from '../../datasource/github-tags';
import * as datasourceHelm from '../../datasource/helm';
import * as datasourcePypi from '../../datasource/pypi';
import * as datasourceRubyGems from '../../datasource/rubygems';
import { logger } from '../../logger';
import * as dockerVersioning from '../../versioning/docker';
import { PackageDependency, PackageFile } from '../types';
export interface HardeningManifest {
apiVersion: string;
name: string;
tags: string[];
args: Args;
labels: Labels;
resources: Resource[];
maintainers: Maintainer[];
}
export interface Args {
BASE_IMAGE: string;
BASE_TAG: string;
}
export interface Labels {
'org.opencontainers.image.title': string;
'org.opencontainers.image.description': string;
'org.opencontainers.image.licenses': string;
'org.opencontainers.image.url': string;
'org.opencontainers.image.vendor': string;
'org.opencontainers.image.version': string;
'mil.dso.ironbank.image.keywords': string;
'mil.dso.ironbank.image.type': string;
'mil.dso.ironbank.product.name': string;
}
export interface Maintainer {
name: string;
username: string;
email: string;
cht_member: boolean;
}
export interface Resource {
tag?: string;
url: string;
name?: string;
filename?: string;
validation?: Validation;
}
export interface Validation {
type: string;
value: string;
}
interface UrlParsedResult {
repo: string;
currentValue: string;
}
function getDatasourceId(lookupName: string, url: string): string {
if (lookupName === 'antirez/redis') {
return datasourceGithubTags.id;
}
if (url.includes('archive')) {
return datasourceGithubTags.id;
}
return datasourceGithubReleases.id;
}
function parseUrl(urlString: string): UrlParsedResult | null {
// istanbul ignore if
if (!urlString) {
return null;
}
const url = _parse(urlString);
if (url.host !== 'github.com') {
return null;
}
const path = url.path.split('/').slice(1);
const repo = path[0] + '/' + path[1];
let currentValue: string = null;
if (path[2] === 'releases' && path[3] === 'download') {
currentValue = path[4];
}
if (path[2] === 'archive') {
if (path[3] === 'refs') {
currentValue = path[5].replace(/\.tar\.gz$/, '');
} else {
currentValue = path[3].replace(/\.tar\.gz$/, '');
}
}
if (currentValue) {
return { repo, currentValue };
}
// istanbul ignore next
return null;
}
export function extractPackageFile(content: string): PackageFile {
const deps: PackageDependency[] = [];
let hasBase = false;
let hasResource = false;
let manifest: HardeningManifest;
try {
manifest = yaml.load(content, { json: true }) as HardeningManifest;
} catch (err) {
logger.debug('Failed to parse hardening_manifest.yaml');
return null;
}
if (!manifest.args?.BASE_TAG || !manifest.args?.BASE_IMAGE || !manifest) {
return null;
}
// extract base image
if (
!(manifest === null) &&
'BASE_TAG' in manifest.args &&
'BASE_IMAGE' in manifest.args
) {
hasBase = true;
const baseResource: Resource = {
url: manifest.args.BASE_IMAGE,
tag: manifest.args.BASE_TAG,
};
const baseDep: PackageDependency = { managerData: { baseResource } };
baseDep.depType = 'ironbank-base';
baseDep.depName = `registry1.dso.mil/ironbank/${String(
manifest.args.BASE_IMAGE
)}`;
baseDep.datasource = datasourceDocker.id;
baseDep.versioning = dockerVersioning.id;
baseDep.lookupName = `registry1.dso.mil/ironbank/${String(
manifest.args.BASE_IMAGE
)}`;
baseDep.currentValue = manifest.args.BASE_TAG;
deps.push(baseDep);
}
// check if there are resource in the HM resource block
if (is.array(manifest.resources)) {
hasResource = true;
}
// no base or resources, return null
if (!hasBase && !hasResource) {
return null;
}
// has base but no resources
if (!hasResource) {
return { deps };
}
// extract resources list in manifest resource block
for (const item of manifest.resources) {
const dep: PackageDependency = { managerData: { item } };
if (item.url) {
// docker
if (item.url.startsWith('docker://')) {
const currentDigest = item.url.split('@')[1];
const [lookupName, currentValue] = item.tag.split(':');
dep.depType = 'ironbank-docker';
dep.depName = lookupName;
dep.datasource = datasourceDocker.id;
dep.versioning = dockerVersioning.id;
dep.lookupName = lookupName;
dep.currentDigest = currentDigest;
dep.currentValue = currentValue;
deps.push(dep);
}
// github-releases
else if (item.url.startsWith('https://github.com')) {
const parsedUrl = parseUrl(item.url);
dep.depType = 'ironbank-github';
dep.depName = parsedUrl.repo;
dep.repo = parsedUrl.repo;
dep.currentValue = parsedUrl.currentValue;
dep.datasource = getDatasourceId(dep.repo, item.url);
dep.lookupName = dep.repo;
deps.push(dep);
}
// helm
else if (item.url.startsWith('helm://')) {
const regex = new RegExp(
'helm://(?<registryUrl>.*/)(?<lookupName>.*?)-(?<currentValue>.*?).tgz'
);
const groups = regex.exec(item.url)?.groups;
if (groups?.registryUrl && groups?.lookupName && groups?.currentValue) {
logger.info(groups.registryUrl);
dep.depType = 'ironbank-helm';
dep.depName = item.name;
dep.datasource = datasourceHelm.HelmDatasource.id;
dep.registryUrls = [
`${String('https://')}${String(groups.registryUrl)}`,
];
dep.lookupName = groups.lookupName;
dep.currentValue = groups.currentValue;
deps.push(dep);
}
}
// rubygems
else if (item.url.startsWith('https://rubygems.org')) {
const regex = new RegExp(
'https://(?<registryUrl>.*)/(.*/)(?<lookupName>.*-?)-(?<currentValue>.*?).gem'
);
const groups = regex.exec(item.url)?.groups;
if (groups?.registryUrl && groups?.lookupName && groups?.currentValue) {
dep.depType = 'ironbank-rubygems';
dep.depName = groups.lookupName;
dep.lookupName = groups.lookupName;
dep.datasource = datasourceRubyGems.id;
dep.currentValue = groups.currentValue;
dep.registryUrls = [
`${String('https://')}${String(groups.registryUrl)}`,
];
deps.push(dep);
}
} else if (item.url.startsWith('https://files.pythonhosted.org')) {
const regex = new RegExp(
'https://(.*)/(.*)/(.*)/(.*)/(.*)/(?<lookupName>.*?)-(?<version>([0-9]+).([0-9]+).([0-9]+))[-|.](.*)'
);
const group = regex.exec(item.url)?.groups;
if (group?.lookupName && group?.version) {
dep.depType = 'ironbank-pypi';
dep.currentDigest = item.validation.value;
dep.currentValue = group.version;
dep.depName = group.lookupName;
dep.datasource = datasourcePypi.id;
dep.lookupName = group.lookupName;
deps.push(dep);
}
}
}
}
if (!deps.length) {
return null;
}
return { deps };
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultConfig = exports.updateArtifacts = exports.updateDependency = exports.extractPackageFile = void 0;
const artifacts_1 = require("./artifacts");
Object.defineProperty(exports, "updateArtifacts", { enumerable: true, get: function () { return artifacts_1.updateArtifacts; } });
const extract_1 = require("./extract");
Object.defineProperty(exports, "extractPackageFile", { enumerable: true, get: function () { return extract_1.extractPackageFile; } });
const update_1 = require("./update");
Object.defineProperty(exports, "updateDependency", { enumerable: true, get: function () { return update_1.updateDependency; } });
exports.defaultConfig = {
fileMatch: ['(^|/)download.yaml$', '(^|/)hardening_manifest.yaml$'],
};
//# sourceMappingURL=index.js.map
\ No newline at end of file
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/manager/ironbank/index.ts"],"names":[],"mappings":";;;AAAA,2CAA8C;AAIC,gGAJtC,2BAAe,OAIsC;AAH9D,uCAA+C;AAGtC,mGAHA,4BAAkB,OAGA;AAF3B,qCAA4C;AAEf,iGAFpB,yBAAgB,OAEoB;AAEhC,QAAA,aAAa,GAAG;IAC3B,SAAS,EAAE,CAAC,qBAAqB,EAAE,+BAA+B,CAAC;CACpE,CAAC","sourcesContent":["import { updateArtifacts } from './artifacts';\nimport { extractPackageFile } from './extract';\nimport { updateDependency } from './update';\n\nexport { extractPackageFile, updateDependency, updateArtifacts };\n\nexport const defaultConfig = {\n fileMatch: ['(^|/)download.yaml$', '(^|/)hardening_manifest.yaml$'],\n};\n"]}
\ No newline at end of file
import { updateArtifacts } from './artifacts';
import { extractPackageFile } from './extract';
import { updateDependency } from './update';
export { extractPackageFile, updateDependency, updateArtifacts };
export declare const defaultConfig: {
fileMatch: string[];
export const defaultConfig = {
fileMatch: ['(^|/)download.yaml$', '(^|/)hardening_manifest.yaml$'],
};
Extracts all dependencies in a hardening_manifest.yaml file.
import { UpdateDependencyConfig } from '../types';
export declare function updateDependency({ fileContent, upgrade, }: UpdateDependencyConfig): Promise<string | null>;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateDependency = void 0;
const path_1 = __importDefault(require("path"));
const url_1 = require("url");
const hasha_1 = require("hasha");
const logger_1 = require("../../logger");
const http_1 = require("../../util/http");
const http = new http_1.Http('ironbank');
async function getHashFromFile(url, filename) {
logger_1.logger.debug('getHashFromFile: ' + url + ' ' + filename);
try {
const result = await http.get(url);
if (result.body) {
const regex = new RegExp('(?<hash>[A-Fa-f0-9]{64})\\s+' +
filename.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
const groups = regex.exec(result.body).groups;
if (groups) {
return groups.hash;
}
}
return null;
}
catch (err) /* istanbul ignore next */ {
return null;
}
}
async function getHashFromUrl(url) {
try {
const parsedUrl = url_1.parse(url);
const filename = path_1.default.basename(parsedUrl.pathname);
let hash;
hash = await getHashFromFile(filename + '.sha256', filename);
if (hash) {
return hash;
}
hash = await getHashFromFile(url.replace(filename, 'SHA256SUMS'), filename);
if (hash) {
return hash;
}
hash = await hasha_1.fromStream(http.stream(url), {
algorithm: 'sha256',
});
return hash;
}
catch (err) /* istanbul ignore next */ {
return null;
}
}
async function getPypiData(url) {
logger_1.logger.debug(`${'getPypiData:'} ${url} ${'filename'}`);
try {
const result = await http.get(url);
if (result.body) {
const results = JSON.parse(result.body);
for (let i = 0; i < results.urls.length; i += 1) {
if (results.urls[i].filename.endsWith('whl')) {
const output = {
sha: results.urls[i].digests.sha256,
updatedUrl: results.urls[i].url,
};
return output;
}
}
}
return null;
}
catch (err) /* istanbul ignore next */ {
return null;
}
}
async function updateDependency({ fileContent, upgrade, }) {
// let newContent = fileContent;
switch (upgrade.depType) {
case 'ironbank-base': {
const oldTag = upgrade.currentValue;
const newTag = upgrade.newValue;
let newContent = fileContent;
newContent = newContent.replace(oldTag, newTag);
return newContent;
}
case 'ironbank-docker': {
const oldTag = upgrade.lookupName + ':' + upgrade.currentValue;
const newTag = upgrade.lookupName + ':' + upgrade.newValue;
const oldUrl = upgrade.managerData.item.url;
const newUrl = `${String(upgrade.managerData.item.url.split('@')[0])}@${upgrade.newDigest}`;
let newContent = fileContent;
newContent = newContent.replace(oldTag, newTag);
newContent = newContent.replace(oldUrl, newUrl);
return newContent;
}
case 'ironbank-github': {
if (!upgrade.currentValue && !upgrade.newValue) {
logger_1.logger.warn(`${'issue updating ironbank-github for'} ${upgrade.lookupName}`);
return null;
}
const currentValue = upgrade.currentValue.replace(/^v/, '');
const newValue = upgrade.newValue.replace(/^v/, '');
const oldUrl = upgrade.managerData.item.url;
const newUrl = oldUrl.replace(new RegExp(currentValue, 'g'), newValue);
const hash = await getHashFromUrl(newUrl);
let newContent = fileContent;
if (hash) {
newContent = newContent.replace(upgrade.managerData.item.validation.value, hash);
newContent = newContent.replace(oldUrl, newUrl);
}
return newContent;
}
case 'ironbank-helm': {
if (!upgrade.currentValue && !upgrade.newValue) {
logger_1.logger.warn(`${'issue updating ironbank-helm for'} ${upgrade.depName}`);
return null;
}
return fileContent.replace(upgrade.currentValue, upgrade.newValue);
}
case 'ironbank-rubygems': {
if (!upgrade.currentValue && !upgrade.newValue) {
logger_1.logger.warn(`${'issue updating ironbank-rubygems for'} ${upgrade.depName}`);
return null;
}
const currentValue = upgrade.currentValue;
const newValue = upgrade.newValue;
const oldUrl = upgrade.managerData.item.url;
const newUrl = oldUrl.replace(new RegExp(currentValue, 'g'), newValue);
const hash = await getHashFromUrl(newUrl);
let newContent = fileContent;
if (hash) {
newContent = newContent.replace(upgrade.managerData.item.validation.value, hash);
newContent = newContent.replace(oldUrl, newUrl);
}
return newContent;
}
case 'ironbank-pypi': {
if (!upgrade.newValue) {
logger_1.logger.warn(`${'issue updating ironbank-pypi for'} ${upgrade.depName}`);
return null;
}
const newValue = upgrade.newValue;
const oldUrl = upgrade.managerData.item.url;
const searchURL = `https://pypi.org/pypi/${upgrade.depName}/${newValue}/json`;
const updatedData = getPypiData(searchURL);
let newContent = fileContent;
if ((await updatedData).sha && (await updatedData).updatedUrl) {
newContent = newContent.replace(upgrade.managerData.item.validation.value, (await updatedData).sha);
newContent = newContent.replace(oldUrl, (await updatedData).updatedUrl);
}
return newContent;
}
default:
return null;
}
}
exports.updateDependency = updateDependency;
//# sourceMappingURL=update.js.map
\ No newline at end of file
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../lib/manager/ironbank/update.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path';\nimport { parse as _parse } from 'url';\nimport { fromStream } from 'hasha';\nimport { logger } from '../../logger';\nimport { Http } from '../../util/http';\nimport { UpdateDependencyConfig } from '../types';\n\nconst http = new Http('ironbank');\n\nasync function getHashFromFile(\n url: string,\n filename: string\n): Promise<string | null> {\n logger.debug('getHashFromFile: ' + url + ' ' + filename);\n try {\n const result = await http.get(url);\n if (result.body) {\n const regex = new RegExp(\n '(?<hash>[A-Fa-f0-9]{64})\\\\s+' +\n filename.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n );\n const groups = regex.exec(result.body).groups;\n if (groups) {\n return groups.hash;\n }\n }\n return null;\n } catch (err) /* istanbul ignore next */ {\n return null;\n }\n}\n\nasync function getHashFromUrl(url: string): Promise<string | string> {\n try {\n const parsedUrl = _parse(url);\n const filename = path.basename(parsedUrl.pathname);\n\n let hash: string;\n hash = await getHashFromFile(filename + '.sha256', filename);\n if (hash) {\n return hash;\n }\n hash = await getHashFromFile(url.replace(filename, 'SHA256SUMS'), filename);\n if (hash) {\n return hash;\n }\n hash = await fromStream(http.stream(url), {\n algorithm: 'sha256',\n });\n return hash;\n } catch (err) /* istanbul ignore next */ {\n return null;\n }\n}\n\nasync function getPypiData(\n url: string\n): Promise<{ sha: string; updatedUrl: string }> {\n logger.debug(`${'getPypiData:'} ${url} ${'filename'}`);\n try {\n const result = await http.get(url);\n if (result.body) {\n const results = JSON.parse(result.body);\n\n for (let i = 0; i < results.urls.length; i += 1) {\n if (results.urls[i].filename.endsWith('whl')) {\n const output = {\n sha: results.urls[i].digests.sha256,\n updatedUrl: results.urls[i].url,\n };\n\n return output;\n }\n }\n }\n return null;\n } catch (err) /* istanbul ignore next */ {\n return null;\n }\n}\n\nexport async function updateDependency({\n fileContent,\n upgrade,\n}: UpdateDependencyConfig): Promise<string | null> {\n // let newContent = fileContent;\n\n switch (upgrade.depType) {\n case 'ironbank-base': {\n const oldTag = upgrade.currentValue;\n const newTag = upgrade.newValue;\n\n let newContent = fileContent;\n newContent = newContent.replace(oldTag, newTag);\n\n return newContent;\n }\n case 'ironbank-docker': {\n const oldTag = upgrade.lookupName + ':' + upgrade.currentValue;\n const newTag = upgrade.lookupName + ':' + upgrade.newValue;\n const oldUrl = upgrade.managerData.item.url;\n const newUrl = `${String(upgrade.managerData.item.url.split('@')[0])}@${\n upgrade.newDigest\n }`;\n\n let newContent = fileContent;\n newContent = newContent.replace(oldTag, newTag);\n newContent = newContent.replace(oldUrl, newUrl);\n\n return newContent;\n }\n case 'ironbank-github': {\n if (!upgrade.currentValue && !upgrade.newValue) {\n logger.warn(\n `${'issue updating ironbank-github for'} ${upgrade.lookupName}`\n );\n return null;\n }\n\n const currentValue = upgrade.currentValue.replace(/^v/, '');\n const newValue = upgrade.newValue.replace(/^v/, '');\n const oldUrl = upgrade.managerData.item.url;\n const newUrl = oldUrl.replace(new RegExp(currentValue, 'g'), newValue);\n const hash = await getHashFromUrl(newUrl);\n let newContent = fileContent;\n if (hash) {\n newContent = newContent.replace(\n upgrade.managerData.item.validation.value,\n hash\n );\n newContent = newContent.replace(oldUrl, newUrl);\n }\n return newContent;\n }\n case 'ironbank-helm': {\n if (!upgrade.currentValue && !upgrade.newValue) {\n logger.warn(`${'issue updating ironbank-helm for'} ${upgrade.depName}`);\n return null;\n }\n\n return fileContent.replace(upgrade.currentValue, upgrade.newValue);\n }\n case 'ironbank-rubygems': {\n if (!upgrade.currentValue && !upgrade.newValue) {\n logger.warn(\n `${'issue updating ironbank-rubygems for'} ${upgrade.depName}`\n );\n return null;\n }\n\n const currentValue = upgrade.currentValue;\n const newValue = upgrade.newValue;\n const oldUrl = upgrade.managerData.item.url;\n const newUrl = oldUrl.replace(new RegExp(currentValue, 'g'), newValue);\n const hash = await getHashFromUrl(newUrl);\n let newContent = fileContent;\n if (hash) {\n newContent = newContent.replace(\n upgrade.managerData.item.validation.value,\n hash\n );\n newContent = newContent.replace(oldUrl, newUrl);\n }\n return newContent;\n }\n case 'ironbank-pypi': {\n if (!upgrade.newValue) {\n logger.warn(`${'issue updating ironbank-pypi for'} ${upgrade.depName}`);\n return null;\n }\n\n const newValue = upgrade.newValue;\n const oldUrl = upgrade.managerData.item.url;\n const searchURL = `https://pypi.org/pypi/${upgrade.depName}/${newValue}/json`;\n const updatedData = getPypiData(searchURL);\n\n let newContent = fileContent;\n if ((await updatedData).sha && (await updatedData).updatedUrl) {\n newContent = newContent.replace(\n upgrade.managerData.item.validation.value,\n (await updatedData).sha\n );\n newContent = newContent.replace(oldUrl, (await updatedData).updatedUrl);\n }\n return newContent;\n }\n default:\n return null;\n }\n}\n"]}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment