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 os
import re import re
import sys import sys
import urllib2
import yaml
import fixtures import fixtures
import mox import mox
import testscenarios import testscenarios
import testtools import testtools
try: try:
import json import json
except ImportError: except ImportError:
@ -18,6 +21,8 @@ from heatclient import exc
import heatclient.shell import heatclient.shell
from heatclient.tests import fakes from heatclient.tests import fakes
from heatclient.v1 import client as v1client from heatclient.v1 import client as v1client
from heatclient.v1 import shell as v1shell
load_tests = testscenarios.load_tests_apply_scenarios load_tests = testscenarios.load_tests_apply_scenarios
TEST_VAR_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), TEST_VAR_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
@ -406,3 +411,77 @@ class ShellTest(TestCase):
] ]
for r in required: for r in required:
self.assertRegexpMatches(create_text, r) 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 json
import textwrap import textwrap
import urllib2
import yaml
from heatclient.common import utils from heatclient.common import utils
import heatclient.exc as exc import heatclient.exc as exc
@ -42,6 +44,52 @@ def _set_template_fields(hc, args, fields):
'or --template-object') '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>', @utils.arg('-f', '--template-file', metavar='<FILE>',
help='Path to the template.') help='Path to the template.')
@utils.arg('-e', '--environment-file', metavar='<FILE>', @utils.arg('-e', '--environment-file', metavar='<FILE>',
@ -94,9 +142,7 @@ def do_stack_create(hc, args):
'disable_rollback': not(args.enable_rollback), 'disable_rollback': not(args.enable_rollback),
'parameters': parameters} 'parameters': parameters}
_set_template_fields(hc, args, fields) _set_template_fields(hc, args, fields)
_process_environment_and_files(hc, args, fields)
if args.environment_file:
fields['environment'] = open(args.environment_file).read()
hc.stacks.create(**fields) hc.stacks.create(**fields)
do_stack_list(hc) do_stack_list(hc)
@ -185,9 +231,7 @@ def do_stack_update(hc, args):
fields = {'stack_id': args.id, fields = {'stack_id': args.id,
'parameters': utils.format_parameters(args.parameters)} 'parameters': utils.format_parameters(args.parameters)}
_set_template_fields(hc, args, fields) _set_template_fields(hc, args, fields)
_process_environment_and_files(hc, args, fields)
if args.environment_file:
fields['environment'] = open(args.environment_file).read()
hc.stacks.update(**fields) hc.stacks.update(**fields)
do_list(hc) do_list(hc)
@ -253,9 +297,7 @@ def do_template_validate(hc, args):
'''Validate a template with parameters.''' '''Validate a template with parameters.'''
fields = {'parameters': utils.format_parameters(args.parameters)} fields = {'parameters': utils.format_parameters(args.parameters)}
_set_template_fields(hc, args, fields) _set_template_fields(hc, args, fields)
_process_environment_and_files(hc, args, fields)
if args.environment_file:
fields['environment'] = open(args.environment_file).read()
validation = hc.stacks.validate(**fields) validation = hc.stacks.validate(**fields)
print json.dumps(validation, indent=2) print json.dumps(validation, indent=2)

View File

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