Merge "Refactor functions out of ProcessTemplateAction"
This commit is contained in:
commit
2b6efe479e
@ -13,15 +13,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import jinja2
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import requests
|
||||
import six
|
||||
import tempfile as tf
|
||||
import yaml
|
||||
|
||||
from heatclient.common import template_utils
|
||||
from heatclient import exc as heat_exc
|
||||
from mistral_lib import actions
|
||||
from swiftclient import exceptions as swiftexceptions
|
||||
@ -34,14 +31,6 @@ from tripleo_common.utils import tarball
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _create_temp_file(data):
|
||||
handle, env_temp_file = tf.mkstemp()
|
||||
with open(env_temp_file, 'w') as temp_file:
|
||||
temp_file.write(json.dumps(data))
|
||||
os.close(handle)
|
||||
return env_temp_file
|
||||
|
||||
|
||||
class J2SwiftLoader(jinja2.BaseLoader):
|
||||
"""Jinja2 loader to fetch included files from swift
|
||||
|
||||
@ -371,82 +360,29 @@ class ProcessTemplatesAction(base.TripleOAction):
|
||||
return actions.Result(error=six.text_type(err))
|
||||
|
||||
template_name = plan_env.get('template', "")
|
||||
environments = plan_env.get('environments', [])
|
||||
env_paths = []
|
||||
temp_files = []
|
||||
|
||||
template_object = os.path.join(swift.url, self.container,
|
||||
template_name)
|
||||
|
||||
LOG.debug('Template: %s' % template_name)
|
||||
LOG.debug('Environments: %s' % environments)
|
||||
try:
|
||||
for env in environments:
|
||||
if env.get('path'):
|
||||
env_paths.append(os.path.join(swift.url, self.container,
|
||||
env['path']))
|
||||
elif env.get('data'):
|
||||
env_temp_file = _create_temp_file(env['data'])
|
||||
temp_files.append(env_temp_file)
|
||||
env_paths.append(env_temp_file)
|
||||
|
||||
# create a dict to hold all user set params and merge
|
||||
# them in the appropriate order
|
||||
merged_params = {}
|
||||
# merge generated passwords into params first
|
||||
passwords = plan_env.get('passwords', {})
|
||||
merged_params.update(passwords)
|
||||
|
||||
# derived parameters are merged before 'parameter defaults'
|
||||
# so that user-specified values can override the derived values.
|
||||
derived_params = plan_env.get('derived_parameters', {})
|
||||
merged_params.update(derived_params)
|
||||
|
||||
# handle user set parameter values next in case a user has set
|
||||
# a new value for a password parameter
|
||||
params = plan_env.get('parameter_defaults', {})
|
||||
merged_params = template_utils.deep_update(merged_params, params)
|
||||
|
||||
if merged_params:
|
||||
env_temp_file = _create_temp_file(
|
||||
{'parameter_defaults': merged_params})
|
||||
temp_files.append(env_temp_file)
|
||||
env_paths.append(env_temp_file)
|
||||
|
||||
registry = plan_env.get('resource_registry', {})
|
||||
if registry:
|
||||
env_temp_file = _create_temp_file(
|
||||
{'resource_registry': registry})
|
||||
temp_files.append(env_temp_file)
|
||||
env_paths.append(env_temp_file)
|
||||
|
||||
def _env_path_is_object(env_path):
|
||||
retval = env_path.startswith(swift.url)
|
||||
LOG.debug('_env_path_is_object %s: %s' % (env_path, retval))
|
||||
return retval
|
||||
|
||||
def _object_request(method, url, token=context.auth_token):
|
||||
response = requests.request(
|
||||
method, url, headers={'X-Auth-Token': token})
|
||||
response.raise_for_status()
|
||||
return response.content
|
||||
|
||||
template_files, template = template_utils.get_template_contents(
|
||||
template_object=template_object,
|
||||
object_request=_object_request)
|
||||
|
||||
env_files, env = (
|
||||
template_utils.process_multiple_environments_and_files(
|
||||
env_paths=env_paths,
|
||||
env_path_is_object=_env_path_is_object,
|
||||
object_request=_object_request))
|
||||
template_files, template = plan_utils.get_template_contents(
|
||||
swift, template_object)
|
||||
except Exception as err:
|
||||
error_text = six.text_type(err)
|
||||
LOG.exception("Error occurred while fetching %s" % template_object)
|
||||
|
||||
temp_env_paths = []
|
||||
try:
|
||||
env_paths, temp_env_paths = plan_utils.build_env_paths(
|
||||
swift, self.container, plan_env)
|
||||
env_files, env = plan_utils.process_environments_and_files(
|
||||
swift, env_paths)
|
||||
except Exception as err:
|
||||
error_text = six.text_type(err)
|
||||
LOG.exception("Error occurred while processing plan files.")
|
||||
finally:
|
||||
# cleanup any local temp files
|
||||
for f in temp_files:
|
||||
for f in temp_env_paths:
|
||||
os.remove(f)
|
||||
|
||||
if error_text:
|
||||
|
@ -13,7 +13,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import mock
|
||||
import os
|
||||
|
||||
from swiftclient import exceptions as swiftexceptions
|
||||
|
||||
@ -111,3 +113,137 @@ class PlanTest(base.TestCase):
|
||||
|
||||
self.swift.get_object.assert_called()
|
||||
self.swift.put_object.assert_called()
|
||||
|
||||
def test_write_json_temp_file(self):
|
||||
name = plan_utils.write_json_temp_file({'foo': 'bar'})
|
||||
with open(name) as f:
|
||||
self.assertEqual({'foo': 'bar'}, json.load(f))
|
||||
os.remove(name)
|
||||
|
||||
@mock.patch('requests.request', autospec=True)
|
||||
def test_object_request(self, request):
|
||||
request.return_value.content = 'foo'
|
||||
|
||||
content = plan_utils.object_request('GET', '/foo/bar', 'asdf1234')
|
||||
|
||||
self.assertEqual('foo', content)
|
||||
request.assert_called_once_with(
|
||||
'GET', '/foo/bar', headers={'X-Auth-Token': 'asdf1234'})
|
||||
|
||||
@mock.patch('tripleo_common.utils.plan.object_request',
|
||||
autospec=True)
|
||||
def test_process_environments_and_files(self, object_request):
|
||||
swift_url = 'https://192.0.2.1:8443/foo'
|
||||
url = '%s/bar' % swift_url
|
||||
object_request.return_value = 'parameter_defaults: {foo: bar}'
|
||||
swift = mock.Mock()
|
||||
swift.url = swift_url
|
||||
swift.token = 'asdf1234'
|
||||
|
||||
result = plan_utils.process_environments_and_files(swift, [url])
|
||||
|
||||
self.assertEqual(
|
||||
{'parameter_defaults': {'foo': 'bar'}},
|
||||
result[1]
|
||||
)
|
||||
object_request.assert_called_once_with(
|
||||
'GET',
|
||||
'https://192.0.2.1:8443/foo/bar',
|
||||
'asdf1234'
|
||||
)
|
||||
|
||||
@mock.patch('tripleo_common.utils.plan.object_request',
|
||||
autospec=True)
|
||||
def test_get_template_contents(self, object_request):
|
||||
swift_url = 'https://192.0.2.1:8443/foo'
|
||||
url = '%s/bar' % swift_url
|
||||
object_request.return_value = 'heat_template_version: 2016-04-30'
|
||||
swift = mock.Mock()
|
||||
swift.url = swift_url
|
||||
swift.token = 'asdf1234'
|
||||
|
||||
result = plan_utils.get_template_contents(swift, url)
|
||||
|
||||
self.assertEqual(
|
||||
{'heat_template_version': '2016-04-30'},
|
||||
result[1]
|
||||
)
|
||||
object_request.assert_called_once_with(
|
||||
'GET',
|
||||
'https://192.0.2.1:8443/foo/bar',
|
||||
'asdf1234'
|
||||
)
|
||||
|
||||
def test_build_env_paths(self):
|
||||
swift = mock.Mock()
|
||||
swift.url = 'https://192.0.2.1:8443/foo'
|
||||
swift.token = 'asdf1234'
|
||||
plan = {
|
||||
'version': '1.0',
|
||||
'environments': [
|
||||
{'path': 'bar.yaml'},
|
||||
{'data': {
|
||||
'parameter_defaults': {'InlineParam': 1}}}
|
||||
],
|
||||
'passwords': {
|
||||
'ThePassword': 'password1'
|
||||
},
|
||||
'derived_parameters': {
|
||||
'DerivedParam': 'DerivedValue',
|
||||
'MergableParam': {
|
||||
'one': 'derived one',
|
||||
'two': 'derived two',
|
||||
},
|
||||
},
|
||||
'parameter_defaults': {
|
||||
'Foo': 'bar',
|
||||
'MergableParam': {
|
||||
'one': 'user one',
|
||||
'three': 'user three',
|
||||
},
|
||||
},
|
||||
'resource_registry': {
|
||||
'Foo::Bar': 'foo_bar.yaml'
|
||||
},
|
||||
}
|
||||
|
||||
env_paths, temp_env_paths = plan_utils.build_env_paths(
|
||||
swift, 'overcloud', plan)
|
||||
|
||||
self.assertEqual(3, len(temp_env_paths))
|
||||
self.assertEqual(
|
||||
['https://192.0.2.1:8443/foo/overcloud/bar.yaml'] + temp_env_paths,
|
||||
env_paths
|
||||
)
|
||||
|
||||
with open(env_paths[1]) as f:
|
||||
self.assertEqual(
|
||||
{'parameter_defaults': {'InlineParam': 1}},
|
||||
json.load(f)
|
||||
)
|
||||
|
||||
with open(env_paths[2]) as f:
|
||||
self.assertEqual(
|
||||
{'parameter_defaults': {
|
||||
'ThePassword': 'password1',
|
||||
'DerivedParam': 'DerivedValue',
|
||||
'Foo': 'bar',
|
||||
'MergableParam': {
|
||||
'one': 'user one',
|
||||
'two': 'derived two',
|
||||
'three': 'user three',
|
||||
}
|
||||
}},
|
||||
json.load(f)
|
||||
)
|
||||
|
||||
with open(env_paths[3]) as f:
|
||||
self.assertEqual(
|
||||
{'resource_registry': {
|
||||
'Foo::Bar': 'foo_bar.yaml'
|
||||
}},
|
||||
json.load(f)
|
||||
)
|
||||
|
||||
for path in temp_env_paths:
|
||||
os.remove(path)
|
||||
|
@ -13,6 +13,12 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from heatclient.common import template_utils
|
||||
import json
|
||||
import os
|
||||
import requests
|
||||
import tempfile
|
||||
import yaml
|
||||
|
||||
from tripleo_common import constants
|
||||
@ -71,3 +77,86 @@ def put_user_env(swift, container_name, env):
|
||||
constants.USER_ENVIRONMENT,
|
||||
yaml.safe_dump(env, default_flow_style=False)
|
||||
)
|
||||
|
||||
|
||||
def write_json_temp_file(data):
|
||||
"""Writes the provided data to a json file and return the filename"""
|
||||
with tempfile.NamedTemporaryFile(delete=False, mode='w') as temp_file:
|
||||
temp_file.write(json.dumps(data))
|
||||
return temp_file.name
|
||||
|
||||
|
||||
def object_request(method, url, token):
|
||||
"""Fetch an object with the provided token"""
|
||||
response = requests.request(
|
||||
method, url, headers={'X-Auth-Token': token})
|
||||
response.raise_for_status()
|
||||
return response.content
|
||||
|
||||
|
||||
def process_environments_and_files(swift, env_paths):
|
||||
"""Wrap process_multiple_environments_and_files with swift object fetch"""
|
||||
def _env_path_is_object(env_path):
|
||||
return env_path.startswith(swift.url)
|
||||
|
||||
def _object_request(method, url, token=swift.token):
|
||||
return object_request(method, url, token)
|
||||
|
||||
return template_utils.process_multiple_environments_and_files(
|
||||
env_paths=env_paths,
|
||||
env_path_is_object=_env_path_is_object,
|
||||
object_request=_object_request)
|
||||
|
||||
|
||||
def get_template_contents(swift, template_object):
|
||||
"""Wrap get_template_contents with swift object fetch"""
|
||||
def _object_request(method, url, token=swift.token):
|
||||
return object_request(method, url, token)
|
||||
|
||||
return template_utils.get_template_contents(
|
||||
template_object=template_object,
|
||||
object_request=_object_request)
|
||||
|
||||
|
||||
def build_env_paths(swift, container, plan_env):
|
||||
environments = plan_env.get('environments', [])
|
||||
env_paths = []
|
||||
temp_env_paths = []
|
||||
|
||||
for env in environments:
|
||||
if env.get('path'):
|
||||
env_paths.append(os.path.join(swift.url, container, env['path']))
|
||||
elif env.get('data'):
|
||||
env_file = write_json_temp_file(env['data'])
|
||||
temp_env_paths.append(env_file)
|
||||
|
||||
# create a dict to hold all user set params and merge
|
||||
# them in the appropriate order
|
||||
merged_params = {}
|
||||
# merge generated passwords into params first
|
||||
passwords = plan_env.get('passwords', {})
|
||||
merged_params.update(passwords)
|
||||
|
||||
# derived parameters are merged before 'parameter defaults'
|
||||
# so that user-specified values can override the derived values.
|
||||
derived_params = plan_env.get('derived_parameters', {})
|
||||
merged_params.update(derived_params)
|
||||
|
||||
# handle user set parameter values next in case a user has set
|
||||
# a new value for a password parameter
|
||||
params = plan_env.get('parameter_defaults', {})
|
||||
merged_params = template_utils.deep_update(merged_params, params)
|
||||
|
||||
if merged_params:
|
||||
env_temp_file = write_json_temp_file(
|
||||
{'parameter_defaults': merged_params})
|
||||
temp_env_paths.append(env_temp_file)
|
||||
|
||||
registry = plan_env.get('resource_registry', {})
|
||||
if registry:
|
||||
env_temp_file = write_json_temp_file(
|
||||
{'resource_registry': registry})
|
||||
temp_env_paths.append(env_temp_file)
|
||||
|
||||
env_paths.extend(temp_env_paths)
|
||||
return env_paths, temp_env_paths
|
||||
|
Loading…
x
Reference in New Issue
Block a user