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
========================
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)
-------------

View File

@ -51,6 +51,7 @@ PORT_SCHEMA = {
'portgroup_uuid': {'type': ['string', 'null']},
'pxe_enabled': {'type': ['string', 'boolean', 'null']},
'uuid': {'type': ['string', 'null']},
'name': {'type': ['string', 'null']},
},
'required': ['address', 'node_uuid'],
'additionalProperties': False,
@ -67,7 +68,8 @@ PATCH_ALLOWED_FIELDS = [
'node_uuid',
'physical_network',
'portgroup_uuid',
'pxe_enabled'
'pxe_enabled',
'name',
]
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 not api_utils.allow_port_is_smartnic():
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):
@ -124,6 +129,7 @@ def convert_with_links(rpc_port, fields=None, sanitize=True):
'physical_network',
'pxe_enabled',
'node_uuid',
'name',
)
)
if rpc_port.portgroup_id:
@ -344,6 +350,9 @@ class PortsController(rest.RestController):
if (not api_utils.allow_local_link_connection_network_type()
and 'network_type' in fields['local_link_connection']):
raise exception.NotAcceptable()
if ('name' in fields
and not api_utils.allow_port_name()):
raise exception.NotAcceptable()
@METRICS.timer('PortsController.get_all')
@method.expose()
@ -484,11 +493,11 @@ class PortsController(rest.RestController):
@METRICS.timer('PortsController.get_one')
@method.expose()
@args.validate(port_uuid=args.uuid, fields=args.string_list)
def get_one(self, port_uuid, fields=None):
@args.validate(port_ident=args.uuid_or_name, fields=args.string_list)
def get_one(self, port_ident, fields=None):
"""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
of the resource to be returned.
:raises: NotAcceptable, HTTPNotFound
@ -497,7 +506,7 @@ class PortsController(rest.RestController):
raise exception.OperationNotPermitted()
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)
self._check_allowed_port_fields(fields)
@ -619,11 +628,11 @@ class PortsController(rest.RestController):
@METRICS.timer('PortsController.patch')
@method.expose()
@method.body('patch')
@args.validate(port_uuid=args.uuid, patch=args.patch)
def patch(self, port_uuid, patch):
@args.validate(port_ident=args.uuid_or_name, patch=args.patch)
def patch(self, port_ident, patch):
"""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.
:raises: NotAcceptable, HTTPNotFound
"""
@ -644,7 +653,7 @@ class PortsController(rest.RestController):
self._check_allowed_port_fields(fields_to_check)
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()
# 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.
: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
"""
context = api.request.context
@ -2021,3 +2022,11 @@ def allow_firmware_interface():
Version 1.84 of the API added support for 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.86: Add firmware interface
# v1.87: Add service verb
# v1.88: Add name field to port.
MINOR_0_JUNO = 0
MINOR_1_INITIAL_VERSION = 1
MINOR_2_AVAILABLE_STATE = 2
@ -213,7 +215,7 @@ MINOR_84_CONTINUE_INSPECTION = 84
MINOR_85_UNHOLD_VERB = 85
MINOR_86_FIRMWARE_INTERFACE = 86
MINOR_87_SERVICE = 87
MINOR_88_PORT_NAME = 88
# When adding another version, update:
# - MINOR_MAX_VERSION
@ -221,7 +223,7 @@ MINOR_87_SERVICE = 87
# explanation of what changed in the new version
# - 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
_MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_1_INITIAL_VERSION)

View File

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

View File

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