Merge "Add plan export command"
This commit is contained in:
commit
76e472ebc1
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Add a new plan export command for exporting deployment plans.
|
@ -78,6 +78,7 @@ openstack.tripleoclient.v1 =
|
|||||||
overcloud_plan_delete = tripleoclient.v1.overcloud_plan:DeletePlan
|
overcloud_plan_delete = tripleoclient.v1.overcloud_plan:DeletePlan
|
||||||
overcloud_plan_deploy = tripleoclient.v1.overcloud_plan:DeployPlan
|
overcloud_plan_deploy = tripleoclient.v1.overcloud_plan:DeployPlan
|
||||||
overcloud_plan_list = tripleoclient.v1.overcloud_plan:ListPlans
|
overcloud_plan_list = tripleoclient.v1.overcloud_plan:ListPlans
|
||||||
|
overcloud_plan_export = tripleoclient.v1.overcloud_plan:ExportPlan
|
||||||
overcloud_profiles_match = tripleoclient.v1.overcloud_profiles:MatchProfiles
|
overcloud_profiles_match = tripleoclient.v1.overcloud_profiles:MatchProfiles
|
||||||
overcloud_profiles_list = tripleoclient.v1.overcloud_profiles:ListProfiles
|
overcloud_profiles_list = tripleoclient.v1.overcloud_profiles:ListProfiles
|
||||||
overcloud_raid_create = tripleoclient.v1.overcloud_raid:CreateRAID
|
overcloud_raid_create = tripleoclient.v1.overcloud_raid:CreateRAID
|
||||||
|
@ -360,3 +360,59 @@ class TestOvercloudDeployPlan(utils.TestCommand):
|
|||||||
'skip_deploy_identifier': False
|
'skip_deploy_identifier': False
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestOvercloudExportPlan(utils.TestCommand):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestOvercloudExportPlan, self).setUp()
|
||||||
|
self.cmd = overcloud_plan.ExportPlan(self.app, None)
|
||||||
|
self.app.client_manager = mock.Mock()
|
||||||
|
self.clients = self.app.client_manager
|
||||||
|
|
||||||
|
# Mock UUID4 generation for every test
|
||||||
|
uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4")
|
||||||
|
self.mock_uuid4 = uuid4_patcher.start()
|
||||||
|
self.addCleanup(self.mock_uuid4.stop)
|
||||||
|
|
||||||
|
# Mock urlopen
|
||||||
|
f = mock.Mock()
|
||||||
|
f.read.return_value = 'tarball contents'
|
||||||
|
urlopen_patcher = mock.patch('six.moves.urllib.request.urlopen',
|
||||||
|
return_value=f)
|
||||||
|
self.mock_urlopen = urlopen_patcher.start()
|
||||||
|
self.addCleanup(self.mock_urlopen.stop)
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
'tripleoclient.workflows.plan_management.export_deployment_plan',
|
||||||
|
autospec=True)
|
||||||
|
def test_export_plan(self, export_deployment_plan_mock):
|
||||||
|
parsed_args = self.check_parser(self.cmd, ['test-plan'],
|
||||||
|
[('plans', ['test-plan'])])
|
||||||
|
|
||||||
|
export_deployment_plan_mock.return_value = 'http://fake-url.com'
|
||||||
|
|
||||||
|
with mock.patch('six.moves.builtins.open', mock.mock_open()):
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
export_deployment_plan_mock.assert_called_once_with(
|
||||||
|
self.clients, plan='test-plan', queue_name='UUID4')
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
'tripleoclient.workflows.plan_management.export_deployment_plan',
|
||||||
|
autospec=True)
|
||||||
|
def test_export_multiple_plans(self, export_deployment_plan_mock):
|
||||||
|
argslist = ['test-plan1', 'test-plan2']
|
||||||
|
verifylist = [('plans', ['test-plan1', 'test-plan2'])]
|
||||||
|
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
|
||||||
|
|
||||||
|
export_deployment_plan_mock.return_value = 'http://fake-url.com'
|
||||||
|
|
||||||
|
with mock.patch('six.moves.builtins.open', mock.mock_open()):
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
mock.call(self.clients, plan='test-plan1', queue_name='UUID4'),
|
||||||
|
mock.call(self.clients, plan='test-plan2', queue_name='UUID4'),
|
||||||
|
]
|
||||||
|
self.assertEqual(export_deployment_plan_mock.call_args_list, expected)
|
||||||
|
@ -12,10 +12,13 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import os.path
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
from osc_lib.i18n import _
|
from osc_lib.i18n import _
|
||||||
|
from six.moves.urllib import request
|
||||||
|
|
||||||
|
|
||||||
from tripleoclient import utils
|
from tripleoclient import utils
|
||||||
from tripleoclient.workflows import deployment
|
from tripleoclient.workflows import deployment
|
||||||
@ -146,3 +149,51 @@ class DeployPlan(command.Command):
|
|||||||
self.app_args.verbose_level,
|
self.app_args.verbose_level,
|
||||||
timeout=parsed_args.timeout,
|
timeout=parsed_args.timeout,
|
||||||
run_validations=parsed_args.run_validations)
|
run_validations=parsed_args.run_validations)
|
||||||
|
|
||||||
|
|
||||||
|
class ExportPlan(command.Command):
|
||||||
|
"""Export a deployment plan"""
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__ + ".ExportPlan")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(ExportPlan, self).get_parser(prog_name)
|
||||||
|
parser.add_argument('plans', metavar='<name>', nargs='+',
|
||||||
|
help=_('Name of the plan(s) to export.'))
|
||||||
|
parser.add_argument('--output-files', '-o', metavar='<output file>',
|
||||||
|
nargs='+', default=[],
|
||||||
|
help=_('Name of the output file(s) for exports. '
|
||||||
|
'Each will default to "<name>.tar.gz".')
|
||||||
|
)
|
||||||
|
parser.add_argument('--force-overwrite', '-f', action='store_true',
|
||||||
|
default=False,
|
||||||
|
help=_('Overwrite output files if they exist.'))
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self.log.debug("take_action(%s)" % parsed_args)
|
||||||
|
clients = self.app.client_manager
|
||||||
|
plans = parsed_args.plans
|
||||||
|
outfiles = parsed_args.output_files
|
||||||
|
overwrite = parsed_args.force_overwrite
|
||||||
|
|
||||||
|
for i, plan in enumerate(plans):
|
||||||
|
print("Exporting plan %s..." % plan)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tarball_name = outfiles[i]
|
||||||
|
except IndexError:
|
||||||
|
tarball_name = '%s.tar.gz' % plan
|
||||||
|
|
||||||
|
if os.path.exists(tarball_name) and not overwrite:
|
||||||
|
print("File '%s' already exists, not exporting."
|
||||||
|
% tarball_name)
|
||||||
|
continue
|
||||||
|
|
||||||
|
tempurl = plan_management.export_deployment_plan(
|
||||||
|
clients, plan=plan, queue_name=str(uuid.uuid4()))
|
||||||
|
f = request.urlopen(tempurl)
|
||||||
|
tarball_contents = f.read()
|
||||||
|
|
||||||
|
with open(tarball_name, 'w') as f:
|
||||||
|
f.write(tarball_contents)
|
||||||
|
@ -183,3 +183,27 @@ def update_plan_from_templates(clients, name, tht_root, roles_file=None,
|
|||||||
update_deployment_plan(clients, container=name,
|
update_deployment_plan(clients, container=name,
|
||||||
queue_name=str(uuid.uuid4()),
|
queue_name=str(uuid.uuid4()),
|
||||||
generate_passwords=generate_passwords)
|
generate_passwords=generate_passwords)
|
||||||
|
|
||||||
|
|
||||||
|
def export_deployment_plan(clients, **workflow_input):
|
||||||
|
workflow_client = clients.workflow_engine
|
||||||
|
tripleoclients = clients.tripleoclient
|
||||||
|
queue_name = workflow_input['queue_name']
|
||||||
|
|
||||||
|
execution = base.start_workflow(
|
||||||
|
workflow_client,
|
||||||
|
'tripleo.plan_management.v1.export_deployment_plan',
|
||||||
|
workflow_input=workflow_input
|
||||||
|
)
|
||||||
|
|
||||||
|
with tripleoclients.messaging_websocket(queue_name) as ws:
|
||||||
|
for payload in base.wait_for_messages(workflow_client, ws, execution,
|
||||||
|
_WORKFLOW_TIMEOUT):
|
||||||
|
if 'message' in payload:
|
||||||
|
print(payload['message'])
|
||||||
|
|
||||||
|
if payload['status'] == 'SUCCESS':
|
||||||
|
return payload['tempurl']
|
||||||
|
else:
|
||||||
|
raise exceptions.WorkflowServiceError(
|
||||||
|
'Exception exporting plan: {}'.format(payload['message']))
|
||||||
|
Loading…
Reference in New Issue
Block a user