Zero Touch Provisioning changes for subcloud configuration
- Adding deploy field to subcloud entity - removing generate config option - modifying subcloud add to take a yaml file instead of individual parameters Depends-On: https://review.opendev.org/#/c/670328/ Change-Id: I3160fb65dde7c4d514246fcf413e8b341b9c75a8 Story: 2004766 Task: 35756 Signed-off-by: Tyler Smith <tyler.smith@windriver.com>
This commit is contained in:
parent
45db426cb0
commit
e96710bfc9
|
@ -13,7 +13,7 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017 Wind River Systems, Inc.
|
# Copyright (c) 2017-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# The right to copy, distribute, modify, or otherwise make use
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
# of this software may be licensed only pursuant to the terms
|
# of this software may be licensed only pursuant to the terms
|
||||||
|
@ -31,6 +31,7 @@ class Subcloud(base.Resource):
|
||||||
|
|
||||||
def __init__(self, manager, subcloud_id, name, description, location,
|
def __init__(self, manager, subcloud_id, name, description, location,
|
||||||
software_version, management_state, availability_status,
|
software_version, management_state, availability_status,
|
||||||
|
deploy_status,
|
||||||
management_subnet, management_start_ip, management_end_ip,
|
management_subnet, management_start_ip, management_end_ip,
|
||||||
management_gateway_ip, systemcontroller_gateway_ip,
|
management_gateway_ip, systemcontroller_gateway_ip,
|
||||||
created_at, updated_at, sync_status="unknown",
|
created_at, updated_at, sync_status="unknown",
|
||||||
|
@ -44,6 +45,7 @@ class Subcloud(base.Resource):
|
||||||
self.management_subnet = management_subnet
|
self.management_subnet = management_subnet
|
||||||
self.management_state = management_state
|
self.management_state = management_state
|
||||||
self.availability_status = availability_status
|
self.availability_status = availability_status
|
||||||
|
self.deploy_status = deploy_status
|
||||||
self.management_start_ip = management_start_ip
|
self.management_start_ip = management_start_ip
|
||||||
self.management_end_ip = management_end_ip
|
self.management_end_ip = management_end_ip
|
||||||
self.management_gateway_ip = management_gateway_ip
|
self.management_gateway_ip = management_gateway_ip
|
||||||
|
@ -74,6 +76,7 @@ class subcloud_manager(base.ResourceManager):
|
||||||
software_version=json_object['software-version'],
|
software_version=json_object['software-version'],
|
||||||
management_state=json_object['management-state'],
|
management_state=json_object['management-state'],
|
||||||
availability_status=json_object['availability-status'],
|
availability_status=json_object['availability-status'],
|
||||||
|
deploy_status=json_object['deploy-status'],
|
||||||
management_subnet=json_object['management-subnet'],
|
management_subnet=json_object['management-subnet'],
|
||||||
management_start_ip=json_object['management-start-ip'],
|
management_start_ip=json_object['management-start-ip'],
|
||||||
management_end_ip=json_object['management-end-ip'],
|
management_end_ip=json_object['management-end-ip'],
|
||||||
|
@ -101,6 +104,7 @@ class subcloud_manager(base.ResourceManager):
|
||||||
software_version=json_object['software-version'],
|
software_version=json_object['software-version'],
|
||||||
management_state=json_object['management-state'],
|
management_state=json_object['management-state'],
|
||||||
availability_status=json_object['availability-status'],
|
availability_status=json_object['availability-status'],
|
||||||
|
deploy_status=json_object['deploy-status'],
|
||||||
management_subnet=json_object['management-subnet'],
|
management_subnet=json_object['management-subnet'],
|
||||||
management_start_ip=json_object['management-start-ip'],
|
management_start_ip=json_object['management-start-ip'],
|
||||||
management_end_ip=json_object['management-end-ip'],
|
management_end_ip=json_object['management-end-ip'],
|
||||||
|
@ -129,6 +133,7 @@ class subcloud_manager(base.ResourceManager):
|
||||||
software_version=json_object['software-version'],
|
software_version=json_object['software-version'],
|
||||||
management_state=json_object['management-state'],
|
management_state=json_object['management-state'],
|
||||||
availability_status=json_object['availability-status'],
|
availability_status=json_object['availability-status'],
|
||||||
|
deploy_status=json_object['deploy-status'],
|
||||||
management_subnet=json_object['management-subnet'],
|
management_subnet=json_object['management-subnet'],
|
||||||
management_start_ip=json_object['management-start-ip'],
|
management_start_ip=json_object['management-start-ip'],
|
||||||
management_end_ip=json_object['management-end-ip'],
|
management_end_ip=json_object['management-end-ip'],
|
||||||
|
@ -157,6 +162,7 @@ class subcloud_manager(base.ResourceManager):
|
||||||
software_version=json_object['software-version'],
|
software_version=json_object['software-version'],
|
||||||
management_state=json_object['management-state'],
|
management_state=json_object['management-state'],
|
||||||
availability_status=json_object['availability-status'],
|
availability_status=json_object['availability-status'],
|
||||||
|
deploy_status=json_object['deploy-status'],
|
||||||
management_subnet=json_object['management-subnet'],
|
management_subnet=json_object['management-subnet'],
|
||||||
management_start_ip=json_object['management-start-ip'],
|
management_start_ip=json_object['management-start-ip'],
|
||||||
management_end_ip=json_object['management-end-ip'],
|
management_end_ip=json_object['management-end-ip'],
|
||||||
|
@ -168,14 +174,6 @@ class subcloud_manager(base.ResourceManager):
|
||||||
endpoint_sync_status=json_object['endpoint_sync_status']))
|
endpoint_sync_status=json_object['endpoint_sync_status']))
|
||||||
return resource
|
return resource
|
||||||
|
|
||||||
def subcloud_generate_config(self, url, data):
|
|
||||||
data = json.dumps(data)
|
|
||||||
resp = self.http_client.post(url, data)
|
|
||||||
if resp.status_code != 200:
|
|
||||||
self._raise_api_exception(resp)
|
|
||||||
json_object = get_json(resp)
|
|
||||||
return json_object['config']
|
|
||||||
|
|
||||||
def add_subcloud(self, **kwargs):
|
def add_subcloud(self, **kwargs):
|
||||||
data = kwargs
|
data = kwargs
|
||||||
url = '/subclouds/'
|
url = '/subclouds/'
|
||||||
|
@ -197,8 +195,3 @@ class subcloud_manager(base.ResourceManager):
|
||||||
data = kwargs
|
data = kwargs
|
||||||
url = '/subclouds/%s' % subcloud_ref
|
url = '/subclouds/%s' % subcloud_ref
|
||||||
return self.subcloud_update(url, data)
|
return self.subcloud_update(url, data)
|
||||||
|
|
||||||
def generate_config_subcloud(self, subcloud_ref, **kwargs):
|
|
||||||
data = kwargs
|
|
||||||
url = '/subclouds/%s/config' % subcloud_ref
|
|
||||||
return self.subcloud_generate_config(url, data)
|
|
||||||
|
|
|
@ -12,13 +12,17 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017 Wind River Systems, Inc.
|
# Copyright (c) 2017-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# The right to copy, distribute, modify, or otherwise make use
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
# of this software may be licensed only pursuant to the terms
|
# of this software may be licensed only pursuant to the terms
|
||||||
# of an applicable Wind River license agreement.
|
# of an applicable Wind River license agreement.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import getpass
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
|
|
||||||
from dcmanagerclient.commands.v1 import base
|
from dcmanagerclient.commands.v1 import base
|
||||||
|
@ -31,6 +35,7 @@ def format(subcloud=None):
|
||||||
'name',
|
'name',
|
||||||
'management',
|
'management',
|
||||||
'availability',
|
'availability',
|
||||||
|
'deploy status',
|
||||||
'sync'
|
'sync'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,6 +45,7 @@ def format(subcloud=None):
|
||||||
subcloud.name,
|
subcloud.name,
|
||||||
subcloud.management_state,
|
subcloud.management_state,
|
||||||
subcloud.availability_status,
|
subcloud.availability_status,
|
||||||
|
subcloud.deploy_status,
|
||||||
subcloud.sync_status
|
subcloud.sync_status
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -58,6 +64,7 @@ def detail_format(subcloud=None):
|
||||||
'software_version',
|
'software_version',
|
||||||
'management',
|
'management',
|
||||||
'availability',
|
'availability',
|
||||||
|
'deploy_status',
|
||||||
'management_subnet',
|
'management_subnet',
|
||||||
'management_start_ip',
|
'management_start_ip',
|
||||||
'management_end_ip',
|
'management_end_ip',
|
||||||
|
@ -76,6 +83,7 @@ def detail_format(subcloud=None):
|
||||||
subcloud.software_version,
|
subcloud.software_version,
|
||||||
subcloud.management_state,
|
subcloud.management_state,
|
||||||
subcloud.availability_status,
|
subcloud.availability_status,
|
||||||
|
subcloud.deploy_status,
|
||||||
subcloud.management_subnet,
|
subcloud.management_subnet,
|
||||||
subcloud.management_start_ip,
|
subcloud.management_start_ip,
|
||||||
subcloud.management_end_ip,
|
subcloud.management_end_ip,
|
||||||
|
@ -108,51 +116,21 @@ class AddSubcloud(base.DCManagerShowOne):
|
||||||
parser = super(AddSubcloud, self).get_parser(parsed_args)
|
parser = super(AddSubcloud, self).get_parser(parsed_args)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--name',
|
'--bootstrap-address',
|
||||||
required=True,
|
required=True,
|
||||||
help='Name of subcloud.'
|
help='IP address for initial subcloud controller.'
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--description',
|
'--bootstrap-values',
|
||||||
|
required=True,
|
||||||
|
help='YAML file containing subcloud configuration settings.'
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'--subcloud-password',
|
||||||
required=False,
|
required=False,
|
||||||
help='Description of subcloud.'
|
help='sysadmin password of the subcloud to be configured.'
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--location',
|
|
||||||
required=False,
|
|
||||||
help='Location of subcloud.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--management-subnet',
|
|
||||||
required=True,
|
|
||||||
help='Management subnet for subcloud in CIDR format.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--management-start-ip',
|
|
||||||
required=True,
|
|
||||||
help='Start of management IP address range for subcloud'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--management-end-ip',
|
|
||||||
required=True,
|
|
||||||
help='End of management IP address range for subcloud',
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--management-gateway-ip',
|
|
||||||
required=True,
|
|
||||||
help='Management gateway IP for subcloud',
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--systemcontroller-gateway-ip',
|
|
||||||
required=True,
|
|
||||||
help='Central gateway IP',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
@ -160,17 +138,39 @@ class AddSubcloud(base.DCManagerShowOne):
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
dcmanager_client = self.app.client_manager.subcloud_manager
|
dcmanager_client = self.app.client_manager.subcloud_manager
|
||||||
kwargs = dict()
|
kwargs = dict()
|
||||||
kwargs['name'] = parsed_args.name
|
kwargs['bootstrap-address'] = parsed_args.bootstrap_address
|
||||||
if parsed_args.description:
|
|
||||||
kwargs['description'] = parsed_args.description
|
# Load the configuration from the yaml file
|
||||||
if parsed_args.location:
|
filename = parsed_args.bootstrap_values
|
||||||
kwargs['location'] = parsed_args.location
|
if os.path.isdir(filename):
|
||||||
kwargs['management-subnet'] = parsed_args.management_subnet
|
error_msg = "Error: %s is a directory." % filename
|
||||||
kwargs['management-start-ip'] = parsed_args.management_start_ip
|
raise exceptions.DCManagerClientException(error_msg)
|
||||||
kwargs['management-end-ip'] = parsed_args.management_end_ip
|
try:
|
||||||
kwargs['management-gateway-ip'] = parsed_args.management_gateway_ip
|
with open(filename, 'rb') as stream:
|
||||||
kwargs['systemcontroller-gateway-ip'] = \
|
kwargs.update(yaml.safe_load(stream))
|
||||||
parsed_args.systemcontroller_gateway_ip
|
except Exception:
|
||||||
|
error_msg = "Error: Could not open file %s." % filename
|
||||||
|
raise exceptions.DCManagerClientException(error_msg)
|
||||||
|
|
||||||
|
# Prompt the user for the subcloud's password if it isn't provided
|
||||||
|
if parsed_args.subcloud_password is not None:
|
||||||
|
kwargs['subcloud_password'] = parsed_args.subcloud_password
|
||||||
|
else:
|
||||||
|
while True:
|
||||||
|
password = getpass.getpass(
|
||||||
|
"Enter the sysadmin password for the subcloud: ")
|
||||||
|
if len(password) < 1:
|
||||||
|
print("Password cannot be empty")
|
||||||
|
continue
|
||||||
|
|
||||||
|
confirm = getpass.getpass(
|
||||||
|
"Re-enter sysadmin password to confirm: ")
|
||||||
|
if password != confirm:
|
||||||
|
print("Passwords did not match")
|
||||||
|
continue
|
||||||
|
kwargs["subcloud_password"] = password
|
||||||
|
break
|
||||||
|
|
||||||
return dcmanager_client.subcloud_manager.add_subcloud(**kwargs)
|
return dcmanager_client.subcloud_manager.add_subcloud(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -339,170 +339,3 @@ class UpdateSubcloud(base.DCManagerShowOne):
|
||||||
print(e)
|
print(e)
|
||||||
error_msg = "Unable to update subcloud %s" % (subcloud_ref)
|
error_msg = "Unable to update subcloud %s" % (subcloud_ref)
|
||||||
raise exceptions.DCManagerClientException(error_msg)
|
raise exceptions.DCManagerClientException(error_msg)
|
||||||
|
|
||||||
|
|
||||||
class GenerateConfigSubcloud(command.Command):
|
|
||||||
"""Generate configuration for a subcloud."""
|
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(GenerateConfigSubcloud, self).get_parser(prog_name)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'subcloud',
|
|
||||||
help='Name or ID of the subcloud to generate config.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--pxe-subnet',
|
|
||||||
required=False,
|
|
||||||
help='PXE boot subnet for subcloud in CIDR format.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--management-vlan',
|
|
||||||
required=False,
|
|
||||||
help='VLAN for subcloud management network.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--management-interface-port',
|
|
||||||
required=False,
|
|
||||||
help='Subcloud management interface port.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--management-interface-mtu',
|
|
||||||
required=False,
|
|
||||||
help='Subcloud management interface mtu.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--cluster-vlan',
|
|
||||||
required=False,
|
|
||||||
help='VLAN for subcloud cluster network.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--cluster-interface-port',
|
|
||||||
required=False,
|
|
||||||
help='Subcloud cluster interface port.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--cluster-interface-mtu',
|
|
||||||
required=False,
|
|
||||||
help='Subcloud cluster interface mtu.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--cluster-subnet',
|
|
||||||
required=False,
|
|
||||||
help='Cluster subnet for subcloud in CIDR format.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--oam-subnet',
|
|
||||||
required=False,
|
|
||||||
help='OAM subnet for subcloud in CIDR format.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--oam-gateway-ip',
|
|
||||||
required=False,
|
|
||||||
help='OAM gateway IP for subcloud.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--oam-floating-ip',
|
|
||||||
required=False,
|
|
||||||
help='OAM floating IP address for subcloud.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--oam-unit-0-ip',
|
|
||||||
required=False,
|
|
||||||
help='OAM unit 0 IP address for subcloud.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--oam-unit-1-ip',
|
|
||||||
required=False,
|
|
||||||
help='OAM unit 1 IP address for subcloud.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--oam-interface-port',
|
|
||||||
required=False,
|
|
||||||
help='Subcloud OAM interface port.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--oam-interface-mtu',
|
|
||||||
required=False,
|
|
||||||
help='Subcloud OAM interface mtu.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'--system-mode',
|
|
||||||
required=False,
|
|
||||||
help='System mode',
|
|
||||||
choices=['simplex', 'duplex', 'duplex-direct']
|
|
||||||
)
|
|
||||||
|
|
||||||
return parser
|
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
|
||||||
subcloud_ref = parsed_args.subcloud
|
|
||||||
dcmanager_client = self.app.client_manager.subcloud_manager
|
|
||||||
|
|
||||||
kwargs = dict()
|
|
||||||
if parsed_args.pxe_subnet:
|
|
||||||
kwargs['pxe-subnet'] = \
|
|
||||||
parsed_args.pxe_subnet
|
|
||||||
if parsed_args.management_vlan:
|
|
||||||
kwargs['management-vlan'] = \
|
|
||||||
parsed_args.management_vlan
|
|
||||||
if parsed_args.management_interface_port:
|
|
||||||
kwargs['management-interface-port'] = \
|
|
||||||
parsed_args.management_interface_port
|
|
||||||
if parsed_args.management_interface_mtu:
|
|
||||||
kwargs['management-interface-mtu'] = \
|
|
||||||
parsed_args.management_interface_mtu
|
|
||||||
if parsed_args.cluster_vlan:
|
|
||||||
kwargs['cluster-vlan'] = \
|
|
||||||
parsed_args.cluster_vlan
|
|
||||||
if parsed_args.cluster_interface_port:
|
|
||||||
kwargs['cluster-interface-port'] = \
|
|
||||||
parsed_args.cluster_interface_port
|
|
||||||
if parsed_args.cluster_interface_mtu:
|
|
||||||
kwargs['cluster-interface-mtu'] = \
|
|
||||||
parsed_args.cluster_interface_mtu
|
|
||||||
if parsed_args.cluster_subnet:
|
|
||||||
kwargs['cluster-subnet'] = parsed_args.cluster_subnet
|
|
||||||
if parsed_args.oam_subnet:
|
|
||||||
kwargs['oam-subnet'] = parsed_args.oam_subnet
|
|
||||||
if parsed_args.oam_gateway_ip:
|
|
||||||
kwargs['oam-gateway-ip'] = parsed_args.oam_gateway_ip
|
|
||||||
if parsed_args.oam_floating_ip:
|
|
||||||
kwargs['oam-floating-ip'] = parsed_args.oam_floating_ip
|
|
||||||
if parsed_args.oam_unit_0_ip:
|
|
||||||
kwargs['oam-unit-0-ip'] = parsed_args.oam_unit_0_ip
|
|
||||||
if parsed_args.oam_unit_1_ip:
|
|
||||||
kwargs['oam-unit-1-ip'] = parsed_args.oam_unit_1_ip
|
|
||||||
if parsed_args.oam_interface_port:
|
|
||||||
kwargs['oam-interface-port'] = parsed_args.oam_interface_port
|
|
||||||
if parsed_args.oam_interface_mtu:
|
|
||||||
kwargs['oam-interface-mtu'] = parsed_args.oam_interface_mtu
|
|
||||||
if parsed_args.system_mode:
|
|
||||||
kwargs['system-mode'] = parsed_args.system_mode
|
|
||||||
|
|
||||||
try:
|
|
||||||
subcloud_config = dcmanager_client.subcloud_manager.\
|
|
||||||
generate_config_subcloud(subcloud_ref, **kwargs)
|
|
||||||
return subcloud_config
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
error_msg = "Unable to generate config for subcloud %s" % \
|
|
||||||
(subcloud_ref)
|
|
||||||
raise exceptions.DCManagerClientException(error_msg)
|
|
||||||
|
|
|
@ -480,7 +480,6 @@ class DCManagerShell(app.App):
|
||||||
'subcloud unmanage': sm.UnmanageSubcloud,
|
'subcloud unmanage': sm.UnmanageSubcloud,
|
||||||
'subcloud manage': sm.ManageSubcloud,
|
'subcloud manage': sm.ManageSubcloud,
|
||||||
'subcloud update': sm.UpdateSubcloud,
|
'subcloud update': sm.UpdateSubcloud,
|
||||||
'subcloud generate-config': sm.GenerateConfigSubcloud,
|
|
||||||
'alarm summary': am.ListAlarmSummary,
|
'alarm summary': am.ListAlarmSummary,
|
||||||
'patch-strategy create': sum.CreatePatchStrategy,
|
'patch-strategy create': sum.CreatePatchStrategy,
|
||||||
'patch-strategy delete': sum.DeletePatchStrategy,
|
'patch-strategy delete': sum.DeletePatchStrategy,
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
# of an applicable Wind River license agreement.
|
# of an applicable Wind River license agreement.
|
||||||
#
|
#
|
||||||
|
|
||||||
import copy
|
|
||||||
import mock
|
import mock
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
import yaml
|
||||||
|
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
|
|
||||||
|
@ -28,20 +30,26 @@ from dcmanagerclient.api.v1 import subcloud_manager as sm
|
||||||
from dcmanagerclient.commands.v1 import subcloud_manager as subcloud_cmd
|
from dcmanagerclient.commands.v1 import subcloud_manager as subcloud_cmd
|
||||||
from dcmanagerclient.tests import base
|
from dcmanagerclient.tests import base
|
||||||
|
|
||||||
|
BOOTSTRAP_ADDRESS = '10.10.10.12'
|
||||||
TIME_NOW = timeutils.utcnow().isoformat()
|
TIME_NOW = timeutils.utcnow().isoformat()
|
||||||
ID = '1'
|
ID = '1'
|
||||||
ID_1 = '2'
|
ID_1 = '2'
|
||||||
NAME = 'subcloud1'
|
NAME = 'subcloud1'
|
||||||
|
SYSTEM_MODE = "duplex"
|
||||||
DESCRIPTION = 'subcloud1 description'
|
DESCRIPTION = 'subcloud1 description'
|
||||||
LOCATION = 'subcloud1 location'
|
LOCATION = 'subcloud1 location'
|
||||||
SOFTWARE_VERSION = '12.34'
|
SOFTWARE_VERSION = '12.34'
|
||||||
MANAGEMENT_STATE = 'unmanaged'
|
MANAGEMENT_STATE = 'unmanaged'
|
||||||
AVAILABILITY_STATUS = 'offline'
|
AVAILABILITY_STATUS = 'offline'
|
||||||
|
DEPLOY_STATUS = 'not-deployed'
|
||||||
MANAGEMENT_SUBNET = '192.168.101.0/24'
|
MANAGEMENT_SUBNET = '192.168.101.0/24'
|
||||||
MANAGEMENT_START_IP = '192.168.101.2'
|
MANAGEMENT_START_IP = '192.168.101.2'
|
||||||
MANAGEMENT_END_IP = '192.168.101.50'
|
MANAGEMENT_END_IP = '192.168.101.50'
|
||||||
MANAGEMENT_GATEWAY_IP = '192.168.101.1'
|
MANAGEMENT_GATEWAY_IP = '192.168.101.1'
|
||||||
SYSTEMCONTROLLER_GATEWAY_IP = '192.168.204.101'
|
SYSTEMCONTROLLER_GATEWAY_IP = '192.168.204.101'
|
||||||
|
EXTERNAL_OAM_SUBNET = "10.10.10.0/24"
|
||||||
|
EXTERNAL_OAM_GATEWAY_ADDRESS = "10.10.10.1"
|
||||||
|
EXTERNAL_OAM_FLOATING_ADDRESS = "10.10.10.12"
|
||||||
|
|
||||||
SUBCLOUD_DICT = {
|
SUBCLOUD_DICT = {
|
||||||
'SUBCLOUD_ID': ID,
|
'SUBCLOUD_ID': ID,
|
||||||
|
@ -51,6 +59,7 @@ SUBCLOUD_DICT = {
|
||||||
'SOFTWARE_VERSION': SOFTWARE_VERSION,
|
'SOFTWARE_VERSION': SOFTWARE_VERSION,
|
||||||
'MANAGEMENT_STATE': MANAGEMENT_STATE,
|
'MANAGEMENT_STATE': MANAGEMENT_STATE,
|
||||||
'AVAILABILITY_STATUS': AVAILABILITY_STATUS,
|
'AVAILABILITY_STATUS': AVAILABILITY_STATUS,
|
||||||
|
'DEPLOY_STATUS': DEPLOY_STATUS,
|
||||||
'MANAGEMENT_SUBNET': MANAGEMENT_SUBNET,
|
'MANAGEMENT_SUBNET': MANAGEMENT_SUBNET,
|
||||||
'MANAGEMENT_START_IP': MANAGEMENT_START_IP,
|
'MANAGEMENT_START_IP': MANAGEMENT_START_IP,
|
||||||
'MANAGEMENT_END_IP': MANAGEMENT_END_IP,
|
'MANAGEMENT_END_IP': MANAGEMENT_END_IP,
|
||||||
|
@ -69,6 +78,7 @@ SUBCLOUD = sm.Subcloud(
|
||||||
software_version=SUBCLOUD_DICT['SOFTWARE_VERSION'],
|
software_version=SUBCLOUD_DICT['SOFTWARE_VERSION'],
|
||||||
management_state=SUBCLOUD_DICT['MANAGEMENT_STATE'],
|
management_state=SUBCLOUD_DICT['MANAGEMENT_STATE'],
|
||||||
availability_status=SUBCLOUD_DICT['AVAILABILITY_STATUS'],
|
availability_status=SUBCLOUD_DICT['AVAILABILITY_STATUS'],
|
||||||
|
deploy_status=SUBCLOUD_DICT['DEPLOY_STATUS'],
|
||||||
management_subnet=SUBCLOUD_DICT['MANAGEMENT_SUBNET'],
|
management_subnet=SUBCLOUD_DICT['MANAGEMENT_SUBNET'],
|
||||||
management_start_ip=SUBCLOUD_DICT['MANAGEMENT_START_IP'],
|
management_start_ip=SUBCLOUD_DICT['MANAGEMENT_START_IP'],
|
||||||
management_end_ip=SUBCLOUD_DICT['MANAGEMENT_END_IP'],
|
management_end_ip=SUBCLOUD_DICT['MANAGEMENT_END_IP'],
|
||||||
|
@ -84,13 +94,13 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
||||||
self.client.subcloud_manager.list_subclouds.return_value = [SUBCLOUD]
|
self.client.subcloud_manager.list_subclouds.return_value = [SUBCLOUD]
|
||||||
actual_call = self.call(subcloud_cmd.ListSubcloud)
|
actual_call = self.call(subcloud_cmd.ListSubcloud)
|
||||||
self.assertEqual([(ID, NAME, MANAGEMENT_STATE, AVAILABILITY_STATUS,
|
self.assertEqual([(ID, NAME, MANAGEMENT_STATE, AVAILABILITY_STATUS,
|
||||||
"unknown")],
|
DEPLOY_STATUS, "unknown")],
|
||||||
actual_call[1])
|
actual_call[1])
|
||||||
|
|
||||||
def test_negative_list_subclouds(self):
|
def test_negative_list_subclouds(self):
|
||||||
self.client.subcloud_manager.list_subclouds.return_value = []
|
self.client.subcloud_manager.list_subclouds.return_value = []
|
||||||
actual_call = self.call(subcloud_cmd.ListSubcloud)
|
actual_call = self.call(subcloud_cmd.ListSubcloud)
|
||||||
self.assertEqual((('<none>', '<none>', '<none>', '<none>',
|
self.assertEqual((('<none>', '<none>', '<none>', '<none>', '<none>',
|
||||||
'<none>'),),
|
'<none>'),),
|
||||||
actual_call[1])
|
actual_call[1])
|
||||||
|
|
||||||
|
@ -113,6 +123,7 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
||||||
SOFTWARE_VERSION,
|
SOFTWARE_VERSION,
|
||||||
MANAGEMENT_STATE,
|
MANAGEMENT_STATE,
|
||||||
AVAILABILITY_STATUS,
|
AVAILABILITY_STATUS,
|
||||||
|
DEPLOY_STATUS,
|
||||||
MANAGEMENT_SUBNET,
|
MANAGEMENT_SUBNET,
|
||||||
MANAGEMENT_START_IP,
|
MANAGEMENT_START_IP,
|
||||||
MANAGEMENT_END_IP,
|
MANAGEMENT_END_IP,
|
||||||
|
@ -127,63 +138,43 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
||||||
self.assertEqual((('<none>', '<none>', '<none>', '<none>',
|
self.assertEqual((('<none>', '<none>', '<none>', '<none>',
|
||||||
'<none>', '<none>', '<none>', '<none>',
|
'<none>', '<none>', '<none>', '<none>',
|
||||||
'<none>', '<none>', '<none>', '<none>',
|
'<none>', '<none>', '<none>', '<none>',
|
||||||
'<none>', '<none>'),),
|
'<none>', '<none>', '<none>'),),
|
||||||
actual_call[1])
|
actual_call[1])
|
||||||
|
|
||||||
def test_add_subcloud(self):
|
@mock.patch('getpass.getpass', return_value='testpassword')
|
||||||
|
def test_add_subcloud(self, getpass):
|
||||||
self.client.subcloud_manager.add_subcloud.\
|
self.client.subcloud_manager.add_subcloud.\
|
||||||
return_value = [SUBCLOUD]
|
return_value = [SUBCLOUD]
|
||||||
|
|
||||||
|
values = {
|
||||||
|
"system_mode": SYSTEM_MODE,
|
||||||
|
"name": NAME,
|
||||||
|
"description": DESCRIPTION,
|
||||||
|
"location": LOCATION,
|
||||||
|
"management_subnet": MANAGEMENT_SUBNET,
|
||||||
|
"management_start_address": MANAGEMENT_START_IP,
|
||||||
|
"management_end_address": MANAGEMENT_END_IP,
|
||||||
|
"management_gateway_address": MANAGEMENT_GATEWAY_IP,
|
||||||
|
"external_oam_subnet": EXTERNAL_OAM_SUBNET,
|
||||||
|
"external_oam_gateway_address": EXTERNAL_OAM_GATEWAY_ADDRESS,
|
||||||
|
"external_oam_floating_address": EXTERNAL_OAM_FLOATING_ADDRESS,
|
||||||
|
}
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile() as f:
|
||||||
|
yaml.dump(values, f)
|
||||||
|
file_path = os.path.abspath(f.name)
|
||||||
actual_call = self.call(
|
actual_call = self.call(
|
||||||
subcloud_cmd.AddSubcloud, app_args=[
|
subcloud_cmd.AddSubcloud, app_args=[
|
||||||
'--name', NAME,
|
'--bootstrap-address', BOOTSTRAP_ADDRESS,
|
||||||
'--description', DESCRIPTION,
|
'--bootstrap-values', file_path,
|
||||||
'--location', LOCATION,
|
])
|
||||||
'--management-subnet', MANAGEMENT_SUBNET,
|
|
||||||
'--management-start-ip', MANAGEMENT_START_IP,
|
|
||||||
'--management-end-ip', MANAGEMENT_END_IP,
|
|
||||||
'--management-gateway-ip', MANAGEMENT_GATEWAY_IP,
|
|
||||||
'--systemcontroller-gateway-ip', SYSTEMCONTROLLER_GATEWAY_IP])
|
|
||||||
self.assertEqual((ID, NAME, DESCRIPTION, LOCATION, SOFTWARE_VERSION,
|
self.assertEqual((ID, NAME, DESCRIPTION, LOCATION, SOFTWARE_VERSION,
|
||||||
MANAGEMENT_STATE, AVAILABILITY_STATUS,
|
MANAGEMENT_STATE, AVAILABILITY_STATUS, DEPLOY_STATUS,
|
||||||
MANAGEMENT_SUBNET, MANAGEMENT_START_IP,
|
MANAGEMENT_SUBNET, MANAGEMENT_START_IP,
|
||||||
MANAGEMENT_END_IP, MANAGEMENT_GATEWAY_IP,
|
MANAGEMENT_END_IP, MANAGEMENT_GATEWAY_IP,
|
||||||
SYSTEMCONTROLLER_GATEWAY_IP,
|
SYSTEMCONTROLLER_GATEWAY_IP,
|
||||||
TIME_NOW, TIME_NOW), actual_call[1])
|
TIME_NOW, TIME_NOW), actual_call[1])
|
||||||
|
|
||||||
def test_add_subcloud_no_optional_parameters(self):
|
|
||||||
subcloud = copy.copy(SUBCLOUD)
|
|
||||||
subcloud.description = ''
|
|
||||||
subcloud.location = ''
|
|
||||||
self.client.subcloud_manager.add_subcloud.\
|
|
||||||
return_value = [subcloud]
|
|
||||||
actual_call = self.call(
|
|
||||||
subcloud_cmd.AddSubcloud, app_args=[
|
|
||||||
'--name', NAME,
|
|
||||||
'--management-subnet', MANAGEMENT_SUBNET,
|
|
||||||
'--management-start-ip', MANAGEMENT_START_IP,
|
|
||||||
'--management-end-ip', MANAGEMENT_END_IP,
|
|
||||||
'--management-gateway-ip', MANAGEMENT_GATEWAY_IP,
|
|
||||||
'--systemcontroller-gateway-ip', SYSTEMCONTROLLER_GATEWAY_IP])
|
|
||||||
self.assertEqual((ID, NAME, '', '', SOFTWARE_VERSION,
|
|
||||||
MANAGEMENT_STATE, AVAILABILITY_STATUS,
|
|
||||||
MANAGEMENT_SUBNET, MANAGEMENT_START_IP,
|
|
||||||
MANAGEMENT_END_IP, MANAGEMENT_GATEWAY_IP,
|
|
||||||
SYSTEMCONTROLLER_GATEWAY_IP,
|
|
||||||
TIME_NOW, TIME_NOW), actual_call[1])
|
|
||||||
|
|
||||||
def test_add_subcloud_without_name(self):
|
|
||||||
self.client.subcloud_manager.add_subcloud.\
|
|
||||||
return_value = [SUBCLOUD]
|
|
||||||
self.assertRaises(
|
|
||||||
SystemExit, self.call, subcloud_cmd.AddSubcloud, app_args=[
|
|
||||||
'--description', DESCRIPTION,
|
|
||||||
'--location', LOCATION,
|
|
||||||
'--management-subnet', MANAGEMENT_SUBNET,
|
|
||||||
'--management-start-ip', MANAGEMENT_START_IP,
|
|
||||||
'--management-end-ip', MANAGEMENT_END_IP,
|
|
||||||
'--management-gateway-ip', MANAGEMENT_GATEWAY_IP,
|
|
||||||
'--systemcontroller-gateway-ip', SYSTEMCONTROLLER_GATEWAY_IP])
|
|
||||||
|
|
||||||
def test_unmanage_subcloud(self):
|
def test_unmanage_subcloud(self):
|
||||||
self.client.subcloud_manager.update_subcloud.\
|
self.client.subcloud_manager.update_subcloud.\
|
||||||
return_value = [SUBCLOUD]
|
return_value = [SUBCLOUD]
|
||||||
|
@ -192,7 +183,7 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
||||||
self.assertEqual((ID, NAME,
|
self.assertEqual((ID, NAME,
|
||||||
DESCRIPTION, LOCATION,
|
DESCRIPTION, LOCATION,
|
||||||
SOFTWARE_VERSION, MANAGEMENT_STATE,
|
SOFTWARE_VERSION, MANAGEMENT_STATE,
|
||||||
AVAILABILITY_STATUS,
|
AVAILABILITY_STATUS, DEPLOY_STATUS,
|
||||||
MANAGEMENT_SUBNET, MANAGEMENT_START_IP,
|
MANAGEMENT_SUBNET, MANAGEMENT_START_IP,
|
||||||
MANAGEMENT_END_IP, MANAGEMENT_GATEWAY_IP,
|
MANAGEMENT_END_IP, MANAGEMENT_GATEWAY_IP,
|
||||||
SYSTEMCONTROLLER_GATEWAY_IP,
|
SYSTEMCONTROLLER_GATEWAY_IP,
|
||||||
|
@ -210,7 +201,7 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
||||||
self.assertEqual((ID, NAME,
|
self.assertEqual((ID, NAME,
|
||||||
DESCRIPTION, LOCATION,
|
DESCRIPTION, LOCATION,
|
||||||
SOFTWARE_VERSION, MANAGEMENT_STATE,
|
SOFTWARE_VERSION, MANAGEMENT_STATE,
|
||||||
AVAILABILITY_STATUS,
|
AVAILABILITY_STATUS, DEPLOY_STATUS,
|
||||||
MANAGEMENT_SUBNET, MANAGEMENT_START_IP,
|
MANAGEMENT_SUBNET, MANAGEMENT_START_IP,
|
||||||
MANAGEMENT_END_IP, MANAGEMENT_GATEWAY_IP,
|
MANAGEMENT_END_IP, MANAGEMENT_GATEWAY_IP,
|
||||||
SYSTEMCONTROLLER_GATEWAY_IP,
|
SYSTEMCONTROLLER_GATEWAY_IP,
|
||||||
|
@ -231,20 +222,8 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
||||||
self.assertEqual((ID, NAME,
|
self.assertEqual((ID, NAME,
|
||||||
DESCRIPTION, LOCATION,
|
DESCRIPTION, LOCATION,
|
||||||
SOFTWARE_VERSION, MANAGEMENT_STATE,
|
SOFTWARE_VERSION, MANAGEMENT_STATE,
|
||||||
AVAILABILITY_STATUS,
|
AVAILABILITY_STATUS, DEPLOY_STATUS,
|
||||||
MANAGEMENT_SUBNET, MANAGEMENT_START_IP,
|
MANAGEMENT_SUBNET, MANAGEMENT_START_IP,
|
||||||
MANAGEMENT_END_IP, MANAGEMENT_GATEWAY_IP,
|
MANAGEMENT_END_IP, MANAGEMENT_GATEWAY_IP,
|
||||||
SYSTEMCONTROLLER_GATEWAY_IP,
|
SYSTEMCONTROLLER_GATEWAY_IP,
|
||||||
TIME_NOW, TIME_NOW), actual_call[1])
|
TIME_NOW, TIME_NOW), actual_call[1])
|
||||||
|
|
||||||
def test_generate_config_subcloud(self):
|
|
||||||
FAKE_CONFIG = "This is a fake config file."
|
|
||||||
self.client.subcloud_manager.generate_config_subcloud.\
|
|
||||||
return_value = FAKE_CONFIG
|
|
||||||
actual_call = self.call(
|
|
||||||
subcloud_cmd.GenerateConfigSubcloud, app_args=[ID])
|
|
||||||
self.assertEqual(FAKE_CONFIG, actual_call)
|
|
||||||
|
|
||||||
def test_generate_config_subcloud_without_subcloud_id(self):
|
|
||||||
self.assertRaises(SystemExit, self.call,
|
|
||||||
subcloud_cmd.GenerateConfigSubcloud, app_args=[])
|
|
||||||
|
|
Loading…
Reference in New Issue