Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge upstream changes #18

Merged
merged 26 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
925341b
Update README.rst
russellballestrini Oct 14, 2019
71ad3d4
Update README.rst
russellballestrini Oct 14, 2019
638db47
Add link to AWS OSS Blog post
ejholmes Nov 15, 2019
1c07ff2
Merge pull request #747 from cloudtools/aws-blogpost
ejholmes Nov 18, 2019
7fc9648
Locked stacks still have requirements (#746)
mromaszewicz Nov 20, 2019
106ddf3
change diff to use CFN change sets instead of comparing template dict…
ITProKyle Feb 9, 2020
46bb7fe
Doc Update: Sturdy -> Onica (#739)
fbattistella Feb 17, 2020
471cc28
Add YAML environment file support (#740)
mromaszewicz Feb 17, 2020
b6d3118
Fix ami lookup 'Name' key error (#734)
Feb 17, 2020
9cf93c3
Fix jinja req and keypair tests
phobologic Feb 17, 2020
98a1cbf
fix diff functional tests
phobologic Feb 17, 2020
722ba88
Move template to an actual resource
phobologic Feb 17, 2020
44a98ef
Fix raw unit tests
phobologic Feb 17, 2020
c113f64
Fix new SNS based functional tests
phobologic Feb 17, 2020
5215e6a
Sleep for 20 seconds between tests to avoid rate limiting
phobologic Feb 17, 2020
13ec7a2
Twiddle with times to try and fix timeouts
phobologic Feb 18, 2020
9bbb391
Add the import-related stack statuses (#752)
laconc Feb 27, 2020
6221107
fix stack.set_outputs not being called by diff if stack did not chang…
ITProKyle Apr 21, 2020
0f8c233
Fix python 2.7/3.5 dependency issue
phobologic Apr 21, 2020
06a4bee
add cf notification arns (#756)
russellballestrini May 29, 2020
72eb1b0
specify dependency for boto3 in the correct way for multiple version …
TomRitserveldt Aug 22, 2020
4e32f25
Release 1.7.1 (#760)
phobologic Aug 22, 2020
eda3a52
address breaking moto change to awslambda (#763)
hauntingEcho Sep 14, 2020
c022c2f
Added Python version validation before update kms decrypt output (#765)
bmcoelho Oct 29, 2020
f563a6f
Release 1.7.2 (#767)
phobologic Nov 10, 2020
867a03f
Fix exception in 'stacker build --dump' when targets are defined
shawnsmith Nov 11, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add cf notification arns (cloudtools#756)
* add cf notification arns parameter

* fixed lint errors

* added NotificationARNs arg to test

* adjustments based on feedback, added test

	modified:   stacker/providers/aws/default.py
	modified:   stacker/stack.py
	modified:   stacker/tests/providers/aws/test_default.py

* docs

* pin more-itertools to version which supports py27
	modified:   setup.py

Co-authored-by: Tim Kukhmazov <Tim.kukhmazov@pnmac.com>
  • Loading branch information
russellballestrini and Tim Kukhmazov authored May 29, 2020
commit 06a4beed9a586f6f975c0896449229724c3795b1
3 changes: 3 additions & 0 deletions docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,9 @@ A stack has the following keys:
an exception if the stack is in an `IN_PROGRESS` state. You can set this
option to `wait` and stacker will wait for the previous update to complete
before attempting to update the stack.
**notification_arns**:
(optional): If provided, accepts a list of None or many AWS SNS Topic ARNs
which will be notified of this stack's CloudFormation state changes.

Stacks Example
~~~~~~~~~~~~~~
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"formic2",
"python-dateutil>=2.0,<3.0",
"MarkupSafe<2.0", # 2.0 dropped python 2.7, 3.5 support - temporary
"more-itertools<6.0.0", # 6.0.0 dropped python 2.7 support - temporary
]

setup_requires = ['pytest-runner']
Expand Down
4 changes: 3 additions & 1 deletion stacker/actions/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,8 @@ def _launch_stack(self, stack, **kwargs):
logger.debug("Creating new stack: %s", stack.fqn)
provider.create_stack(stack.fqn, template, parameters, tags,
force_change_set,
stack_policy=stack_policy)
stack_policy=stack_policy,
notification_arns=stack.notification_arns)
return SubmittedStatus("creating new stack")

try:
Expand All @@ -359,6 +360,7 @@ def _launch_stack(self, stack, **kwargs):
force_interactive=stack.protected,
force_change_set=force_change_set,
stack_policy=stack_policy,
notification_arns=stack.notification_arns
)

logger.debug("Updating existing stack: %s", stack.fqn)
Expand Down
3 changes: 3 additions & 0 deletions stacker/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,9 @@ class Stack(Model):

in_progress_behavior = StringType(serialize_when_none=False)

notification_arns = ListType(
StringType, serialize_when_none=False, default=[])

def validate_class_path(self, data, value):
if value and data["template_path"]:
raise ValidationError(
Expand Down
1 change: 1 addition & 0 deletions stacker/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ def get_stacks(self):
locked=stack_def.locked,
enabled=stack_def.enabled,
protected=stack_def.protected,
notification_arns=stack_def.notification_arns
)
stacks.append(stack)
self._stacks = stacks
Expand Down
57 changes: 43 additions & 14 deletions stacker/providers/aws/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,17 +334,26 @@ def wait_till_change_set_complete(cfn_client, change_set_id, try_count=25,
return response


def create_change_set(cfn_client, fqn, template, parameters, tags,
change_set_type='UPDATE', replacements_only=False,
service_role=None):
def create_change_set(
cfn_client,
fqn,
template,
parameters,
tags,
change_set_type='UPDATE',
replacements_only=False,
service_role=None,
notification_arns=None
):
logger.debug("Attempting to create change set of type %s for stack: %s.",
change_set_type,
fqn)
args = generate_cloudformation_args(
fqn, parameters, tags, template,
change_set_type=change_set_type,
service_role=service_role,
change_set_name=get_change_set_name()
change_set_name=get_change_set_name(),
notification_arns=notification_arns
)
try:
response = cfn_client.create_change_set(**args)
Expand Down Expand Up @@ -414,12 +423,18 @@ def check_tags_contain(actual, expected):
return actual_set >= expected_set


def generate_cloudformation_args(stack_name, parameters, tags, template,
capabilities=DEFAULT_CAPABILITIES,
change_set_type=None,
service_role=None,
stack_policy=None,
change_set_name=None):
def generate_cloudformation_args(
stack_name,
parameters,
tags,
template,
capabilities=DEFAULT_CAPABILITIES,
change_set_type=None,
service_role=None,
stack_policy=None,
change_set_name=None,
notification_arns=None,
):
"""Used to generate the args for common cloudformation API interactions.

This is used for create_stack/update_stack/create_change_set calls in
Expand All @@ -443,6 +458,8 @@ def generate_cloudformation_args(stack_name, parameters, tags, template,
object representing a stack policy.
change_set_name (str, optional): An optional change set name to use
with create_change_set.
notification_arns (list, optional): An optional list of SNS topic ARNs
to send CloudFormation Events to.

Returns:
dict: A dictionary of arguments to be used in the Cloudformation API
Expand All @@ -461,6 +478,9 @@ def generate_cloudformation_args(stack_name, parameters, tags, template,
if change_set_name:
args["ChangeSetName"] = change_set_name

if notification_arns:
args["NotificationARNs"] = notification_arns

if change_set_type:
args["ChangeSetType"] = change_set_type

Expand Down Expand Up @@ -738,9 +758,13 @@ def destroy_stack(self, stack, **kwargs):
self.cloudformation.delete_stack(**args)
return True

def create_stack(self, fqn, template, parameters, tags,
force_change_set=False, stack_policy=None,
**kwargs):
def create_stack(
self, fqn, template, parameters, tags,
force_change_set=False,
stack_policy=None,
notification_arns=None,
**kwargs
):
"""Create a new Cloudformation stack.

Args:
Expand All @@ -754,6 +778,8 @@ def create_stack(self, fqn, template, parameters, tags,
force_change_set (bool): Whether or not to force change set use.
stack_policy (:class:`stacker.providers.base.Template`): A template
object representing a stack policy.
notification_arns (list, optional): An optional list of SNS topic
ARNs to send CloudFormation Events to.
"""

logger.debug("Attempting to create stack %s:.", fqn)
Expand All @@ -780,6 +806,7 @@ def create_stack(self, fqn, template, parameters, tags,
fqn, parameters, tags, template,
service_role=self.service_role,
stack_policy=stack_policy,
notification_arns=notification_arns
)

try:
Expand Down Expand Up @@ -1029,7 +1056,8 @@ def noninteractive_changeset_update(self, fqn, template, old_parameters,
)

def default_update_stack(self, fqn, template, old_parameters, parameters,
tags, stack_policy=None, **kwargs):
tags, stack_policy=None,
notification_arns=[], **kwargs):
"""Update a Cloudformation stack in default mode.

Args:
Expand All @@ -1051,6 +1079,7 @@ def default_update_stack(self, fqn, template, old_parameters, parameters,
fqn, parameters, tags, template,
service_role=self.service_role,
stack_policy=stack_policy,
notification_arns=notification_arns
)

try:
Expand Down
18 changes: 15 additions & 3 deletions stacker/stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,23 @@ class Stack(object):
blueprint.
locked (bool, optional): Whether or not the stack is locked.
force (bool, optional): Whether to force updates on this stack.
enabled (bool, optional): Whether this stack is enabled
enabled (bool, optional): Whether this stack is enabled.
protected (boot, optional): Whether this stack is protected.
notification_arns (list, optional): An optional list of SNS topic ARNs
to send CloudFormation Events to.

"""

def __init__(self, definition, context, variables=None, mappings=None,
locked=False, force=False, enabled=True, protected=False):
def __init__(
self, definition, context,
variables=None,
mappings=None,
locked=False,
force=False,
enabled=True,
protected=False,
notification_arns=None,
):
self.logging = True
self.name = definition.name
self.fqn = context.get_fqn(definition.stack_name or self.name)
Expand All @@ -75,6 +86,7 @@ def __init__(self, definition, context, variables=None, mappings=None,
self.context = context
self.outputs = None
self.in_progress_behavior = definition.in_progress_behavior
self.notification_arns = notification_arns

def __repr__(self):
return self.fqn
Expand Down
42 changes: 37 additions & 5 deletions stacker/tests/providers/aws/test_default.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,11 +403,18 @@ def test_generate_cloudformation_args(self):
template_url = "http://fake.s3url.com/blah.json"
template_body = '{"fake_body": "woot"}'
std_args = {
"stack_name": stack_name, "parameters": [], "tags": [],
"template": Template(url=template_url)}
std_return = {"StackName": stack_name, "Parameters": [], "Tags": [],
"Capabilities": DEFAULT_CAPABILITIES,
"TemplateURL": template_url}
"stack_name": stack_name,
"parameters": [],
"tags": [],
"template": Template(url=template_url)
}
std_return = {
"StackName": stack_name,
"Parameters": [],
"Tags": [],
"Capabilities": DEFAULT_CAPABILITIES,
"TemplateURL": template_url,
}
result = generate_cloudformation_args(**std_args)
self.assertEqual(result, std_return)

Expand Down Expand Up @@ -439,6 +446,31 @@ def test_generate_cloudformation_args(self):
result = generate_cloudformation_args(**std_args)
self.assertEqual(result, template_body_result)

def test_generate_cloudformation_args_with_notification_arns(self):
stack_name = "mystack"
template_url = "http://fake.s3url.com/blah.json"
std_args = {
"stack_name": stack_name,
"parameters": [],
"tags": [],
"template": Template(url=template_url),
"notification_arns": [
"arn:aws:sns:us-east-1:1234567890:test-cf-deploy-notify-sns-topic-CfDeployNotify" # noqa
]
}
std_return = {
"StackName": stack_name,
"Parameters": [],
"Tags": [],
"Capabilities": DEFAULT_CAPABILITIES,
"TemplateURL": template_url,
"NotificationARNs": [
"arn:aws:sns:us-east-1:1234567890:test-cf-deploy-notify-sns-topic-CfDeployNotify" # noqa
]
}
result = generate_cloudformation_args(**std_args)
self.assertEqual(result, std_return)


class TestProviderDefaultMode(unittest.TestCase):
def setUp(self):
Expand Down