feat: add 'vendor' and 'category' for port object

Added support for the 'vendor' and 'category' fields for the port
object.

Change-Id: Id2ec4308b1ab4c9fba538c811af52b32206730f8
Signed-off-by: Doug Goldstein <cardoe@cardoe.com>
(cherry picked from commit 924107bcd2)
This commit is contained in:
Doug Goldstein
2026-01-13 12:24:32 -06:00
parent d6eca3931f
commit b2c1dfac69
5 changed files with 176 additions and 2 deletions

View File

@@ -118,6 +118,18 @@ class CreateBaremetalPort(command.ShowOne):
metavar='<port description>',
help=_("An optional description for the port."))
parser.add_argument(
'--vendor',
dest='vendor',
metavar='<port vendor>',
help=_("An optional vendor for the port."))
parser.add_argument(
'--category',
dest='category',
metavar='<port category>',
help=_("An optional category for the port."))
return parser
def take_action(self, parsed_args):
@@ -138,7 +150,8 @@ class CreateBaremetalPort(command.ShowOne):
field_list = ['address', 'uuid', 'extra', 'node_uuid', 'pxe_enabled',
'local_link_connection', 'portgroup_uuid',
'physical_network', 'name', 'description']
'physical_network', 'name', 'description', 'vendor',
'category']
fields = dict((k, v) for (k, v) in vars(parsed_args).items()
if k in field_list and v is not None)
fields = utils.args_array_to_dict(fields, 'extra')
@@ -255,6 +268,18 @@ class UnsetBaremetalPort(command.Command):
action='store_true',
help=_("Unset the description for this port."))
parser.add_argument(
'--vendor',
dest='vendor',
action='store_true',
help=_("Unset the vendor for this port."))
parser.add_argument(
'--category',
dest='category',
action='store_true',
help=_("Unset the category for this port."))
return parser
def take_action(self, parsed_args):
@@ -281,6 +306,12 @@ class UnsetBaremetalPort(command.Command):
if parsed_args.description:
properties.extend(utils.args_array_to_patch('remove',
['description']))
if parsed_args.vendor:
properties.extend(utils.args_array_to_patch('remove',
['vendor']))
if parsed_args.category:
properties.extend(utils.args_array_to_patch('remove',
['category']))
if properties:
baremetal_client.port.update(parsed_args.port, properties)
@@ -378,6 +409,18 @@ class SetBaremetalPort(command.Command):
dest='description',
help=_("Set a description for this port"))
parser.add_argument(
'--vendor',
metavar='<vendor>',
dest='vendor',
help=_("Set a vendor for this port"))
parser.add_argument(
'--category',
metavar='<category>',
dest='category',
help=_("Set a category for this port"))
return parser
def take_action(self, parsed_args):
@@ -421,6 +464,14 @@ class SetBaremetalPort(command.Command):
port_description = ["description=%s" % parsed_args.description]
properties.extend(utils.args_array_to_patch('add',
port_description))
if parsed_args.vendor:
port_vendor = ["vendor=%s" % parsed_args.vendor]
properties.extend(utils.args_array_to_patch('add',
port_vendor))
if parsed_args.category:
port_category = ["category=%s" % parsed_args.category]
properties.extend(utils.args_array_to_patch('add',
port_category))
if properties:
baremetal_client.port.update(parsed_args.port, properties)

View File

@@ -326,6 +326,60 @@ class TestCreateBaremetalPort(TestBaremetalPort):
self.baremetal_mock.port.create.assert_called_once_with(**args)
def test_baremetal_port_create_vendor(self):
arglist = [
baremetal_fakes.baremetal_port_address,
'--node', baremetal_fakes.baremetal_uuid,
'--vendor', 'VendorA'
]
verifylist = [
('node_uuid', baremetal_fakes.baremetal_uuid),
('address', baremetal_fakes.baremetal_port_address),
('vendor', 'VendorA')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
self.cmd.take_action(parsed_args)
# Set expected values
args = {
'address': baremetal_fakes.baremetal_port_address,
'node_uuid': baremetal_fakes.baremetal_uuid,
'vendor': 'VendorA'
}
self.baremetal_mock.port.create.assert_called_once_with(**args)
def test_baremetal_port_create_category(self):
arglist = [
baremetal_fakes.baremetal_port_address,
'--node', baremetal_fakes.baremetal_uuid,
'--category', 'Green'
]
verifylist = [
('node_uuid', baremetal_fakes.baremetal_uuid),
('address', baremetal_fakes.baremetal_port_address),
('category', 'Green')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
self.cmd.take_action(parsed_args)
# Set expected values
args = {
'address': baremetal_fakes.baremetal_port_address,
'node_uuid': baremetal_fakes.baremetal_uuid,
'category': 'Green'
}
self.baremetal_mock.port.create.assert_called_once_with(**args)
class TestShowBaremetalPort(TestBaremetalPort):
def setUp(self):
@@ -505,6 +559,30 @@ class TestBaremetalPortUnset(TestBaremetalPort):
'port',
[{'path': '/description', 'op': 'remove'}])
def test_baremetal_port_unset_vendor(self):
arglist = ['port', '--vendor']
verifylist = [('port', 'port'),
('vendor', True)]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.port.update.assert_called_once_with(
'port',
[{'path': '/vendor', 'op': 'remove'}])
def test_baremetal_port_unset_category(self):
arglist = ['port', '--category']
verifylist = [('port', 'port'),
('category', True)]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.port.update.assert_called_once_with(
'port',
[{'path': '/category', 'op': 'remove'}])
class TestBaremetalPortSet(TestBaremetalPort):
def setUp(self):
@@ -705,6 +783,38 @@ class TestBaremetalPortSet(TestBaremetalPort):
[{'path': '/description', 'value': 'Public Network',
'op': 'add'}])
def test_baremetal_port_set_vendor(self):
arglist = [
baremetal_fakes.baremetal_port_uuid,
'--vendor', 'VendorA']
verifylist = [
('port', baremetal_fakes.baremetal_port_uuid),
('vendor', 'VendorA')]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.port.update.assert_called_once_with(
baremetal_fakes.baremetal_port_uuid,
[{'path': '/vendor', 'value': 'VendorA',
'op': 'add'}])
def test_baremetal_port_set_category(self):
arglist = [
baremetal_fakes.baremetal_port_uuid,
'--category', 'Green']
verifylist = [
('port', baremetal_fakes.baremetal_port_uuid),
('category', 'Green')]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.port.update.assert_called_once_with(
baremetal_fakes.baremetal_port_uuid,
[{'path': '/category', 'value': 'Green',
'op': 'add'}])
class TestBaremetalPortDelete(TestBaremetalPort):
def setUp(self):
@@ -858,6 +968,7 @@ class TestBaremetalPortList(TestBaremetalPort):
self.baremetal_mock.port.list.assert_called_with(**kwargs)
collist = ('UUID', 'Address', 'Created At', 'Extra', 'Node UUID',
'Category', 'Vendor',
'Local Link Connection', 'Portgroup UUID',
'PXE boot enabled', 'Physical Network', 'Updated At',
'Internal Info', 'Is Smart NIC port',
@@ -878,6 +989,8 @@ class TestBaremetalPortList(TestBaremetalPort):
'',
'',
'',
'',
'',
), )
self.assertEqual(datalist, tuple(data))

View File

@@ -30,7 +30,7 @@ class PortManager(base.CreateManager):
_creation_attributes = ['address', 'extra', 'local_link_connection',
'node_uuid', 'physical_network', 'portgroup_uuid',
'pxe_enabled', 'uuid', 'is_smartnic', 'name',
'description']
'description', 'vendor', 'category']
_resource_name = 'ports'
def list(self, address=None, limit=None, marker=None, sort_key=None,

View File

@@ -131,6 +131,8 @@ class Resource(object):
'value': 'Value',
'volume_id': 'Volume ID',
'volume_type': 'Driver Volume Type',
'category': 'Category',
'vendor': 'Vendor',
'local_link_connection': 'Local Link Connection',
'pxe_enabled': 'PXE boot enabled',
'portgroup_uuid': 'Portgroup UUID',
@@ -347,6 +349,8 @@ PORT_DETAILED_RESOURCE = Resource(
'created_at',
'extra',
'node_uuid',
'category',
'vendor',
'local_link_connection',
'portgroup_uuid',
'pxe_enabled',

View File

@@ -0,0 +1,6 @@
---
features:
- |
Adds ``vendor`` field and ``category`` field support, which is introduced
in ironic API 1.100 and 1.101 respectively. These field is used to store
informational text about the port for trait based scheduling.