Restrict subcloud deploy configure to primary site
Restrict subcloud's secondary sites (the peer site where subcloud in SPG can be migrated to) from reconfiguring the subcloud. This is necessary because subcloud reconfig may update the OpenStack endpoints/routes/network IPs and impact the ability to migrate the subcloud back to the primary site. - Introduced a check in "deploy configure" to ensure that the target subcloud is managed by its primary site. The site status is inferred from the subcloud's peer group priority on the site. Test Plan: Setup a DC system with GR configuration (2 sites + subclouds) and verify the "subcloud deploy config" command with the following arrangements: 1. PASS: For a subcloud that's not part of protection group (not in any SPG / not part of GR), ensure that the operation is not restricted. 2. PASS: Add subcloud to SPG and keep it managed by primary site, ensure that the operation is not restricted. 3. PASS: Add system peer, create SPG association with a secondary site, and migrate the subcloud from #2. Verify that "deploy config" is restricted and it fails with following error message: "Subcloud must be managed by its primary site" 4. PASS: Using the subcloud from #3, migrate it back to the primary site. Attempt to deploy config and ensure that the operation is not restricted. Closes-Bug: 2054161 Change-Id: I7e986771a32882bfad917c85439e6f6b99dfe173 Signed-off-by: Salman Rana <salman.rana@windriver.com>
This commit is contained in:
parent
23e2cf4a85
commit
fc0a5f0e53
|
@ -31,7 +31,6 @@ from dcmanager.rpc import client as rpc_client
|
|||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
PEER_GROUP_PRIMARY_PRIORITY = 0
|
||||
MIN_PEER_GROUP_ASSOCIATION_PRIORITY = 1
|
||||
MAX_PEER_GROUP_ASSOCIATION_PRIORITY = 65536
|
||||
ASSOCIATION_SYNC_STATUS_LIST = \
|
||||
|
@ -191,9 +190,9 @@ class PeerGroupAssociationsController(restcomm.GenericPathController):
|
|||
pecan.abort(httpclient.BAD_REQUEST,
|
||||
_('Invalid peer_group_priority'))
|
||||
|
||||
if (peer_group.group_priority == PEER_GROUP_PRIMARY_PRIORITY and
|
||||
if (peer_group.group_priority == consts.PEER_GROUP_PRIMARY_PRIORITY and
|
||||
peer_group_priority is None) or (
|
||||
peer_group.group_priority > PEER_GROUP_PRIMARY_PRIORITY and
|
||||
peer_group.group_priority > consts.PEER_GROUP_PRIMARY_PRIORITY and
|
||||
peer_group_priority is not None):
|
||||
pecan.abort(httpclient.BAD_REQUEST,
|
||||
_('Peer Group Association create is not allowed when '
|
||||
|
@ -201,7 +200,7 @@ class PeerGroupAssociationsController(restcomm.GenericPathController):
|
|||
'and it is required when the subcloud peer group '
|
||||
'priority is 0.'))
|
||||
|
||||
is_primary = peer_group.group_priority == PEER_GROUP_PRIMARY_PRIORITY
|
||||
is_primary = peer_group.group_priority == consts.PEER_GROUP_PRIMARY_PRIORITY
|
||||
|
||||
# only one combination of peer_group_id + system_peer_id can exists
|
||||
association = None
|
||||
|
|
|
@ -309,6 +309,17 @@ class PhasedSubcloudDeployController(object):
|
|||
pecan.abort(400, _('Subcloud prestage is ongoing %s') %
|
||||
subcloud.prestage_status)
|
||||
|
||||
# If the subcloud belongs to a peer group, ensure that
|
||||
# it's not being configured in a secondary site.
|
||||
if subcloud.peer_group_id is not None:
|
||||
peer_group = utils.subcloud_peer_group_get_by_ref(
|
||||
context, str(subcloud.peer_group_id))
|
||||
if peer_group is not None:
|
||||
if peer_group.group_priority != consts.PEER_GROUP_PRIMARY_PRIORITY:
|
||||
pecan.abort(400,
|
||||
_('Subcloud can only be configured in'
|
||||
' its primary site.'))
|
||||
|
||||
psd_common.populate_payload_with_pre_existing_data(
|
||||
payload, subcloud, SUBCLOUD_CONFIG_GET_FILE_CONTENTS)
|
||||
|
||||
|
|
|
@ -461,6 +461,8 @@ PEER_GROUP_MIGRATING = 'migrating'
|
|||
PEER_GROUP_MIGRATION_COMPLETE = 'complete'
|
||||
PEER_GROUP_MIGRATION_NONE = 'none'
|
||||
|
||||
PEER_GROUP_PRIMARY_PRIORITY = 0
|
||||
|
||||
# Peer group association type
|
||||
ASSOCIATION_TYPE_PRIMARY = 'primary'
|
||||
ASSOCIATION_TYPE_NON_PRIMARY = 'non-primary'
|
||||
|
|
|
@ -28,6 +28,8 @@ from dcmanager.tests.unit.api.v1.controllers.test_subclouds import \
|
|||
from dcmanager.tests.unit.api.v1.controllers.test_subclouds import \
|
||||
TestSubcloudPost
|
||||
from dcmanager.tests.unit.common import fake_subcloud
|
||||
from dcmanager.tests.unit.manager.test_system_peer_manager import \
|
||||
TestSystemPeerManager
|
||||
from dcmanager.tests import utils
|
||||
|
||||
FAKE_URL = '/v1.0/phased-subcloud-deploy'
|
||||
|
@ -345,6 +347,48 @@ class TestSubcloudDeployConfig(testroot.DCManagerApiTest):
|
|||
str(subcloud.id) + '/configure',
|
||||
headers=FAKE_HEADERS, params=data)
|
||||
|
||||
def test_configure_primary_subcloud_peer_group(self):
|
||||
data_install = copy.copy(FAKE_SUBCLOUD_INSTALL_VALUES)
|
||||
data_install.pop('software_version')
|
||||
|
||||
fake_password = \
|
||||
(base64.b64encode('testpass'.encode("utf-8"))).decode('ascii')
|
||||
data = {'sysadmin_password': fake_password}
|
||||
|
||||
self.mock_rpc_client().subcloud_deploy_config.return_value = True
|
||||
self.mock_get_request_data.return_value = data
|
||||
|
||||
# Create a subcloud and add it to SPG with primary priority
|
||||
peer_group = TestSystemPeerManager.create_subcloud_peer_group_static(
|
||||
self.ctx,
|
||||
group_priority=consts.PEER_GROUP_PRIMARY_PRIORITY,
|
||||
peer_group_name='SubcloudPeerGroup1')
|
||||
|
||||
subcloud = TestSystemPeerManager.create_subcloud_with_pg_static(
|
||||
self.ctx,
|
||||
peer_group_id=peer_group.id,
|
||||
name='subcloud1',
|
||||
data_install=json.dumps(data_install))
|
||||
|
||||
response = self.app.patch_json(FAKE_URL + '/' + str(subcloud.id) +
|
||||
'/configure',
|
||||
headers=FAKE_HEADERS,
|
||||
params=data)
|
||||
self.mock_rpc_client().subcloud_deploy_config.assert_called_once_with(
|
||||
mock.ANY, subcloud.id, data, initial_deployment=True)
|
||||
self.assertEqual(response.status_int, 200)
|
||||
|
||||
# Change the SPG as if it was on peer site
|
||||
db_api.subcloud_peer_group_update(
|
||||
self.ctx,
|
||||
peer_group.id,
|
||||
group_priority=consts.PEER_GROUP_PRIMARY_PRIORITY + 1)
|
||||
|
||||
six.assertRaisesRegex(self, webtest.app.AppError, "400 *",
|
||||
self.app.patch_json, FAKE_URL + '/' +
|
||||
str(subcloud.id) + '/configure',
|
||||
headers=FAKE_HEADERS, params=data)
|
||||
|
||||
|
||||
class TestSubcloudDeployInstall(testroot.DCManagerApiTest):
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in New Issue