Skip to content

Commit

Permalink
Merge branch 'master' into release-candidate-4.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
alexharv074 committed Jul 3, 2024
2 parents f4aecc4 + 39af284 commit 793e01f
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 177 deletions.
18 changes: 0 additions & 18 deletions .github/workflows/comment-integration-tests.yaml

This file was deleted.

4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ repos:
hooks:
- id: yamllint
- repo: https://github.com/awslabs/cfn-python-lint
rev: v1.2.5.a11
rev: v1.4.2
hooks:
- id: cfn-python-lint
args:
Expand Down Expand Up @@ -47,7 +47,7 @@ repos:
language_version: python3.10
args: ['--check']
- repo: https://github.com/sirosen/check-jsonschema
rev: 0.28.5
rev: 0.28.6
hooks:
- id: check-github-workflows
- id: check-github-actions
115 changes: 0 additions & 115 deletions integration-tests/steps/stack_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,68 +97,6 @@ def step_impl(context, stack_group_name):
sceptre_plan.delete()


@when('the user describes stack_group "{stack_group_name}"')
def step_impl(context, stack_group_name):
sceptre_context = SceptreContext(
command_path=stack_group_name, project_path=context.sceptre_dir
)

sceptre_plan = SceptrePlan(sceptre_context)
responses = sceptre_plan.describe()

stack_names = get_full_stack_names(context, stack_group_name)
cfn_stacks = {}

for response in responses.values():
if response is None:
continue
for stack in response["Stacks"]:
cfn_stacks[stack["StackName"]] = stack["StackStatus"]

context.response = [
{short_name: cfn_stacks[full_name]}
for short_name, full_name in stack_names.items()
if cfn_stacks.get(full_name)
]


@when('the user describes stack_group "{stack_group_name}" with ignore dependencies')
def step_impl(context, stack_group_name):
sceptre_context = SceptreContext(
command_path=stack_group_name,
project_path=context.sceptre_dir,
ignore_dependencies=True,
)

sceptre_plan = SceptrePlan(sceptre_context)
responses = sceptre_plan.describe()

stack_names = get_full_stack_names(context, stack_group_name)
cfn_stacks = {}

for response in responses.values():
if response is None:
continue
for stack in response["Stacks"]:
cfn_stacks[stack["StackName"]] = stack["StackStatus"]

context.response = [
{short_name: cfn_stacks[full_name]}
for short_name, full_name in stack_names.items()
if cfn_stacks.get(full_name)
]


@when('the user describes resources in stack_group "{stack_group_name}"')
def step_impl(context, stack_group_name):
sceptre_context = SceptreContext(
command_path=stack_group_name, project_path=context.sceptre_dir
)

sceptre_plan = SceptrePlan(sceptre_context)
context.response = sceptre_plan.describe_resources().values()


@when(
'the user describes resources in stack_group "{stack_group_name}" with ignore dependencies'
)
Expand Down Expand Up @@ -196,14 +134,6 @@ def step_impl(context, stack_group_name):
check_stack_status(context, full_stack_names, None)


@then('all stacks in stack_group "{stack_group_name}" are described as "{status}"')
def step_impl(context, stack_group_name, status):
stacks_names = get_stack_names(context, stack_group_name)
expected_response = [{stack_name: status} for stack_name in stacks_names]
for response in context.response:
assert response in expected_response


@then('stack "{stack_name}" is described as "{status}"')
def step_impl(context, stack_name, status):
response = next(
Expand All @@ -214,51 +144,6 @@ def step_impl(context, stack_name, status):
assert response[stack_name] == status


@then('only all resources in stack_group "{stack_group_name}" are described')
def step_impl(context, stack_group_name):
stacks_names = get_full_stack_names(context, stack_group_name)
expected_resources = {}
sceptre_response = []
for stack_resources in context.response:
for resource in stack_resources.values():
sceptre_response.append(resource[0]["PhysicalResourceId"])

for short_name, full_name in stacks_names.items():
time.sleep(1)
response = retry_boto_call(
context.client.describe_stack_resources, StackName=full_name
)
expected_resources[short_name] = response["StackResources"]

for short_name, resources in expected_resources.items():
for resource in resources:
sceptre_response.remove(resource["PhysicalResourceId"])

assert sceptre_response == []


@then('only resources in stack "{stack_name}" are described')
def step_impl(context, stack_name):
expected_resources = {}
sceptre_response = []
for stack_resources in context.response:
for resource in stack_resources.values():
if resource:
sceptre_response.append(resource[0].get("PhysicalResourceId"))

response = retry_boto_call(
context.client.describe_stack_resources,
StackName=get_cloudformation_stack_name(context, stack_name),
)
expected_resources[stack_name] = response["StackResources"]

for short_name, resources in expected_resources.items():
for resource in resources:
sceptre_response.remove(resource["PhysicalResourceId"])

assert sceptre_response == []


@then('that stack "{first_stack}" was created before "{second_stack}"')
def step_impl(context, first_stack, second_stack):
stacks = [
Expand Down
39 changes: 0 additions & 39 deletions integration-tests/steps/stacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,30 +310,6 @@ def step_impl(context, stack_name):
launch_stack(context, stack_name, False, True)


@when('the user describes the resources of stack "{stack_name}"')
def step_impl(context, stack_name):
sceptre_context = SceptreContext(
command_path=stack_name + ".yaml", project_path=context.sceptre_dir
)

sceptre_plan = SceptrePlan(sceptre_context)
context.output = list(sceptre_plan.describe_resources().values())


@when(
'the user describes the resources of stack "{stack_name}" with ignore dependencies'
)
def step_impl(context, stack_name):
sceptre_context = SceptreContext(
command_path=stack_name + ".yaml",
project_path=context.sceptre_dir,
ignore_dependencies=True,
)

sceptre_plan = SceptrePlan(sceptre_context)
context.output = list(sceptre_plan.describe_resources().values())


@when('the user diffs stack "{stack_name}" with "{diff_type}"')
def step_impl(context, stack_name, diff_type):
sceptre_context = SceptreContext(
Expand Down Expand Up @@ -381,21 +357,6 @@ def step_impl(context, stack_name):
assert status is None


@then('the resources of stack "{stack_name}" are described')
def step_impl(context, stack_name):
full_name = get_cloudformation_stack_name(context, stack_name)
response = retry_boto_call(
context.client.describe_stack_resources, StackName=full_name
)
properties = {"LogicalResourceId", "PhysicalResourceId"}
formatted_response = [
{k: v for k, v in item.items() if k in properties}
for item in response["StackResources"]
]

assert [{stack_name: formatted_response}] == context.output


@then(
'stack "{stack_name}" does not exist and stack "{dependant_stack_name}" exists in "{desired_state}"'
)
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ classifiers = [

[tool.poetry.plugins."sceptre.hooks"]
"asg_scheduled_actions" = "sceptre.hooks.asg_scaling_processes:ASGScalingProcesses"
"asg_scaling_processes" = "sceptre.hooks.asg_scaling_processes:ASGScalingProcesses"
"cmd" = "sceptre.hooks.cmd:Cmd"

[tool.poetry.plugins."sceptre.resolvers"]
Expand Down
18 changes: 15 additions & 3 deletions sceptre/stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def __init__(
)

self.s3_details = s3_details
self.parameters = self._ensure_parameters(parameters or {})
self.parameters = self._cast_parameters(parameters or {})
self.sceptre_user_data = sceptre_user_data or {}
self.notifications = notifications or []

Expand All @@ -276,10 +276,21 @@ def _ensure_boolean(self, config_name: str, value: Any) -> bool:
)
return value

def _ensure_parameters(
def _cast_parameters(
self, parameters: Dict[str, Any]
) -> Dict[str, Union[str, List[Union[str, Resolver]], Resolver]]:
"""Ensure CloudFormation parameters are of valid types"""
"""Cast CloudFormation parameters to valid types"""

def cast_value(value: Any) -> Union[str, List[Union[str, Resolver]], Resolver]:
if isinstance(value, bool):
return "true" if value else "false"
elif isinstance(value, (int, float)):
return str(value)
elif isinstance(value, list):
return [cast_value(item) for item in value]
elif isinstance(value, Resolver):
return value
return value

def cast_value(value: Any) -> Union[str, List[Union[str, Resolver]], Resolver]:
if isinstance(value, bool):
Expand Down Expand Up @@ -311,6 +322,7 @@ def is_valid(value: Any) -> bool:
raise InvalidConfigFileError(
f"{self.name}: Values for parameters must be strings, lists or resolvers, got {casted_parameters}"
)

return casted_parameters

def __repr__(self):
Expand Down

0 comments on commit 793e01f

Please sign in to comment.