Add notification_sns support, stack group option handling cleanup
This commit is contained in:
parent
c28d9c751d
commit
3fcca2b782
@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## 0.7.0
|
||||
- Add support for SNS Notifcations to Cloudformation create and update operations
|
||||
- Refactored recursive handling of options withing stack groups
|
||||
|
||||
## 0.6.2
|
||||
- Fixed custom root directory to allow automated template tests
|
||||
|
||||
|
@ -2,7 +2,7 @@ import logging
|
||||
|
||||
__author__ = "Stefan Reimer"
|
||||
__email__ = "stefan@zero-downtimet.net"
|
||||
__version__ = "0.6.2"
|
||||
__version__ = "0.7.0"
|
||||
|
||||
|
||||
# Set up logging to ``/dev/null`` like a library is supposed to.
|
||||
|
@ -33,17 +33,23 @@ class StackStatus(object):
|
||||
|
||||
|
||||
class Stack(object):
|
||||
def __init__(self, name, path, rel_path, tags=None, parameters=None, options=None, region='global', profile=None, template=None, ctx={}):
|
||||
self.id = (profile, region, name)
|
||||
def __init__(self, name, template, path, rel_path, sg_config={}, ctx={}):
|
||||
self.stackname = name
|
||||
self.template = template
|
||||
self.path = path
|
||||
self.rel_path = rel_path
|
||||
self.tags = tags
|
||||
self.parameters = parameters
|
||||
self.options = options
|
||||
self.region = region
|
||||
self.profile = profile
|
||||
self.template = template
|
||||
self.ctx = ctx
|
||||
|
||||
self.tags = sg_config.get('tags', {})
|
||||
self.parameters = sg_config.get('parameters', {})
|
||||
self.options = sg_config.get('options', {})
|
||||
self.region = sg_config.get('region', 'global')
|
||||
self.profile = sg_config.get('profile', '')
|
||||
self.onfailure = sg_config.get('onfailure', "DELETE")
|
||||
self.notfication_sns = sg_config.get('notification_sns', [])
|
||||
|
||||
self.id = (self.profile, self.region, self.stackname)
|
||||
|
||||
self.md5 = None
|
||||
self.mode = 'CloudBender'
|
||||
self.provides = template
|
||||
@ -51,19 +57,17 @@ class Stack(object):
|
||||
self.cfn_parameters = []
|
||||
self.cfn_data = None
|
||||
self.connection_manager = BotoConnection(self.profile, self.region)
|
||||
self.ctx = ctx
|
||||
self.status = None
|
||||
self.dependencies = set()
|
||||
self.default_lock = None
|
||||
self.multi_delete = True
|
||||
self.onfailure = "DELETE"
|
||||
|
||||
def dump_config(self):
|
||||
logger.debug("<Stack {}: {}>".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", "onfailure"]:
|
||||
for p in ["region", "stackname", "template", "default_lock", "multi_delete", "provides", "onfailure", "notification_sns"]:
|
||||
if p in _config:
|
||||
setattr(self, p, _config[p])
|
||||
|
||||
@ -345,6 +349,7 @@ class Stack(object):
|
||||
'TemplateBody': self.cfn_template,
|
||||
'Parameters': self.cfn_parameters,
|
||||
'OnFailure': self.onfailure,
|
||||
'NotificationARNs': self.notfication_sns,
|
||||
'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)
|
||||
@ -366,6 +371,7 @@ class Stack(object):
|
||||
{'StackName': self.stackname,
|
||||
'TemplateBody': self.cfn_template,
|
||||
'Parameters': self.cfn_parameters,
|
||||
'NotificationARNs': self.notfication_sns,
|
||||
'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)
|
||||
|
@ -26,7 +26,7 @@ class StackGroup(object):
|
||||
for sg in self.sgs:
|
||||
sg.dump_config()
|
||||
|
||||
logger.debug("<StackGroup {}: {}>".format(self.name, vars(self)))
|
||||
logger.debug("<StackGroup {}: {}>".format(self.name, self.config))
|
||||
|
||||
for s in self.stacks:
|
||||
s.dump_config()
|
||||
@ -46,14 +46,9 @@ class StackGroup(object):
|
||||
self.name = os.path.split(self.path)[1]
|
||||
|
||||
# Merge config with parent config
|
||||
_config = dict_merge(parent_config, _config)
|
||||
self.config = dict_merge(parent_config, _config)
|
||||
|
||||
tags = _config.get('tags', {})
|
||||
parameters = _config.get('parameters', {})
|
||||
options = _config.get('options', {})
|
||||
region = _config.get('region', 'global')
|
||||
profile = _config.get('profile', '')
|
||||
stackname_prefix = _config.get('stacknameprefix', '')
|
||||
stackname_prefix = self.config.get('stacknameprefix', '')
|
||||
|
||||
logger.debug("StackGroup {} added.".format(self.name))
|
||||
|
||||
@ -65,23 +60,17 @@ class StackGroup(object):
|
||||
if stackname_prefix:
|
||||
stackname = stackname_prefix + stackname
|
||||
|
||||
new_stack = Stack(
|
||||
name=stackname, template=template, path=stack_path, rel_path=str(self.rel_path),
|
||||
tags=dict(tags), parameters=dict(parameters), options=dict(options),
|
||||
region=str(region), profile=str(profile), ctx=self.ctx)
|
||||
new_stack = Stack(name=stackname, template=template, path=stack_path, rel_path=str(self.rel_path), sg_config=self.config, ctx=self.ctx)
|
||||
new_stack.read_config()
|
||||
self.stacks.append(new_stack)
|
||||
|
||||
# Create StackGroups recursively
|
||||
for sub_group in [f.path for f in os.scandir(self.path) if f.is_dir()]:
|
||||
sg = StackGroup(sub_group, self.ctx)
|
||||
sg.read_config(_config)
|
||||
sg.read_config(self.config)
|
||||
|
||||
self.sgs.append(sg)
|
||||
|
||||
# Return raw, merged config to parent
|
||||
return _config
|
||||
|
||||
def get_stacks(self, name=None, recursive=True, match_by='name'):
|
||||
""" Returns [stack] matching stack_name or [all] """
|
||||
stacks = []
|
||||
|
Loading…
Reference in New Issue
Block a user