Add 'subcloud deploy bootstrap' command to dcmanager
Adds the subcloud deploy bootstrap command to dcmanager client. It only performs the bootstrap phase, where all parameters are validated and the bootstrap playbook is executed. Usage: dcmanager subcloud deploy bootstrap --sysadmin-password <password> [--bootstrap-address <subcloud-bootstrap-address>] [--bootstrap-values <bootstrap-values.yaml>] subcloud-name Test Plan: 1. PASS - Bootstrap a subcloud using all the parameters and verify that the correct API call is made; 2. PASS - Bootstrap a subcloud using only the required parameters (--sysadmin-password and subcloud-name) and verify that the correct API call is made; 3. PASS - Verify that the CLI asks for the sysadmin-password if it's not provided through the --sysadmin-password parameter; 4. PASS - Verify that it's not possible to bootstrap a subcloud without the required parameters (--sysadmin-password and subcloud-name); 5. PASS - Verify that the dcmanager help subcloud deploy bootstrap shows the correct help message containing all options. Story: 2010756 Task: 48104 Change-Id: I7033e8247bdcfae243c6a86c0f632b88ef206ce9 Signed-off-by: Gustavo Herzmann <gustavo.herzmann@windriver.com>
This commit is contained in:
parent
dbb950d3ff
commit
860132451a
|
@ -42,3 +42,9 @@ class phased_subcloud_deploy_manager(base.ResourceManager):
|
|||
data = kwargs.get('data')
|
||||
files = kwargs.get('files')
|
||||
return self._deploy_operation(BASE_URL, files, data)
|
||||
|
||||
def subcloud_deploy_bootstrap(self, subcloud_ref, **kwargs):
|
||||
data = kwargs.get('data')
|
||||
files = kwargs.get('files')
|
||||
url = BASE_URL + "%s/bootstrap" % subcloud_ref
|
||||
return self._deploy_operation(url, files, data, "patch")
|
||||
|
|
|
@ -118,3 +118,71 @@ class CreatePhasedSubcloudDeploy(base.DCManagerShowOne):
|
|||
|
||||
return dcmanager_client.subcloud_deploy_create(
|
||||
files=files, data=data)
|
||||
|
||||
|
||||
class BootstrapPhasedSubcloudDeploy(base.DCManagerShowOne):
|
||||
"""Bootstrap a subcloud."""
|
||||
|
||||
def _get_format_function(self):
|
||||
return utils.subcloud_detail_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super().get_parser(prog_name)
|
||||
|
||||
parser.add_argument(
|
||||
'subcloud',
|
||||
help='Name or ID of the subcloud to bootstrap.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--bootstrap-address',
|
||||
required=False,
|
||||
help='IP address for initial subcloud controller.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--bootstrap-values',
|
||||
required=False,
|
||||
help='YAML file containing subcloud configuration settings. '
|
||||
'Can be either a local file path or a URL.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--sysadmin-password',
|
||||
required=False,
|
||||
help='sysadmin password of the subcloud to be configured, '
|
||||
'if not provided you will be prompted.'
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
dcmanager_client = self.app.client_manager.\
|
||||
phased_subcloud_deploy_manager.phased_subcloud_deploy_manager
|
||||
files = dict()
|
||||
data = dict()
|
||||
|
||||
if parsed_args.bootstrap_address:
|
||||
data['bootstrap-address'] = parsed_args.bootstrap_address
|
||||
|
||||
# Get the bootstrap values yaml file
|
||||
if parsed_args.bootstrap_values:
|
||||
if not os.path.isfile(parsed_args.bootstrap_values):
|
||||
error_msg = "bootstrap-values does not exist: %s" % \
|
||||
parsed_args.bootstrap_values
|
||||
raise exceptions.DCManagerClientException(error_msg)
|
||||
files['bootstrap_values'] = parsed_args.bootstrap_values
|
||||
|
||||
# Prompt the user for the subcloud's password if it isn't provided
|
||||
if parsed_args.sysadmin_password:
|
||||
data['sysadmin_password'] = base64.b64encode(
|
||||
parsed_args.sysadmin_password.encode("utf-8"))
|
||||
else:
|
||||
password = utils.prompt_for_password()
|
||||
data["sysadmin_password"] = base64.b64encode(
|
||||
password.encode("utf-8"))
|
||||
|
||||
subcloud_ref = parsed_args.subcloud
|
||||
|
||||
return dcmanager_client.subcloud_deploy_bootstrap(
|
||||
subcloud_ref, files=files, data=data)
|
||||
|
|
|
@ -545,6 +545,7 @@ class DCManagerShell(app.App):
|
|||
'subcloud-group show': gm.ShowSubcloudGroup,
|
||||
'subcloud-group update': gm.UpdateSubcloudGroup,
|
||||
'subcloud deploy create': psdm.CreatePhasedSubcloudDeploy,
|
||||
'subcloud deploy bootstrap': psdm.BootstrapPhasedSubcloudDeploy,
|
||||
'subcloud-deploy upload': sdm.SubcloudDeployUpload,
|
||||
'subcloud-deploy show': sdm.SubcloudDeployShow,
|
||||
'alarm summary': am.ListAlarmSummary,
|
||||
|
|
|
@ -12,6 +12,7 @@ from dcmanagerclient.commands.v1 import phased_subcloud_deploy_manager as cmd
|
|||
from dcmanagerclient.tests import base
|
||||
|
||||
|
||||
@mock.patch('getpass.getpass', new=mock.Mock(return_value='testpassword'))
|
||||
class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -20,8 +21,7 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
self.client = self.app.client_manager.phased_subcloud_deploy_manager.\
|
||||
phased_subcloud_deploy_manager
|
||||
|
||||
@mock.patch('getpass.getpass', return_value='testpassword')
|
||||
def test_subcloud_deploy_create(self, getpass):
|
||||
def test_subcloud_deploy_create(self):
|
||||
self.client.subcloud_deploy_create.return_value = [
|
||||
base.SUBCLOUD_RESOURCE]
|
||||
|
||||
|
@ -42,3 +42,18 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
'--release', base.SOFTWARE_VERSION,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
|
||||
def test_subcloud_deploy_bootstrap(self):
|
||||
self.client.subcloud_deploy_bootstrap.return_value = [
|
||||
base.SUBCLOUD_RESOURCE]
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w') as bootstrap_file:
|
||||
bootstrap_file_path = os.path.abspath(bootstrap_file.name)
|
||||
|
||||
actual_call = self.call(
|
||||
cmd.BootstrapPhasedSubcloudDeploy, app_args=[
|
||||
base.ID,
|
||||
'--bootstrap-address', base.BOOTSTRAP_ADDRESS,
|
||||
'--bootstrap-values', bootstrap_file_path,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
|
|
Loading…
Reference in New Issue