/ cloudformation-templates / node_modules / aws-cdk / test / api / cloudformation-deployments.test.js
cloudformation-deployments.test.js
1 "use strict"; 2 Object.defineProperty(exports, "__esModule", { value: true }); 3 jest.mock('../../lib/api/deploy-stack'); 4 const cloudformation_deployments_1 = require("../../lib/api/cloudformation-deployments"); 5 const deploy_stack_1 = require("../../lib/api/deploy-stack"); 6 const toolkit_info_1 = require("../../lib/api/toolkit-info"); 7 const util_1 = require("../util"); 8 const mock_sdk_1 = require("../util/mock-sdk"); 9 let sdkProvider; 10 let deployments; 11 let mockToolkitInfoLookup; 12 beforeEach(() => { 13 jest.resetAllMocks(); 14 sdkProvider = new mock_sdk_1.MockSdkProvider(); 15 deployments = new cloudformation_deployments_1.CloudFormationDeployments({ sdkProvider }); 16 toolkit_info_1.ToolkitInfo.lookup = mockToolkitInfoLookup = jest.fn().mockResolvedValue(toolkit_info_1.ToolkitInfo.bootstrapStackNotFoundInfo(sdkProvider.sdk)); 17 }); 18 function mockSuccessfulBootstrapStackLookup(props) { 19 const outputs = { 20 BucketName: 'BUCKET_NAME', 21 BucketDomainName: 'BUCKET_ENDPOINT', 22 BootstrapVersion: '1', 23 ...props, 24 }; 25 const fakeStack = mock_sdk_1.mockBootstrapStack(sdkProvider.sdk, { 26 Outputs: Object.entries(outputs).map(([k, v]) => ({ 27 OutputKey: k, 28 OutputValue: `${v}`, 29 })), 30 }); 31 mockToolkitInfoLookup.mockResolvedValue(toolkit_info_1.ToolkitInfo.fromStack(fakeStack, sdkProvider.sdk)); 32 } 33 test('placeholders are substituted in CloudFormation execution role', async () => { 34 await deployments.deployStack({ 35 stack: util_1.testStack({ 36 stackName: 'boop', 37 properties: { 38 cloudFormationExecutionRoleArn: 'bloop:${AWS::Region}:${AWS::AccountId}', 39 }, 40 }), 41 }); 42 expect(deploy_stack_1.deployStack).toHaveBeenCalledWith(expect.objectContaining({ 43 roleArn: 'bloop:here:123456789012', 44 })); 45 }); 46 test('role with placeholders is assumed if assumerole is given', async () => { 47 const mockForEnvironment = jest.fn(); 48 sdkProvider.forEnvironment = mockForEnvironment; 49 await deployments.deployStack({ 50 stack: util_1.testStack({ 51 stackName: 'boop', 52 properties: { 53 assumeRoleArn: 'bloop:${AWS::Region}:${AWS::AccountId}', 54 }, 55 }), 56 }); 57 expect(mockForEnvironment).toHaveBeenCalledWith(expect.anything(), expect.anything(), expect.objectContaining({ 58 assumeRoleArn: 'bloop:here:123456789012', 59 })); 60 }); 61 test('deployment fails if bootstrap stack is missing', async () => { 62 await expect(deployments.deployStack({ 63 stack: util_1.testStack({ 64 stackName: 'boop', 65 properties: { 66 assumeRoleArn: 'bloop:${AWS::Region}:${AWS::AccountId}', 67 requiresBootstrapStackVersion: 99, 68 }, 69 }), 70 })).rejects.toThrow(/requires a bootstrap stack/); 71 }); 72 test('deployment fails if bootstrap stack is too old', async () => { 73 mockSuccessfulBootstrapStackLookup({ 74 BootstrapVersion: 5, 75 }); 76 await expect(deployments.deployStack({ 77 stack: util_1.testStack({ 78 stackName: 'boop', 79 properties: { 80 assumeRoleArn: 'bloop:${AWS::Region}:${AWS::AccountId}', 81 requiresBootstrapStackVersion: 99, 82 }, 83 }), 84 })).rejects.toThrow(/requires bootstrap stack version '99', found '5'/); 85 }); 86 test('if toolkit stack cannot be found but SSM parameter name is present deployment succeeds', async () => { 87 // FIXME: Mocking a successful bootstrap stack lookup here should not be necessary. 88 // This should fail and return a placeholder failure object. 89 mockSuccessfulBootstrapStackLookup({ 90 BootstrapVersion: 2, 91 }); 92 let requestedParameterName; 93 sdkProvider.stubSSM({ 94 getParameter(request) { 95 requestedParameterName = request.Name; 96 return { 97 Parameter: { 98 Value: '99', 99 }, 100 }; 101 }, 102 }); 103 await deployments.deployStack({ 104 stack: util_1.testStack({ 105 stackName: 'boop', 106 properties: { 107 assumeRoleArn: 'bloop:${AWS::Region}:${AWS::AccountId}', 108 requiresBootstrapStackVersion: 99, 109 bootstrapStackVersionSsmParameter: '/some/parameter', 110 }, 111 }), 112 }); 113 expect(requestedParameterName).toEqual('/some/parameter'); 114 }); 115 //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWRmb3JtYXRpb24tZGVwbG95bWVudHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNsb3VkZm9ybWF0aW9uLWRlcGxveW1lbnRzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLENBQUM7QUFFeEMseUZBQXFGO0FBQ3JGLDZEQUF5RDtBQUN6RCw2REFBeUQ7QUFDekQsa0NBQW9DO0FBQ3BDLCtDQUF1RTtBQUV2RSxJQUFJLFdBQTRCLENBQUM7QUFDakMsSUFBSSxXQUFzQyxDQUFDO0FBQzNDLElBQUkscUJBQWdDLENBQUM7QUFDckMsVUFBVSxDQUFDLEdBQUcsRUFBRTtJQUNkLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUNyQixXQUFXLEdBQUcsSUFBSSwwQkFBZSxFQUFFLENBQUM7SUFDcEMsV0FBVyxHQUFHLElBQUksc0RBQXlCLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQzdELDBCQUFXLENBQUMsTUFBTSxHQUFHLHFCQUFxQixHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQywwQkFBVyxDQUFDLDBCQUEwQixDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3BJLENBQUMsQ0FBQyxDQUFDO0FBRUgsU0FBUyxrQ0FBa0MsQ0FBQyxLQUEyQjtJQUNyRSxNQUFNLE9BQU8sR0FBRztRQUNkLFVBQVUsRUFBRSxhQUFhO1FBQ3pCLGdCQUFnQixFQUFFLGlCQUFpQjtRQUNuQyxnQkFBZ0IsRUFBRSxHQUFHO1FBQ3JCLEdBQUcsS0FBSztLQUNULENBQUM7SUFFRixNQUFNLFNBQVMsR0FBRyw2QkFBa0IsQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFO1FBQ3BELE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENB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WSxDQUFDLE9BQU87WUFDbEIsc0JBQXNCLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztZQUN0QyxPQUFPO2dCQUNMLFNBQVMsRUFBRTtvQkFDVCxLQUFLLEVBQUUsSUFBSTtpQkFDWjthQUNGLENBQUM7UUFDSixDQUFDO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsTUFBTSxXQUFXLENBQUMsV0FBVyxDQUFDO1FBQzVCLEtBQUssRUFBRSxnQkFBUyxDQUFDO1lBQ2YsU0FBUyxFQUFFLE1BQU07WUFDakIsVUFBVSxFQUFFO2dCQUNWLGFBQWEsRUFBRSx3Q0FBd0M7Z0JBQ3ZELDZCQUE2QixFQUFFLEVBQUU7Z0JBQ2pDLGlDQUFpQyxFQUFFLGlCQUFpQjthQUNyRDtTQUNGLENBQUM7S0FDSCxDQUFDLENBQUM7SUFFSCxNQUFNLENBQUMsc0JBQXVCLENBQUMsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUM3RCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImplc3QubW9jaygnLi4vLi4vbGliL2FwaS9kZXBsb3ktc3RhY2snKTtcblxuaW1wb3J0IHsgQ2xvdWRGb3JtYXRpb25EZXBsb3ltZW50cyB9IGZyb20gJy4uLy4uL2xpYi9hcGkvY2xvdWRmb3JtYXRpb24tZGVwbG95bWVudHMnO1xuaW1wb3J0IHsgZGVwbG95U3RhY2sgfSBmcm9tICcuLi8uLi9saWIvYXBpL2RlcGxveS1zdGFjayc7XG5pbXBvcnQgeyBUb29sa2l0SW5mbyB9IGZyb20gJy4uLy4uL2xpYi9hcGkvdG9vbGtpdC1pbmZvJztcbmltcG9ydCB7IHRlc3RTdGFjayB9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHsgbW9ja0Jvb3RzdHJhcFN0YWNrLCBNb2NrU2RrUHJvdmlkZXIgfSBmcm9tICcuLi91dGlsL21vY2stc2RrJztcblxubGV0IHNka1Byb3ZpZGVyOiBNb2NrU2RrUHJvdmlkZXI7XG5sZXQgZGVwbG95bWVudHM6IENsb3VkRm9ybWF0aW9uRGVwbG95bWVudHM7XG5sZXQgbW9ja1Rvb2xraXRJbmZvTG9va3VwOiBqZXN0Lk1vY2s7XG5iZWZvcmVFYWNoKCgpID0+IHtcbiAgamVzdC5yZXNldEFsbE1vY2tzKCk7XG4gIHNka1Byb3ZpZGVyID0gbmV3IE1vY2tTZGtQcm92aWRlcigpO1xuICBkZXBsb3ltZW50cyA9IG5ldyBDbG91ZEZvcm1hdGlvbkRlcGxveW1lbnRzKHsgc2RrUHJvdmlkZXIgfSk7XG4gIFRvb2xraXRJbmZvLmxvb2t1cCA9IG1vY2tUb29sa2l0SW5mb0xvb2t1cCA9IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShUb29sa2l0SW5mby5ib290c3RyYXBTdGFja05vdEZvdW5kSW5mbyhzZGtQcm92aWRlci5zZGspKTtcbn0pO1xuXG5mdW5jdGlvbiBtb2NrU3VjY2Vzc2Z1bEJvb3RzdHJhcFN0YWNrTG9va3VwKHByb3BzPzogUmVjb3JkPHN0cmluZywgYW55Pikge1xuICBjb25zdCBvdXRwdXRzID0ge1xuICAgIEJ1Y2tldE5hbWU6ICdCVUNLRVRfTkFNRScsXG4gICAgQnVja2V0RG9tYWluTmFtZTogJ0JVQ0tFVF9FTkRQT0lOVCcsXG4gICAgQm9vdHN0cmFwVmVyc2lvbjogJzEnLFxuICAgIC4uLnByb3BzLFxuICB9O1xuXG4gIGNvbnN0IGZha2VTdGFjayA9IG1vY2tCb290c3RyYXBTdGFjayhzZGtQcm92aWRlci5zZGssIHtcbiAgICBPdXRwdXRzOiBPYmplY3QuZW50cmllcyhvdXRwdXRzKS5tYXAoKFtrLCB2XSkgPT4gKHtcbiAgICAgIE91dHB1dEtleTogayxcbiAgICAgIE91dHB1dFZhbHVlOiBgJHt2fWAsXG4gICAgfSkpLFxuICB9KTtcblxuICBtb2NrVG9vbGtpdEluZm9Mb29rdXAubW9ja1Jlc29sdmVkVmFsdWUoVG9vbGtpdEluZm8uZnJvbVN0YWNrKGZha2VTdGFjaywgc2RrUHJvdmlkZXIuc2RrKSk7XG59XG5cbnRlc3QoJ3BsYWNlaG9sZGVycyBhcmUgc3Vic3RpdHV0ZWQgaW4gQ2xvdWRGb3JtYXRpb24gZXhlY3V0aW9uIHJvbGUnLCBhc3luYyAoKSA9PiB7XG4gIGF3YWl0IGRlcGxveW1lbnRzLmRlcGxveVN0YWNrKHtcbiAgICBzdGFjazogdGVzdFN0YWNrKHtcbiAgICAgIHN0YWNrTmFtZTogJ2Jvb3AnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBjbG91ZEZvcm1hdGlvbkV4ZWN1dGlvblJvbGVBcm46ICdibG9vcDoke0FXUzo6UmVnaW9ufToke0FXUzo6QWNjb3VudElkfScsXG4gICAgICB9LFxuICAgIH0pLFxuICB9KTtcblxuICBleHBlY3QoZGVwbG95U3RhY2spLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICByb2xlQXJuOiAnYmxvb3A6aGVyZToxMjM0NTY3ODkwMTInLFxuICB9KSk7XG59KTtcblxudGVzdCgncm9sZSB3aXRoIHBsYWNlaG9sZGVycyBpcyBhc3N1bWVkIGlmIGFzc3VtZXJvbGUgaXMgZ2l2ZW4nLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IG1vY2tGb3JFbnZpcm9ubWVudCA9IGplc3QuZm4oKTtcbiAgc2RrUHJvdmlkZXIuZm9yRW52aXJvbm1lbnQgPSBtb2NrRm9yRW52aXJvbm1lbnQ7XG5cbiAgYXdhaXQgZGVwbG95bWVudHMuZGVwbG95U3RhY2soe1xuICAgIHN0YWNrOiB0ZXN0U3RhY2soe1xuICAgICAgc3RhY2tOYW1lOiAnYm9vcCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGFzc3VtZVJvbGVBcm46ICdibG9vcDoke0FXUzo6UmVnaW9ufToke0FXUzo6QWNjb3VudElkfScsXG4gICAgICB9LFxuICAgIH0pLFxuICB9KTtcblxuICBleHBlY3QobW9ja0ZvckVudmlyb25tZW50KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChleHBlY3QuYW55dGhpbmcoKSwgZXhwZWN0LmFueXRoaW5nKCksIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICBhc3N1bWVSb2xlQXJuOiAnYmxvb3A6aGVyZToxMjM0NTY3ODkwMTInLFxuICB9KSk7XG59KTtcblxudGVzdCgnZGVwbG95bWVudCBmYWlscyBpZiBib290c3RyYXAgc3RhY2sgaXMgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgYXdhaXQgZXhwZWN0KGRlcGxveW1lbnRzLmRlcGxveVN0YWNrKHtcbiAgICBzdGFjazogdGVzdFN0YWNrKHtcbiAgICAgIHN0YWNrTmFtZTogJ2Jvb3AnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBhc3N1bWVSb2xlQXJuOiAnYmxvb3A6JHtBV1M6OlJlZ2lvbn06JHtBV1M6OkFjY291bnRJZH0nLFxuICAgICAgICByZXF1aXJlc0Jvb3RzdHJhcFN0YWNrVmVyc2lvbjogOTksXG4gICAgICB9LFxuICAgIH0pLFxuICB9KSkucmVqZWN0cy50b1Rocm93KC9yZXF1aXJlcyBhIGJvb3RzdHJhcCBzdGFjay8pO1xufSk7XG5cbnRlc3QoJ2RlcGxveW1lbnQgZmFpbHMgaWYgYm9vdHN0cmFwIHN0YWNrIGlzIHRvbyBvbGQnLCBhc3luYyAoKSA9PiB7XG4gIG1vY2tTdWNjZXNzZnVsQm9vdHN0cmFwU3RhY2tMb29rdXAoe1xuICAgIEJvb3RzdHJhcFZlcnNpb246IDUsXG4gIH0pO1xuXG4gIGF3YWl0IGV4cGVjdChkZXBsb3ltZW50cy5kZXBsb3lTdGFjayh7XG4gICAgc3RhY2s6IHRlc3RTdGFjayh7XG4gICAgICBzdGFja05hbWU6ICdib29wJyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYXNzdW1lUm9sZUFybjogJ2Jsb29wOiR7QVdTOjpSZWdpb259OiR7QVdTOjpBY2NvdW50SWR9JyxcbiAgICAgICAgcmVxdWlyZXNCb290c3RyYXBTdGFja1ZlcnNpb246IDk5LFxuICAgICAgfSxcbiAgICB9KSxcbiAgfSkpLnJlamVjdHMudG9UaHJvdygvcmVxdWlyZXMgYm9vdHN0cmFwIHN0YWNrIHZlcnNpb24gJzk5JywgZm91bmQgJzUnLyk7XG59KTtcblxudGVzdCgnaWYgdG9vbGtpdCBzdGFjayBjYW5ub3QgYmUgZm91bmQgYnV0IFNTTSBwYXJhbWV0ZXIgbmFtZSBpcyBwcmVzZW50IGRlcGxveW1lbnQgc3VjY2VlZHMnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEZJWE1FOiBNb2NraW5nIGEgc3VjY2Vzc2Z1bCBib290c3RyYXAgc3RhY2sgbG9va3VwIGhlcmUgc2hvdWxkIG5vdCBiZSBuZWNlc3NhcnkuXG4gIC8vIFRoaXMgc2hvdWxkIGZhaWwgYW5kIHJldHVybiBhIHBsYWNlaG9sZGVyIGZhaWx1cmUgb2JqZWN0LlxuICBtb2NrU3VjY2Vzc2Z1bEJvb3RzdHJhcFN0YWNrTG9va3VwKHtcbiAgICBCb290c3RyYXBWZXJzaW9uOiAyLFxuICB9KTtcblxuICBsZXQgcmVxdWVzdGVkUGFyYW1ldGVyTmFtZTogc3RyaW5nO1xuICBzZGtQcm92aWRlci5zdHViU1NNKHtcbiAgICBnZXRQYXJhbWV0ZXIocmVxdWVzdCkge1xuICAgICAgcmVxdWVzdGVkUGFyYW1ldGVyTmFtZSA9IHJlcXVlc3QuTmFtZTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIFBhcmFtZXRlcjoge1xuICAgICAgICAgIFZhbHVlOiAnOTknLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICB9KTtcblxuICBhd2FpdCBkZXBsb3ltZW50cy5kZXBsb3lTdGFjayh7XG4gICAgc3RhY2s6IHRlc3RTdGFjayh7XG4gICAgICBzdGFja05hbWU6ICdib29wJyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYXNzdW1lUm9sZUFybjogJ2Jsb29wOiR7QVdTOjpSZWdpb259OiR7QVdTOjpBY2NvdW50SWR9JyxcbiAgICAgICAgcmVxdWlyZXNCb290c3RyYXBTdGFja1ZlcnNpb246IDk5LFxuICAgICAgICBib290c3RyYXBTdGFja1ZlcnNpb25Tc21QYXJhbWV0ZXI6ICcvc29tZS9wYXJhbWV0ZXInLFxuICAgICAgfSxcbiAgICB9KSxcbiAgfSk7XG5cbiAgZXhwZWN0KHJlcXVlc3RlZFBhcmFtZXRlck5hbWUhKS50b0VxdWFsKCcvc29tZS9wYXJhbWV0ZXInKTtcbn0pO1xuIl19