Support port name: API

This patch implements API changes for port name support.

Change-Id: I192ae52847087f7b43a7204ec6ee9e299c305eb5
Story: 2003091
Task: 23180
This commit is contained in:
Kaifeng Wang 2020-12-05 00:23:16 +08:00 committed by Julia Kreger
parent 0eb3f40f10
commit 8db7220bae
6 changed files with 40 additions and 13 deletions

View File

@ -2,6 +2,12 @@
REST API Version History REST API Version History
======================== ========================
1.88 (Bobcat)
-----------------------
Added the ``name`` field to the port API. It should be unique when set,
and can be used to identify a port resource.
1.87 (Bobcat) 1.87 (Bobcat)
------------- -------------

View File

@ -51,6 +51,7 @@ PORT_SCHEMA = {
'portgroup_uuid': {'type': ['string', 'null']}, 'portgroup_uuid': {'type': ['string', 'null']},
'pxe_enabled': {'type': ['string', 'boolean', 'null']}, 'pxe_enabled': {'type': ['string', 'boolean', 'null']},
'uuid': {'type': ['string', 'null']}, 'uuid': {'type': ['string', 'null']},
'name': {'type': ['string', 'null']},
}, },
'required': ['address', 'node_uuid'], 'required': ['address', 'node_uuid'],
'additionalProperties': False, 'additionalProperties': False,
@ -67,7 +68,8 @@ PATCH_ALLOWED_FIELDS = [
'node_uuid', 'node_uuid',
'physical_network', 'physical_network',
'portgroup_uuid', 'portgroup_uuid',
'pxe_enabled' 'pxe_enabled',
'name',
] ]
PORT_VALIDATOR_EXTRA = args.dict_valid( PORT_VALIDATOR_EXTRA = args.dict_valid(
@ -109,6 +111,9 @@ def hide_fields_in_newer_versions(port):
# if requested version is < 1.53, hide is_smartnic field. # if requested version is < 1.53, hide is_smartnic field.
if not api_utils.allow_port_is_smartnic(): if not api_utils.allow_port_is_smartnic():
port.pop('is_smartnic', None) port.pop('is_smartnic', None)
# if requested version is < 1.69, hide name field.
if not api_utils.allow_port_name():
port.pop('name', None)
def convert_with_links(rpc_port, fields=None, sanitize=True): def convert_with_links(rpc_port, fields=None, sanitize=True):
@ -124,6 +129,7 @@ def convert_with_links(rpc_port, fields=None, sanitize=True):
'physical_network', 'physical_network',
'pxe_enabled', 'pxe_enabled',
'node_uuid', 'node_uuid',
'name',
) )
) )
if rpc_port.portgroup_id: if rpc_port.portgroup_id:
@ -344,6 +350,9 @@ class PortsController(rest.RestController):
if (not api_utils.allow_local_link_connection_network_type() if (not api_utils.allow_local_link_connection_network_type()
and 'network_type' in fields['local_link_connection']): and 'network_type' in fields['local_link_connection']):
raise exception.NotAcceptable() raise exception.NotAcceptable()
if ('name' in fields
and not api_utils.allow_port_name()):
raise exception.NotAcceptable()
@METRICS.timer('PortsController.get_all') @METRICS.timer('PortsController.get_all')
@method.expose() @method.expose()
@ -484,11 +493,11 @@ class PortsController(rest.RestController):
@METRICS.timer('PortsController.get_one') @METRICS.timer('PortsController.get_one')
@method.expose() @method.expose()
@args.validate(port_uuid=args.uuid, fields=args.string_list) @args.validate(port_ident=args.uuid_or_name, fields=args.string_list)
def get_one(self, port_uuid, fields=None): def get_one(self, port_ident, fields=None):
"""Retrieve information about the given port. """Retrieve information about the given port.
:param port_uuid: UUID of a port. :param port_ident: UUID or name of a port.
:param fields: Optional, a list with a specified set of fields :param fields: Optional, a list with a specified set of fields
of the resource to be returned. of the resource to be returned.
:raises: NotAcceptable, HTTPNotFound :raises: NotAcceptable, HTTPNotFound
@ -497,7 +506,7 @@ class PortsController(rest.RestController):
raise exception.OperationNotPermitted() raise exception.OperationNotPermitted()
rpc_port, rpc_node = api_utils.check_port_policy_and_retrieve( rpc_port, rpc_node = api_utils.check_port_policy_and_retrieve(
'baremetal:port:get', port_uuid) 'baremetal:port:get', port_ident)
api_utils.check_allow_specify_fields(fields) api_utils.check_allow_specify_fields(fields)
self._check_allowed_port_fields(fields) self._check_allowed_port_fields(fields)
@ -619,11 +628,11 @@ class PortsController(rest.RestController):
@METRICS.timer('PortsController.patch') @METRICS.timer('PortsController.patch')
@method.expose() @method.expose()
@method.body('patch') @method.body('patch')
@args.validate(port_uuid=args.uuid, patch=args.patch) @args.validate(port_ident=args.uuid_or_name, patch=args.patch)
def patch(self, port_uuid, patch): def patch(self, port_ident, patch):
"""Update an existing port. """Update an existing port.
:param port_uuid: UUID of a port. :param port_ident: UUID or name of a port.
:param patch: a json PATCH document to apply to this port. :param patch: a json PATCH document to apply to this port.
:raises: NotAcceptable, HTTPNotFound :raises: NotAcceptable, HTTPNotFound
""" """
@ -644,7 +653,7 @@ class PortsController(rest.RestController):
self._check_allowed_port_fields(fields_to_check) self._check_allowed_port_fields(fields_to_check)
rpc_port, rpc_node = api_utils.check_port_policy_and_retrieve( rpc_port, rpc_node = api_utils.check_port_policy_and_retrieve(
'baremetal:port:update', port_uuid) 'baremetal:port:update', port_ident)
port_dict = rpc_port.as_dict() port_dict = rpc_port.as_dict()
# NOTE(lucasagomes): # NOTE(lucasagomes):

View File

@ -1656,7 +1656,8 @@ def check_port_policy_and_retrieve(policy_name, port_ident, portgroup=False):
a port or portgroup by. a port or portgroup by.
:raises: HTTPForbidden if the policy forbids access. :raises: HTTPForbidden if the policy forbids access.
:raises: NodeNotFound if the node is not found. :raises: PortNotFound if the port is not found.
:raises: PortgroupNotFound if the portgroup is not found.
:return: RPC port identified by port_ident associated node :return: RPC port identified by port_ident associated node
""" """
context = api.request.context context = api.request.context
@ -2021,3 +2022,11 @@ def allow_firmware_interface():
Version 1.84 of the API added support for firmware interface. Version 1.84 of the API added support for firmware interface.
""" """
return api.request.version.minor >= versions.MINOR_86_FIRMWARE_INTERFACE return api.request.version.minor >= versions.MINOR_86_FIRMWARE_INTERFACE
def allow_port_name():
"""Check if name is allowed for ports.
Version 1.88 of the API added name field to the port object.
"""
return api.request.version.minor >= versions.MINOR_88_PORT_NAME

View File

@ -125,6 +125,8 @@ BASE_VERSION = 1
# v1.85: Add unhold verb # v1.85: Add unhold verb
# v1.86: Add firmware interface # v1.86: Add firmware interface
# v1.87: Add service verb # v1.87: Add service verb
# v1.88: Add name field to port.
MINOR_0_JUNO = 0 MINOR_0_JUNO = 0
MINOR_1_INITIAL_VERSION = 1 MINOR_1_INITIAL_VERSION = 1
MINOR_2_AVAILABLE_STATE = 2 MINOR_2_AVAILABLE_STATE = 2
@ -213,7 +215,7 @@ MINOR_84_CONTINUE_INSPECTION = 84
MINOR_85_UNHOLD_VERB = 85 MINOR_85_UNHOLD_VERB = 85
MINOR_86_FIRMWARE_INTERFACE = 86 MINOR_86_FIRMWARE_INTERFACE = 86
MINOR_87_SERVICE = 87 MINOR_87_SERVICE = 87
MINOR_88_PORT_NAME = 88
# When adding another version, update: # When adding another version, update:
# - MINOR_MAX_VERSION # - MINOR_MAX_VERSION
@ -221,7 +223,7 @@ MINOR_87_SERVICE = 87
# explanation of what changed in the new version # explanation of what changed in the new version
# - common/release_mappings.py, RELEASE_MAPPING['master']['api'] # - common/release_mappings.py, RELEASE_MAPPING['master']['api']
MINOR_MAX_VERSION = MINOR_87_SERVICE MINOR_MAX_VERSION = MINOR_88_PORT_NAME
# String representations of the minor and maximum versions # String representations of the minor and maximum versions
_MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_1_INITIAL_VERSION) _MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_1_INITIAL_VERSION)

View File

@ -617,7 +617,7 @@ RELEASE_MAPPING = {
} }
}, },
'master': { 'master': {
'api': '1.87', 'api': '1.88',
'rpc': '1.58', 'rpc': '1.58',
'objects': { 'objects': {
'Allocation': ['1.1'], 'Allocation': ['1.1'],

View File

@ -1892,6 +1892,7 @@ class TestPost(test_api_base.BaseApiTest):
pdict.pop('physical_network') pdict.pop('physical_network')
pdict.pop('is_smartnic') pdict.pop('is_smartnic')
pdict.pop('portgroup_uuid') pdict.pop('portgroup_uuid')
pdict.pop('name')
headers = {api_base.Version.string: str(api_v1.min_version())} headers = {api_base.Version.string: str(api_v1.min_version())}
response = self.post_json('/ports', pdict, headers=headers) response = self.post_json('/ports', pdict, headers=headers)
self.assertEqual('application/json', response.content_type) self.assertEqual('application/json', response.content_type)