Skip to content

Commit

Permalink
[Resolve Sceptre#288] Fix how user variables are accessed in config t…
Browse files Browse the repository at this point in the history
…emplating (Sceptre#290)

Now variables supplied using the --var and --var-file command options
are available in the jinja templating as `{{ var.* }}`.
  • Loading branch information
cbosss authored and theseanything committed Jan 9, 2018
1 parent 8c9a0a9 commit 93cb49d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 12 deletions.
19 changes: 10 additions & 9 deletions sceptre/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,37 +56,38 @@ def cli(
# Enable deprecation warnings
warnings.simplefilter("always", DeprecationWarning)
ctx.obj = {
"options": {},
"user_variables": {},
"output_format": output,
"no_colour": no_colour,
"sceptre_dir": directory if directory else os.getcwd()
}
user_variables = {}
if var_file:
for fh in var_file:
parsed = yaml.safe_load(fh.read())
# intersection
overloaded_keys = set(user_variables.keys()) & set(parsed.keys())
ctx.obj["user_variables"].update(parsed)

# the rest of this block is for debug purposes only
existing_keys = set(ctx.obj["user_variables"].keys())
new_keys = set(parsed.keys())
overloaded_keys = existing_keys & new_keys # intersection
if overloaded_keys:
logger.debug(
"Duplicate variables encountered: {0}. "
"Using values from: {1}."
.format(", ".join(overloaded_keys), fh.name)
)
user_variables.update(parsed)

if var:
# --var options overwrite --var-file options
for variable in var:
variable_key, variable_value = variable.split("=")
if variable_key in user_variables:
if variable_key in ctx.obj["user_variables"]:
logger.debug(
"Duplicate variable encountered: {0}. "
"Using value from --var option."
.format(variable_key)
)
user_variables.update({variable_key: variable_value})
if user_variables:
ctx.obj["options"]["user_variables"] = user_variables
ctx.obj["user_variables"].update({variable_key: variable_value})


cli.add_command(init_group)
Expand Down
6 changes: 4 additions & 2 deletions sceptre/cli/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def write(var, output_format="str", no_colour=True):

def get_stack_or_env(ctx, path):
"""
Parses the path to generate relevant Envrionment and Stack object.
Parses the path to generate relevant Environment and Stack object.
:param ctx: Cli context.
:type ctx: click.Context
Expand All @@ -101,7 +101,9 @@ def get_stack_or_env(ctx, path):
stack = None
env = None

config_reader = ConfigReader(ctx.obj["sceptre_dir"], ctx.obj["options"])
config_reader = ConfigReader(
ctx.obj["sceptre_dir"], ctx.obj["user_variables"]
)

if os.path.splitext(path)[1]:
stack = config_reader.construct_stack(path)
Expand Down
39 changes: 38 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from sceptre.stack_status import StackStatus, StackChangeSetStatus
from sceptre.cli.helpers import setup_logging, write, ColouredFormatter
from sceptre.cli.helpers import CustomJsonEncoder, catch_exceptions
from sceptre.cli.helpers import get_stack_or_env
from botocore.exceptions import ClientError
from sceptre.exceptions import SceptreException

Expand Down Expand Up @@ -103,7 +104,7 @@ def test_user_variables(self, command, files, output):
@cli.command()
@click.pass_context
def noop(ctx):
click.echo(yaml.safe_dump(ctx.obj["options"]["user_variables"]))
click.echo(yaml.safe_dump(ctx.obj["user_variables"]))

self.patcher_getcwd.stop()
with self.runner.isolated_filesystem():
Expand Down Expand Up @@ -732,3 +733,39 @@ def test_CustomJsonEncoder_with_non_json_serialisable_object(self):
encoder = CustomJsonEncoder()
response = encoder.encode(datetime.datetime(2016, 5, 3))
assert response == '"2016-05-03 00:00:00"'

def test_get_stack_or_env_with_stack(self):
ctx = MagicMock(obj={
"sceptre_dir": sentinel.sceptre_dir,
"user_variables": sentinel.user_variables
})
stack, env = get_stack_or_env(ctx, "stack.yaml")
self.mock_ConfigReader.assert_called_once_with(
sentinel.sceptre_dir, sentinel.user_variables
)
assert isinstance(stack, Stack)
assert env is None

def test_get_stack_or_env_with_nested_stack(self):
ctx = MagicMock(obj={
"sceptre_dir": sentinel.sceptre_dir,
"user_variables": sentinel.user_variables
})
stack, env = get_stack_or_env(ctx, "environment/dir/stack.yaml")
self.mock_ConfigReader.assert_called_once_with(
sentinel.sceptre_dir, sentinel.user_variables
)
assert isinstance(stack, Stack)
assert env is None

def test_get_stack_or_env_with_env(self):
ctx = MagicMock(obj={
"sceptre_dir": sentinel.sceptre_dir,
"user_variables": sentinel.user_variables
})
stack, env = get_stack_or_env(ctx, "environment/dir")
self.mock_ConfigReader.assert_called_once_with(
sentinel.sceptre_dir, sentinel.user_variables
)
assert isinstance(env, Environment)
assert stack is None

0 comments on commit 93cb49d

Please sign in to comment.