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:
parent
bc028e0b65
commit
5c303a5e0a
@ -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)
|
||||
----------------------
|
||||
|
||||
|
@ -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']:
|
||||
|
@ -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 = [
|
||||
|
@ -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)
|
||||
|
@ -320,7 +320,7 @@ RELEASE_MAPPING = {
|
||||
}
|
||||
},
|
||||
'master': {
|
||||
'api': '1.72',
|
||||
'api': '1.73',
|
||||
'rpc': '1.54',
|
||||
'objects': {
|
||||
'Allocation': ['1.1'],
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
||||
|
@ -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>`_.
|
Loading…
Reference in New Issue
Block a user