Skip to content

Commit

Permalink
Merge pull request #61 from remind101/add_local_parameters
Browse files Browse the repository at this point in the history
Local parameters for python
  • Loading branch information
phobologic committed Aug 12, 2015
2 parents 6d33081 + e8290f2 commit 3d697e7
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 2 deletions.
52 changes: 51 additions & 1 deletion stacker/blueprints/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,49 @@

from troposphere import Parameter, Template

from ..exceptions import MissingLocalParameterException

logger = logging.getLogger(__name__)


def get_local_parameters(parameter_def, parameters):
"""Gets local parameters from parameter list.
Given a local parameter definition, and a list of parameters, extract the
local parameters, or use a default if provided. If the parameter isn't
present, and there is no default, then throw an exception.
Args:
parameter_def (dict): A dictionary of expected/allowed parameters
and their defaults. If a parameter is in the list, but does not
have a default, it is considered required.
parameters (dict): A dictionary of parameters to pull local parameters
from.
Returns:
dict: A dictionary of local parameters.
Raises:
MissingLocalParameterException: If a parameter is defined in
parameter_def, does not have a default, and does not exist in
parameters.
"""
local = {}

for param, attrs in parameter_def.items():
try:
value = parameters[param]
except KeyError:
try:
value = attrs['default']
except KeyError:
raise MissingLocalParameterException(param)
local[param] = value

return local


class Blueprint(object):
"""Base implementation for dealing with a troposphere template.
Expand All @@ -23,6 +63,7 @@ def __init__(self, name, context, mappings=None):
self.mappings = mappings
self.context = context
self.outputs = {}
self.local_parameters = self.get_local_parameters()
self.reset_template()

@property
Expand All @@ -38,12 +79,21 @@ def required_parameters(self):
required.append((k, v))
return required

def get_local_parameters(self):
local_parameters = getattr(self, 'LOCAL_PARAMETERS', {})
return get_local_parameters(local_parameters, self.context.parameters)

def setup_parameters(self):
t = self.template
parameters = getattr(self, 'PARAMETERS')
# First look for CF_PARAMETERS, then fall back to regular PARAMETERS
# for backwards compatibility.
parameters = getattr(self, 'CF_PARAMETERS',
getattr(self, 'PARAMETERS', {}))

if not parameters:
logger.debug("No parameters defined.")
return

for param, attrs in parameters.items():
p = Parameter(param,
Type=attrs.get('type'),
Expand Down
11 changes: 10 additions & 1 deletion stacker/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,22 @@ class MissingParameterException(Exception):

def __init__(self, parameters, *args, **kwargs):
self.parameters = parameters
message = 'Missing required parameters: %s' % (
message = 'Missing required cloudformation parameters: %s' % (
', '.join(parameters),
)
super(MissingParameterException, self).__init__(message, *args,
**kwargs)


class MissingLocalParameterException(Exception):

def __init__(self, parameter, *args, **kwargs):
self.parameter = parameter
message = 'Missing required local parameter: %s' % parameter
super(MissingLocalParameterException, self).__init__(message, *args,
**kwargs)


class OutputDoesNotExist(Exception):

def __init__(self, stack_name, output, *args, **kwargs):
Expand Down
Empty file.
29 changes: 29 additions & 0 deletions stacker/tests/blueprints/test_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import unittest

from stacker.blueprints.base import get_local_parameters
from stacker.exceptions import MissingLocalParameterException


class TestLocalParameters(unittest.TestCase):
def test_default_parameter(self):
parameter_def = {'Param1': {'default': 0}}
parameters = {}

local = get_local_parameters(parameter_def, parameters)
self.assertEquals(local['Param1'], 0)

def test_missing_required(self):
parameter_def = {'Param1': {'default': 0}, 'Param2': {}}
parameters = {}

with self.assertRaises(MissingLocalParameterException) as cm:
get_local_parameters(parameter_def, parameters)

self.assertEquals('Param2', cm.exception.parameter)

def test_supplied_parameter(self):
parameter_def = {'Param1': {'default': 0}, 'Param2': {}}
parameters = {'Param1': 1, 'Param2': 2}

local = get_local_parameters(parameter_def, parameters)
self.assertEquals(parameters, local)

0 comments on commit 3d697e7

Please sign in to comment.