diff --git a/CHANGES.md b/CHANGES.md index 18f01b7..7b7995d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,8 @@ # Changelog +## 0.6.1 +- Add support for onfailure for create stack, defaults to DELETE + ## 0.6.0 - Implemented Piped mode again Allows all stack references to be supplied via injected parameters diff --git a/cloudbender/__init__.py b/cloudbender/__init__.py index 138fbc1..e6baf92 100644 --- a/cloudbender/__init__.py +++ b/cloudbender/__init__.py @@ -2,7 +2,7 @@ import logging __author__ = "Stefan Reimer" __email__ = "stefan@zero-downtimet.net" -__version__ = "0.6.0" +__version__ = "0.6.1" # Set up logging to ``/dev/null`` like a library is supposed to. diff --git a/cloudbender/core.py b/cloudbender/core.py index c3016be..f10d8f5 100644 --- a/cloudbender/core.py +++ b/cloudbender/core.py @@ -25,7 +25,7 @@ class CloudBender(object): raise "Check '{0}' exists and is a valid project folder.".format(root_path) def read_config(self): - """Load the /config.yaml, /*.yaml as stacks, sub-folders are child groups """ + """Load the /config.yaml, /*.yaml as stacks, sub-folders are sub-groups """ # Read top level config.yaml and extract CloudBender CTX _config = read_config_file(os.path.join(self.ctx['config_path'], 'config.yaml')) diff --git a/cloudbender/exceptions.py b/cloudbender/exceptions.py index 6c1c844..80bb076 100644 --- a/cloudbender/exceptions.py +++ b/cloudbender/exceptions.py @@ -1,2 +1,6 @@ class ParameterNotFound(Exception): """My documentation""" + + +class ParameterIllegalValue(Exception): + """My documentation""" diff --git a/cloudbender/stack.py b/cloudbender/stack.py index d1f2a75..f9add4d 100644 --- a/cloudbender/stack.py +++ b/cloudbender/stack.py @@ -14,7 +14,7 @@ from .utils import dict_merge, search_refs from .connection import BotoConnection from .jinja import JinjaEnv, read_config_file from . import __version__ -from .exceptions import ParameterNotFound +from .exceptions import ParameterNotFound, ParameterIllegalValue import cfnlint.core @@ -56,13 +56,14 @@ class Stack(object): self.dependencies = set() self.default_lock = None self.multi_delete = True + self.onfailure = "DELETE" def dump_config(self): logger.debug("".format(self.id, vars(self))) def read_config(self): _config = read_config_file(self.path) - for p in ["region", "stackname", "template", "default_lock", "multi_delete", "provides"]: + for p in ["region", "stackname", "template", "default_lock", "multi_delete", "provides", "onfailure"]: if p in _config: setattr(self, p, _config[p]) @@ -88,6 +89,10 @@ class Stack(object): for dep in _config['dependencies']: self.dependencies.add(dep) + # Some sanity checks + if self.onfailure not in ["DO_NOTHING", "ROLLBACK", "DELETE"]: + raise ParameterIllegalValue("onfailure must be one of DO_NOTHING | ROLLBACK | DELETE") + logger.debug("Stack {} added.".format(self.id)) def render(self): @@ -339,6 +344,7 @@ class Stack(object): {'StackName': self.stackname, 'TemplateBody': self.cfn_template, 'Parameters': self.cfn_parameters, + 'OnFailure': self.onfailure, 'Tags': [{"Key": str(k), "Value": str(v)} for k, v in self.tags.items()], 'Capabilities': ['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND']}, profile=self.profile, region=self.region)