Render local charm overlay from string

Stop requiring the charm to ship with a boiler plate overlay for
setting a relative path for local charm location. Instead render the
overlay from a string var. As part of this some of the template
rendering code was refactored.
This commit is contained in:
Liam Young
2018-04-18 07:35:55 +00:00
parent 8155057e36
commit 2e522f2ab4
2 changed files with 113 additions and 23 deletions

View File

@@ -30,6 +30,29 @@ class TestCharmLifecycleDeploy(ut_utils.BaseTestCase):
{'OS_VIP04': '10.10.0.2'}
)
def test_get_charm_config_contex(self):
self.patch_object(lc_deploy.utils, 'get_charm_config')
self.get_charm_config.return_value = {
'charm_name': 'mycharm'}
self.assertEqual(
lc_deploy.get_charm_config_contex(),
{'charm_location': '../../../mycharm', 'charm_name': 'mycharm'})
def test_get_template_overlay_context(self):
self.patch_object(lc_deploy, 'get_template_context_from_env')
self.patch_object(lc_deploy, 'get_charm_config_contex')
self.get_template_context_from_env.return_value = {
'OS_VIP04': '10.10.0.2'}
self.get_charm_config_contex.return_value = {
'charm_location': '../../../mycharm',
'charm_name': 'mycharm'}
self.assertEqual(
lc_deploy.get_template_overlay_context(),
{
'OS_VIP04': '10.10.0.2',
'charm_location': '../../../mycharm',
'charm_name': 'mycharm'})
def test_get_overlay_template_dir(self):
self.assertEqual(
lc_deploy.get_overlay_template_dir(),
@@ -69,19 +92,27 @@ class TestCharmLifecycleDeploy(ut_utils.BaseTestCase):
jinja2.exceptions.TemplateNotFound(name='bob')
self.assertIsNone(lc_deploy.get_template('mybundle.yaml'))
def test_render_overlay(self):
self.patch_object(lc_deploy, 'get_template_context_from_env')
def test_render_template(self):
self.patch_object(lc_deploy, 'get_template_overlay_context')
template_mock = mock.MagicMock()
template_mock.render.return_value = 'Template contents'
self.patch_object(lc_deploy, 'get_template')
self.get_template.return_value = template_mock
m = mock.mock_open()
with mock.patch('zaza.charm_lifecycle.deploy.open', m, create=True):
lc_deploy.render_overlay('mybundle.yaml', '/tmp/')
lc_deploy.render_template(template_mock, '/tmp/mybundle.yaml')
m.assert_called_once_with('/tmp/mybundle.yaml', 'w')
handle = m()
handle.write.assert_called_once_with('Template contents')
def test_render_overlay(self):
self.patch_object(lc_deploy, 'render_template')
template_mock = mock.MagicMock()
self.patch_object(lc_deploy, 'get_template')
self.get_template.return_value = template_mock
lc_deploy.render_overlay('my_overlay.yaml', '/tmp/special-dir')
self.render_template.assert_called_once_with(
template_mock,
'/tmp/special-dir/my_overlay.yaml')
def test_render_overlay_no_template(self):
self.patch_object(lc_deploy, 'get_template')
self.get_template.return_value = None
@@ -89,23 +120,24 @@ class TestCharmLifecycleDeploy(ut_utils.BaseTestCase):
def test_render_overlays(self):
RESP = {
'local-charm-overlay.yaml': '/tmp/local-charm-overlay.yaml',
'mybundles/mybundle.yaml': '/tmp/mybundle.yaml'}
self.patch_object(lc_deploy, 'render_local_overlay')
self.render_local_overlay.return_value = '/tmp/local-overlay.yaml'
self.patch_object(lc_deploy, 'render_overlay')
self.render_overlay.side_effect = lambda x, y: RESP[x]
self.assertEqual(
lc_deploy.render_overlays('mybundles/mybundle.yaml', '/tmp'),
['/tmp/local-charm-overlay.yaml', '/tmp/mybundle.yaml'])
['/tmp/local-overlay.yaml', '/tmp/mybundle.yaml'])
def test_render_overlays_missing(self):
RESP = {
'local-charm-overlay.yaml': None,
'mybundles/mybundle.yaml': '/tmp/mybundle.yaml'}
RESP = {'mybundles/mybundle.yaml': None}
self.patch_object(lc_deploy, 'render_overlay')
self.patch_object(lc_deploy, 'render_local_overlay')
self.render_local_overlay.return_value = '/tmp/local.yaml'
self.render_overlay.side_effect = lambda x, y: RESP[x]
self.assertEqual(
lc_deploy.render_overlays('mybundles/mybundle.yaml', '/tmp'),
['/tmp/mybundle.yaml'])
['/tmp/local.yaml'])
def test_deploy_bundle(self):
self.patch_object(lc_deploy, 'render_overlays')

View File

@@ -11,7 +11,6 @@ import juju_wait
import zaza.charm_lifecycle.utils as utils
DEFAULT_OVERLAY_TEMPLATE_DIR = 'tests/bundles/overlays'
DEFAULT_OVERLAYS = ['local-charm-overlay.yaml']
VALID_ENVIRONMENT_KEY_PREFIXES = [
'FIP_RANGE',
'GATEWAY',
@@ -20,11 +19,15 @@ VALID_ENVIRONMENT_KEY_PREFIXES = [
'OS_',
'VIP_RANGE',
]
LOCAL_OVERLAY_TEMPLATE = """
applications:
{{ charm_name }}:
charm: {{ charm_location }}
"""
def is_valid_env_key(key):
"""Check if key is a valid environment variable name for use with template
rendering
:param key: List of configure functions functions
:type key: str
@@ -49,6 +52,34 @@ def get_template_context_from_env():
return {k: v for k, v in os.environ.items() if is_valid_env_key(k)}
def get_charm_config_contex():
"""Return settings from charm config file
:returns: Context for template rendering
:rtype: dict
"""
test_config = utils.get_charm_config()
ctxt = {
'charm_name': test_config['charm_name'],
'charm_location': '../../../{}'.format(test_config['charm_name'])}
return ctxt
def get_template_overlay_context():
"""Combine contexts which can be used for overlay template rendering
:returns: Context for template rendering
:rtype: dict
"""
context = {}
contexts = [
get_template_context_from_env(),
get_charm_config_contex()]
for c in contexts:
context.update(c)
return context
def get_overlay_template_dir():
"""Return the directory to look for overlay template files in.
@@ -96,6 +127,19 @@ def get_template(target_file):
return template
def render_template(template, target_file):
"""Render the template to the file supplied
:param template: Template to be rendered
:type template: jinja2.Template
:param target_file: File name for rendered template
:type target_file: str
"""
with open(target_file, "w") as fh:
fh.write(
template.render(get_template_overlay_context()))
def render_overlay(overlay_name, target_dir):
"""Render the overlay template in the directory supplied
@@ -112,9 +156,24 @@ def render_overlay(overlay_name, target_dir):
rendered_template_file = os.path.join(
target_dir,
os.path.basename(overlay_name))
with open(rendered_template_file, "w") as fh:
fh.write(
template.render(get_template_context_from_env()))
render_template(template, rendered_template_file)
return rendered_template_file
def render_local_overlay(target_dir):
"""Render the local overlay template in the directory supplied
:param target_dir: Directory to render overlay in
:type overlay_name: str
:returns: Path to rendered overlay
:rtype: str
"""
template = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
LOCAL_OVERLAY_TEMPLATE)
rendered_template_file = os.path.join(
target_dir,
os.path.basename('local-charm-overlay.yaml'))
render_template(template, rendered_template_file)
return rendered_template_file
@@ -125,14 +184,13 @@ def render_overlays(bundle, target_dir):
:type bundle: str
:param target_dir: Directory to render overlay in
:type overlay_name: str
:returns: Path to rendered overlay
:rtype: str
:returns: List of rendered overlays
:rtype: [str, str,...]
"""
overlays = []
for overlay in DEFAULT_OVERLAYS + [bundle]:
rendered_overlay = render_overlay(overlay, target_dir)
if rendered_overlay:
overlays.append(rendered_overlay)
overlays = [render_local_overlay(target_dir)]
rendered_bundle_overlay = render_overlay(bundle, target_dir)
if rendered_bundle_overlay:
overlays.append(rendered_bundle_overlay)
return overlays