Adding upgrade strategy commands
dcmanager strategy-config dcmanager upgrade-strategy This change refactors the existing sw-update code so that patch and upgrades share common functionality. This adds the strategy 'type' to the CLI output so that a user can differentiate between which strategy type is being orchestrated. patch-strategy-config is generic to all update types, so a new strategy-config CLI command is now registered. Change-Id: Icd33eb26f907e8e250ebddbba7d2cebea3592ac7 Depends-On: https://review.opendev.org/#/c/721620 Story: 2007403 Task: 39654 Signed-off-by: albailey <Al.Bailey@windriver.com>
This commit is contained in:
parent
19f027179c
commit
c640a51440
|
@ -20,23 +20,22 @@
|
||||||
# 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 six
|
||||||
|
|
||||||
import keystoneauth1.identity.generic as auth_plugin
|
import keystoneauth1.identity.generic as auth_plugin
|
||||||
from keystoneauth1 import session as ks_session
|
from keystoneauth1 import session as ks_session
|
||||||
|
import osprofiler.profiler
|
||||||
|
|
||||||
from dcmanagerclient.api import httpclient
|
from dcmanagerclient.api import httpclient
|
||||||
from dcmanagerclient.api.v1 import alarm_manager as am
|
from dcmanagerclient.api.v1 import alarm_manager as am
|
||||||
|
from dcmanagerclient.api.v1 import fw_update_manager as fum
|
||||||
|
from dcmanagerclient.api.v1 import strategy_step_manager as ssm
|
||||||
from dcmanagerclient.api.v1 import subcloud_deploy_manager as sdm
|
from dcmanagerclient.api.v1 import subcloud_deploy_manager as sdm
|
||||||
from dcmanagerclient.api.v1 import subcloud_group_manager as gm
|
from dcmanagerclient.api.v1 import subcloud_group_manager as gm
|
||||||
from dcmanagerclient.api.v1 import subcloud_manager as sm
|
from dcmanagerclient.api.v1 import subcloud_manager as sm
|
||||||
from dcmanagerclient.api.v1 import sw_update_manager as sum
|
from dcmanagerclient.api.v1 import sw_patch_manager as spm
|
||||||
from dcmanagerclient.api.v1 import sw_update_options_manager as suom
|
from dcmanagerclient.api.v1 import sw_update_options_manager as suom
|
||||||
|
from dcmanagerclient.api.v1 import sw_upgrade_manager as supm
|
||||||
|
|
||||||
import osprofiler.profiler
|
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
|
|
||||||
_DEFAULT_DCMANAGER_URL = "http://localhost:8119/v1.0"
|
_DEFAULT_DCMANAGER_URL = "http://localhost:8119/v1.0"
|
||||||
|
|
||||||
|
@ -102,11 +101,13 @@ class Client(object):
|
||||||
self.subcloud_deploy_manager = sdm.subcloud_deploy_manager(
|
self.subcloud_deploy_manager = sdm.subcloud_deploy_manager(
|
||||||
self.http_client)
|
self.http_client)
|
||||||
self.alarm_manager = am.alarm_manager(self.http_client)
|
self.alarm_manager = am.alarm_manager(self.http_client)
|
||||||
self.sw_update_manager = sum.sw_update_manager(self.http_client)
|
self.fw_update_manager = fum.fw_update_manager(self.http_client)
|
||||||
|
self.sw_patch_manager = spm.sw_patch_manager(self.http_client)
|
||||||
self.sw_update_options_manager = \
|
self.sw_update_options_manager = \
|
||||||
suom.sw_update_options_manager(self.http_client)
|
suom.sw_update_options_manager(self.http_client)
|
||||||
self.strategy_step_manager = sum.strategy_step_manager(
|
self.sw_upgrade_manager = supm.sw_upgrade_manager(self.http_client)
|
||||||
self.http_client)
|
self.strategy_step_manager = \
|
||||||
|
ssm.strategy_step_manager(self.http_client)
|
||||||
|
|
||||||
|
|
||||||
def authenticate(dcmanager_url=None, username=None,
|
def authenticate(dcmanager_url=None, username=None,
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Copyright (c) 2017 Ericsson AB.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
|
# of this software may be licensed only pursuant to the terms
|
||||||
|
# of an applicable Wind River license agreement.
|
||||||
|
#
|
||||||
|
from dcmanagerclient.api.v1.sw_update_manager import sw_update_manager
|
||||||
|
|
||||||
|
SW_UPDATE_TYPE_FIRMWARE = 'firmware'
|
||||||
|
|
||||||
|
|
||||||
|
class fw_update_manager(sw_update_manager):
|
||||||
|
|
||||||
|
def __init__(self, http_client):
|
||||||
|
super(fw_update_manager, self).__init__(
|
||||||
|
http_client,
|
||||||
|
update_type=SW_UPDATE_TYPE_FIRMWARE)
|
|
@ -0,0 +1,87 @@
|
||||||
|
# Copyright (c) 2017 Ericsson AB.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2017-2020 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
|
# of this software may be licensed only pursuant to the terms
|
||||||
|
# of an applicable Wind River license agreement.
|
||||||
|
#
|
||||||
|
from dcmanagerclient.api import base
|
||||||
|
from dcmanagerclient.api.base import get_json
|
||||||
|
|
||||||
|
|
||||||
|
class StrategyStep(base.Resource):
|
||||||
|
resource_name = 'strategy_step'
|
||||||
|
|
||||||
|
def __init__(self, manager, cloud, stage, state, details,
|
||||||
|
started_at, finished_at, created_at, updated_at):
|
||||||
|
self.manager = manager
|
||||||
|
self.cloud = cloud
|
||||||
|
self.stage = stage
|
||||||
|
self.state = state
|
||||||
|
self.details = details
|
||||||
|
self.started_at = started_at
|
||||||
|
self.finished_at = finished_at
|
||||||
|
self.created_at = created_at
|
||||||
|
self.updated_at = updated_at
|
||||||
|
|
||||||
|
|
||||||
|
class strategy_step_manager(base.ResourceManager):
|
||||||
|
|
||||||
|
def __init__(self, http_client):
|
||||||
|
super(strategy_step_manager, self).__init__(http_client)
|
||||||
|
self.resource_class = StrategyStep
|
||||||
|
self.steps_url = '/sw-update-strategy/steps'
|
||||||
|
self.response_key = 'strategy-steps'
|
||||||
|
|
||||||
|
def list_strategy_steps(self):
|
||||||
|
return self._strategy_step_list(self.steps_url)
|
||||||
|
|
||||||
|
def strategy_step_detail(self, cloud_name):
|
||||||
|
url = '{}/{}'.format(self.steps_url, cloud_name)
|
||||||
|
return self._strategy_step_detail(url)
|
||||||
|
|
||||||
|
def build_from_json(self, json_object):
|
||||||
|
return self.resource_class(
|
||||||
|
self,
|
||||||
|
cloud=json_object['cloud'],
|
||||||
|
stage=json_object['stage'],
|
||||||
|
state=json_object['state'],
|
||||||
|
details=json_object['details'],
|
||||||
|
started_at=json_object['started-at'],
|
||||||
|
finished_at=json_object['finished-at'],
|
||||||
|
created_at=json_object['created-at'],
|
||||||
|
updated_at=json_object['updated-at'])
|
||||||
|
|
||||||
|
def _strategy_step_list(self, url):
|
||||||
|
resp = self.http_client.get(url)
|
||||||
|
if resp.status_code != 200:
|
||||||
|
self._raise_api_exception(resp)
|
||||||
|
json_response_key = get_json(resp)
|
||||||
|
json_objects = json_response_key[self.response_key]
|
||||||
|
resource = []
|
||||||
|
for json_object in json_objects:
|
||||||
|
resource.append(self.build_from_json(json_object))
|
||||||
|
return resource
|
||||||
|
|
||||||
|
def _strategy_step_detail(self, url):
|
||||||
|
resp = self.http_client.get(url)
|
||||||
|
if resp.status_code != 200:
|
||||||
|
self._raise_api_exception(resp)
|
||||||
|
json_object = get_json(resp)
|
||||||
|
resource = list()
|
||||||
|
resource.append(self.build_from_json(json_object))
|
||||||
|
return resource
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Copyright (c) 2017 Ericsson AB.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2017 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
|
# of this software may be licensed only pursuant to the terms
|
||||||
|
# of an applicable Wind River license agreement.
|
||||||
|
#
|
||||||
|
from dcmanagerclient.api.v1.sw_update_manager import sw_update_manager
|
||||||
|
|
||||||
|
SW_UPDATE_TYPE_PATCH = 'patch'
|
||||||
|
|
||||||
|
|
||||||
|
class sw_patch_manager(sw_update_manager):
|
||||||
|
def __init__(self, http_client):
|
||||||
|
super(sw_patch_manager, self).__init__(
|
||||||
|
http_client,
|
||||||
|
update_type=SW_UPDATE_TYPE_PATCH)
|
|
@ -26,13 +26,21 @@ from dcmanagerclient.api import base
|
||||||
from dcmanagerclient.api.base import get_json
|
from dcmanagerclient.api.base import get_json
|
||||||
|
|
||||||
|
|
||||||
|
# todo(abailey): Update SwUpdateStrategy based on 'subcloud group'
|
||||||
class SwUpdateStrategy(base.Resource):
|
class SwUpdateStrategy(base.Resource):
|
||||||
resource_name = 'sw_update_strategy'
|
resource_name = 'sw_update_strategy'
|
||||||
|
|
||||||
def __init__(self, manager, subcloud_apply_type, max_parallel_subclouds,
|
def __init__(self,
|
||||||
stop_on_failure, state,
|
manager,
|
||||||
created_at, updated_at):
|
strategy_type,
|
||||||
|
subcloud_apply_type,
|
||||||
|
max_parallel_subclouds,
|
||||||
|
stop_on_failure,
|
||||||
|
state,
|
||||||
|
created_at,
|
||||||
|
updated_at):
|
||||||
self.manager = manager
|
self.manager = manager
|
||||||
|
self.strategy_type = strategy_type
|
||||||
self.subcloud_apply_type = subcloud_apply_type
|
self.subcloud_apply_type = subcloud_apply_type
|
||||||
self.max_parallel_subclouds = max_parallel_subclouds
|
self.max_parallel_subclouds = max_parallel_subclouds
|
||||||
self.stop_on_failure = stop_on_failure
|
self.stop_on_failure = stop_on_failure
|
||||||
|
@ -41,169 +49,94 @@ class SwUpdateStrategy(base.Resource):
|
||||||
self.updated_at = updated_at
|
self.updated_at = updated_at
|
||||||
|
|
||||||
|
|
||||||
class StrategyStep(base.Resource):
|
|
||||||
resource_name = 'strategy_step'
|
|
||||||
|
|
||||||
def __init__(self, manager, cloud, stage, state, details,
|
|
||||||
started_at, finished_at, created_at, updated_at):
|
|
||||||
self.manager = manager
|
|
||||||
self.cloud = cloud
|
|
||||||
self.stage = stage
|
|
||||||
self.state = state
|
|
||||||
self.details = details
|
|
||||||
self.started_at = started_at
|
|
||||||
self.finished_at = finished_at
|
|
||||||
self.created_at = created_at
|
|
||||||
self.updated_at = updated_at
|
|
||||||
|
|
||||||
|
|
||||||
class sw_update_manager(base.ResourceManager):
|
class sw_update_manager(base.ResourceManager):
|
||||||
resource_class = SwUpdateStrategy
|
"""sw_update_managea
|
||||||
|
|
||||||
def create_patch_strategy(self, **kwargs):
|
sw_update_manager is an abstract class that is used by subclasses to
|
||||||
|
manage API actions for specific update strategy types such as software
|
||||||
|
patches and firmware updates.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, http_client,
|
||||||
|
update_type,
|
||||||
|
resource_class=SwUpdateStrategy,
|
||||||
|
url='sw-update-strategy'):
|
||||||
|
super(sw_update_manager, self).__init__(http_client)
|
||||||
|
self.resource_class = resource_class
|
||||||
|
self.update_type = update_type
|
||||||
|
# create_url is typically /<foo>/
|
||||||
|
self.create_url = '/{}/'.format(url)
|
||||||
|
# get_url is typically /<foo>
|
||||||
|
self.get_url = '/{}'.format(url)
|
||||||
|
# delete_url is typically /<foo> (same as get)
|
||||||
|
self.delete_url = '/{}'.format(url)
|
||||||
|
# actions_url is typically /<foo>/actions
|
||||||
|
self.actions_url = '/{}/actions'.format(url)
|
||||||
|
|
||||||
|
def create_sw_update_strategy(self, **kwargs):
|
||||||
data = kwargs
|
data = kwargs
|
||||||
data.update({'type': 'patch'})
|
data.update({'type': self.update_type})
|
||||||
url = '/sw-update-strategy/'
|
return self._sw_update_create(self.create_url, data)
|
||||||
return self.sw_update_create(url, data)
|
|
||||||
|
|
||||||
def patch_strategy_detail(self):
|
def update_sw_strategy_detail(self):
|
||||||
url = '/sw-update-strategy'
|
return self._sw_update_detail(self.get_url)
|
||||||
return self.sw_update_detail(url)
|
|
||||||
|
|
||||||
def delete_patch_strategy(self):
|
def delete_sw_update_strategy(self):
|
||||||
url = '/sw-update-strategy'
|
return self._sw_update_delete(self.delete_url)
|
||||||
return self.sw_update_delete(url)
|
|
||||||
|
|
||||||
def apply_patch_strategy(self):
|
def apply_sw_update_strategy(self):
|
||||||
data = {'action': 'apply'}
|
data = {'action': 'apply'}
|
||||||
url = '/sw-update-strategy/actions'
|
return self._sw_update_action(self.actions_url, data)
|
||||||
return self.sw_update_action(url, data)
|
|
||||||
|
|
||||||
def abort_patch_strategy(self):
|
def abort_sw_update_strategy(self):
|
||||||
data = {'action': 'abort'}
|
data = {'action': 'abort'}
|
||||||
url = '/sw-update-strategy/actions'
|
return self._sw_update_action(self.actions_url, data)
|
||||||
return self.sw_update_action(url, data)
|
|
||||||
|
|
||||||
def sw_update_create(self, url, data):
|
def _build_from_json(self, json_object):
|
||||||
|
return self.resource_class(
|
||||||
|
self,
|
||||||
|
strategy_type=json_object['type'],
|
||||||
|
subcloud_apply_type=json_object['subcloud-apply-type'],
|
||||||
|
max_parallel_subclouds=json_object['max-parallel-subclouds'],
|
||||||
|
stop_on_failure=json_object['stop-on-failure'],
|
||||||
|
state=json_object['state'],
|
||||||
|
created_at=json_object['created-at'],
|
||||||
|
updated_at=json_object['updated-at'])
|
||||||
|
|
||||||
|
def _sw_update_create(self, url, data):
|
||||||
data = json.dumps(data)
|
data = json.dumps(data)
|
||||||
resp = self.http_client.post(url, data)
|
resp = self.http_client.post(url, data)
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
self._raise_api_exception(resp)
|
self._raise_api_exception(resp)
|
||||||
json_object = get_json(resp)
|
json_object = get_json(resp)
|
||||||
resource = list()
|
resource = list()
|
||||||
resource.append(
|
resource.append(self._build_from_json(json_object))
|
||||||
self.resource_class(
|
|
||||||
self,
|
|
||||||
subcloud_apply_type=json_object['subcloud-apply-type'],
|
|
||||||
max_parallel_subclouds=json_object['max-parallel-subclouds'],
|
|
||||||
stop_on_failure=json_object['stop-on-failure'],
|
|
||||||
state=json_object['state'],
|
|
||||||
created_at=json_object['created-at'],
|
|
||||||
updated_at=json_object['updated-at']))
|
|
||||||
return resource
|
return resource
|
||||||
|
|
||||||
def sw_update_delete(self, url):
|
def _sw_update_delete(self, url):
|
||||||
resp = self.http_client.delete(url)
|
resp = self.http_client.delete(url)
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
self._raise_api_exception(resp)
|
self._raise_api_exception(resp)
|
||||||
json_object = get_json(resp)
|
json_object = get_json(resp)
|
||||||
resource = list()
|
resource = list()
|
||||||
resource.append(
|
resource.append(self._build_from_json(json_object))
|
||||||
self.resource_class(
|
|
||||||
self,
|
|
||||||
subcloud_apply_type=json_object['subcloud-apply-type'],
|
|
||||||
max_parallel_subclouds=json_object['max-parallel-subclouds'],
|
|
||||||
stop_on_failure=json_object['stop-on-failure'],
|
|
||||||
state=json_object['state'],
|
|
||||||
created_at=json_object['created-at'],
|
|
||||||
updated_at=json_object['updated-at']))
|
|
||||||
return resource
|
return resource
|
||||||
|
|
||||||
def sw_update_detail(self, url):
|
def _sw_update_detail(self, url):
|
||||||
resp = self.http_client.get(url)
|
resp = self.http_client.get(url)
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
self._raise_api_exception(resp)
|
self._raise_api_exception(resp)
|
||||||
json_object = get_json(resp)
|
json_object = get_json(resp)
|
||||||
resource = list()
|
resource = list()
|
||||||
resource.append(
|
resource.append(self._build_from_json(json_object))
|
||||||
self.resource_class(
|
|
||||||
self,
|
|
||||||
subcloud_apply_type=json_object['subcloud-apply-type'],
|
|
||||||
max_parallel_subclouds=json_object['max-parallel-subclouds'],
|
|
||||||
stop_on_failure=json_object['stop-on-failure'],
|
|
||||||
state=json_object['state'],
|
|
||||||
created_at=json_object['created-at'],
|
|
||||||
updated_at=json_object['updated-at']))
|
|
||||||
return resource
|
return resource
|
||||||
|
|
||||||
def sw_update_action(self, url, data):
|
def _sw_update_action(self, url, data):
|
||||||
data = json.dumps(data)
|
data = json.dumps(data)
|
||||||
resp = self.http_client.post(url, data)
|
resp = self.http_client.post(url, data)
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
self._raise_api_exception(resp)
|
self._raise_api_exception(resp)
|
||||||
json_object = get_json(resp)
|
json_object = get_json(resp)
|
||||||
resource = list()
|
resource = list()
|
||||||
resource.append(
|
resource.append(self._build_from_json(json_object))
|
||||||
self.resource_class(
|
|
||||||
self,
|
|
||||||
subcloud_apply_type=json_object['subcloud-apply-type'],
|
|
||||||
max_parallel_subclouds=json_object['max-parallel-subclouds'],
|
|
||||||
stop_on_failure=json_object['stop-on-failure'],
|
|
||||||
state=json_object['state'],
|
|
||||||
created_at=json_object['created-at'],
|
|
||||||
updated_at=json_object['updated-at']))
|
|
||||||
return resource
|
|
||||||
|
|
||||||
|
|
||||||
class strategy_step_manager(base.ResourceManager):
|
|
||||||
resource_class = StrategyStep
|
|
||||||
|
|
||||||
def list_strategy_steps(self):
|
|
||||||
url = '/sw-update-strategy/steps'
|
|
||||||
return self.strategy_step_list(url)
|
|
||||||
|
|
||||||
def strategy_step_detail(self, cloud_name):
|
|
||||||
url = '/sw-update-strategy/steps/%s' % cloud_name
|
|
||||||
return self._strategy_step_detail(url)
|
|
||||||
|
|
||||||
def strategy_step_list(self, url):
|
|
||||||
resp = self.http_client.get(url)
|
|
||||||
if resp.status_code != 200:
|
|
||||||
self._raise_api_exception(resp)
|
|
||||||
json_response_key = get_json(resp)
|
|
||||||
json_objects = json_response_key['strategy-steps']
|
|
||||||
resource = []
|
|
||||||
for json_object in json_objects:
|
|
||||||
resource.append(
|
|
||||||
self.resource_class(
|
|
||||||
self,
|
|
||||||
cloud=json_object['cloud'],
|
|
||||||
stage=json_object['stage'],
|
|
||||||
state=json_object['state'],
|
|
||||||
details=json_object['details'],
|
|
||||||
started_at=json_object['started-at'],
|
|
||||||
finished_at=json_object['finished-at'],
|
|
||||||
created_at=json_object['created-at'],
|
|
||||||
updated_at=json_object['updated-at'],
|
|
||||||
))
|
|
||||||
return resource
|
|
||||||
|
|
||||||
def _strategy_step_detail(self, url):
|
|
||||||
resp = self.http_client.get(url)
|
|
||||||
if resp.status_code != 200:
|
|
||||||
self._raise_api_exception(resp)
|
|
||||||
json_object = get_json(resp)
|
|
||||||
resource = list()
|
|
||||||
resource.append(
|
|
||||||
self.resource_class(
|
|
||||||
self,
|
|
||||||
cloud=json_object['cloud'],
|
|
||||||
stage=json_object['stage'],
|
|
||||||
state=json_object['state'],
|
|
||||||
details=json_object['details'],
|
|
||||||
started_at=json_object['started-at'],
|
|
||||||
finished_at=json_object['finished-at'],
|
|
||||||
created_at=json_object['created-at'],
|
|
||||||
updated_at=json_object['updated-at'],
|
|
||||||
))
|
|
||||||
return resource
|
return resource
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Copyright (c) 2017 Ericsson AB.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
|
# of this software may be licensed only pursuant to the terms
|
||||||
|
# of an applicable Wind River license agreement.
|
||||||
|
#
|
||||||
|
from dcmanagerclient.api.v1.sw_update_manager import sw_update_manager
|
||||||
|
|
||||||
|
SW_UPDATE_TYPE_UPGRADE = 'upgrade'
|
||||||
|
|
||||||
|
|
||||||
|
class sw_upgrade_manager(sw_update_manager):
|
||||||
|
|
||||||
|
def __init__(self, http_client):
|
||||||
|
super(sw_upgrade_manager, self).__init__(
|
||||||
|
http_client,
|
||||||
|
update_type=SW_UPDATE_TYPE_UPGRADE)
|
|
@ -0,0 +1,59 @@
|
||||||
|
# Copyright (c) 2017 Ericsson AB.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
|
# of this software may be licensed only pursuant to the terms
|
||||||
|
# of an applicable Wind River license agreement.
|
||||||
|
#
|
||||||
|
from dcmanagerclient.commands.v1 import sw_update_manager
|
||||||
|
|
||||||
|
|
||||||
|
class FwUpdateManagerMixin(object):
|
||||||
|
"""This Mixin provides the update manager used for firmware updates."""
|
||||||
|
|
||||||
|
def get_sw_update_manager(self):
|
||||||
|
dcmanager_client = self.app.client_manager.fw_update_manager
|
||||||
|
return dcmanager_client.fw_update_manager
|
||||||
|
|
||||||
|
|
||||||
|
class CreateFwUpdateStrategy(FwUpdateManagerMixin,
|
||||||
|
sw_update_manager.CreateSwUpdateStrategy):
|
||||||
|
"""Create a firmware update strategy."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ShowFwUpdateStrategy(FwUpdateManagerMixin,
|
||||||
|
sw_update_manager.ShowSwUpdateStrategy):
|
||||||
|
"""Show the details of a firmware update strategy for a subcloud."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteFwUpdateStrategy(FwUpdateManagerMixin,
|
||||||
|
sw_update_manager.DeleteSwUpdateStrategy):
|
||||||
|
"""Delete firmware update strategy from the database."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ApplyFwUpdateStrategy(FwUpdateManagerMixin,
|
||||||
|
sw_update_manager.ApplySwUpdateStrategy):
|
||||||
|
"""Apply a firmware update strategy."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AbortFwUpdateStrategy(FwUpdateManagerMixin,
|
||||||
|
sw_update_manager.AbortSwUpdateStrategy):
|
||||||
|
"""Abort a firmware update strategy."""
|
||||||
|
pass
|
|
@ -0,0 +1,59 @@
|
||||||
|
# Copyright (c) 2017 Ericsson AB.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2017-2020 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
|
# of this software may be licensed only pursuant to the terms
|
||||||
|
# of an applicable Wind River license agreement.
|
||||||
|
#
|
||||||
|
from dcmanagerclient.commands.v1 import sw_update_manager
|
||||||
|
|
||||||
|
|
||||||
|
class SwPatchManagerMixin(object):
|
||||||
|
"""This Mixin provides the update manager used for sw patch."""
|
||||||
|
|
||||||
|
def get_sw_update_manager(self):
|
||||||
|
dcmanager_client = self.app.client_manager.sw_patch_manager
|
||||||
|
return dcmanager_client.sw_patch_manager
|
||||||
|
|
||||||
|
|
||||||
|
class CreatePatchUpdateStrategy(SwPatchManagerMixin,
|
||||||
|
sw_update_manager.CreateSwUpdateStrategy):
|
||||||
|
"""Create a patch update strategy."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ShowPatchUpdateStrategy(SwPatchManagerMixin,
|
||||||
|
sw_update_manager.ShowSwUpdateStrategy):
|
||||||
|
"""Show the details of a patch update strategy for a subcloud."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DeletePatchUpdateStrategy(SwPatchManagerMixin,
|
||||||
|
sw_update_manager.DeleteSwUpdateStrategy):
|
||||||
|
"""Delete patch update strategy from the database."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ApplyPatchUpdateStrategy(SwPatchManagerMixin,
|
||||||
|
sw_update_manager.ApplySwUpdateStrategy):
|
||||||
|
"""Apply a patch update strategy."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AbortPatchUpdateStrategy(SwPatchManagerMixin,
|
||||||
|
sw_update_manager.AbortSwUpdateStrategy):
|
||||||
|
"""Abort a patch update strategy."""
|
||||||
|
pass
|
|
@ -12,7 +12,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) 2020 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
|
||||||
|
@ -22,9 +22,16 @@
|
||||||
from dcmanagerclient.commands.v1 import base
|
from dcmanagerclient.commands.v1 import base
|
||||||
from dcmanagerclient import exceptions
|
from dcmanagerclient import exceptions
|
||||||
|
|
||||||
|
# These are the abstract base classes used for sw update managers such as
|
||||||
|
# - sw-patch-manager
|
||||||
|
# - fw-update-manager
|
||||||
|
#
|
||||||
|
# also handles 'steps' and 'strategies'
|
||||||
|
|
||||||
|
|
||||||
def detail_format(sw_update_strategy=None):
|
def detail_format(sw_update_strategy=None):
|
||||||
columns = (
|
columns = (
|
||||||
|
'strategy type',
|
||||||
'subcloud apply type',
|
'subcloud apply type',
|
||||||
'max parallel subclouds',
|
'max parallel subclouds',
|
||||||
'stop on failure',
|
'stop on failure',
|
||||||
|
@ -35,6 +42,7 @@ def detail_format(sw_update_strategy=None):
|
||||||
|
|
||||||
if sw_update_strategy:
|
if sw_update_strategy:
|
||||||
data = (
|
data = (
|
||||||
|
sw_update_strategy.strategy_type,
|
||||||
sw_update_strategy.subcloud_apply_type,
|
sw_update_strategy.subcloud_apply_type,
|
||||||
sw_update_strategy.max_parallel_subclouds,
|
sw_update_strategy.max_parallel_subclouds,
|
||||||
sw_update_strategy.stop_on_failure,
|
sw_update_strategy.stop_on_failure,
|
||||||
|
@ -104,14 +112,18 @@ def detail_strategy_step_format(strategy_step=None):
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
class CreatePatchStrategy(base.DCManagerShowOne):
|
class CreateSwUpdateStrategy(base.DCManagerShowOne):
|
||||||
"""Create a patch strategy."""
|
"""Create a software update strategy."""
|
||||||
|
|
||||||
|
def get_sw_update_manager(self):
|
||||||
|
# This method must be overrridden by the concrete subclass
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return detail_format
|
return detail_format
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(CreatePatchStrategy, self).get_parser(prog_name)
|
parser = super(CreateSwUpdateStrategy, self).get_parser(prog_name)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--subcloud-apply-type',
|
'--subcloud-apply-type',
|
||||||
|
@ -131,20 +143,18 @@ class CreatePatchStrategy(base.DCManagerShowOne):
|
||||||
'--stop-on-failure',
|
'--stop-on-failure',
|
||||||
required=False,
|
required=False,
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Do not patch any additional subclouds after a failure.'
|
help='Do not update any additional subclouds after a failure.'
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'cloud_name',
|
'cloud_name',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
default=None,
|
default=None,
|
||||||
help='Name of a single cloud to patch.'
|
help='Name of a single cloud to update.'
|
||||||
)
|
)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
dcmanager_client = self.app.client_manager.sw_update_manager
|
|
||||||
kwargs = dict()
|
kwargs = dict()
|
||||||
if parsed_args.subcloud_apply_type:
|
if parsed_args.subcloud_apply_type:
|
||||||
kwargs['subcloud-apply-type'] = parsed_args.subcloud_apply_type
|
kwargs['subcloud-apply-type'] = parsed_args.subcloud_apply_type
|
||||||
|
@ -155,118 +165,114 @@ class CreatePatchStrategy(base.DCManagerShowOne):
|
||||||
kwargs['stop-on-failure'] = 'true'
|
kwargs['stop-on-failure'] = 'true'
|
||||||
if parsed_args.cloud_name is not None:
|
if parsed_args.cloud_name is not None:
|
||||||
kwargs['cloud_name'] = parsed_args.cloud_name
|
kwargs['cloud_name'] = parsed_args.cloud_name
|
||||||
return dcmanager_client.sw_update_manager.create_patch_strategy(
|
return self.get_sw_update_manager().create_sw_update_strategy(**kwargs)
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class ShowPatchStrategy(base.DCManagerShowOne):
|
class ShowSwUpdateStrategy(base.DCManagerShowOne):
|
||||||
"""Show the details of a patch strategy for a subcloud."""
|
"""Show the details of an software update strategy for a subcloud."""
|
||||||
|
|
||||||
|
def get_sw_update_manager(self):
|
||||||
|
# This method must be overrridden by the concrete subclass
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return detail_format
|
return detail_format
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(ShowPatchStrategy, self).get_parser(prog_name)
|
|
||||||
return parser
|
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
dcmanager_client = self.app.client_manager.sw_update_manager
|
return self.get_sw_update_manager().update_sw_strategy_detail()
|
||||||
return dcmanager_client.sw_update_manager.patch_strategy_detail()
|
|
||||||
|
|
||||||
|
|
||||||
class DeletePatchStrategy(base.DCManagerShowOne):
|
class DeleteSwUpdateStrategy(base.DCManagerShowOne):
|
||||||
"""Delete patch strategy from the database."""
|
"""Delete a software update strategy from the database."""
|
||||||
|
|
||||||
|
def get_sw_update_manager(self):
|
||||||
|
# This method must be overrridden by the concrete subclass
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return detail_format
|
return detail_format
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(DeletePatchStrategy, self).get_parser(prog_name)
|
|
||||||
return parser
|
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
dcmanager_client = self.app.client_manager.sw_update_manager
|
|
||||||
try:
|
try:
|
||||||
return dcmanager_client.sw_update_manager.delete_patch_strategy()
|
return self.get_sw_update_manager().delete_sw_update_strategy()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
error_msg = "Unable to delete patch strategy"
|
error_msg = "Unable to delete sw update strategy"
|
||||||
raise exceptions.DCManagerClientException(error_msg)
|
raise exceptions.DCManagerClientException(error_msg)
|
||||||
|
|
||||||
|
|
||||||
class ApplyPatchStrategy(base.DCManagerShowOne):
|
class ApplySwUpdateStrategy(base.DCManagerShowOne):
|
||||||
"""Apply a patch strategy."""
|
"""Apply a software update strategy."""
|
||||||
|
|
||||||
|
def get_sw_update_manager(self):
|
||||||
|
# This method must be overrridden by the concrete subclass
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return detail_format
|
return detail_format
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(ApplyPatchStrategy, self).get_parser(prog_name)
|
|
||||||
return parser
|
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
dcmanager_client = self.app.client_manager.sw_update_manager
|
|
||||||
try:
|
try:
|
||||||
return dcmanager_client.sw_update_manager.apply_patch_strategy()
|
return self.get_sw_update_manager().apply_sw_update_strategy()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
error_msg = "Unable to apply patch strategy"
|
error_msg = "Unable to apply sw update strategy"
|
||||||
raise exceptions.DCManagerClientException(error_msg)
|
raise exceptions.DCManagerClientException(error_msg)
|
||||||
|
|
||||||
|
|
||||||
class AbortPatchStrategy(base.DCManagerShowOne):
|
class AbortSwUpdateStrategy(base.DCManagerShowOne):
|
||||||
"""Abort a patch strategy."""
|
"""Abort a software update strategy."""
|
||||||
|
|
||||||
|
def get_sw_update_manager(self):
|
||||||
|
# This method must be overrridden by the concrete subclass
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return detail_format
|
return detail_format
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(AbortPatchStrategy, self).get_parser(prog_name)
|
|
||||||
return parser
|
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
dcmanager_client = self.app.client_manager.sw_update_manager
|
|
||||||
try:
|
try:
|
||||||
return dcmanager_client.sw_update_manager.abort_patch_strategy()
|
return self.get_sw_update_manager().abort_sw_update_strategy()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
error_msg = "Unable to abort patch strategy"
|
error_msg = "Unable to abort sw update strategy"
|
||||||
raise exceptions.DCManagerClientException(error_msg)
|
raise exceptions.DCManagerClientException(error_msg)
|
||||||
|
|
||||||
|
|
||||||
class ListStrategyStep(base.DCManagerLister):
|
class ListSwUpdateStrategyStep(base.DCManagerLister):
|
||||||
"""List strategy steps."""
|
"""List strategy steps."""
|
||||||
|
|
||||||
|
def get_strategy_step_manager(self):
|
||||||
|
dcmanager_client = self.app.client_manager.strategy_step_manager
|
||||||
|
return dcmanager_client.strategy_step_manager
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return strategy_step_format
|
return strategy_step_format
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super(ListStrategyStep, self).get_parser(prog_name)
|
|
||||||
return parser
|
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
dcmanager_client = self.app.client_manager.strategy_step_manager
|
return self.get_strategy_step_manager().list_strategy_steps()
|
||||||
return dcmanager_client.strategy_step_manager.list_strategy_steps()
|
|
||||||
|
|
||||||
|
|
||||||
class ShowStrategyStep(base.DCManagerShowOne):
|
class ShowSwUpdateStrategyStep(base.DCManagerShowOne):
|
||||||
"""Show the details of a strategy step."""
|
"""Show the details of a strategy step."""
|
||||||
|
|
||||||
|
def get_strategy_step_manager(self):
|
||||||
|
dcmanager_client = self.app.client_manager.strategy_step_manager
|
||||||
|
return dcmanager_client.strategy_step_manager
|
||||||
|
|
||||||
def _get_format_function(self):
|
def _get_format_function(self):
|
||||||
return detail_strategy_step_format
|
return detail_strategy_step_format
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(ShowStrategyStep, self).get_parser(prog_name)
|
parser = super(ShowSwUpdateStrategyStep, self).get_parser(prog_name)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'cloud_name',
|
'cloud_name',
|
||||||
help='Name of cloud to view the details.'
|
help='Name of cloud to view the details.'
|
||||||
)
|
)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def _get_resources(self, parsed_args):
|
def _get_resources(self, parsed_args):
|
||||||
cloud_name = parsed_args.cloud_name
|
cloud_name = parsed_args.cloud_name
|
||||||
dcmanager_client = self.app.client_manager.strategy_step_manager
|
return self.get_strategy_step_manager().strategy_step_detail(
|
||||||
return dcmanager_client.strategy_step_manager.strategy_step_detail(
|
|
||||||
cloud_name)
|
cloud_name)
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
# Copyright (c) 2017 Ericsson AB.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
|
# of this software may be licensed only pursuant to the terms
|
||||||
|
# of an applicable Wind River license agreement.
|
||||||
|
#
|
||||||
|
from dcmanagerclient.commands.v1 import sw_update_manager
|
||||||
|
|
||||||
|
|
||||||
|
class SwUpgradeManagerMixin(object):
|
||||||
|
"""This Mixin provides the update manager used for software upgrades."""
|
||||||
|
|
||||||
|
def get_sw_update_manager(self):
|
||||||
|
dcmanager_client = self.app.client_manager.sw_upgrade_manager
|
||||||
|
return dcmanager_client.sw_upgrade_manager
|
||||||
|
|
||||||
|
|
||||||
|
class CreateSwUpgradeStrategy(SwUpgradeManagerMixin,
|
||||||
|
sw_update_manager.CreateSwUpdateStrategy):
|
||||||
|
"""Create a software upgrade strategy."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ShowSwUpgradeStrategy(SwUpgradeManagerMixin,
|
||||||
|
sw_update_manager.ShowSwUpdateStrategy):
|
||||||
|
"""Show the details of a software upgrade strategy for a subcloud."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteSwUpgradeStrategy(SwUpgradeManagerMixin,
|
||||||
|
sw_update_manager.DeleteSwUpdateStrategy):
|
||||||
|
"""Delete software upgrade strategy from the database."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ApplySwUpgradeStrategy(SwUpgradeManagerMixin,
|
||||||
|
sw_update_manager.ApplySwUpdateStrategy):
|
||||||
|
"""Apply a software upgrade strategy."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AbortSwUpgradeStrategy(SwUpgradeManagerMixin,
|
||||||
|
sw_update_manager.AbortSwUpdateStrategy):
|
||||||
|
"""Abort a software upgrade strategy."""
|
||||||
|
pass
|
|
@ -37,11 +37,14 @@ from osc_lib.command import command
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from dcmanagerclient.commands.v1 import alarm_manager as am
|
from dcmanagerclient.commands.v1 import alarm_manager as am
|
||||||
|
# from dcmanagerclient.commands.v1 import fw_update_manager as fum
|
||||||
from dcmanagerclient.commands.v1 import subcloud_deploy_manager as sdm
|
from dcmanagerclient.commands.v1 import subcloud_deploy_manager as sdm
|
||||||
from dcmanagerclient.commands.v1 import subcloud_group_manager as gm
|
from dcmanagerclient.commands.v1 import subcloud_group_manager as gm
|
||||||
from dcmanagerclient.commands.v1 import subcloud_manager as sm
|
from dcmanagerclient.commands.v1 import subcloud_manager as sm
|
||||||
|
from dcmanagerclient.commands.v1 import sw_patch_manager as spm
|
||||||
from dcmanagerclient.commands.v1 import sw_update_manager as sum
|
from dcmanagerclient.commands.v1 import sw_update_manager as sum
|
||||||
from dcmanagerclient.commands.v1 import sw_update_options_manager as suom
|
from dcmanagerclient.commands.v1 import sw_update_options_manager as suom
|
||||||
|
from dcmanagerclient.commands.v1 import sw_upgrade_manager as supm
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -449,9 +452,11 @@ class DCManagerShell(app.App):
|
||||||
subcloud_group_manager=self.client,
|
subcloud_group_manager=self.client,
|
||||||
subcloud_deploy_manager=self.client,
|
subcloud_deploy_manager=self.client,
|
||||||
alarm_manager=self.client,
|
alarm_manager=self.client,
|
||||||
sw_update_manager=self.client,
|
fw_update_manager=self.client,
|
||||||
|
sw_patch_manager=self.client,
|
||||||
strategy_step_manager=self.client,
|
strategy_step_manager=self.client,
|
||||||
sw_update_options_manager=self.client)
|
sw_update_options_manager=self.client,
|
||||||
|
sw_upgrade_manager=self.client)
|
||||||
)
|
)
|
||||||
self.client_manager = ClientManager()
|
self.client_manager = ClientManager()
|
||||||
|
|
||||||
|
@ -493,17 +498,31 @@ class DCManagerShell(app.App):
|
||||||
'subcloud-deploy upload': sdm.SubcloudDeployUpload,
|
'subcloud-deploy upload': sdm.SubcloudDeployUpload,
|
||||||
'subcloud-deploy show': sdm.SubcloudDeployShow,
|
'subcloud-deploy show': sdm.SubcloudDeployShow,
|
||||||
'alarm summary': am.ListAlarmSummary,
|
'alarm summary': am.ListAlarmSummary,
|
||||||
'patch-strategy create': sum.CreatePatchStrategy,
|
# 'fw-update-strategy create': fum.CreateFwUpdateStrategy,
|
||||||
'patch-strategy delete': sum.DeletePatchStrategy,
|
# 'fw-update-strategy delete': fum.DeleteFwUpdateStrategy,
|
||||||
'patch-strategy apply': sum.ApplyPatchStrategy,
|
# 'fw-update-strategy apply': fum.ApplyFwUpdateStrategy,
|
||||||
'patch-strategy abort': sum.AbortPatchStrategy,
|
# 'fw-update-strategy abort': fum.AbortFwUpdateStrategy,
|
||||||
'patch-strategy show': sum.ShowPatchStrategy,
|
# 'fw-update-strategy show': fum.ShowFwUpdateStrategy,
|
||||||
'strategy-step list': sum.ListStrategyStep,
|
'patch-strategy create': spm.CreatePatchUpdateStrategy,
|
||||||
'strategy-step show': sum.ShowStrategyStep,
|
'patch-strategy delete': spm.DeletePatchUpdateStrategy,
|
||||||
|
'patch-strategy apply': spm.ApplyPatchUpdateStrategy,
|
||||||
|
'patch-strategy abort': spm.AbortPatchUpdateStrategy,
|
||||||
|
'patch-strategy show': spm.ShowPatchUpdateStrategy,
|
||||||
|
'strategy-step list': sum.ListSwUpdateStrategyStep,
|
||||||
|
'strategy-step show': sum.ShowSwUpdateStrategyStep,
|
||||||
'patch-strategy-config update': suom.UpdateSwUpdateOptions,
|
'patch-strategy-config update': suom.UpdateSwUpdateOptions,
|
||||||
'patch-strategy-config list': suom.ListSwUpdateOptions,
|
'patch-strategy-config list': suom.ListSwUpdateOptions,
|
||||||
'patch-strategy-config show': suom.ShowSwUpdateOptions,
|
'patch-strategy-config show': suom.ShowSwUpdateOptions,
|
||||||
'patch-strategy-config delete': suom.DeleteSwUpdateOptions,
|
'patch-strategy-config delete': suom.DeleteSwUpdateOptions,
|
||||||
|
'strategy-config update': suom.UpdateSwUpdateOptions,
|
||||||
|
'strategy-config list': suom.ListSwUpdateOptions,
|
||||||
|
'strategy-config show': suom.ShowSwUpdateOptions,
|
||||||
|
'strategy-config delete': suom.DeleteSwUpdateOptions,
|
||||||
|
'upgrade-strategy create': supm.CreateSwUpgradeStrategy,
|
||||||
|
'upgrade-strategy delete': supm.DeleteSwUpgradeStrategy,
|
||||||
|
'upgrade-strategy apply': supm.ApplySwUpgradeStrategy,
|
||||||
|
'upgrade-strategy abort': supm.AbortSwUpgradeStrategy,
|
||||||
|
'upgrade-strategy show': supm.ShowSwUpgradeStrategy,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Copyright (c) 2017 Ericsson AB.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
|
# of this software may be licensed only pursuant to the terms
|
||||||
|
# of an applicable Wind River license agreement.
|
||||||
|
#
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from oslo_utils import timeutils
|
||||||
|
|
||||||
|
from dcmanagerclient.api.v1.strategy_step_manager import StrategyStep
|
||||||
|
from dcmanagerclient.commands.v1 import sw_update_manager as cli_cmd
|
||||||
|
from dcmanagerclient.tests import base
|
||||||
|
|
||||||
|
TEST_CLOUD_ID = 1
|
||||||
|
TEST_STAGE = 1
|
||||||
|
TEST_STATE = 'initializing'
|
||||||
|
TEST_DETAILS = 'some details'
|
||||||
|
TIME_NOW = timeutils.utcnow().isoformat()
|
||||||
|
TEST_STARTED_AT = TIME_NOW
|
||||||
|
TEST_FINISHED_AT = TIME_NOW
|
||||||
|
TEST_CREATED_AT = TIME_NOW
|
||||||
|
TEST_UPDATED_AT = TIME_NOW
|
||||||
|
|
||||||
|
|
||||||
|
class TestCLI(base.BaseCommandTest):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestCLI, self).setUp()
|
||||||
|
|
||||||
|
def test_list_strategy_steps(self):
|
||||||
|
sample_step = StrategyStep(mock,
|
||||||
|
TEST_CLOUD_ID,
|
||||||
|
TEST_STAGE,
|
||||||
|
TEST_STATE,
|
||||||
|
TEST_DETAILS,
|
||||||
|
TEST_STARTED_AT,
|
||||||
|
TEST_FINISHED_AT,
|
||||||
|
TEST_CREATED_AT,
|
||||||
|
TEST_UPDATED_AT)
|
||||||
|
results = []
|
||||||
|
results.append(sample_step)
|
||||||
|
self.app.client_manager.strategy_step_manager.strategy_step_manager.\
|
||||||
|
list_strategy_steps.return_value = results
|
||||||
|
|
||||||
|
actual_call = self.call(cli_cmd.ListSwUpdateStrategyStep)
|
||||||
|
# ListStrategyStep returns a tuple, want the second field of the tuple
|
||||||
|
result_steps = actual_call[1]
|
||||||
|
# Only 1 step
|
||||||
|
self.assertEqual(1, len(result_steps))
|
||||||
|
# The step object is a tuple based on the formatter
|
||||||
|
for step in result_steps:
|
||||||
|
self.assertEqual(TEST_CLOUD_ID, step[0])
|
Loading…
Reference in New Issue