De-client-ify many baremetal calls
Update calls for numerous baremetal methods to utilize the _baremetal_client calls instead of python-ironicclient. Also corrected a minor baremetal port test and fixed the base noauth test endpoint override as python-ironicclient was previously injecting that for us. Change-Id: I358a63a52067f7d48d71f0b23652491b2497fe43
This commit is contained in:
parent
e70e5a586f
commit
f9465f5abe
@ -27,26 +27,6 @@ class MachinePortGetByAddress(task_manager.Task):
|
|||||||
return client.ironic_client.port.get_by_address(**self.args)
|
return client.ironic_client.port.get_by_address(**self.args)
|
||||||
|
|
||||||
|
|
||||||
class MachinePortCreate(task_manager.Task):
|
|
||||||
def main(self, client):
|
|
||||||
return client.ironic_client.port.create(**self.args)
|
|
||||||
|
|
||||||
|
|
||||||
class MachinePortDelete(task_manager.Task):
|
|
||||||
def main(self, client):
|
|
||||||
return client.ironic_client.port.delete(**self.args)
|
|
||||||
|
|
||||||
|
|
||||||
class MachineNodeList(task_manager.Task):
|
|
||||||
def main(self, client):
|
|
||||||
return client.ironic_client.node.list(**self.args)
|
|
||||||
|
|
||||||
|
|
||||||
class MachineNodePortList(task_manager.Task):
|
|
||||||
def main(self, client):
|
|
||||||
return client.ironic_client.node.list_ports(**self.args)
|
|
||||||
|
|
||||||
|
|
||||||
class MachineNodeUpdate(task_manager.Task):
|
class MachineNodeUpdate(task_manager.Task):
|
||||||
def main(self, client):
|
def main(self, client):
|
||||||
return client.ironic_client.node.update(**self.args)
|
return client.ironic_client.node.update(**self.args)
|
||||||
@ -55,13 +35,3 @@ class MachineNodeUpdate(task_manager.Task):
|
|||||||
class MachineNodeValidate(task_manager.Task):
|
class MachineNodeValidate(task_manager.Task):
|
||||||
def main(self, client):
|
def main(self, client):
|
||||||
return client.ironic_client.node.validate(**self.args)
|
return client.ironic_client.node.validate(**self.args)
|
||||||
|
|
||||||
|
|
||||||
class MachineSetMaintenance(task_manager.Task):
|
|
||||||
def main(self, client):
|
|
||||||
return client.ironic_client.node.set_maintenance(**self.args)
|
|
||||||
|
|
||||||
|
|
||||||
class MachineSetPower(task_manager.Task):
|
|
||||||
def main(self, client):
|
|
||||||
return client.ironic_client.node.set_power_state(**self.args)
|
|
||||||
|
@ -39,14 +39,22 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
|
|||||||
error_message=msg)
|
error_message=msg)
|
||||||
|
|
||||||
def list_nics_for_machine(self, uuid):
|
def list_nics_for_machine(self, uuid):
|
||||||
with _utils.shade_exceptions(
|
"""Returns a list of ports present on the machine node.
|
||||||
"Error fetching port list for node {node_id}".format(
|
|
||||||
node_id=uuid)):
|
:param uuid: String representing machine UUID value in
|
||||||
return self._normalize_machines(
|
order to identify the machine.
|
||||||
self.manager.submit_task(
|
:returns: A dictionary containing containing a list of ports,
|
||||||
_tasks.MachineNodePortList(node_id=uuid)))
|
associated with the label "ports".
|
||||||
|
"""
|
||||||
|
msg = "Error fetching port list for node {node_id}".format(
|
||||||
|
node_id=uuid)
|
||||||
|
url = "/nodes/{node_id}/ports".format(node_id=uuid)
|
||||||
|
return self._baremetal_client.get(url,
|
||||||
|
microversion="1.6",
|
||||||
|
error_message=msg)
|
||||||
|
|
||||||
def get_nic_by_mac(self, mac):
|
def get_nic_by_mac(self, mac):
|
||||||
|
# TODO(TheJulia): Query /ports?address=mac when converting
|
||||||
try:
|
try:
|
||||||
return self.manager.submit_task(
|
return self.manager.submit_task(
|
||||||
_tasks.MachineNodePortGet(port_id=mac))
|
_tasks.MachineNodePortGet(port_id=mac))
|
||||||
@ -54,8 +62,11 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def list_machines(self):
|
def list_machines(self):
|
||||||
return self._normalize_machines(
|
msg = "Error fetching machine node list"
|
||||||
self.manager.submit_task(_tasks.MachineNodeList()))
|
data = self._baremetal_client.get("/nodes",
|
||||||
|
microversion="1.6",
|
||||||
|
error_message=msg)
|
||||||
|
return self._get_and_munchify('nodes', data)
|
||||||
|
|
||||||
def get_machine(self, name_or_id):
|
def get_machine(self, name_or_id):
|
||||||
"""Get Machine by name or uuid
|
"""Get Machine by name or uuid
|
||||||
@ -92,10 +103,12 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
|
|||||||
if the node is not found.
|
if the node is not found.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
port = self.manager.submit_task(
|
port_url = '/ports/detail?address={mac}'.format(mac=mac)
|
||||||
_tasks.MachinePortGetByAddress(address=mac))
|
port = self._baremetal_client.get(port_url, microversion=1.6)
|
||||||
return self.get_machine(port.node_uuid)
|
machine_url = '/nodes/{machine}'.format(
|
||||||
except ironic_exceptions.ClientException:
|
machine=port['ports'][0]['node_uuid'])
|
||||||
|
return self._baremetal_client.get(machine_url, microversion=1.6)
|
||||||
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def inspect_machine(self, name_or_id, wait=False, timeout=3600):
|
def inspect_machine(self, name_or_id, wait=False, timeout=3600):
|
||||||
@ -209,7 +222,8 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
|
|||||||
baremetal node.
|
baremetal node.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
msg = ("Baremetal machine node failed failed to be created.")
|
msg = ("Baremetal machine node failed to be created.")
|
||||||
|
port_msg = ("Baremetal machine port failed to be created.")
|
||||||
|
|
||||||
url = '/nodes'
|
url = '/nodes'
|
||||||
# TODO(TheJulia): At some point we need to figure out how to
|
# TODO(TheJulia): At some point we need to figure out how to
|
||||||
@ -223,9 +237,11 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
|
|||||||
created_nics = []
|
created_nics = []
|
||||||
try:
|
try:
|
||||||
for row in nics:
|
for row in nics:
|
||||||
nic = self.manager.submit_task(
|
payload = {'address': row['mac'],
|
||||||
_tasks.MachinePortCreate(address=row['mac'],
|
'node_uuid': machine['uuid']}
|
||||||
node_uuid=machine['uuid']))
|
nic = self._baremetal_client.post('/ports',
|
||||||
|
json=payload,
|
||||||
|
error_message=port_msg)
|
||||||
created_nics.append(nic['uuid'])
|
created_nics.append(nic['uuid'])
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -234,9 +250,13 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
|
|||||||
try:
|
try:
|
||||||
for uuid in created_nics:
|
for uuid in created_nics:
|
||||||
try:
|
try:
|
||||||
self.manager.submit_task(
|
port_url = '/ports/{uuid}'.format(uuid=uuid)
|
||||||
_tasks.MachinePortDelete(
|
# NOTE(TheJulia): Added in hope that it is logged.
|
||||||
port_id=uuid))
|
port_msg = ('Failed to delete port {port} for node'
|
||||||
|
'{node}').format(port=uuid,
|
||||||
|
node=machine['uuid'])
|
||||||
|
self._baremetal_client.delete(port_url,
|
||||||
|
error_message=port_msg)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
@ -347,14 +367,27 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
|
|||||||
"Error unregistering node '%s' due to current provision "
|
"Error unregistering node '%s' due to current provision "
|
||||||
"state '%s'" % (uuid, machine['provision_state']))
|
"state '%s'" % (uuid, machine['provision_state']))
|
||||||
|
|
||||||
|
# NOTE(TheJulia) There is a high possibility of a lock being present
|
||||||
|
# if the machine was just moved through the state machine. This was
|
||||||
|
# previously concealed by exception retry logic that detected the
|
||||||
|
# failure, and resubitted the request in python-ironicclient.
|
||||||
|
try:
|
||||||
|
self.wait_for_baremetal_node_lock(machine, timeout=timeout)
|
||||||
|
except OpenStackCloudException as e:
|
||||||
|
raise OpenStackCloudException("Error unregistering node '%s': "
|
||||||
|
"Exception occured while waiting "
|
||||||
|
"to be able to proceed: %s"
|
||||||
|
% (machine['uuid'], e))
|
||||||
|
|
||||||
for nic in nics:
|
for nic in nics:
|
||||||
with _utils.shade_exceptions(
|
port_msg = ("Error removing NIC {nic} from baremetal API for "
|
||||||
"Error removing NIC {nic} from baremetal API for node "
|
"node {uuid}").format(nic=nic, uuid=uuid)
|
||||||
"{uuid}".format(nic=nic, uuid=uuid)):
|
port_url = '/ports/detail?address={mac}'.format(mac=nic['mac'])
|
||||||
port = self.manager.submit_task(
|
port = self._baremetal_client.get(port_url, microversion=1.6,
|
||||||
_tasks.MachinePortGetByAddress(address=nic['mac']))
|
error_message=port_msg)
|
||||||
self.manager.submit_task(
|
port_url = '/ports/{uuid}'.format(uuid=port['ports'][0]['uuid'])
|
||||||
_tasks.MachinePortDelete(port_id=port.uuid))
|
self._baremetal_client.delete(port_url, error_message=port_msg)
|
||||||
|
|
||||||
with _utils.shade_exceptions(
|
with _utils.shade_exceptions(
|
||||||
"Error unregistering machine {node_id} from the baremetal "
|
"Error unregistering machine {node_id} from the baremetal "
|
||||||
"API".format(node_id=uuid)):
|
"API".format(node_id=uuid)):
|
||||||
@ -639,25 +672,17 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
|
|||||||
|
|
||||||
:returns: None
|
:returns: None
|
||||||
"""
|
"""
|
||||||
with _utils.shade_exceptions(
|
msg = ("Error setting machine maintenance state to {state} on node "
|
||||||
"Error setting machine maintenance state to {state} on node "
|
"{node}").format(state=state, node=name_or_id)
|
||||||
"{node}".format(state=state, node=name_or_id)
|
url = '/nodes/{name_or_id}/maintenance'.format(name_or_id=name_or_id)
|
||||||
):
|
if state:
|
||||||
if state:
|
payload = {'reason': reason}
|
||||||
result = self.manager.submit_task(
|
self._baremetal_client.put(url,
|
||||||
_tasks.MachineSetMaintenance(node_id=name_or_id,
|
json=payload,
|
||||||
state='true',
|
error_message=msg)
|
||||||
maint_reason=reason))
|
else:
|
||||||
else:
|
self._baremetal_client.delete(url, error_message=msg)
|
||||||
result = self.manager.submit_task(
|
return None
|
||||||
_tasks.MachineSetMaintenance(node_id=name_or_id,
|
|
||||||
state='false'))
|
|
||||||
if result is not None:
|
|
||||||
raise OpenStackCloudException(
|
|
||||||
"Failed setting machine maintenance state to %s "
|
|
||||||
"on node %s. Received: %s" % (
|
|
||||||
state, name_or_id, result))
|
|
||||||
return None
|
|
||||||
|
|
||||||
def remove_machine_from_maintenance(self, name_or_id):
|
def remove_machine_from_maintenance(self, name_or_id):
|
||||||
"""Remove Baremetal Machine from Maintenance State
|
"""Remove Baremetal Machine from Maintenance State
|
||||||
@ -694,18 +719,19 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
|
|||||||
|
|
||||||
:returns: None
|
:returns: None
|
||||||
"""
|
"""
|
||||||
with _utils.shade_exceptions(
|
msg = ("Error setting machine power state to {state} on node "
|
||||||
"Error setting machine power state to {state} on node "
|
"{node}").format(state=state, node=name_or_id)
|
||||||
"{node}".format(state=state, node=name_or_id)
|
url = '/nodes/{name_or_id}/states/power'.format(name_or_id=name_or_id)
|
||||||
):
|
if 'reboot' in state:
|
||||||
power = self.manager.submit_task(
|
desired_state = 'rebooting'
|
||||||
_tasks.MachineSetPower(node_id=name_or_id,
|
else:
|
||||||
state=state))
|
desired_state = 'power {state}'.format(state=state)
|
||||||
if power is not None:
|
payload = {'target': desired_state}
|
||||||
raise OpenStackCloudException(
|
self._baremetal_client.put(url,
|
||||||
"Failed setting machine power state %s on node %s. "
|
json=payload,
|
||||||
"Received: %s" % (state, name_or_id, power))
|
error_message=msg,
|
||||||
return None
|
microversion="1.6")
|
||||||
|
return None
|
||||||
|
|
||||||
def set_machine_power_on(self, name_or_id):
|
def set_machine_power_on(self, name_or_id):
|
||||||
"""Activate baremetal machine power
|
"""Activate baremetal machine power
|
||||||
|
@ -22,7 +22,6 @@ import time
|
|||||||
import types
|
import types
|
||||||
|
|
||||||
import keystoneauth1.exceptions
|
import keystoneauth1.exceptions
|
||||||
import simplejson
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from shade import _log
|
from shade import _log
|
||||||
@ -162,7 +161,7 @@ class RequestTask(BaseTask):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
result_json = self._response.json()
|
result_json = self._response.json()
|
||||||
except (simplejson.scanner.JSONDecodeError, ValueError) as e:
|
except Exception as e:
|
||||||
result_json = self._response.text
|
result_json = self._response.text
|
||||||
self._client.log.debug(
|
self._client.log.debug(
|
||||||
'Could not decode json in response: %(e)s', {'e': str(e)})
|
'Could not decode json in response: %(e)s', {'e': str(e)})
|
||||||
|
@ -1384,6 +1384,33 @@ class TestBaremetalNode(base.IronicTestCase):
|
|||||||
|
|
||||||
self.assert_calls()
|
self.assert_calls()
|
||||||
|
|
||||||
|
def test_unregister_machine_locked_timeout(self):
|
||||||
|
mac_address = self.fake_baremetal_port['address']
|
||||||
|
nics = [{'mac': mac_address}]
|
||||||
|
self.fake_baremetal_node['provision_state'] = 'available'
|
||||||
|
self.fake_baremetal_node['reservation'] = 'conductor99'
|
||||||
|
self.register_uris([
|
||||||
|
dict(
|
||||||
|
method='GET',
|
||||||
|
uri=self.get_mock_url(
|
||||||
|
resource='nodes',
|
||||||
|
append=[self.fake_baremetal_node['uuid']]),
|
||||||
|
json=self.fake_baremetal_node),
|
||||||
|
dict(
|
||||||
|
method='GET',
|
||||||
|
uri=self.get_mock_url(
|
||||||
|
resource='nodes',
|
||||||
|
append=[self.fake_baremetal_node['uuid']]),
|
||||||
|
json=self.fake_baremetal_node),
|
||||||
|
])
|
||||||
|
self.assertRaises(
|
||||||
|
exc.OpenStackCloudException,
|
||||||
|
self.op_cloud.unregister_machine,
|
||||||
|
nics,
|
||||||
|
self.fake_baremetal_node['uuid'],
|
||||||
|
timeout=0.001)
|
||||||
|
self.assert_calls()
|
||||||
|
|
||||||
def test_unregister_machine_unavailable(self):
|
def test_unregister_machine_unavailable(self):
|
||||||
# This is a list of invalid states that the method
|
# This is a list of invalid states that the method
|
||||||
# should fail on.
|
# should fail on.
|
||||||
|
@ -64,8 +64,6 @@ class TestBaremetalPort(base.IronicTestCase):
|
|||||||
self.assert_calls()
|
self.assert_calls()
|
||||||
|
|
||||||
def test_list_nics_for_machine(self):
|
def test_list_nics_for_machine(self):
|
||||||
port_list = [self.fake_baremetal_port,
|
|
||||||
self.fake_baremetal_port2]
|
|
||||||
self.register_uris([
|
self.register_uris([
|
||||||
dict(method='GET',
|
dict(method='GET',
|
||||||
uri=self.get_mock_url(
|
uri=self.get_mock_url(
|
||||||
@ -77,8 +75,8 @@ class TestBaremetalPort(base.IronicTestCase):
|
|||||||
|
|
||||||
return_value = self.op_cloud.list_nics_for_machine(
|
return_value = self.op_cloud.list_nics_for_machine(
|
||||||
self.fake_baremetal_node['uuid'])
|
self.fake_baremetal_node['uuid'])
|
||||||
expected_value = port_list
|
self.assertEqual(2, len(return_value['ports']))
|
||||||
self.assertEqual(expected_value, return_value)
|
self.assertEqual(self.fake_baremetal_port, return_value['ports'][0])
|
||||||
self.assert_calls()
|
self.assert_calls()
|
||||||
|
|
||||||
def test_list_nics_for_machine_failure(self):
|
def test_list_nics_for_machine_failure(self):
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from keystoneauth1 import plugin
|
|
||||||
|
|
||||||
import shade
|
import shade
|
||||||
from shade.tests.unit import base
|
from shade.tests.unit import base
|
||||||
|
|
||||||
@ -34,9 +32,6 @@ class TestShadeOperatorNoAuth(base.RequestsMockTestCase):
|
|||||||
# By clearing the URI registry, we remove all calls to a keystone
|
# By clearing the URI registry, we remove all calls to a keystone
|
||||||
# catalog or getting a token
|
# catalog or getting a token
|
||||||
self._uri_registry.clear()
|
self._uri_registry.clear()
|
||||||
# TODO(mordred) Remove this if with next KSA release
|
|
||||||
if hasattr(plugin.BaseAuthPlugin, 'get_endpoint_data'):
|
|
||||||
self.use_ironic()
|
|
||||||
self.register_uris([
|
self.register_uris([
|
||||||
dict(method='GET',
|
dict(method='GET',
|
||||||
uri=self.get_mock_url(
|
uri=self.get_mock_url(
|
||||||
@ -50,9 +45,14 @@ class TestShadeOperatorNoAuth(base.RequestsMockTestCase):
|
|||||||
|
|
||||||
The new way of doing this is with the keystoneauth none plugin.
|
The new way of doing this is with the keystoneauth none plugin.
|
||||||
"""
|
"""
|
||||||
|
# NOTE(TheJulia): When we are using the python-ironicclient
|
||||||
|
# library, the library will automatically prepend the URI path
|
||||||
|
# with 'v1'. As such, since we are overriding the endpoint,
|
||||||
|
# we must explicitly do the same as we move away from the
|
||||||
|
# client library.
|
||||||
self.cloud_noauth = shade.operator_cloud(
|
self.cloud_noauth = shade.operator_cloud(
|
||||||
auth_type='none',
|
auth_type='none',
|
||||||
baremetal_endpoint_override="https://bare-metal.example.com")
|
baremetal_endpoint_override="https://bare-metal.example.com/v1")
|
||||||
|
|
||||||
self.cloud_noauth.list_machines()
|
self.cloud_noauth.list_machines()
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ class TestShadeOperatorNoAuth(base.RequestsMockTestCase):
|
|||||||
self.cloud_noauth = shade.operator_cloud(
|
self.cloud_noauth = shade.operator_cloud(
|
||||||
auth_type='admin_token',
|
auth_type='admin_token',
|
||||||
auth=dict(
|
auth=dict(
|
||||||
endpoint='https://bare-metal.example.com',
|
endpoint='https://bare-metal.example.com/v1',
|
||||||
token='ignored'))
|
token='ignored'))
|
||||||
|
|
||||||
self.cloud_noauth.list_machines()
|
self.cloud_noauth.list_machines()
|
||||||
|
Loading…
Reference in New Issue
Block a user