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

Add support for specifying variable types using named parameter types #547

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 20 additions & 2 deletions stacker/blueprints/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@
}


def normalize_defined_variables(variables):
"""Looks for any variable definitions that are a "str", and assumes that
they're the name of a CloudFormation parameter type, in which case the type
is converted to a CFNType.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs Args

Returns:
dict: normalized variable definitions
"""
for k, v in variables.iteritems():
if isinstance(v["type"], str):
v["type"] = CFNType.from_name(v["type"])
return variables


class CFNParameter(object):

def __init__(self, name, value):
Expand Down Expand Up @@ -339,7 +353,8 @@ def get_parameter_definitions(self):

"""
output = {}
for var_name, attrs in self.defined_variables().iteritems():
defined_variables = self._normalized_defined_variables()
for var_name, attrs in defined_variables.iteritems():
var_type = attrs.get("type")
if isinstance(var_type, CFNType):
cfn_attrs = copy.deepcopy(attrs)
Expand Down Expand Up @@ -391,6 +406,9 @@ def defined_variables(self):
"""
return copy.deepcopy(getattr(self, "VARIABLES", {}))

def _normalized_defined_variables(self):
return normalize_defined_variables(self.defined_variables())

def get_variables(self):
"""Return a dictionary of variables available to the template.

Expand Down Expand Up @@ -435,7 +453,7 @@ def resolve_variables(self, provided_variables):

"""
self.resolved_variables = {}
defined_variables = self.defined_variables()
defined_variables = self._normalized_defined_variables()
variable_dict = dict((var.name, var) for var in provided_variables)
for var_name, var_def in defined_variables.iteritems():
value = resolve_variable(
Expand Down
4 changes: 4 additions & 0 deletions stacker/blueprints/variables/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ def __init__(self, parameter_type):
"""
self.parameter_type = parameter_type

@staticmethod
def from_name(name):
return CFNType(name)


CFNString = CFNType("String")
CFNNumber = CFNType("Number")
Expand Down
6 changes: 5 additions & 1 deletion stacker/tests/blueprints/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ class TestBlueprint(Blueprint):
"Param2": {"type": CFNNumber},
"Param3": {"type": CFNCommaDelimitedList},
"Param4": {"default": "foo", "type": str},
"Param5": {"default": 5, "type": int}
"Param5": {"default": 5, "type": int},
"Param6": {"type": "AWS::EC2::Image::Id"}
}

def create_template(self):
Expand All @@ -86,6 +87,9 @@ def create_template(self):
},
"Param3": {
"Type": "CommaDelimitedList"
},
"Param6": {
"Type": "AWS::EC2::Image::Id"
}
},
"Resources": {}
Expand Down
22 changes: 11 additions & 11 deletions stacker/tests/fixtures/mock_blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ class FunctionalTests(Blueprint):

VARIABLES = {
"StackerNamespace": {
"type": CFNString,
"type": "String",
"description": "The stacker namespace that the tests will use. "
"Access to cloudformation will be restricted to "
"only allow access to stacks with this prefix."},
"StackerBucket": {
"type": CFNString,
"type": "String",
"description": "The name of the bucket that the tests will use "
"for uploading templates."}
}
Expand Down Expand Up @@ -172,38 +172,38 @@ class VPC(Blueprint):
"default": 2,
},
"PrivateSubnets": {
"type": CFNCommaDelimitedList,
"type": "CommaDelimitedList",
"description": "Comma separated list of subnets to use for "
"non-public hosts. NOTE: Must have as many subnets "
"as AZCount"},
"PublicSubnets": {
"type": CFNCommaDelimitedList,
"type": "CommaDelimitedList",
"description": "Comma separated list of subnets to use for "
"public hosts. NOTE: Must have as many subnets "
"as AZCount"},
"InstanceType": {
"type": CFNString,
"type": "String",
"description": "NAT EC2 instance type.",
"default": "m3.medium"},
"BaseDomain": {
"type": CFNString,
"type": "String",
"default": "",
"description": "Base domain for the stack."},
"InternalDomain": {
"type": CFNString,
"type": "String",
"default": "",
"description": "Internal domain name, if you have one."},
"CidrBlock": {
"type": CFNString,
"type": "String",
"description": "Base CIDR block for subnets.",
"default": "10.128.0.0/16"},
"ImageName": {
"type": CFNString,
"type": "String",
"description": "The image name to use from the AMIMap (usually "
"found in the config file.)",
"default": "NAT"},
"UseNatGateway": {
"type": CFNString,
"type": "String",
"allowed_values": ["true", "false"],
"description": "If set to true, will configure a NAT Gateway"
"instead of NAT instances.",
Expand All @@ -217,7 +217,7 @@ def create_template(self):
class DiffTester(Blueprint):
VARIABLES = {
"InstanceType": {
"type": CFNString,
"type": "String",
"description": "NAT EC2 instance type.",
"default": "m3.medium"},
"WaitConditionCount": {
Expand Down