Aliases for a few unfortunately named state transitions

This RFE proposes a new microversion that will provide
aliases to two poorly named provisioning verbs
to match the existing CLI commands

Story: #2007551
Task: #39402
Change-Id: Ifd14aebbfb4b17c5108f44092dac0b89d1c2c50a
This commit is contained in:
kafilat-adeleke 2021-04-06 09:58:20 +01:00
parent bc028e0b65
commit 5c303a5e0a
9 changed files with 85 additions and 4 deletions

View File

@ -2,6 +2,11 @@
REST API Version History
========================
1.73 (Xena)
----------------------
Add a new ``deploy`` verb as an alias to ``active`` and
``undeploy`` verb as an alias to ``deleted``.
1.72 (Wallaby, 17.0)
----------------------

View File

@ -825,7 +825,7 @@ class NodeStatesController(rest.RestController):
# Note that there is a race condition. The node state(s) could change
# by the time the RPC call is made and the TaskManager manager gets a
# lock.
if target in (ir_states.ACTIVE, ir_states.REBUILD):
if target in (ir_states.ACTIVE, ir_states.REBUILD, ir_states.DEPLOY):
rebuild = (target == ir_states.REBUILD)
if deploy_steps:
_check_deploy_steps(deploy_steps)
@ -847,7 +847,7 @@ class NodeStatesController(rest.RestController):
msg, status_code=http_client.BAD_REQUEST)
api.request.rpcapi.do_node_rescue(
api.request.context, rpc_node.uuid, rescue_password, topic)
elif target == ir_states.DELETED:
elif target in (ir_states.DELETED, ir_states.UNDEPLOY):
api.request.rpcapi.do_node_tear_down(
api.request.context, rpc_node.uuid, topic)
elif target == ir_states.VERBS['inspect']:

View File

@ -67,6 +67,8 @@ MIN_VERB_VERSIONS = {
states.VERBS['adopt']: versions.MINOR_17_ADOPT_VERB,
states.VERBS['rescue']: versions.MINOR_38_RESCUE_INTERFACE,
states.VERBS['unrescue']: versions.MINOR_38_RESCUE_INTERFACE,
states.VERBS['deploy']: versions.MINOR_73_DEPLOY_UNDEPLOY_VERBS,
states.VERBS['undeploy']: versions.MINOR_73_DEPLOY_UNDEPLOY_VERBS,
}
V31_FIELDS = [

View File

@ -110,6 +110,7 @@ BASE_VERSION = 1
# v1.70: Add disable_ramdisk to manual cleaning.
# v1.71: Add signifier for Scope based roles.
# v1.72: Add agent_status and agent_status_message to /v1/heartbeat
# v1.73: Add support for deploy and undeploy verbs
MINOR_0_JUNO = 0
MINOR_1_INITIAL_VERSION = 1
@ -184,6 +185,7 @@ MINOR_69_DEPLOY_STEPS = 69
MINOR_70_CLEAN_DISABLE_RAMDISK = 70
MINOR_71_RBAC_SCOPES = 71
MINOR_72_HEARTBEAT_STATUS = 72
MINOR_73_DEPLOY_UNDEPLOY_VERBS = 73
# When adding another version, update:
# - MINOR_MAX_VERSION
@ -191,7 +193,7 @@ MINOR_72_HEARTBEAT_STATUS = 72
# explanation of what changed in the new version
# - common/release_mappings.py, RELEASE_MAPPING['master']['api']
MINOR_MAX_VERSION = MINOR_72_HEARTBEAT_STATUS
MINOR_MAX_VERSION = MINOR_73_DEPLOY_UNDEPLOY_VERBS
# String representations of the minor and maximum versions
_MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_1_INITIAL_VERSION)

View File

@ -320,7 +320,7 @@ RELEASE_MAPPING = {
}
},
'master': {
'api': '1.72',
'api': '1.73',
'rpc': '1.54',
'objects': {
'Allocation': ['1.1'],

View File

@ -41,7 +41,9 @@ LOG = logging.getLogger(__name__)
# TODO(tenbrae): add add'l state mappings here
VERBS = {
'active': 'deploy',
'deploy': 'deploy',
'deleted': 'delete',
'undeploy': 'delete',
'manage': 'manage',
'provide': 'provide',
'inspect': 'inspect',
@ -96,6 +98,11 @@ This state is replacing the NOSTATE state used prior to Kilo.
ACTIVE = 'active'
""" Node is successfully deployed and associated with an instance. """
DEPLOY = 'deploy'
""" Node is successfully deployed and associated with an instance.
This is an alias for ACTIVE.
"""
DEPLOYWAIT = 'wait call-back'
""" Node is waiting to be deployed.
@ -137,6 +144,11 @@ represented in target_provision_state.
CLEANING = 'cleaning'
""" Node is being automatically cleaned to prepare it for provisioning. """
UNDEPLOY = 'undeploy'
""" Node tear down process has started.
This is an alias for DELETED.
"""
CLEANWAIT = 'clean wait'
""" Node is waiting for a clean step to be finished.

View File

@ -5093,6 +5093,25 @@ class TestPut(test_api_base.BaseApiTest):
self.assertEqual(urlparse.urlparse(ret.location).path,
expected_location)
def test_provision_deploy(self):
ret = self.put_json('/nodes/%s/states/provision' % self.node.uuid,
{'target': states.DEPLOY},
headers={api_base.Version.string: "1.73"})
self.assertEqual(http_client.ACCEPTED, ret.status_code)
self.assertEqual(b'', ret.body)
self.mock_dnd.assert_called_once_with(mock.ANY,
context=mock.ANY,
node_id=self.node.uuid,
rebuild=False,
configdrive=None,
topic='test-topic',
deploy_steps=None)
# Check location header
self.assertIsNotNone(ret.location)
expected_location = '/v1/nodes/%s/states' % self.node.uuid
self.assertEqual(urlparse.urlparse(ret.location).path,
expected_location)
def test_provision_by_name_unsupported(self):
ret = self.put_json('/nodes/%s/states/provision' % self.node.name,
{'target': states.ACTIVE},
@ -5354,6 +5373,23 @@ ORHMKeXMO8fcK0By7CiMKwHSXCoEQgfQhWwpMdSsO8LgHCjh87DQc= """
self.assertEqual(urlparse.urlparse(ret.location).path,
expected_location)
def test_provision_with_tear_down_undeploy(self):
node = self.node
node.provision_state = states.ACTIVE
node.target_provision_state = states.NOSTATE
node.save()
ret = self.put_json('/nodes/%s/states/provision' % node.uuid,
{'target': states.UNDEPLOY})
self.assertEqual(http_client.ACCEPTED, ret.status_code)
self.assertEqual(b'', ret.body)
self.mock_dntd.assert_called_once_with(
mock.ANY, mock.ANY, node.uuid, 'test-topic')
# Check location header
self.assertIsNotNone(ret.location)
expected_location = '/v1/nodes/%s/states' % node.uuid
self.assertEqual(urlparse.urlparse(ret.location).path,
expected_location)
def test_provision_already_in_progress(self):
node = self.node
node.provision_state = states.DEPLOYING

View File

@ -556,6 +556,24 @@ class TestCheckAllowFields(base.TestCase):
self.assertRaises(exception.NotAcceptable,
utils.check_allow_management_verbs, 'clean')
def test_check_allow_deploy_verbs(self, mock_request):
mock_request.version.minor = 73
utils.check_allow_management_verbs('deploy')
def test_check_allow_deploy_verbs_fail(self, mock_request):
mock_request.version.minor = 72
self.assertRaises(exception.NotAcceptable,
utils.check_allow_management_verbs, 'deploy')
def test_check_allow_undeploy_verbs(self, mock_request):
mock_request.version.minor = 73
utils.check_allow_management_verbs('undeploy')
def test_check_allow_undeploy_verbs_fail(self, mock_request):
mock_request.version.minor = 72
self.assertFalse(
utils.check_allow_management_verbs('undeploy'))
def test_check_allow_unknown_verbs(self, mock_request):
utils.check_allow_management_verbs('rebuild')

View File

@ -0,0 +1,6 @@
---
features:
- |
Adds a new ``deploy`` verb as an alias to ``active`` and
``undeploy`` verb as an alias to ``deleted``
See `story 2007551 <https://storyboard.openstack.org/#!/story/2007551>`_.