Add support for reset_interfaces in node's PATCH
Change-Id: I52ee891d6549827d9a055f23d475fe42f422c4d2 Depends-On: https://review.openstack.org/582951 Story: #2002868 Task: #22822
This commit is contained in:
parent
d401c94848
commit
7c77aba2b9
@ -209,7 +209,7 @@ class Manager(object):
|
||||
return self.__list(url, response_key=response_key)
|
||||
|
||||
def _update(self, resource_id, patch, method='PATCH',
|
||||
os_ironic_api_version=None):
|
||||
os_ironic_api_version=None, params=None):
|
||||
"""Update a resource.
|
||||
|
||||
:param resource_id: Resource identifier.
|
||||
@ -217,6 +217,7 @@ class Manager(object):
|
||||
:param method: Name of the method for the request.
|
||||
:param os_ironic_api_version: String version (e.g. "1.35") to use for
|
||||
the request. If not specified, the client's default is used.
|
||||
:param params: query parameters to pass.
|
||||
"""
|
||||
|
||||
url = self._path(resource_id)
|
||||
@ -226,6 +227,8 @@ class Manager(object):
|
||||
if os_ironic_api_version is not None:
|
||||
kwargs['headers'] = {'X-OpenStack-Ironic-API-Version':
|
||||
os_ironic_api_version}
|
||||
if params:
|
||||
kwargs['params'] = params
|
||||
resp, body = self.api.json_request(method, url, **kwargs)
|
||||
# PATCH/PUT requests may not return a body
|
||||
if body:
|
||||
|
@ -43,7 +43,7 @@ from ironicclient import exc
|
||||
# http://specs.openstack.org/openstack/ironic-specs/specs/kilo/api-microversions.html # noqa
|
||||
# for full details.
|
||||
DEFAULT_VER = '1.9'
|
||||
LAST_KNOWN_API_VERSION = 44
|
||||
LAST_KNOWN_API_VERSION = 45
|
||||
LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -1085,6 +1085,12 @@ class SetBaremetalNode(command.Command):
|
||||
reset_help=_('Reset the vendor interface to its hardware type '
|
||||
'default'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--reset-interfaces',
|
||||
action='store_true', default=None,
|
||||
help=_('Reset all interfaces not specified explicitly to their '
|
||||
'default implementations. Only valid with --driver.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--resource-class',
|
||||
metavar='<resource_class>',
|
||||
@ -1162,6 +1168,9 @@ class SetBaremetalNode(command.Command):
|
||||
driver = ["driver=%s" % parsed_args.driver]
|
||||
properties.extend(utils.args_array_to_patch(
|
||||
'add', driver))
|
||||
if parsed_args.reset_interfaces and not parsed_args.driver:
|
||||
raise exc.CommandError(
|
||||
_("--reset-interfaces can only be specified with --driver"))
|
||||
|
||||
for iface in SUPPORTED_INTERFACES:
|
||||
field = '%s_interface' % iface
|
||||
@ -1193,7 +1202,9 @@ class SetBaremetalNode(command.Command):
|
||||
'add', ['instance_info/' + x for x
|
||||
in parsed_args.instance_info]))
|
||||
if properties:
|
||||
baremetal_client.node.update(parsed_args.node, properties)
|
||||
baremetal_client.node.update(
|
||||
parsed_args.node, properties,
|
||||
reset_interfaces=parsed_args.reset_interfaces)
|
||||
elif not parsed_args.target_raid_config:
|
||||
self.log.warning("Please specify what to set.")
|
||||
|
||||
|
@ -1920,7 +1920,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
'node_uuid',
|
||||
[{'path': '/properties/path/to/property',
|
||||
'value': 'value',
|
||||
'op': 'add'}])
|
||||
'op': 'add'}],
|
||||
reset_interfaces=None)
|
||||
|
||||
def test_baremetal_set_multiple_properties(self):
|
||||
arglist = [
|
||||
@ -1948,7 +1949,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
'op': 'add'},
|
||||
{'path': '/properties/other/path',
|
||||
'value': 'value2',
|
||||
'op': 'add'}]
|
||||
'op': 'add'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
def test_baremetal_set_instance_uuid(self):
|
||||
@ -1967,7 +1969,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/instance_uuid', 'value': 'xxxxx', 'op': 'add'}]
|
||||
[{'path': '/instance_uuid', 'value': 'xxxxx', 'op': 'add'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
def test_baremetal_set_name(self):
|
||||
@ -1986,7 +1989,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/name', 'value': 'xxxxx', 'op': 'add'}]
|
||||
[{'path': '/name', 'value': 'xxxxx', 'op': 'add'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
def test_baremetal_set_chassis(self):
|
||||
@ -2006,7 +2010,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/chassis_uuid', 'value': chassis, 'op': 'add'}]
|
||||
[{'path': '/chassis_uuid', 'value': chassis, 'op': 'add'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
def test_baremetal_set_driver(self):
|
||||
@ -2025,9 +2030,48 @@ class TestBaremetalSet(TestBaremetal):
|
||||
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/driver', 'value': 'xxxxx', 'op': 'add'}]
|
||||
[{'path': '/driver', 'value': 'xxxxx', 'op': 'add'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
def test_baremetal_set_driver_reset_interfaces(self):
|
||||
arglist = [
|
||||
'node_uuid',
|
||||
'--driver', 'xxxxx',
|
||||
'--reset-interfaces',
|
||||
]
|
||||
verifylist = [
|
||||
('node', 'node_uuid'),
|
||||
('driver', 'xxxxx'),
|
||||
('reset_interfaces', True),
|
||||
]
|
||||
|
||||
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': '/driver', 'value': 'xxxxx', 'op': 'add'}],
|
||||
reset_interfaces=True,
|
||||
)
|
||||
|
||||
def test_reset_interfaces_without_driver(self):
|
||||
arglist = [
|
||||
'node_uuid',
|
||||
'--reset-interfaces',
|
||||
]
|
||||
verifylist = [
|
||||
('node', 'node_uuid'),
|
||||
('reset_interfaces', True),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.assertRaises(exc.CommandError,
|
||||
self.cmd.take_action, parsed_args)
|
||||
self.assertFalse(self.baremetal_mock.node.update.called)
|
||||
|
||||
def _test_baremetal_set_hardware_interface(self, interface):
|
||||
arglist = [
|
||||
'node_uuid',
|
||||
@ -2045,7 +2089,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/%s_interface' % interface,
|
||||
'value': 'xxxxx', 'op': 'add'}]
|
||||
'value': 'xxxxx', 'op': 'add'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
def test_baremetal_set_bios_interface(self):
|
||||
@ -2100,7 +2145,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/%s_interface' % interface, 'op': 'remove'}]
|
||||
[{'path': '/%s_interface' % interface, 'op': 'remove'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
def test_baremetal_reset_bios_interface(self):
|
||||
@ -2155,7 +2201,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/resource_class', 'value': 'foo', 'op': 'add'}]
|
||||
[{'path': '/resource_class', 'value': 'foo', 'op': 'add'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
def test_baremetal_set_extra(self):
|
||||
@ -2174,7 +2221,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/extra/foo', 'value': 'bar', 'op': 'add'}]
|
||||
[{'path': '/extra/foo', 'value': 'bar', 'op': 'add'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
def test_baremetal_set_driver_info(self):
|
||||
@ -2193,7 +2241,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/driver_info/foo', 'value': 'bar', 'op': 'add'}]
|
||||
[{'path': '/driver_info/foo', 'value': 'bar', 'op': 'add'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
def test_baremetal_set_instance_info(self):
|
||||
@ -2212,7 +2261,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/instance_info/foo', 'value': 'bar', 'op': 'add'}]
|
||||
[{'path': '/instance_info/foo', 'value': 'bar', 'op': 'add'}],
|
||||
reset_interfaces=None,
|
||||
)
|
||||
|
||||
@mock.patch.object(commonutils, 'get_from_stdin', autospec=True)
|
||||
@ -2264,7 +2314,8 @@ class TestBaremetalSet(TestBaremetal):
|
||||
assert_called_once_with('node_uuid', expected_target_raid_config)
|
||||
self.baremetal_mock.node.update.assert_called_once_with(
|
||||
'node_uuid',
|
||||
[{'path': '/name', 'value': 'xxxxx', 'op': 'add'}])
|
||||
[{'path': '/name', 'value': 'xxxxx', 'op': 'add'}],
|
||||
reset_interfaces=None)
|
||||
|
||||
@mock.patch.object(commonutils, 'get_from_stdin', autospec=True)
|
||||
@mock.patch.object(commonutils, 'handle_json_or_file_arg', autospec=True)
|
||||
|
@ -44,8 +44,10 @@ class FakeAPI(object):
|
||||
self.responses = responses
|
||||
self.calls = []
|
||||
|
||||
def _request(self, method, url, headers=None, body=None):
|
||||
def _request(self, method, url, headers=None, body=None, params=None):
|
||||
call = (method, url, headers or {}, body)
|
||||
if params:
|
||||
call += (params,)
|
||||
self.calls.append(call)
|
||||
return self.responses[url][method]
|
||||
|
||||
|
@ -908,6 +908,19 @@ class NodeManagerTest(testtools.TestCase):
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(NEW_DRIVER, node.driver)
|
||||
|
||||
def test_update_with_reset_interfaces(self):
|
||||
patch = {'op': 'replace',
|
||||
'value': NEW_DRIVER,
|
||||
'path': '/driver'}
|
||||
node = self.mgr.update(node_id=NODE1['uuid'], patch=patch,
|
||||
reset_interfaces=True)
|
||||
expect = [
|
||||
('PATCH', '/v1/nodes/%s' % NODE1['uuid'],
|
||||
{}, patch, {'reset_interfaces': True}),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(NEW_DRIVER, node.driver)
|
||||
|
||||
def test_update_microversion_override(self):
|
||||
patch = {'op': 'replace',
|
||||
'value': NEW_DRIVER,
|
||||
|
@ -343,10 +343,14 @@ class NodeManager(base.CreateManager):
|
||||
return self._delete(resource_id=node_id)
|
||||
|
||||
def update(self, node_id, patch, http_method='PATCH',
|
||||
os_ironic_api_version=None):
|
||||
os_ironic_api_version=None, reset_interfaces=None):
|
||||
params = {}
|
||||
if reset_interfaces is not None:
|
||||
params['reset_interfaces'] = reset_interfaces
|
||||
return self._update(resource_id=node_id, patch=patch,
|
||||
method=http_method,
|
||||
os_ironic_api_version=os_ironic_api_version)
|
||||
os_ironic_api_version=os_ironic_api_version,
|
||||
params=params)
|
||||
|
||||
def vendor_passthru(self, node_id, method, args=None,
|
||||
http_method=None):
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds the new argument ``--reset-interfaces`` to the
|
||||
``openstack baremetal node set`` command. It can be used together with
|
||||
``--driver`` to reset all interfaces to their defaults.
|
Loading…
Reference in New Issue
Block a user