Files
python-heatclient/heatclient/common/template_utils.py
Steven Hardy 884d5403bc Pass empty dict not None for empty environment
The server rejects any request with a None environment, so pass an
empty dict not None (we should probably also make the server more
robust so it can cope with None, but this seems the quickest and
most backwards compatible fix for now)

Change-Id: I0c3e8cd14faf257528be2254070bc40821675431
Closes-Bug: #1273993
2014-01-29 10:05:15 +00:00

125 lines
3.9 KiB
Python

# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import urllib
from heatclient.common import environment_format
from heatclient.common import template_format
from heatclient import exc
from heatclient.openstack.common.py3kcompat import urlutils
def get_template_contents(template_file=None, template_url=None,
template_object=None, object_request=None):
# Transform a bare file path to a file:// URL.
if template_file:
template_url = normalise_file_path_to_url(template_file)
if template_url:
tpl = urlutils.urlopen(template_url).read()
elif template_object:
template_url = template_object
tpl = object_request and object_request('GET',
template_object)
else:
raise exc.CommandError('Need to specify exactly one of '
'--template-file, --template-url '
'or --template-object')
if not tpl:
raise exc.CommandError('Could not fetch template from %s'
% template_url)
try:
return template_format.parse(tpl)
except ValueError as e:
raise exc.CommandError(
'Error parsing template %s %s' % (template_url, e))
def get_file_contents(from_dict, files, base_url=None,
ignore_if=None):
for key, value in iter(from_dict.items()):
if ignore_if and ignore_if(key, value):
continue
if base_url and not base_url.endswith('/'):
base_url = base_url + '/'
str_url = urlutils.urljoin(base_url, value)
try:
files[str_url] = urlutils.urlopen(str_url).read()
except urlutils.URLError:
raise exc.CommandError('Could not fetch %s from the environment'
% str_url)
from_dict[key] = str_url
def base_url_for_url(url):
parsed = urlutils.urlparse(url)
parsed_dir = os.path.dirname(parsed.path)
return urlutils.urljoin(url, parsed_dir)
def normalise_file_path_to_url(path):
if urlutils.urlparse(path).scheme:
return path
path = os.path.abspath(path)
return urlutils.urljoin('file:', urllib.pathname2url(path))
def process_environment_and_files(env_path=None, template_path=None):
files = {}
env = {}
if not env_path:
return files, env
env_url = normalise_file_path_to_url(env_path)
env_base_url = base_url_for_url(env_url)
raw_env = urlutils.urlopen(env_url).read()
env = environment_format.parse(raw_env)
resolve_environment_urls(
env.get('resource_registry'),
files,
env_base_url)
return files, env
def resolve_environment_urls(resource_registry, files, env_base_url):
rr = resource_registry
base_url = rr.get('base_url', env_base_url)
def ignore_if(key, value):
if key == 'base_url':
return True
if isinstance(value, dict):
return True
if '::' in value:
# Built in providers like: "X::Compute::Server"
# don't need downloading.
return True
get_file_contents(rr, files, base_url, ignore_if)
for res_name, res_dict in iter(rr.get('resources', {}).items()):
res_base_url = res_dict.get('base_url', base_url)
get_file_contents(res_dict, files, res_base_url, ignore_if)