Пример #1
0
    def deploy(self):
        """
        [option]

        option:
        stack-name: CloudFormation stack name
        template-path: CloudFormation template file path
        params-path: CloudFormation template parameters file path.
                     allowed file type: json, jsonnet
        """
        client = boto3.client('cloudformation')

        if not os.path.isfile(self.template_path):
            raise exceptions.InvalidTemplatePathError(template_path=self.template_path)
        with open(self.template_path, "r") as f:
            template_str = f.read()

        params = self.__load_cfn_params(self.params_path)
        tags = []
        s3_uploader = None

        deployer = Deployer(client)
        self.__deploy(deployer, self.stack_name, template_str,
                      params, ['CAPABILITY_IAM', 'CAPABILITY_AUTO_EXPAND'],
                      True, None, None, s3_uploader, tags, False)
Пример #2
0
    def setUp(self):
        self.session = mock.Mock()
        self.session.get_scoped_config.return_value = {}
        self.parsed_args = FakeArgs(
            template_file='./foo',
            stack_name="some_stack_name",
            parameter_overrides=["Key1=Value1", "Key2=Value2"],
            no_execute_changeset=False,
            execute_changeset=True,
            capabilities=None,
            role_arn=None,
            notification_arns=[],
            fail_on_empty_changeset=True,
            s3_bucket=None,
            s3_prefix="some prefix",
            kms_key_id="some kms key id",
            force_upload=True,
            tags=["tagkey1=tagvalue1"])
        self.parsed_globals = FakeArgs(region="us-east-1",
                                       endpoint_url=None,
                                       verify_ssl=None)
        self.deploy_command = DeployCommand(self.session)

        self.deployer = Deployer(Mock())
        self.deployer.create_and_wait_for_changeset = Mock()
        self.deployer.execute_changeset = Mock()
        self.deployer.wait_for_execute = Mock()
Пример #3
0
    def test_wait_for_execute_no_changes(self):
        stack_name = "stack_name"
        changeset_type = "CREATE"

        mock_client = mock.Mock()
        mock_deployer = Deployer(mock_client)
        mock_waiter = mock.Mock()
        mock_client.get_waiter.return_value = mock_waiter

        waiter_error = botocore.exceptions.WaiterError(name="name",
                                                       reason="reason",
                                                       last_response={})
        mock_waiter.wait.side_effect = waiter_error

        with self.assertRaises(exceptions.DeployFailedError):
            mock_deployer.wait_for_execute(stack_name, changeset_type)

        waiter_config = {
            'Delay': 30,
            'MaxAttempts': 120,
        }
        mock_waiter.wait.assert_called_once_with(StackName=stack_name,
                                                 WaiterConfig=waiter_config)

        mock_client.get_waiter.assert_called_once_with("stack_create_complete")
Пример #4
0
    def _run_main(self, parsed_args, parsed_globals):
        cloudformation_client = \
            self._session.create_client(
                    'cloudformation', region_name=parsed_globals.region,
                    endpoint_url=parsed_globals.endpoint_url,
                    verify=parsed_globals.verify_ssl)

        template_path = parsed_args.template_file
        if not os.path.isfile(template_path):
            raise exceptions.InvalidTemplatePathError(
                    template_path=template_path)

        # Parse parameters
        with open(template_path, "r") as handle:
            template_str = handle.read()

        stack_name = parsed_args.stack_name
        parameter_overrides = self.parse_parameter_arg(
                parsed_args.parameter_overrides)

        template_dict = yaml_parse(template_str)

        parameters = self.merge_parameters(template_dict, parameter_overrides)

        deployer = Deployer(cloudformation_client)
        return self.deploy(deployer, stack_name, template_str,
                           parameters, parsed_args.capabilities,
                           parsed_args.execute_changeset, parsed_args.role_arn,
                           parsed_args.notification_arns,
                           parsed_args.fail_on_empty_changeset)
Пример #5
0
    def setUp(self):
        client = botocore.session.get_session().create_client(
            'cloudformation', region_name="us-east-1")
        self.stub_client = Stubber(client)

        self.changeset_prefix = "some-changeset-prefix"
        self.deployer = Deployer(client, self.changeset_prefix)
Пример #6
0
    def test_wait_for_changeset_failed_to_create_changeset(self):
        stack_name = "stack_name"
        changeset_id = "changeset-id"

        mock_client = mock.Mock()
        mock_deployer = Deployer(mock_client)
        mock_waiter = mock.Mock()
        mock_client.get_waiter.return_value = mock_waiter

        response = {"Status": "FAILED", "StatusReason": "some reason"}

        waiter_error = botocore.exceptions.WaiterError(name="name",
                                                       reason="reason",
                                                       last_response=response)
        mock_waiter.wait.side_effect = waiter_error

        with self.assertRaises(RuntimeError):
            mock_deployer.wait_for_changeset(changeset_id, stack_name)

        waiter_config = {'Delay': 5}
        mock_waiter.wait.assert_called_once_with(ChangeSetName=changeset_id,
                                                 StackName=stack_name,
                                                 WaiterConfig=waiter_config)

        mock_client.get_waiter.assert_called_once_with(
            "change_set_create_complete")
Пример #7
0
    def test_wait_for_changeset_no_changes(self):
        stack_name = "stack_name"
        changeset_id = "changeset-id"

        mock_client = Mock()
        mock_deployer = Deployer(mock_client)
        mock_waiter = Mock()
        mock_client.get_waiter.return_value = mock_waiter

        response = {
            "Status": "FAILED",
            "StatusReason": "No updates are to be performed"
        }

        waiter_error = botocore.exceptions.WaiterError(name="name",
                                                       reason="reason",
                                                       last_response=response)
        mock_waiter.wait.side_effect = waiter_error

        with self.assertRaises(exceptions.ChangeEmptyError):
            mock_deployer.wait_for_changeset(changeset_id, stack_name)

        mock_waiter.wait.assert_called_once_with(ChangeSetName=changeset_id,
                                                 StackName=stack_name)

        mock_client.get_waiter.assert_called_once_with(
                "change_set_create_complete")
Пример #8
0
 def publish(self, stack_name):
     d = Deployer(boto3.client('cloudformation'))
     result = d.create_and_wait_for_changeset(
         stack_name=stack_name,
         cfn_template=self.get_template(),
         parameter_values=[],
         capabilities=['CAPABILITY_IAM'])
     d.execute_changeset(result.changeset_id, stack_name)
     d.wait_for_execute(stack_name, result.changeset_type)
Пример #9
0
    def _run_main(self, parsed_args, parsed_globals):
        cloudformation_client = \
            self._session.create_client(
                    'cloudformation', region_name=parsed_globals.region,
                    endpoint_url=parsed_globals.endpoint_url,
                    verify=parsed_globals.verify_ssl)

        template_path = parsed_args.template_file
        if not os.path.isfile(template_path):
            raise exceptions.InvalidTemplatePathError(
                    template_path=template_path)

        # Parse parameters
        with open(template_path, "r") as handle:
            template_str = handle.read()

        stack_name = parsed_args.stack_name
        parameter_overrides = self.parse_key_value_arg(
                parsed_args.parameter_overrides,
                self.PARAMETER_OVERRIDE_CMD)

        tags_dict = self.parse_key_value_arg(parsed_args.tags, self.TAGS_CMD)
        tags = [{"Key": key, "Value": value}
                for key, value in tags_dict.items()]

        template_dict = yaml_parse(template_str)

        parameters = self.merge_parameters(template_dict, parameter_overrides)

        template_size = os.path.getsize(parsed_args.template_file)
        if template_size > 51200 and not parsed_args.s3_bucket:
            raise exceptions.DeployBucketRequiredError()

        bucket = parsed_args.s3_bucket
        if bucket:
            s3_client = self._session.create_client(
                "s3",
                config=Config(signature_version='s3v4'),
                region_name=parsed_globals.region,
                verify=parsed_globals.verify_ssl)

            s3_uploader = S3Uploader(s3_client,
                                      bucket,
                                      parsed_args.s3_prefix,
                                      parsed_args.kms_key_id,
                                      parsed_args.force_upload)
        else:
            s3_uploader = None

        deployer = Deployer(cloudformation_client)
        return self.deploy(deployer, stack_name, template_str,
                           parameters, parsed_args.capabilities,
                           parsed_args.execute_changeset, parsed_args.role_arn,
                           parsed_args.notification_arns, s3_uploader,
                           tags,
                           parsed_args.fail_on_empty_changeset)
def deploy_template(session, config, packaged_yaml, approve=False):
    success = True
    print('\nDeploying...')
    client = session.create_client('cloudformation')
    stack_name = conventions.generate_stack_name(config['Parameters'])
    deployer = Deployer(client)
    tags = conventions.merge_tags(config.get('Tags', {}), config['Parameters'])

    try:
        result = deployer.create_and_wait_for_changeset(
            stack_name=stack_name,
            cfn_template=packaged_yaml,
            parameter_values=deploy_template_parameters_builder(
                config['Parameters']),
            capabilities=['CAPABILITY_NAMED_IAM'],
            role_arn=None,
            notification_arns=None,
            s3_uploader=None,
            tags=deploy_template_tags_builder(tags))
        display_changeset(session, stack_name, result.changeset_id)
        if not approve:
            utils.get_confirmation()

        execute_changeset_token = str(uuid.uuid4())
        client.execute_change_set(ChangeSetName=result.changeset_id,
                                  StackName=stack_name,
                                  ClientRequestToken=execute_changeset_token)
        deployer.wait_for_execute(stack_name, result.changeset_type)
    except exceptions.ChangeEmptyError as ex:
        logging.error(ex)
        success = False
    except exceptions.DeployFailedError as ex:
        logging.error(ex)
        # print(colored(ex.response['Error']['Message'], 'red'))
        stack_events = get_stack_events(session, stack_name,
                                        execute_changeset_token)
        aws.display_cfn_stack_events(stack_events)
        success = False
    except botocore.exceptions.ClientError as ex:
        logging.error(ex)
        success = False

    print('Done.')
    return success
Пример #11
0
    def setUp(self):
        self.session = mock.Mock()
        self.session.get_scoped_config.return_value = {}
        self.parsed_args = FakeArgs(
            template_file='./foo',
            stack_name="some_stack_name",
            parameter_overrides=["Key1=Value1", "Key2=Value2"],
            no_execute_changeset=False,
            execute_changeset=True,
            capabilities=None)
        self.parsed_globals = FakeArgs(region="us-east-1",
                                       endpoint_url=None,
                                       verify_ssl=None)
        self.deploy_command = DeployCommand(self.session)

        self.deployer = Deployer(Mock())
        self.deployer.create_and_wait_for_changeset = Mock()
        self.deployer.execute_changeset = Mock()
        self.deployer.wait_for_execute = Mock()