From e393172e541577034b20f17fdcf1fc4019bec7fb Mon Sep 17 00:00:00 2001 From: Stefan Reimer Date: Wed, 30 Jan 2019 13:00:06 +0000 Subject: [PATCH] Add initial change set support --- cloudbender/__init__.py | 2 +- cloudbender/cli.py | 16 +++++++++++++++- cloudbender/stack.py | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/cloudbender/__init__.py b/cloudbender/__init__.py index 93a40c9..fd1a756 100644 --- a/cloudbender/__init__.py +++ b/cloudbender/__init__.py @@ -2,7 +2,7 @@ import logging __author__ = 'Stefan Reimer' __email__ = 'stefan@zero-downtimet.net' -__version__ = '1.1.0' +__version__ = '1.1.1' # Set up logging to ``/dev/null`` like a library is supposed to. diff --git a/cloudbender/cli.py b/cloudbender/cli.py index b6f63f8..7b4539b 100644 --- a/cloudbender/cli.py +++ b/cloudbender/cli.py @@ -46,12 +46,25 @@ def render(ctx, stack_name, multi): @click.option("--multi", is_flag=True, help="Allow more than one stack to match") @click.pass_context def validate(ctx, stack_name, multi): + """ Validates already rendered templates using cfn-lint """ stacks = _find_stacks(ctx, stack_name, multi) for s in stacks: s.validate() +@click.command() +@click.argument("stack_name") +@click.argument("change_set_name") +@click.pass_context +def create_change_set(ctx, stack_name, change_set_name): + """ Creates a change set for an existing stack """ + stacks = _find_stacks(ctx, stack_name) + + for s in stacks: + s.create_change_set(change_set_name) + + @click.command() @click.argument("stack_name") @click.option("--multi", is_flag=True, help="Allow more than one stack to match") @@ -143,7 +156,7 @@ def sort_stacks(ctx, stacks): assert not data, "A cyclic dependency exists amongst %r" % data -def _find_stacks(ctx, stack_name,multi): +def _find_stacks(ctx, stack_name,multi=False): cb = ctx.obj['cb'] # ALL acts ass config and multi=True @@ -169,6 +182,7 @@ cli.add_command(validate) cli.add_command(provision) cli.add_command(delete) cli.add_command(clean) +cli.add_command(create_change_set) if __name__ == '__main__': cli(obj={}) diff --git a/cloudbender/stack.py b/cloudbender/stack.py index 68a5aeb..f93a965 100644 --- a/cloudbender/stack.py +++ b/cloudbender/stack.py @@ -366,6 +366,28 @@ class Stack(object): return self._wait_for_completion() + def create_change_set(self, change_set_name): + """ Creates a Change Set with the name ``change_set_name``. """ + + # Prepare parameters + self.resolve_parameters() + self.write_parameter_file() + + if not self.cfn_template: + self.read_template_file() + + logger.info('Creating change set {0} for stack {1}'.format(change_set_name, self.stackname)) + response = self.connection_manager.call('cloudformation', 'create_change_set', + {'StackName':self.stackname, + 'ChangeSetName': change_set_name, + 'TemplateBody':self.cfn_template, + 'Parameters':self.cfn_parameters, + 'Tags':[ {"Key": str(k), "Value": str(v)} for k, v in self.tags.items() ], + 'Capabilities':['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM']}, + profile=self.profile, region=self.region) + return self._wait_for_completion() + + def describe(self): """ Returns the a description of the stack.