Browse Source

Updates supporting ironic-neutron integration

This patchset adds port creation with new optional parameters specifying
new port attributes (local_link_connection, pxe_enabled).
It also adds new parameter network_interface to node object.

Co-Authored-By: Vasyl Saienko (vsaienko@mirantis.com)
Co-Authored-By: William Stevenson (will.stevenson@sap.com)

Partial-bug: #1526403
Depends-on: I67495196c3334f51ed034f4ca6e32a3e01a58f15

Change-Id: If2fb996783b9ac26a5bae2aadd6387207750def9
changes/44/206144/35
Vasyl Saienko 5 years ago
committed by Jim Rollenhagen
parent
commit
d1ea9b44f6
14 changed files with 118 additions and 10 deletions
  1. +1
    -1
      ironicclient/osc/plugin.py
  2. +17
    -1
      ironicclient/osc/v1/baremetal_node.py
  3. +15
    -1
      ironicclient/osc/v1/baremetal_port.py
  4. +27
    -1
      ironicclient/tests/unit/osc/v1/test_baremetal_node.py
  5. +0
    -1
      ironicclient/tests/unit/v1/test_node.py
  6. +1
    -0
      ironicclient/tests/unit/v1/test_node_shell.py
  7. +10
    -0
      ironicclient/tests/unit/v1/test_port.py
  8. +1
    -1
      ironicclient/tests/unit/v1/test_port_shell.py
  9. +2
    -1
      ironicclient/v1/node.py
  10. +7
    -1
      ironicclient/v1/node_shell.py
  11. +2
    -1
      ironicclient/v1/port.py
  12. +15
    -1
      ironicclient/v1/port_shell.py
  13. +6
    -0
      ironicclient/v1/resource_fields.py
  14. +14
    -0
      releasenotes/notes/add-neutron-integration-fields-cee7596c49722de6.yaml

+ 1
- 1
ironicclient/osc/plugin.py View File

@ -23,7 +23,7 @@ LOG = logging.getLogger(__name__)
DEFAULT_BAREMETAL_API_VERSION = '1.6'
API_VERSION_OPTION = 'os_baremetal_api_version'
API_NAME = 'baremetal'
LAST_KNOWN_API_VERSION = 14
LAST_KNOWN_API_VERSION = 20
API_VERSIONS = {
'1.%d' % i: 'ironicclient.v1.client.Client'
for i in range(1, LAST_KNOWN_API_VERSION + 1)


+ 17
- 1
ironicclient/osc/v1/baremetal_node.py View File

@ -151,6 +151,11 @@ class CreateBaremetalNode(show.ShowOne):
'--name',
metavar='<name>',
help="Unique name for the node.")
parser.add_argument(
'--network-interface',
metavar='<network_interface>',
help='Network interface used for switching node to '
'cleaning/provisioning networks.')
return parser
@ -160,7 +165,8 @@ class CreateBaremetalNode(show.ShowOne):
baremetal_client = self.app.client_manager.baremetal
field_list = ['chassis_uuid', 'driver', 'driver_info',
'properties', 'extra', 'uuid', 'name']
'properties', 'extra', 'uuid', 'name',
'network_interface']
fields = dict((k, v) for (k, v) in vars(parsed_args).items()
if k in field_list and not (v is None))
fields = utils.args_array_to_dict(fields, 'driver_info')
@ -554,6 +560,11 @@ class SetBaremetalNode(command.Command):
metavar="<driver>",
help="Set the driver for the node",
)
parser.add_argument(
'--network-interface',
metavar='<network_interface>',
help='Set the network interface for the node',
)
parser.add_argument(
"--property",
metavar="<key=value>",
@ -603,6 +614,11 @@ class SetBaremetalNode(command.Command):
driver = ["driver=%s" % parsed_args.driver]
properties.extend(utils.args_array_to_patch(
'add', driver))
if parsed_args.network_interface:
network_interface = [
"network_interface=%s" % parsed_args.network_interface]
properties.extend(utils.args_array_to_patch(
'add', network_interface))
if parsed_args.property:
properties.extend(utils.args_array_to_patch(
'add', ['properties/' + x for x in parsed_args.property]))


+ 15
- 1
ironicclient/osc/v1/baremetal_port.py View File

@ -46,6 +46,18 @@ class CreateBaremetalPort(show.ShowOne):
action='append',
help="Record arbitrary key/value metadata. "
"Can be specified multiple times.")
parser.add_argument(
'-l', '--local-link-connection',
metavar="<key=value>",
action='append',
help="Key/value metadata describing Local link connection "
"information. Valid keys are switch_info, switch_id, "
"port_id. Can be specified multiple times.")
parser.add_argument(
'--pxe-enabled',
metavar='<boolean>',
help='Indicates whether this Port should be used when '
'PXE booting this Node.')
return parser
@ -53,10 +65,12 @@ class CreateBaremetalPort(show.ShowOne):
self.log.debug("take_action(%s)" % parsed_args)
baremetal_client = self.app.client_manager.baremetal
field_list = ['address', 'extra', 'node_uuid']
field_list = ['address', 'extra', 'node_uuid', 'pxe_enabled',
'local_link_connection']
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')
fields = utils.args_array_to_dict(fields, 'local_link_connection')
port = baremetal_client.port.create(**fields)
data = dict([(f, getattr(port, f, '')) for f in


+ 27
- 1
ironicclient/tests/unit/osc/v1/test_baremetal_node.py View File

@ -162,6 +162,11 @@ class TestBaremetalCreate(TestBaremetal):
[('name', 'name')],
{'name': 'name'})
def test_baremetal_create_with_network_interface(self):
self.check_with_options(['--network-interface', 'neutron'],
[('network_interface', 'neutron')],
{'network_interface': 'neutron'})
class TestBaremetalDelete(TestBaremetal):
def setUp(self):
@ -315,7 +320,8 @@ class TestBaremetalList(TestBaremetal):
'Target Power State', 'Target Provision State',
'Target RAID configuration',
'Updated At', 'Inspection Finished At',
'Inspection Started At', 'UUID', 'Name')
'Inspection Started At', 'UUID', 'Name',
'Network Interface')
self.assertEqual(collist, columns)
datalist = ((
'',
@ -345,6 +351,7 @@ class TestBaremetalList(TestBaremetal):
'',
baremetal_fakes.baremetal_uuid,
baremetal_fakes.baremetal_name,
'',
), )
self.assertEqual(datalist, tuple(data))
@ -801,6 +808,25 @@ class TestBaremetalSet(TestBaremetal):
[{'path': '/driver', 'value': 'xxxxx', 'op': 'add'}]
)
def test_baremetal_set_network_interface(self):
arglist = [
'node_uuid',
'--network-interface', 'xxxxx',
]
verifylist = [
('node', 'node_uuid'),
('network_interface', 'xxxxx')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.node.update.assert_called_once_with(
'node_uuid',
[{'path': '/network_interface', 'value': 'xxxxx', 'op': 'add'}]
)
def test_baremetal_set_extra(self):
arglist = [
'node_uuid',


+ 0
- 1
ironicclient/tests/unit/v1/test_node.py View File

@ -53,7 +53,6 @@ PORT = {'id': 456,
'node_id': 123,
'address': 'AA:AA:AA:AA:AA:AA',
'extra': {}}
POWER_STATE = {'power_state': 'power off',
'target_power_state': 'power on'}


+ 1
- 0
ironicclient/tests/unit/v1/test_node_shell.py View File

@ -46,6 +46,7 @@ class NodeShellTest(utils.BaseTestCase):
'maintenance',
'maintenance_reason',
'name',
'network_interface',
'power_state',
'properties',
'provision_state',


+ 10
- 0
ironicclient/tests/unit/v1/test_port.py View File

@ -26,12 +26,16 @@ PORT = {'id': 987,
'uuid': '11111111-2222-3333-4444-555555555555',
'node_uuid': '55555555-4444-3333-2222-111111111111',
'address': 'AA:BB:CC:DD:EE:FF',
'pxe_enabled': True,
'local_link_connection': {},
'extra': {}}
PORT2 = {'id': 988,
'uuid': '55555555-4444-3333-2222-111111111111',
'node_uuid': '55555555-4444-3333-2222-111111111111',
'address': 'AA:AA:AA:BB:BB:BB',
'pxe_enabled': True,
'local_link_connection': {},
'extra': {}}
CREATE_PORT = copy.deepcopy(PORT)
@ -263,6 +267,9 @@ class PortManagerTest(testtools.TestCase):
self.assertEqual(PORT['uuid'], port.uuid)
self.assertEqual(PORT['address'], port.address)
self.assertEqual(PORT['node_uuid'], port.node_uuid)
self.assertEqual(PORT['pxe_enabled'], port.pxe_enabled)
self.assertEqual(PORT['local_link_connection'],
port.local_link_connection)
def test_ports_show_by_address(self):
port = self.mgr.get_by_address(PORT['address'])
@ -274,6 +281,9 @@ class PortManagerTest(testtools.TestCase):
self.assertEqual(PORT['uuid'], port.uuid)
self.assertEqual(PORT['address'], port.address)
self.assertEqual(PORT['node_uuid'], port.node_uuid)
self.assertEqual(PORT['pxe_enabled'], port.pxe_enabled)
self.assertEqual(PORT['local_link_connection'],
port.local_link_connection)
def test_port_show_fields(self):
port = self.mgr.get(PORT['uuid'], fields=['uuid', 'address'])


+ 1
- 1
ironicclient/tests/unit/v1/test_port_shell.py View File

@ -32,7 +32,7 @@ class PortShellTest(utils.BaseTestCase):
port = object()
p_shell._print_port_show(port)
exp = ['address', 'created_at', 'extra', 'node_uuid', 'updated_at',
'uuid']
'uuid', 'pxe_enabled', 'local_link_connection']
act = actual.keys()
self.assertEqual(sorted(exp), sorted(act))


+ 2
- 1
ironicclient/v1/node.py View File

@ -37,7 +37,8 @@ class Node(base.Resource):
class NodeManager(base.CreateManager):
resource_class = Node
_creation_attributes = ['chassis_uuid', 'driver', 'driver_info',
'extra', 'uuid', 'properties', 'name']
'extra', 'uuid', 'properties', 'name',
'network_interface']
_resource_name = 'nodes'
def list(self, associated=None, maintenance=None, marker=None, limit=None,


+ 7
- 1
ironicclient/v1/node_shell.py View File

@ -202,10 +202,16 @@ def do_node_list(cc, args):
'-n', '--name',
metavar='<name>',
help="Unique name for the node.")
@cliutils.arg(
'--network-interface',
metavar='<network_interface>',
help='Network interface used for switching node to cleaning/provisioning '
'networks.')
def do_node_create(cc, args):
"""Register a new node with the Ironic service."""
field_list = ['chassis_uuid', 'driver', 'driver_info',
'properties', 'extra', 'uuid', 'name']
'properties', 'extra', 'uuid', 'name',
'network_interface']
fields = dict((k, v) for (k, v) in vars(args).items()
if k in field_list and not (v is None))
fields = utils.args_array_to_dict(fields, 'driver_info')


+ 2
- 1
ironicclient/v1/port.py View File

@ -27,7 +27,8 @@ class Port(base.Resource):
class PortManager(base.CreateManager):
resource_class = Port
_creation_attributes = ['address', 'extra', 'node_uuid', 'uuid']
_creation_attributes = ['address', 'extra', 'local_link_connection',
'node_uuid', 'pxe_enabled', 'uuid']
_resource_name = 'ports'
def list(self, address=None, limit=None, marker=None, sort_key=None,


+ 15
- 1
ironicclient/v1/port_shell.py View File

@ -143,6 +143,18 @@ def do_port_list(cc, args):
metavar='<node>',
required=True,
help='UUID of the node that this port belongs to.')
@cliutils.arg(
'-l', '--local-link-connection',
metavar="<key=value>",
action='append',
help="Key/value metadata describing Local link connection information. "
"Valid keys are switch_info, switch_id, port_id."
"Can be specified multiple times.")
@cliutils.arg(
'--pxe-enabled',
metavar='<boolean>',
help='Indicates whether this Port should be used when '
'PXE booting this Node.')
@cliutils.arg(
'-e', '--extra',
metavar="<key=value>",
@ -155,10 +167,12 @@ def do_port_list(cc, args):
help="UUID of the port.")
def do_port_create(cc, args):
"""Create a new port."""
field_list = ['address', 'extra', 'node_uuid', 'uuid']
field_list = ['address', 'extra', 'node_uuid', 'uuid',
'local_link_connection', 'pxe_enabled']
fields = dict((k, v) for (k, v) in vars(args).items()
if k in field_list and not (v is None))
fields = utils.args_array_to_dict(fields, 'extra')
fields = utils.args_array_to_dict(fields, 'local_link_connection')
port = cc.port.create(**fields)
data = dict([(f, getattr(port, f, '')) for f in field_list])


+ 6
- 0
ironicclient/v1/resource_fields.py View File

@ -64,6 +64,9 @@ class Resource(object):
'target_raid_config': 'Target RAID configuration',
'updated_at': 'Updated At',
'uuid': 'UUID',
'local_link_connection': 'Local Link Connection',
'pxe_enabled': 'PXE boot enabled',
'network_interface': 'Network Interface',
}
def __init__(self, field_ids, sort_excluded=None):
@ -151,6 +154,7 @@ NODE_DETAILED_RESOURCE = Resource(
'inspection_started_at',
'uuid',
'name',
'network_interface',
],
sort_excluded=[
# The server cannot sort on "chassis_uuid" because it isn't a column in
@ -189,6 +193,8 @@ PORT_DETAILED_RESOURCE = Resource(
'created_at',
'extra',
'node_uuid',
'local_link_connection',
'pxe_enabled',
'updated_at',
],
sort_excluded=[


+ 14
- 0
releasenotes/notes/add-neutron-integration-fields-cee7596c49722de6.yaml View File

@ -0,0 +1,14 @@
---
features:
- |
Add support of new fields:
* ``node.network_interface`` is introduced in API 1.20,
specifies the network interface to use for a node.
* ``port.local_link_connection`` contains the port binding
profile.
* ``port.pxe_enabled`` indicates whether PXE is enabled
for the port.
The ``port.local_link_connection`` and ``port.pxe_enabled`` fields
were introduced in API 1.19.

Loading…
Cancel
Save