Upload provider templates referenced in the environment.

blueprint provider-upload
Change-Id: I3cbfe90dd8b4d152837666fa7f50b4b4a33bee27
This commit is contained in:
Angus Salkeld 2013-06-29 20:54:38 +10:00
parent a77fd1348d
commit 7774ac3217
3 changed files with 131 additions and 9 deletions

View File

@ -3,11 +3,14 @@ import httplib2
import os
import re
import sys
import urllib2
import yaml
import fixtures
import mox
import testscenarios
import testtools
try:
import json
except ImportError:
@ -18,6 +21,8 @@ from heatclient import exc
import heatclient.shell
from heatclient.tests import fakes
from heatclient.v1 import client as v1client
from heatclient.v1 import shell as v1shell
load_tests = testscenarios.load_tests_apply_scenarios
TEST_VAR_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
@ -406,3 +411,77 @@ class ShellTest(TestCase):
]
for r in required:
self.assertRegexpMatches(create_text, r)
class ShellEnvironmentTest(TestCase):
def setUp(self):
super(ShellEnvironmentTest, self).setUp()
self.m = mox.Mox()
self.addCleanup(self.m.VerifyAll)
self.addCleanup(self.m.UnsetStubs)
def collect_links(self, env, content, url, map_name):
jenv = yaml.safe_load(env)
fields = {'files': {}}
self.m.StubOutWithMock(urllib2, 'urlopen')
urllib2.urlopen(url).AndReturn(cStringIO.StringIO(content))
self.m.ReplayAll()
v1shell._get_file_contents(jenv['resource_registry'],
fields)
self.assertEqual(fields['files'][map_name], content)
def test_global_files(self):
a = "A's contents."
url = 'file:///home/b/a.yaml'
env = '''
resource_registry:
"OS::Thingy": "%s"
''' % url
self.collect_links(env, a, url, url)
def test_nested_files(self):
a = "A's contents."
url = 'file:///home/b/a.yaml'
env = '''
resource_registry:
resources:
freddy:
"OS::Thingy": "%s"
''' % url
self.collect_links(env, a, url, url)
def test_http_url(self):
a = "A's contents."
url = 'http://no.where/container/a.yaml'
env = '''
resource_registry:
"OS::Thingy": "%s"
''' % url
self.collect_links(env, a, url, url)
def test_with_base_url(self):
a = "A's contents."
url = 'ftp://no.where/container/a.yaml'
env = '''
resource_registry:
base_url: "ftp://no.where/container/"
resources:
server_for_me:
"OS::Thingy": a.yaml
'''
self.collect_links(env, a, url, 'a.yaml')
def test_unsupported_protocol(self):
env = '''
resource_registry:
"OS::Thingy": "sftp://no.where/dev/null/a.yaml"
'''
jenv = yaml.safe_load(env)
fields = {'files': {}}
self.assertRaises(exc.CommandError,
v1shell._get_file_contents,
jenv['resource_registry'],
fields)

View File

@ -15,6 +15,8 @@
import json
import textwrap
import urllib2
import yaml
from heatclient.common import utils
import heatclient.exc as exc
@ -42,6 +44,52 @@ def _set_template_fields(hc, args, fields):
'or --template-object')
def _get_file_contents(resource_registry, fields, base_url=''):
base_url = resource_registry.get('base_url', base_url)
for key, value in iter(resource_registry.items()):
if key == 'base_url':
continue
if isinstance(value, dict):
_get_file_contents(value, fields, base_url)
continue
facade = key
provider = value
if '::' in provider:
# Built in providers like: "X::Compute::Server"
# don't need downloading.
continue
str_url = base_url + provider
name = str_url[len(base_url):]
try:
fields['files'][name] = urllib2.urlopen(str_url).read()
except urllib2.URLError:
raise exc.CommandError('Could not fetch %s from the environment'
% str_url)
resource_registry[facade] = name
def _process_environment_and_files(hc, args, fields):
"""go through the env/resource_registry
look for base_url, urls and file
get them all and put them in the files section
modify the environment to just include the relative path as a name
"""
if not args.environment_file:
return
raw_env = open(args.environment_file).read()
env = yaml.safe_load(raw_env)
fields['environment'] = env
fields['files'] = {}
rr = env.get('resource_registry')
if rr:
_get_file_contents(rr, fields)
@utils.arg('-f', '--template-file', metavar='<FILE>',
help='Path to the template.')
@utils.arg('-e', '--environment-file', metavar='<FILE>',
@ -94,9 +142,7 @@ def do_stack_create(hc, args):
'disable_rollback': not(args.enable_rollback),
'parameters': parameters}
_set_template_fields(hc, args, fields)
if args.environment_file:
fields['environment'] = open(args.environment_file).read()
_process_environment_and_files(hc, args, fields)
hc.stacks.create(**fields)
do_stack_list(hc)
@ -185,9 +231,7 @@ def do_stack_update(hc, args):
fields = {'stack_id': args.id,
'parameters': utils.format_parameters(args.parameters)}
_set_template_fields(hc, args, fields)
if args.environment_file:
fields['environment'] = open(args.environment_file).read()
_process_environment_and_files(hc, args, fields)
hc.stacks.update(**fields)
do_list(hc)
@ -253,9 +297,7 @@ def do_template_validate(hc, args):
'''Validate a template with parameters.'''
fields = {'parameters': utils.format_parameters(args.parameters)}
_set_template_fields(hc, args, fields)
if args.environment_file:
fields['environment'] = open(args.environment_file).read()
_process_environment_and_files(hc, args, fields)
validation = hc.stacks.validate(**fields)
print json.dumps(validation, indent=2)

View File

@ -6,3 +6,4 @@ httplib2
iso8601>=0.1.4
prettytable>=0.6,<0.8
python-keystoneclient>=0.2,<0.3
pyyaml>=3.1.0