Add sw version validation to all release param endpoints
Incorporate the existing release version validation with all the dcmanager operations/commands endpoints that allow the user to specify a release version: - subcloud add - subcloud prestage - subcloud redeploy - subcloud deploy show - subcloud deploy resume - subcloud deploy create - subcloud deploy install - prestage-strategy create - subcloud-backup restore Please note that the "subcloud deploy upload" release validation was addressed in a previous change [1]. These changes add the validate_release_version_supported check (previously introduced [1]) to all the endpoints that consume a release parameter. This is done to check whether a specified release version is supported by the current active version. [1] https://review.opendev.org/c/starlingx/distcloud/+/891911 Test Plan: For each command listed above, test the release parameter (--release): 1. PASS: Verify that the current active version is accepted as a valid parameter. 2. PASS: Verify that all the supported upgrade versions in /usr/rootdirs/opt/upgrades/metadata.xml are accepted as a valid release parameter. 3. PASS: Verify that any upgrade version that's not included in metadata.xml is rejected with an error "<release> is not a supported release version". The only exception to this is the current active version, it must always be valid. 4. PASS: Delete all the "supported_upgrades" elements in metadata.xml and verify the error "Unable to validate the release version" is printed. 5. PASS: Delete metadata.xml and verify that "Unable to validate the release version" error is printed. 6. PASS: Verify that the current active version is valid regardless of metadata.xml file and its contents. 7. PASS: Exclude the release parameter and verify that the command is successful (completed with the current active version). Closes-Bug: 2036479 Change-Id: I1608a68ce6863f51dc0b90e0a6f6b9b588e85689 Signed-off-by: Salman Rana <salman.rana@windriver.com>
This commit is contained in:
parent
4ed1f39731
commit
628d3f276d
@ -206,7 +206,11 @@ class PhasedSubcloudDeployController(object):
|
|||||||
pecan.abort(400, _('The deploy install command can only be used '
|
pecan.abort(400, _('The deploy install command can only be used '
|
||||||
'during initial deployment.'))
|
'during initial deployment.'))
|
||||||
|
|
||||||
payload['software_version'] = payload.get('release', subcloud.software_version)
|
unvalidated_sw_version = payload.get('release', subcloud.software_version)
|
||||||
|
# get_sw_version will simply return back
|
||||||
|
# the passed unvalidated_sw_version after validating it.
|
||||||
|
payload['software_version'] = utils.get_sw_version(unvalidated_sw_version)
|
||||||
|
|
||||||
psd_common.populate_payload_with_pre_existing_data(
|
psd_common.populate_payload_with_pre_existing_data(
|
||||||
payload, subcloud, SUBCLOUD_INSTALL_GET_FILE_CONTENTS)
|
payload, subcloud, SUBCLOUD_INSTALL_GET_FILE_CONTENTS)
|
||||||
|
|
||||||
@ -426,11 +430,15 @@ class PhasedSubcloudDeployController(object):
|
|||||||
# Consider the incoming release parameter only if install is one
|
# Consider the incoming release parameter only if install is one
|
||||||
# of the pending deploy states
|
# of the pending deploy states
|
||||||
if INSTALL in deploy_states_to_run:
|
if INSTALL in deploy_states_to_run:
|
||||||
payload['software_version'] = payload.get('release', subcloud.software_version)
|
unvalidated_sw_version = payload.get('release', subcloud.software_version)
|
||||||
else:
|
else:
|
||||||
LOG.debug('Disregarding release parameter for %s as installation is complete.'
|
LOG.debug('Disregarding release parameter for %s as installation is complete.'
|
||||||
% subcloud.name)
|
% subcloud.name)
|
||||||
payload['software_version'] = subcloud.software_version
|
unvalidated_sw_version = subcloud.software_version
|
||||||
|
|
||||||
|
# get_sw_version will simply return back the passed
|
||||||
|
# unvalidated_sw_version after validating it.
|
||||||
|
payload['software_version'] = utils.get_sw_version(unvalidated_sw_version)
|
||||||
|
|
||||||
# Need to remove bootstrap_values from the list of files to populate
|
# Need to remove bootstrap_values from the list of files to populate
|
||||||
# pre existing data so it does not overwrite newly loaded values
|
# pre existing data so it does not overwrite newly loaded values
|
||||||
|
@ -15,7 +15,6 @@ import pecan
|
|||||||
from pecan import expose
|
from pecan import expose
|
||||||
from pecan import request as pecan_request
|
from pecan import request as pecan_request
|
||||||
from pecan import response
|
from pecan import response
|
||||||
import tsconfig.tsconfig as tsc
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from dcmanager.api.controllers import restcomm
|
from dcmanager.api.controllers import restcomm
|
||||||
@ -370,7 +369,8 @@ class SubcloudBackupController(object):
|
|||||||
|
|
||||||
if payload.get('with_install'):
|
if payload.get('with_install'):
|
||||||
# Confirm the requested or active load is still in dc-vault
|
# Confirm the requested or active load is still in dc-vault
|
||||||
payload['software_version'] = payload.get('release', tsc.SW_VERSION)
|
payload['software_version'] = utils.get_sw_version(
|
||||||
|
payload.get('release'))
|
||||||
matching_iso, err_msg = utils.get_matching_iso(payload['software_version'])
|
matching_iso, err_msg = utils.get_matching_iso(payload['software_version'])
|
||||||
if err_msg:
|
if err_msg:
|
||||||
LOG.exception(err_msg)
|
LOG.exception(err_msg)
|
||||||
|
@ -32,12 +32,9 @@ from dcmanager.api.controllers import restcomm
|
|||||||
from dcmanager.api.policies import subcloud_deploy as subcloud_deploy_policy
|
from dcmanager.api.policies import subcloud_deploy as subcloud_deploy_policy
|
||||||
from dcmanager.api import policy
|
from dcmanager.api import policy
|
||||||
from dcmanager.common import consts
|
from dcmanager.common import consts
|
||||||
from dcmanager.common import exceptions
|
|
||||||
from dcmanager.common.i18n import _
|
from dcmanager.common.i18n import _
|
||||||
from dcmanager.common import utils
|
from dcmanager.common import utils
|
||||||
|
|
||||||
import tsconfig.tsconfig as tsc
|
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -106,20 +103,9 @@ class SubcloudDeployController(object):
|
|||||||
error_msg = "error: argument %s is required" % missing_str.rstrip()
|
error_msg = "error: argument %s is required" % missing_str.rstrip()
|
||||||
pecan.abort(httpclient.BAD_REQUEST, error_msg)
|
pecan.abort(httpclient.BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
software_version = tsc.SW_VERSION
|
deploy_dicts['software_version'] = utils.get_sw_version(request.POST.get('release'))
|
||||||
if request.POST.get('release'):
|
|
||||||
try:
|
|
||||||
utils.validate_release_version_supported(request.POST.get('release'))
|
|
||||||
software_version = request.POST.get('release')
|
|
||||||
except exceptions.ValidateFail as e:
|
|
||||||
pecan.abort(httpclient.BAD_REQUEST,
|
|
||||||
_("Error: invalid release version parameter. %s" % e))
|
|
||||||
except Exception:
|
|
||||||
pecan.abort(httpclient.INTERNAL_SERVER_ERROR,
|
|
||||||
_('Error: unable to validate the release version.'))
|
|
||||||
deploy_dicts['software_version'] = software_version
|
|
||||||
|
|
||||||
dir_path = os.path.join(dccommon_consts.DEPLOY_DIR, software_version)
|
dir_path = os.path.join(dccommon_consts.DEPLOY_DIR, deploy_dicts['software_version'])
|
||||||
for f in consts.DEPLOY_COMMON_FILE_OPTIONS:
|
for f in consts.DEPLOY_COMMON_FILE_OPTIONS:
|
||||||
if f not in request.POST:
|
if f not in request.POST:
|
||||||
continue
|
continue
|
||||||
@ -152,10 +138,8 @@ class SubcloudDeployController(object):
|
|||||||
policy.authorize(subcloud_deploy_policy.POLICY_ROOT % "get", {},
|
policy.authorize(subcloud_deploy_policy.POLICY_ROOT % "get", {},
|
||||||
restcomm.extract_credentials_for_policy())
|
restcomm.extract_credentials_for_policy())
|
||||||
deploy_dicts = dict()
|
deploy_dicts = dict()
|
||||||
if not release:
|
deploy_dicts['software_version'] = utils.get_sw_version(release)
|
||||||
release = tsc.SW_VERSION
|
dir_path = os.path.join(dccommon_consts.DEPLOY_DIR, deploy_dicts['software_version'])
|
||||||
deploy_dicts['software_version'] = release
|
|
||||||
dir_path = os.path.join(dccommon_consts.DEPLOY_DIR, release)
|
|
||||||
for f in consts.DEPLOY_COMMON_FILE_OPTIONS:
|
for f in consts.DEPLOY_COMMON_FILE_OPTIONS:
|
||||||
filename = None
|
filename = None
|
||||||
if os.path.isdir(dir_path):
|
if os.path.isdir(dir_path):
|
||||||
|
@ -41,8 +41,6 @@ from dccommon import exceptions as dccommon_exceptions
|
|||||||
|
|
||||||
from keystoneauth1 import exceptions as keystone_exceptions
|
from keystoneauth1 import exceptions as keystone_exceptions
|
||||||
|
|
||||||
import tsconfig.tsconfig as tsc
|
|
||||||
|
|
||||||
from dcmanager.api.controllers import restcomm
|
from dcmanager.api.controllers import restcomm
|
||||||
from dcmanager.api.policies import subclouds as subclouds_policy
|
from dcmanager.api.policies import subclouds as subclouds_policy
|
||||||
from dcmanager.api import policy
|
from dcmanager.api import policy
|
||||||
@ -748,9 +746,7 @@ class SubcloudsController(object):
|
|||||||
LOG.warning(msg)
|
LOG.warning(msg)
|
||||||
pecan.abort(400, msg)
|
pecan.abort(400, msg)
|
||||||
|
|
||||||
# If a subcloud release is not passed, use the current
|
payload['software_version'] = utils.get_sw_version(payload.get('release'))
|
||||||
# system controller software_version
|
|
||||||
payload['software_version'] = payload.get('release', tsc.SW_VERSION)
|
|
||||||
|
|
||||||
# Don't load previously stored bootstrap_values if they are present in
|
# Don't load previously stored bootstrap_values if they are present in
|
||||||
# the request, as this would override the already loaded values from it.
|
# the request, as this would override the already loaded values from it.
|
||||||
@ -831,8 +827,8 @@ class SubcloudsController(object):
|
|||||||
LOG.exception("validate_prestage failed")
|
LOG.exception("validate_prestage failed")
|
||||||
pecan.abort(400, _(str(exc)))
|
pecan.abort(400, _(str(exc)))
|
||||||
|
|
||||||
prestage_software_version = payload.get(
|
prestage_software_version = utils.get_sw_version(
|
||||||
consts.PRESTAGE_REQUEST_RELEASE, tsc.SW_VERSION)
|
payload.get(consts.PRESTAGE_REQUEST_RELEASE))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.dcmanager_rpc_client.prestage_subcloud(context, payload)
|
self.dcmanager_rpc_client.prestage_subcloud(context, payload)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Copyright (c) 2017 Ericsson AB.
|
# Copyright (c) 2017 Ericsson AB.
|
||||||
# Copyright (c) 2017-2022 Wind River Systems, Inc.
|
# Copyright (c) 2017-2023 Wind River Systems, Inc.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
@ -205,6 +205,10 @@ class SwUpdateStrategyController(object):
|
|||||||
if group is None:
|
if group is None:
|
||||||
pecan.abort(400, _('Invalid group_id'))
|
pecan.abort(400, _('Invalid group_id'))
|
||||||
|
|
||||||
|
# get_sw_version is used here to validate the
|
||||||
|
# release parameter if specified.
|
||||||
|
utils.get_sw_version(payload.get('release'))
|
||||||
|
|
||||||
# Not adding validation for extra args. Passing them through.
|
# Not adding validation for extra args. Passing them through.
|
||||||
try:
|
try:
|
||||||
# Ask dcmanager-manager to create the strategy.
|
# Ask dcmanager-manager to create the strategy.
|
||||||
|
@ -972,9 +972,7 @@ def pre_deploy_create(payload: dict, context: RequestContext,
|
|||||||
|
|
||||||
validate_bootstrap_values(payload)
|
validate_bootstrap_values(payload)
|
||||||
|
|
||||||
# If a subcloud release is not passed, use the current
|
payload['software_version'] = utils.get_sw_version(payload.get('release'))
|
||||||
# system controller software_version
|
|
||||||
payload['software_version'] = payload.get('release', tsc.SW_VERSION)
|
|
||||||
|
|
||||||
validate_subcloud_name_availability(context, payload['name'])
|
validate_subcloud_name_availability(context, payload['name'])
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import itertools
|
|||||||
import json
|
import json
|
||||||
import netaddr
|
import netaddr
|
||||||
import os
|
import os
|
||||||
|
import pecan
|
||||||
import pwd
|
import pwd
|
||||||
import re
|
import re
|
||||||
import resource as sys_resource
|
import resource as sys_resource
|
||||||
@ -46,6 +47,7 @@ from dccommon import exceptions as dccommon_exceptions
|
|||||||
from dccommon import kubeoperator
|
from dccommon import kubeoperator
|
||||||
from dcmanager.common import consts
|
from dcmanager.common import consts
|
||||||
from dcmanager.common import exceptions
|
from dcmanager.common import exceptions
|
||||||
|
from dcmanager.common.i18n import _
|
||||||
from dcmanager.db import api as db_api
|
from dcmanager.db import api as db_api
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -1225,6 +1227,28 @@ def create_subcloud_rehome_data_template():
|
|||||||
return {'saved_payload': {}}
|
return {'saved_payload': {}}
|
||||||
|
|
||||||
|
|
||||||
|
def get_sw_version(release=None):
|
||||||
|
"""Get the sw_version to be used.
|
||||||
|
|
||||||
|
Return the sw_version by first validating a set release version.
|
||||||
|
If a release is not specified then use the current system controller
|
||||||
|
software_version.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if release:
|
||||||
|
try:
|
||||||
|
validate_release_version_supported(release)
|
||||||
|
return release
|
||||||
|
except exceptions.ValidateFail as e:
|
||||||
|
pecan.abort(400,
|
||||||
|
_("Error: invalid release version parameter. %s" % e))
|
||||||
|
except Exception:
|
||||||
|
pecan.abort(500,
|
||||||
|
_('Error: unable to validate the release version.'))
|
||||||
|
else:
|
||||||
|
return tsc.SW_VERSION
|
||||||
|
|
||||||
|
|
||||||
def validate_release_version_supported(release_version_to_check):
|
def validate_release_version_supported(release_version_to_check):
|
||||||
"""Given a release version, check whether it's supported by the current active version.
|
"""Given a release version, check whether it's supported by the current active version.
|
||||||
|
|
||||||
@ -1242,7 +1266,8 @@ def validate_release_version_supported(release_version_to_check):
|
|||||||
supported_versions = get_current_supported_upgrade_versions()
|
supported_versions = get_current_supported_upgrade_versions()
|
||||||
|
|
||||||
if release_version_to_check not in supported_versions:
|
if release_version_to_check not in supported_versions:
|
||||||
msg = "%s is not a supported release version" % release_version_to_check
|
msg = "%s is not a supported release version (%s)" % \
|
||||||
|
(release_version_to_check, ",".join(supported_versions))
|
||||||
raise exceptions.ValidateFail(msg)
|
raise exceptions.ValidateFail(msg)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -404,9 +404,11 @@ class TestSubcloudDeployInstall(testroot.DCManagerApiTest):
|
|||||||
self.mock_rpc_client().subcloud_deploy_install.return_value = True
|
self.mock_rpc_client().subcloud_deploy_install.return_value = True
|
||||||
self.mock_get_vault_load_files.return_value = ('iso_file_path', 'sig_file_path')
|
self.mock_get_vault_load_files.return_value = ('iso_file_path', 'sig_file_path')
|
||||||
|
|
||||||
response = self.app.patch_json(
|
with mock.patch('builtins.open',
|
||||||
FAKE_URL + '/' + str(subcloud.id) + '/install',
|
mock.mock_open(read_data=fake_subcloud.FAKE_UPGRADES_METADATA)):
|
||||||
headers=FAKE_HEADERS, params=install_payload)
|
response = self.app.patch_json(
|
||||||
|
FAKE_URL + '/' + str(subcloud.id) + '/install',
|
||||||
|
headers=FAKE_HEADERS, params=install_payload)
|
||||||
|
|
||||||
self.assertEqual(response.status_int, 200)
|
self.assertEqual(response.status_int, 200)
|
||||||
self.assertEqual(consts.DEPLOY_STATE_PRE_INSTALL,
|
self.assertEqual(consts.DEPLOY_STATE_PRE_INSTALL,
|
||||||
|
@ -1272,9 +1272,11 @@ class TestSubcloudRestore(testroot.DCManagerApiTest):
|
|||||||
mock_listdir.return_value = ['test.iso', 'test.sig']
|
mock_listdir.return_value = ['test.iso', 'test.sig']
|
||||||
mock_rpc_client().restore_subcloud_backups.return_value = True
|
mock_rpc_client().restore_subcloud_backups.return_value = True
|
||||||
|
|
||||||
response = self.app.patch_json(FAKE_URL_RESTORE,
|
with mock.patch('builtins.open',
|
||||||
headers=FAKE_HEADERS,
|
mock.mock_open(read_data=fake_subcloud.FAKE_UPGRADES_METADATA)):
|
||||||
params=data)
|
response = self.app.patch_json(FAKE_URL_RESTORE,
|
||||||
|
headers=FAKE_HEADERS,
|
||||||
|
params=data)
|
||||||
|
|
||||||
self.assertEqual(response.status_int, 200)
|
self.assertEqual(response.status_int, 200)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ from dcmanager.common import consts
|
|||||||
from dcmanager.common import phased_subcloud_deploy as psd_common
|
from dcmanager.common import phased_subcloud_deploy as psd_common
|
||||||
from dcmanager.common import utils as dutils
|
from dcmanager.common import utils as dutils
|
||||||
from dcmanager.tests.unit.api import test_root_controller as testroot
|
from dcmanager.tests.unit.api import test_root_controller as testroot
|
||||||
|
from dcmanager.tests.unit.common import fake_subcloud
|
||||||
from dcmanager.tests import utils
|
from dcmanager.tests import utils
|
||||||
|
|
||||||
from tsconfig.tsconfig import SW_VERSION
|
from tsconfig.tsconfig import SW_VERSION
|
||||||
@ -48,12 +49,6 @@ FAKE_DEPLOY_FILES = {
|
|||||||
FAKE_DEPLOY_CHART_PREFIX: FAKE_DEPLOY_CHART_FILE,
|
FAKE_DEPLOY_CHART_PREFIX: FAKE_DEPLOY_CHART_FILE,
|
||||||
}
|
}
|
||||||
|
|
||||||
FAKE_UPGRADES_METADATA = '''
|
|
||||||
<build>\n<version>0.2</version>\n<supported_upgrades>
|
|
||||||
\n<upgrade>\n<version>%s</version>\n<required_patches>PATCH_0001</required_patches>
|
|
||||||
\n</upgrade>\n</supported_upgrades>\n</build>
|
|
||||||
''' % FAKE_SOFTWARE_VERSION
|
|
||||||
|
|
||||||
|
|
||||||
class TestSubcloudDeploy(testroot.DCManagerApiTest):
|
class TestSubcloudDeploy(testroot.DCManagerApiTest):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -72,7 +67,8 @@ class TestSubcloudDeploy(testroot.DCManagerApiTest):
|
|||||||
mock_upload_files.return_value = True
|
mock_upload_files.return_value = True
|
||||||
params += fields
|
params += fields
|
||||||
|
|
||||||
with mock.patch('builtins.open', mock.mock_open(read_data=FAKE_UPGRADES_METADATA)):
|
with mock.patch('builtins.open',
|
||||||
|
mock.mock_open(read_data=fake_subcloud.FAKE_UPGRADES_METADATA)):
|
||||||
response = self.app.post(FAKE_URL,
|
response = self.app.post(FAKE_URL,
|
||||||
headers=FAKE_HEADERS,
|
headers=FAKE_HEADERS,
|
||||||
params=params)
|
params=params)
|
||||||
@ -218,7 +214,11 @@ class TestSubcloudDeploy(testroot.DCManagerApiTest):
|
|||||||
mock_get_filename_by_prefix.side_effect = \
|
mock_get_filename_by_prefix.side_effect = \
|
||||||
get_filename_by_prefix_side_effect
|
get_filename_by_prefix_side_effect
|
||||||
url = FAKE_URL + '/' + FAKE_SOFTWARE_VERSION
|
url = FAKE_URL + '/' + FAKE_SOFTWARE_VERSION
|
||||||
response = self.app.get(url, headers=FAKE_HEADERS)
|
|
||||||
|
with mock.patch('builtins.open',
|
||||||
|
mock.mock_open(read_data=fake_subcloud.FAKE_UPGRADES_METADATA)):
|
||||||
|
response = self.app.get(url, headers=FAKE_HEADERS)
|
||||||
|
|
||||||
self.assertEqual(response.status_code, http_client.OK)
|
self.assertEqual(response.status_code, http_client.OK)
|
||||||
self.assertEqual(FAKE_SOFTWARE_VERSION,
|
self.assertEqual(FAKE_SOFTWARE_VERSION,
|
||||||
response.json['subcloud_deploy']['software_version'])
|
response.json['subcloud_deploy']['software_version'])
|
||||||
|
@ -554,11 +554,13 @@ class TestSubcloudPost(testroot.DCManagerApiTest,
|
|||||||
base64.b64encode('fake pass'.encode("utf-8")).decode("utf-8"),
|
base64.b64encode('fake pass'.encode("utf-8")).decode("utf-8"),
|
||||||
'release': '21.12'})
|
'release': '21.12'})
|
||||||
|
|
||||||
response = self.app.post(self.get_api_prefix(),
|
with mock.patch('builtins.open',
|
||||||
params=params,
|
mock.mock_open(read_data=fake_subcloud.FAKE_UPGRADES_METADATA)):
|
||||||
upload_files=upload_files,
|
response = self.app.post(self.get_api_prefix(),
|
||||||
headers=self.get_api_headers(),
|
params=params,
|
||||||
expect_errors=True)
|
upload_files=upload_files,
|
||||||
|
headers=self.get_api_headers(),
|
||||||
|
expect_errors=True)
|
||||||
|
|
||||||
# Verify the request was rejected
|
# Verify the request was rejected
|
||||||
self.assertEqual(response.status_code, http_client.BAD_REQUEST)
|
self.assertEqual(response.status_code, http_client.BAD_REQUEST)
|
||||||
@ -585,11 +587,13 @@ class TestSubcloudPost(testroot.DCManagerApiTest,
|
|||||||
base64.b64encode('fake pass'.encode("utf-8")).decode("utf-8"),
|
base64.b64encode('fake pass'.encode("utf-8")).decode("utf-8"),
|
||||||
'release': software_version})
|
'release': software_version})
|
||||||
|
|
||||||
response = self.app.post(self.get_api_prefix(),
|
with mock.patch('builtins.open',
|
||||||
params=params,
|
mock.mock_open(read_data=fake_subcloud.FAKE_UPGRADES_METADATA)):
|
||||||
upload_files=upload_files,
|
response = self.app.post(self.get_api_prefix(),
|
||||||
headers=self.get_api_headers(),
|
params=params,
|
||||||
expect_errors=True)
|
upload_files=upload_files,
|
||||||
|
headers=self.get_api_headers(),
|
||||||
|
expect_errors=True)
|
||||||
|
|
||||||
self.assertEqual(response.status_code, http_client.OK)
|
self.assertEqual(response.status_code, http_client.OK)
|
||||||
self.assertEqual(software_version, response.json['software-version'])
|
self.assertEqual(software_version, response.json['software-version'])
|
||||||
@ -719,11 +723,15 @@ class TestSubcloudPost(testroot.DCManagerApiTest,
|
|||||||
self.set_list_of_post_files(subclouds.SUBCLOUD_ADD_GET_FILE_CONTENTS)
|
self.set_list_of_post_files(subclouds.SUBCLOUD_ADD_GET_FILE_CONTENTS)
|
||||||
self.install_data = copy.copy(self.FAKE_INSTALL_DATA)
|
self.install_data = copy.copy(self.FAKE_INSTALL_DATA)
|
||||||
upload_files = self.get_post_upload_files()
|
upload_files = self.get_post_upload_files()
|
||||||
response = self.app.post(self.get_api_prefix(),
|
|
||||||
params=params,
|
with mock.patch('builtins.open',
|
||||||
upload_files=upload_files,
|
mock.mock_open(read_data=fake_subcloud.FAKE_UPGRADES_METADATA)):
|
||||||
headers=self.get_api_headers(),
|
response = self.app.post(self.get_api_prefix(),
|
||||||
expect_errors=True)
|
params=params,
|
||||||
|
upload_files=upload_files,
|
||||||
|
headers=self.get_api_headers(),
|
||||||
|
expect_errors=True)
|
||||||
|
|
||||||
self.assertEqual(response.status_code, http_client.BAD_REQUEST)
|
self.assertEqual(response.status_code, http_client.BAD_REQUEST)
|
||||||
|
|
||||||
# Revert the change of bootstrap_data
|
# Revert the change of bootstrap_data
|
||||||
@ -1689,10 +1697,12 @@ class TestSubcloudAPIOther(testroot.DCManagerApiTest):
|
|||||||
("deploy_config", "config_fake_filename",
|
("deploy_config", "config_fake_filename",
|
||||||
json.dumps(config_data).encode("utf-8"))]
|
json.dumps(config_data).encode("utf-8"))]
|
||||||
|
|
||||||
response = self.app.patch(
|
with mock.patch('builtins.open',
|
||||||
FAKE_URL + '/' + str(subcloud.id) + '/redeploy',
|
mock.mock_open(read_data=fake_subcloud.FAKE_UPGRADES_METADATA)):
|
||||||
headers=FAKE_HEADERS, params=redeploy_data,
|
response = self.app.patch(
|
||||||
upload_files=upload_files)
|
FAKE_URL + '/' + str(subcloud.id) + '/redeploy',
|
||||||
|
headers=FAKE_HEADERS, params=redeploy_data,
|
||||||
|
upload_files=upload_files)
|
||||||
|
|
||||||
mock_validate_bootstrap_values.assert_called_once()
|
mock_validate_bootstrap_values.assert_called_once()
|
||||||
mock_validate_subcloud_config.assert_called_once()
|
mock_validate_subcloud_config.assert_called_once()
|
||||||
|
@ -116,6 +116,14 @@ FAKE_SUBCLOUD_INSTALL_VALUES_WITH_PERSISTENT_SIZE = {
|
|||||||
"persistent_size": 40000,
|
"persistent_size": 40000,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FAKE_UPGRADES_METADATA = '''
|
||||||
|
<build>\n<version>0.1</version>\n<supported_upgrades>
|
||||||
|
\n<upgrade>\n<version>%s</version>\n</upgrade>
|
||||||
|
\n<upgrade>\n<version>21.12</version>\n</upgrade>
|
||||||
|
\n<upgrade>\n<version>22.12</version>\n</upgrade>
|
||||||
|
\n</supported_upgrades>\n</build>
|
||||||
|
''' % FAKE_SOFTWARE_VERSION
|
||||||
|
|
||||||
|
|
||||||
def create_fake_subcloud(ctxt, **kwargs):
|
def create_fake_subcloud(ctxt, **kwargs):
|
||||||
values = {
|
values = {
|
||||||
|
Loading…
Reference in New Issue
Block a user