UNPKG

@codius/manifest

Version:

A module for validating Codius manifests

246 lines (211 loc) 11.5 kB
/* eslint-env mocha */ const chai = require('chai') const chaiAsPromised = require('chai-as-promised') const { expect } = chai chai.use(chaiAsPromised) const cryptoUtils = require('../src/common/crypto-utils.js') const fse = require('fs-extra') const { generateManifest } = require('../src/generate-manifest.js') const validManifestMock = './test/mocks/manifest.test.json' const axios = require('axios') const varsStatic = './test/mocks/codiusvars.test.json' const varsMock = './test/codiusvars.mock.json' const manifestStatic = './test/mocks/codius.test.json' const manifestMock = './test/mocks/codius.mock.json' const sinon = require('sinon') describe('Generate Complete Manifest', function () { let validManifest = fse.readJsonSync(validManifestMock) const varsJson = fse.readJsonSync(varsStatic) // codiusvars.json const manifestJson = fse.readJsonSync(manifestStatic) // codius.json beforeEach(async function () { // Create mocks for codiusvars.json and codius.json await fse.writeJson(varsMock, varsJson) await fse.writeJson(manifestMock, manifestJson) this.sinon = sinon.createSandbox() this.get = this.sinon.stub(axios, 'get') this.generateNonce = this.sinon.stub(cryptoUtils, 'generateNonce').returns('123450325') }) afterEach(function () { this.sinon.restore() }) after(async function () { // Remove the codiusvars.json and codius.json mock files await fse.remove(varsMock) await fse.remove(manifestMock) }) it('should return the correct manifest when given valid codius files', async function () { const result = await generateManifest(varsStatic, manifestStatic) expect(result).to.deep.equal(validManifest) }) it('should throw error if the codius manifest has schema errors', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) delete manifest['manifest']['name'] await fse.writeJson(manifestMock, manifest) const result = generateManifest(varsMock, manifestMock) return expect(result).to.be.rejected }) it('should throw error if codiusvars has schema errors', async function () { const vars = JSON.parse(JSON.stringify(varsJson)) delete vars['vars'] await fse.writeJson(varsMock, vars) const result = generateManifest(varsMock, manifestMock) return expect(result).to.be.rejected }) it('should override public vars that are already defined', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) manifest['manifest']['vars']['AWS_ACCESS_KEY'] = { value: 'ABSCEDADFSDSF' } await fse.writeJson(manifestMock, manifest) const result = generateManifest(varsMock, manifestMock) return expect(result).to.eventually.become(validManifest) }) it('should create the public encoding for private variables', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) delete manifest['manifest']['vars']['AWS_SECRET_KEY'] await fse.writeJson(manifestMock, manifest) const result = generateManifest(varsMock, manifestMock) return expect(result).to.eventually.become(validManifest) }) it('should override the public encodings for all private vars', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) manifest['manifest']['vars']['AWS_SECRET_KEY'] = { 'encoding': 'private:sha256', 'value': 'thisaninvalidhash' } await fse.writeJson(manifestMock, manifest) const result = generateManifest(varsMock, manifestMock) return expect(result).to.eventually.become(validManifest) }) it('should remove all description fields from the final manifest', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) manifest['manifest']['vars']['AWS_SECRET_KEY']['description'] = 'An AWS secret key' manifest['manifest']['vars']['AWS_ACCESS_KEY']['description'] = 'An AWS access key' await fse.writeJson(manifestMock, manifest) const result = generateManifest(varsMock, manifestMock) return expect(result).to.eventually.become(validManifest) }) it('should not include manifest.vars and manifest.private in final manifest if codiusvars has empty public and private var fields', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) delete manifest['manifest']['vars'] manifest['manifest']['containers'][0]['environment']['AWS_SECRET_KEY'] = 'AWS_SECRET_KEY' manifest['manifest']['containers'][0]['environment']['AWS_ACCESS_KEY'] = 'AWS_ACCESS_KEY' await fse.writeJson(manifestMock, manifest) const vars = JSON.parse(JSON.stringify(varsJson)) vars['vars']['public'] = {} vars['vars']['private'] = {} await fse.writeJson(varsMock, vars) const newValidManifest = JSON.parse(JSON.stringify(validManifest)) delete newValidManifest['manifest']['vars'] delete newValidManifest['private'] newValidManifest['manifest']['containers'][0]['environment']['AWS_SECRET_KEY'] = 'AWS_SECRET_KEY' newValidManifest['manifest']['containers'][0]['environment']['AWS_ACCESS_KEY'] = 'AWS_ACCESS_KEY' const result = generateManifest(varsMock, manifestMock) return expect(result).to.eventually.become(newValidManifest) }) it('should add an empty private var field to the final manifest if the public vars are defined', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) delete manifest['manifest']['vars']['AWS_SECRET_KEY'] delete manifest['manifest']['containers'][0]['environment']['AWS_SECRET_KEY'] delete manifest['private'] await fse.writeJson(manifestMock, manifest) const vars = JSON.parse(JSON.stringify(varsJson)) delete vars['vars']['private']['AWS_SECRET_KEY'] await fse.writeJson(varsMock, vars) const newValidManifest = JSON.parse(JSON.stringify(validManifest)) newValidManifest['private'] = {} delete newValidManifest['manifest']['containers'][0]['environment']['AWS_SECRET_KEY'] delete newValidManifest['manifest']['vars']['AWS_SECRET_KEY'] const result = generateManifest(varsMock, manifestMock) return expect(result).to.eventually.become(newValidManifest) } ) it('should add public encodings for private vars field even if public vars are not defined in codiusvars', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) delete manifest['manifest']['vars'] manifest['manifest']['containers'][0]['environment']['AWS_SECRET_KEY'] = '$AWS_SECRET_KEY' manifest['manifest']['containers'][0]['environment']['AWS_ACCESS_KEY'] = 'AWS_ACCESS_KEY' await fse.writeJson(manifestMock, manifest) const vars = JSON.parse(JSON.stringify(varsJson)) vars['vars']['public'] = {} await fse.writeJson(varsMock, vars) const newValidManifest = JSON.parse(JSON.stringify(validManifest)) delete newValidManifest['manifest']['vars']['AWS_ACCESS_KEY'] newValidManifest['manifest']['containers'][0]['environment']['AWS_SECRET_KEY'] = '$AWS_SECRET_KEY' newValidManifest['manifest']['containers'][0]['environment']['AWS_ACCESS_KEY'] = 'AWS_ACCESS_KEY' const result = generateManifest(varsMock, manifestMock) return expect(result).to.eventually.become(newValidManifest) }) it('should add manifest.vars field to final manifest if vars are defined in codiusvars but not in codius', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) delete manifest['manifest']['vars'] await fse.writeJson(manifestMock, manifest) const result = generateManifest(varsMock, manifestMock) return expect(result).to.eventually.become(validManifest) }) it('should not throw an error if the environment and vars fields are undefined', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) delete manifest['manifest']['containers'][0]['environment'] delete manifest['manifest']['vars'] await fse.writeJson(manifestMock, manifest) const vars = JSON.parse(JSON.stringify(varsJson)) vars['vars']['public'] = {} vars['vars']['private'] = {} await fse.writeJson(varsMock, vars) const newValidManifest = JSON.parse(JSON.stringify(validManifest)) delete newValidManifest['manifest']['vars'] delete newValidManifest['private'] delete newValidManifest['manifest']['containers'][0]['environment'] const result = generateManifest(varsMock, manifestMock) return expect(result).to.eventually.become(newValidManifest) }) it('should remove empty environment fields from containers in final manifest', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) manifest['manifest']['containers'][0]['environment'] = {} delete manifest['manifest']['vars'] await fse.writeJson(manifestMock, manifest) const vars = JSON.parse(JSON.stringify(varsJson)) vars['vars']['public'] = {} vars['vars']['private'] = {} await fse.writeJson(varsMock, vars) const newValidManifest = JSON.parse(JSON.stringify(validManifest)) delete newValidManifest['manifest']['vars'] delete newValidManifest['private'] delete newValidManifest['manifest']['containers'][0]['environment'] const result = generateManifest(varsMock, manifestMock) return expect(result).to.eventually.become(newValidManifest) }) // Relies on response from docker registry api to pass it('should produce an error if a container contains an invalid image', async function () { const manifestUrl = 'https://registry-1.docker.io/v2/library/nginx/manifests/1231984' this.get.withArgs(manifestUrl).throws('Error: Request failed with status code 404') this.get.callThrough() const manifest = JSON.parse(JSON.stringify(manifestJson)) manifest['manifest']['containers'][0]['image'] = 'nginx:1231984' await fse.writeJson(manifestMock, manifest) const result = generateManifest(varsMock, manifestMock) return expect(result).to.be.rejectedWith('Unable to get manifest info from registry.') }).timeout(3000) // Relies on response from docker registry api to pass it('should resolve image tags to proper digest', async function () { const manifestUrl = 'https://registry-1.docker.io/v2/library/nginx/manifests/1.15.0' this.get.withArgs(manifestUrl).returns({ headers: { 'docker-content-digest': 'sha256:62a095e5da5f977b9f830adaf64d604c614024bf239d21068e4ca826d0d629a4' } }) this.get.callThrough() const manifest = JSON.parse(JSON.stringify(manifestJson)) manifest['manifest']['containers'][0]['image'] = 'nginx:1.15.0' await fse.writeJson(manifestMock, manifest) const result = generateManifest(varsMock, manifestMock) validManifest['manifest']['containers'][0]['image'] = 'nginx@sha256:62a095e5da5f977b9f830adaf64d604c614024bf239d21068e4ca826d0d629a4' return expect(result).to.eventually.become(validManifest) }).timeout(3000) it('should not update image hash if digest is already specified', async function () { const manifest = JSON.parse(JSON.stringify(manifestJson)) manifest['manifest']['containers'][0]['image'] = 'nginx@sha256:0946416199aca5c7bd2c3173f8a909b0873e9017562f1a445d061fce6664a049' await fse.writeJson(manifestMock, manifest) const result = generateManifest(varsMock, manifestMock) validManifest['manifest']['containers'][0]['image'] = `nginx@sha256:0946416199aca5c7bd2c3173f8a909b0873e9017562f1a445d061fce6664a049` return expect(result).to.eventually.become(validManifest) }).timeout(3000) })