Skip to content

Commit

Permalink
mid work
Browse files Browse the repository at this point in the history
  • Loading branch information
iliapolo committed Aug 31, 2024
1 parent 208af15 commit bcaa766
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 33 deletions.
24 changes: 18 additions & 6 deletions lib/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,6 @@ export class Manifest {
if (errors.length > 0) {
throw new Error(`Invalid assembly manifest:\n${errors.map((e) => e.stack).join('\n')}`);
}

// // now we are safe to cast and work on the expected type and perform custom validations
// this.validateStackArtifactAssumeRoleAdditionalOptions(manifest as AssemblyManifest);
}

private static saveManifest(
Expand Down Expand Up @@ -314,14 +311,17 @@ export class Manifest {

private static validateAssemblyManifestAssumeRoleAdditionalOptions(manifest: AssemblyManifest) {
for (const [aid, artifact] of Object.entries(manifest.artifacts ?? {})) {
if (!artifact.properties) {
continue;
}
switch (artifact.type) {
case 'aws:cloudformation:stack':
const properties = artifact.properties as assembly.AwsCloudFormationStackProperties;

if (properties.assumeRoleAdditionalOptions) {
this.validateAssumeRoleAdditionalOptions(
properties.assumeRoleAdditionalOptions,
`artifacts.${aid}.properties.assumeRoleAdditionalOptions`,
`artifacts.${aid}.properties`,
'assumeRoleArn',
'assumeRoleExternalId'
);
Expand All @@ -330,7 +330,7 @@ export class Manifest {
if (properties.lookupRole?.assumeRoleAdditionalOptions) {
this.validateAssumeRoleAdditionalOptions(
properties.lookupRole.assumeRoleAdditionalOptions,
`artifacts.${aid}.properties.lookupRole.assumeRoleAdditionalOptions`,
`artifacts.${aid}.properties.lookupRole`,
'arn',
'assumeRoleExternalId'
);
Expand All @@ -349,7 +349,19 @@ export class Manifest {
if (destination.assumeRoleAdditionalOptions) {
this.validateAssumeRoleAdditionalOptions(
destination.assumeRoleAdditionalOptions,
`files.${aid}.destinations.${did}.assumeRoleAdditionalOptions`,
`files.${aid}.destinations.${did}`,
'assumeRoleArn',
'assumeRoleExternalId'
);
}
}
}
for (const [aid, artifact] of Object.entries(manifest.dockerImages ?? {})) {
for (const [did, destination] of Object.entries(artifact.destinations ?? {})) {
if (destination.assumeRoleAdditionalOptions) {
this.validateAssumeRoleAdditionalOptions(
destination.assumeRoleAdditionalOptions,
`dockerImages.${aid}.destinations.${did}`,
'assumeRoleArn',
'assumeRoleExternalId'
);
Expand Down
150 changes: 128 additions & 22 deletions test/assets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { FileAssetPackaging, Manifest } from '../lib';
describe('Docker image asset', () => {
test('valid input', () => {
expect(() => {
validate({
load({
version: Manifest.version(),
dockerImages: {
asset: {
Expand Down Expand Up @@ -40,7 +40,7 @@ describe('Docker image asset', () => {

test('invalid input', () => {
expect(() => {
validate({
load({
version: Manifest.version(),
dockerImages: {
asset: {
Expand All @@ -58,34 +58,73 @@ describe('Docker image asset', () => {
}).toThrow(/instance\.dockerImages\.asset\.source\.directory is not of a type\(s\) string/);
});

test('manifest load fails when assumeRoleAdditionalOptions.RoleArn is used in image destination', () => {
expect(() => {
validate({
version: Manifest.version(),
dockerImages: {
asset: {
source: {
directory: '.',
test('cannot use assumeRoleAdditionalOptions.RoleArn', () => {
const manifest = {
version: Manifest.version(),
dockerImages: {
asset: {
source: {
directory: '.',
},
destinations: {
dest: {
region: 'us-north-20',
repositoryName: 'REPO',
imageTag: 'TAG',
assumeRoleAdditionalOptions: {
RoleArn: 'some-role-arn',
},
},
destinations: {
dest: {
region: 'us-north-20',
repositoryName: 'REPO',
imageTag: 'TAG',
},
},
},
};
const expectedError = `RoleArn is not allowed inside 'dockerImages.asset.destinations.dest.assumeRoleAdditionalOptions'. Use 'dockerImages.asset.destinations.dest.assumeRoleArn' instead.`;
expect(() => {
load(manifest);
}).toThrow(expectedError);
expect(() => {
save(manifest, 'somewhere');
}).toThrow(expectedError);
});

test('cannot use assumeRoleAdditionalOptions.ExternalId', () => {
const manifest = {
version: Manifest.version(),
dockerImages: {
asset: {
source: {
directory: '.',
},
destinations: {
dest: {
region: 'us-north-20',
repositoryName: 'REPO',
imageTag: 'TAG',
assumeRoleAdditionalOptions: {
ExternalId: 'some-external-id',
},
},
},
},
});
}).toThrow(/instance\.dockerImages\.asset\.source\.directory is not of a type\(s\) string/);
},
};
const expectedError = `ExternalId is not allowed inside 'dockerImages.asset.destinations.dest.assumeRoleAdditionalOptions'. Use 'dockerImages.asset.destinations.dest.assumeRoleExternalId' instead.`;

expect(() => {
load(manifest);
}).toThrow(expectedError);
expect(() => {
save(manifest, 'somewhere');
}).toThrow(expectedError);
});
});

describe('File asset', () => {
describe('valid input', () => {
test('without packaging', () => {
expect(() => {
validate({
load({
version: Manifest.version(),
files: {
asset: {
Expand Down Expand Up @@ -120,7 +159,7 @@ describe('File asset', () => {
for (const packaging of Object.values(FileAssetPackaging)) {
test(`with "${packaging}" packaging`, () => {
expect(() => {
validate({
load({
version: Manifest.version(),
files: {
asset: {
Expand All @@ -146,7 +185,7 @@ describe('File asset', () => {
describe('invalid input', () => {
test('bad "source.path" property', () => {
expect(() => {
validate({
load({
version: Manifest.version(),
files: {
asset: {
Expand Down Expand Up @@ -180,7 +219,7 @@ describe('File asset', () => {

test('bad "source.packaging" property', () => {
expect(() => {
validate({
load({
version: Manifest.version(),
files: {
asset: {
Expand All @@ -200,10 +239,71 @@ describe('File asset', () => {
});
}).toThrow(/instance\.files\.asset\.source\.packaging is not one of enum values: file,zip/);
});

test('cannot use assumeRoleAdditionalOptions.RoleArn', () => {
const manifest = {
version: Manifest.version(),
files: {
asset: {
source: {
path: 'a/b/c',
},
destinations: {
dest: {
region: 'us-north-20',
bucketName: 'Bouquet',
objectKey: 'key',
assumeRoleAdditionalOptions: {
RoleArn: 'some-role-arn',
},
},
},
},
},
};
const expectedError = `RoleArn is not allowed inside 'files.asset.destinations.dest.assumeRoleAdditionalOptions'. Use 'files.asset.destinations.dest.assumeRoleArn' instead.`;
expect(() => {
load(manifest);
}).toThrow(expectedError);
expect(() => {
save(manifest, 'somewhere');
}).toThrow(expectedError);
});

test('cannot use assumeRoleAdditionalOptions.ExternalId', () => {
const manifest = {
version: Manifest.version(),
files: {
asset: {
source: {
path: 'a/b/c',
},
destinations: {
dest: {
region: 'us-north-20',
bucketName: 'Bouquet',
objectKey: 'key',
assumeRoleAdditionalOptions: {
ExternalId: 'some-external-id',
},
},
},
},
},
};
const expectedError = `ExternalId is not allowed inside 'files.asset.destinations.dest.assumeRoleAdditionalOptions'. Use 'files.asset.destinations.dest.assumeRoleExternalId' instead.`;

expect(() => {
load(manifest);
}).toThrow(expectedError);
expect(() => {
save(manifest, 'somewhere');
}).toThrow(expectedError);
});
});
});

function validate(manifest: any) {
function load(manifest: any) {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'assets.test.'));
const filePath = path.join(dir, 'manifest.json');
fs.writeFileSync(filePath, JSON.stringify(manifest, undefined, 2));
Expand All @@ -214,3 +314,9 @@ function validate(manifest: any) {
fs.rmdirSync(dir);
}
}

function save(manifest: any, to: string) {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'assets.test.'));
const filePath = path.join(dir, to);
Manifest.saveAssetManifest(manifest, filePath);
}
Loading

0 comments on commit bcaa766

Please sign in to comment.