/ 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