Provide a specific stack_name when deploy a template use heat-translator
Currently, the stack name of a template is random when use heat-translator online, and there is not any other feedback information except success or failure, the result is not very convenient. So it is necessary to provide a stack name when deploy a template, and the stack name will be 'heat_' + filename + '_' + first part of a uuid if no specific stack name provided. Change-Id: Icd92835d4bdd8bbb7417210bccd648c0f2e4171b Signed-off-by: shangxdy <shang.xiaodong@zte.com.cn>
This commit is contained in:
parent
f16fa4e627
commit
7baea64001
|
@ -105,6 +105,12 @@ class TranslatorShell(object):
|
|||
help=_('Whether to deploy the generated template '
|
||||
'or not.'))
|
||||
|
||||
parser.add_argument('--stack-name',
|
||||
metavar='<stack-name>',
|
||||
required=False,
|
||||
help=_('The name to use for the Heat stack when '
|
||||
'deploy the generated template.'))
|
||||
|
||||
self._append_global_identity_args(parser, argv)
|
||||
|
||||
return parser
|
||||
|
@ -131,6 +137,7 @@ class TranslatorShell(object):
|
|||
output_file = args.output_file
|
||||
validate_only = args.validate_only
|
||||
deploy = args.deploy
|
||||
stack_name = args.stack_name
|
||||
|
||||
parsed_params = {}
|
||||
if args.parameters:
|
||||
|
@ -172,8 +179,11 @@ class TranslatorShell(object):
|
|||
'Keystone to deploy on Heat, '
|
||||
'please check your credentials'))
|
||||
|
||||
file_name = os.path.basename(
|
||||
os.path.splitext(template_file)[0])
|
||||
self.deploy_on_heat(keystone_session, keystone_auth,
|
||||
hot, parsed_params)
|
||||
hot, stack_name, file_name,
|
||||
parsed_params)
|
||||
|
||||
self._write_output(hot, output_file)
|
||||
else:
|
||||
|
@ -183,19 +193,31 @@ class TranslatorShell(object):
|
|||
log.error(msg)
|
||||
raise ValueError(msg)
|
||||
|
||||
def deploy_on_heat(self, session, auth, template, parameters):
|
||||
def deploy_on_heat(self, session, auth, template,
|
||||
stack_name, file_name, parameters):
|
||||
endpoint = auth.get_endpoint(session, service_type="orchestration")
|
||||
client = heatclient.client.Client('1',
|
||||
session=session,
|
||||
auth=auth,
|
||||
endpoint=endpoint)
|
||||
heat_client = heatclient.client.Client('1',
|
||||
session=session,
|
||||
auth=auth,
|
||||
endpoint=endpoint)
|
||||
|
||||
stack_name = "heat_" + str(uuid.uuid4()).split("-")[0]
|
||||
heat_stack_name = stack_name if stack_name else \
|
||||
'heat_' + file_name + '_' + str(uuid.uuid4()).split("-")[0]
|
||||
msg = _('Deploy the generated template, the stack name is %(name)s.')\
|
||||
% {'name': heat_stack_name}
|
||||
log.debug(msg)
|
||||
tpl = yaml.load(template)
|
||||
tpl['heat_template_version'] = str(tpl['heat_template_version'])
|
||||
client.stacks.create(stack_name=stack_name,
|
||||
template=tpl,
|
||||
parameters=parameters)
|
||||
self._create_stack(heat_client=heat_client,
|
||||
stack_name=heat_stack_name,
|
||||
template=tpl,
|
||||
parameters=parameters)
|
||||
|
||||
def _create_stack(self, heat_client, stack_name, template, parameters):
|
||||
if heat_client:
|
||||
self.heat_client.stacks.create(stack_name=stack_name,
|
||||
template=template,
|
||||
parameters=parameters)
|
||||
|
||||
def _parse_parameters(self, parameter_list):
|
||||
parsed_inputs = {}
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import json
|
||||
import mock
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
@ -94,3 +97,71 @@ class ShellTest(TestCase):
|
|||
shutil.rmtree(temp_dir)
|
||||
self.assertTrue(temp_dir is None or
|
||||
not os.path.exists(temp_dir))
|
||||
|
||||
@mock.patch('uuid.uuid4')
|
||||
@mock.patch.object(shell.TranslatorShell, '_create_stack')
|
||||
@mock.patch('keystoneauth1.loading.load_auth_from_argparse_arguments')
|
||||
@mock.patch('keystoneauth1.loading.load_session_from_argparse_arguments')
|
||||
@mock.patch('translator.common.flavors.get_flavors')
|
||||
@mock.patch('translator.common.images.get_images')
|
||||
def test_template_deploy(self, mock_populate_image_dict,
|
||||
mock_flavor_dict,
|
||||
mock_keystone_session,
|
||||
mock_keystone_auth,
|
||||
mock_client,
|
||||
mock_uuid):
|
||||
mock_uuid.return_value = 'abcXXX-abcXXX'
|
||||
mock_flavor_dict.return_value = {
|
||||
'm1.medium': {'mem_size': 4096, 'disk_size': 40, 'num_cpus': 2}
|
||||
}
|
||||
mock_populate_image_dict.return_value = {
|
||||
"rhel-6.5-test-image": {
|
||||
"version": "6.5",
|
||||
"architecture": "x86_64",
|
||||
"distribution": "RHEL",
|
||||
"type": "Linux"
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
data = {
|
||||
'outputs': {},
|
||||
'heat_template_version': '2013-05-23',
|
||||
'description': 'Template for deploying a single server '
|
||||
'with predefined properties.\n',
|
||||
'parameters': {},
|
||||
'resources': {
|
||||
'my_server': {
|
||||
'type': 'OS::Nova::Server',
|
||||
'properties': {
|
||||
'flavor': 'm1.medium',
|
||||
'user_data_format': 'SOFTWARE_CONFIG',
|
||||
'image': 'rhel-6.5-test-image'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mock_heat_res = {
|
||||
"stacks": [
|
||||
{
|
||||
"id": "d648ad27-fb9c-44d1-b293-646ea6c4f8da",
|
||||
"stack_status": "CREATE_IN_PROGRESS",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
class mock_response(object):
|
||||
def __init__(self, status_code, _content):
|
||||
self.status_code = status_code
|
||||
self._content = _content
|
||||
|
||||
mock_response_obj = mock_response(201, json.dumps(mock_heat_res))
|
||||
mock_client.return_value = mock_response_obj
|
||||
shell.main([self.template_file, self.template_type, "--deploy"])
|
||||
args, kwargs = mock_client.call_args
|
||||
self.assertEqual(kwargs["stack_name"],
|
||||
'heat_tosca_helloworld_abcXXX')
|
||||
self.assertEqual(kwargs["template"], data)
|
||||
except Exception as e:
|
||||
self.fail(e)
|
||||
|
|
Loading…
Reference in New Issue