def test_variable_resolve_default_lookup_empty(self): var = Variable("Param1", "${default fakeStack::}") self.assertEqual(len(var.lookups), 1) var.resolve(self.context, self.provider) self.assertTrue(var.resolved) self.assertEqual(var.value, "") self.assertEqual(len(var.lookups), 0)
def test_variable_resolve_simple_lookup(self): var = Variable("Param1", "${output fakeStack::FakeOutput}") self.assertEqual(len(var.lookups), 1) self.provider.get_output.return_value = "resolved" var.resolve(self.context, self.provider) self.assertTrue(var.resolved) self.assertEqual(var.value, "resolved")
def test_variable_resolve_nested_lookup(self): stack = Stack(definition=generate_definition("vpc", 1), context=self.context) stack.set_outputs({ "FakeOutput": "resolved", "FakeOutput2": "resolved2", }) def mock_handler(value, context, provider, **kwargs): return "looked up: {}".format(value) register_lookup_handler("lookup", mock_handler) self.context.get_stack.return_value = stack var = Variable( "Param1", "${lookup ${lookup ${output fakeStack::FakeOutput}}}", ) self.assertEqual( len(var.lookups), 1, "should only parse out the first complete lookup first", ) var.resolve(self.context, self.provider) self.assertTrue(var.resolved) self.assertEqual(var.value, "looked up: looked up: resolved")
def test_resolve_variable_provided_resolved(self): var_name = "testVar" var_def = {"type": str} provided_variable = Variable(var_name, "${mock 1}") provided_variable.resolve(context=MagicMock(), provider=MagicMock()) blueprint_name = "testBlueprint" value = resolve_variable(var_name, var_def, provided_variable, blueprint_name) self.assertEqual(value, "1")
def test_variable_resolve_simple_lookup(self): stack = Stack( definition=generate_definition("vpc", 1), context=self.context) stack.set_outputs({ "FakeOutput": "resolved", "FakeOutput2": "resolved2", }) self.context.get_stack.return_value = stack var = Variable("Param1", "${output fakeStack::FakeOutput}") var.resolve(self.context, self.provider) self.assertTrue(var.resolved) self.assertEqual(var.value, "resolved")
def test_variable_resolve_nested_lookup(self): def mock_handler(value, context, provider, **kwargs): return "looked up: {}".format(value) register_lookup_handler("lookup", mock_handler) self.provider.get_output.return_value = "resolved" var = Variable( "Param1", "${lookup ${lookup ${output fakeStack::FakeOutput}}}", ) self.assertEqual( len(var.lookups), 1, "should only parse out the first complete lookup first", ) var.resolve(self.context, self.provider) self.assertTrue(var.resolved) self.assertEqual(var.value, "looked up: looked up: resolved")
def test_variable_resolve_multiple_lookups_string(self): var = Variable( "Param1", "url://${fakeStack::FakeOutput}@${fakeStack::FakeOutput2}", ) self.assertEqual(len(var.lookups), 2) def _get_output(fqn, output_name): outputs = { "FakeOutput": "resolved", "FakeOutput2": "resolved2", } return outputs[output_name] self.provider.get_output.side_effect = _get_output var.resolve(self.context, self.provider) self.assertTrue(var.resolved) self.assertEqual(var.value, "url://resolved@resolved2")
def test_variable_resolve_multiple_lookups_string(self): var = Variable( "Param1", "url://${output fakeStack::FakeOutput}@" "${output fakeStack::FakeOutput2}", ) stack = Stack( definition=generate_definition("vpc", 1), context=self.context) stack.set_outputs({ "FakeOutput": "resolved", "FakeOutput2": "resolved2", }) self.context.get_stack.return_value = stack var.resolve(self.context, self.provider) self.assertTrue(var.resolved) self.assertEqual(var.value, "url://resolved@resolved2")
def test_variable_resolve_nested_lookup(self): stack = Stack( definition=generate_definition("vpc", 1), context=self.context) stack.set_outputs({ "FakeOutput": "resolved", "FakeOutput2": "resolved2", }) def mock_handler(value, context, provider, **kwargs): return "looked up: {}".format(value) register_lookup_handler("lookup", mock_handler) self.context.get_stack.return_value = stack var = Variable( "Param1", "${lookup ${lookup ${output fakeStack::FakeOutput}}}", ) var.resolve(self.context, self.provider) self.assertTrue(var.resolved) self.assertEqual(var.value, "looked up: looked up: resolved")
def handle_hooks(stage, hooks, provider, context): """ Used to handle pre/post_build hooks. These are pieces of code that we want to run before/after the builder builds the stacks. Args: stage (string): The current stage (pre_run, post_run, etc). hooks (list): A list of :class:`stacker.config.Hook` containing the hooks to execute. provider (:class:`stacker.provider.base.BaseProvider`): The provider the current stack is using. context (:class:`stacker.context.Context`): The current stacker context. """ from stacker.variables import Variable if not hooks: logger.debug("No %s hooks defined.", stage) return hook_paths = [] for i, h in enumerate(hooks): try: hook_paths.append(h.path) except KeyError: raise ValueError("%s hook #%d missing path." % (stage, i)) logger.info("Executing %s hooks: %s", stage, ", ".join(hook_paths)) for hook in hooks: data_key = hook.data_key required = hook.required enabled = hook.enabled if not enabled: logger.debug("hook with method %s is disabled, skipping", hook.path) continue # Resolve variables kwargs = hook.args.copy() if hook.args else {} try: for key, value in kwargs.items(): var = Variable('{}.args.{}'.format(hook.path, key), value) var.resolve(context, provider) kwargs[key] = var.value except FailedVariableLookup as e: if required: raise logger.warning( "Failed to resolve variable in non-required hook " " %s: %s", hook.path, e) continue try: method = load_object_from_string(hook.path) except (AttributeError, ImportError): logger.exception("Unable to load method at %s:", hook.path) if required: raise continue try: result = method(context=context, provider=provider, **kwargs) except Exception: logger.exception("Method %s threw an exception:", hook.path) if required: raise continue if not result: if required: logger.error("Required hook %s failed. Return value: %s", hook.path, result) sys.exit(1) logger.warning("Non-required hook %s failed. Return value: %s", hook.path, result) else: if isinstance(result, collections.Mapping): if data_key: logger.debug( "Adding result for hook %s to context in " "data_key %s.", hook.path, data_key) context.set_hook_data(data_key, result) else: logger.debug( "Hook %s returned result data, but no data " "key set, so ignoring.", hook.path)
def test_variable_resolve_no_lookups(self): var = Variable("Param1", "2") self.assertEqual(len(var.lookups), 0) var.resolve(self.context, self.provider) self.assertTrue(var.resolved) self.assertEqual(var.value, "2")
def test_resolve_catch_exception(self): var = Variable("Param1", "${output fakeStack::FakeOutput}") with self.assertRaises(FailedVariableLookup): var.resolve(self.context, self.provider)
def test_variable_resolve_default_lookup_empty(self): var = Variable("Param1", "${default fakeStack::}") var.resolve(self.context, self.provider) self.assertTrue(var.resolved) self.assertEqual(var.value, "")