diff --git a/doc/source/user/resources/baremetal/index.rst b/doc/source/user/resources/baremetal/index.rst index 1b284f304..1fabe14b2 100644 --- a/doc/source/user/resources/baremetal/index.rst +++ b/doc/source/user/resources/baremetal/index.rst @@ -13,3 +13,4 @@ Baremetal Resources v1/volume_connector v1/volume_target v1/deploy_templates + v1/conductor diff --git a/doc/source/user/resources/baremetal/v1/conductor.rst b/doc/source/user/resources/baremetal/v1/conductor.rst new file mode 100644 index 000000000..9e1bd1176 --- /dev/null +++ b/doc/source/user/resources/baremetal/v1/conductor.rst @@ -0,0 +1,13 @@ +openstack.baremetal.v1.conductor +================================ + +.. automodule:: openstack.baremetal.v1.conductor + +The Conductor Class +------------------- + +The ``Conductor`` class inherits +from :class:`~openstack.resource.Resource`. + +.. autoclass:: openstack.baremetal.v1.conductor.Conductor + :members: diff --git a/openstack/baremetal/v1/_proxy.py b/openstack/baremetal/v1/_proxy.py index b395dbc6d..0fb8a4978 100644 --- a/openstack/baremetal/v1/_proxy.py +++ b/openstack/baremetal/v1/_proxy.py @@ -20,6 +20,8 @@ from openstack.baremetal.v1 import port_group as _portgroup from openstack.baremetal.v1 import volume_connector as _volumeconnector from openstack.baremetal.v1 import volume_target as _volumetarget from openstack.baremetal.v1 import deploy_templates as _deploytemplates +from openstack.baremetal.v1 import conductor as _conductor + from openstack import exceptions from openstack import proxy from openstack import utils @@ -1415,3 +1417,30 @@ class Proxy(proxy.Proxy): """ return self._get_resource(_deploytemplates.DeployTemplate, deploy_template).patch(self, patch) + + def conductors(self, details=False, **query): + """Retrieve a generator of conductors. + + :param bool details: A boolean indicating whether the detailed + information for every conductor should be returned. + + :returns: A generator of conductor instances. + """ + + if details: + query['details'] = True + return _conductor.Conductor.list(self, **query) + + def get_conductor(self, conductor, fields=None): + """Get a specific conductor. + + :param conductor: The value can be the name of a conductor or a + :class:`~openstack.baremetal.v1.conductor.Conductor` instance. + + :returns: One :class:`~openstack.baremetal.v1.conductor.Conductor` + + :raises: :class:`~openstack.exceptions.ResourceNotFound` when no + conductor matching the name could be found. + """ + return self._get_with_fields(_conductor.Conductor, + conductor, fields=fields) diff --git a/openstack/baremetal/v1/conductor.py b/openstack/baremetal/v1/conductor.py new file mode 100644 index 000000000..05ecf043e --- /dev/null +++ b/openstack/baremetal/v1/conductor.py @@ -0,0 +1,42 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from openstack.baremetal.v1 import _common +from openstack import resource + + +class Conductor(_common.ListMixin, resource.Resource): + + resources_key = 'conductors' + base_path = '/conductors' + + # capabilities + allow_create = False + allow_fetch = True + allow_commit = False + allow_delete = False + allow_list = True + allow_patch = False + + _query_mapping = resource.QueryParameters( + 'detail', + fields={'type': _common.fields_type}, + ) + + _max_microversion = '1.49' + created_at = resource.Body('created_at') + updated_at = resource.Body('updated_at') + hostname = resource.Body('hostname') + conductor_group = resource.Body('conductor_group') + alive = resource.Body('alive', type=bool) + links = resource.Body('links', type=list) + drivers = resource.Body('drivers', type=list) diff --git a/openstack/tests/functional/baremetal/test_baremetal_conductor.py b/openstack/tests/functional/baremetal/test_baremetal_conductor.py new file mode 100644 index 000000000..310304dee --- /dev/null +++ b/openstack/tests/functional/baremetal/test_baremetal_conductor.py @@ -0,0 +1,29 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +from openstack.tests.functional.baremetal import base + + +class TestBareMetalConductor(base.BaseBaremetalTest): + + min_microversion = '1.49' + + def test_list_get_conductor(self): + node = self.create_node(name='node-name') + conductors = self.conn.baremetal.conductors() + hostname_list = [conductor.hostname for conductor in conductors] + self.assertIn(node.conductor, hostname_list) + conductor1 = self.conn.baremetal.get_conductor(node.conductor) + self.assertIsNotNone(conductor1.conductor_group) + self.assertIsNotNone(conductor1.links) + self.assertTrue(conductor1.alive) diff --git a/openstack/tests/unit/baremetal/v1/test_conductor.py b/openstack/tests/unit/baremetal/v1/test_conductor.py new file mode 100644 index 000000000..55900f4ed --- /dev/null +++ b/openstack/tests/unit/baremetal/v1/test_conductor.py @@ -0,0 +1,61 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from openstack.tests.unit import base + +from openstack.baremetal.v1 import conductor + +FAKE = { + "links": [ + { + "href": "http://127.0.0.1:6385/v1/conductors/compute2.localdomain", + "rel": "self" + }, + { + "href": "http://127.0.0.1:6385/conductors/compute2.localdomain", + "rel": "bookmark" + } + ], + "created_at": "2018-12-05T07:03:19+00:00", + "hostname": "compute2.localdomain", + "conductor_group": "", + "updated_at": "2018-12-05T07:03:21+00:00", + "alive": True, + "drivers": [ + "ipmi" + ] +} + + +class TestContainer(base.TestCase): + + def test_basic(self): + sot = conductor.Conductor() + self.assertIsNone(sot.resource_key) + self.assertEqual('conductors', sot.resources_key) + self.assertEqual('/conductors', sot.base_path) + self.assertFalse(sot.allow_create) + self.assertTrue(sot.allow_fetch) + self.assertFalse(sot.allow_commit) + self.assertFalse(sot.allow_delete) + self.assertTrue(sot.allow_list) + self.assertFalse(sot.allow_patch) + + def test_instantiate(self): + sot = conductor.Conductor(**FAKE) + self.assertEqual(FAKE['created_at'], sot.created_at) + self.assertEqual(FAKE['updated_at'], sot.updated_at) + self.assertEqual(FAKE['hostname'], sot.hostname) + self.assertEqual(FAKE['conductor_group'], sot.conductor_group) + self.assertEqual(FAKE['alive'], sot.alive) + self.assertEqual(FAKE['links'], sot.links) + self.assertEqual(FAKE['drivers'], sot.drivers) diff --git a/releasenotes/notes/ironic-conductors-support-3bf27e8b2f0299ba.yaml b/releasenotes/notes/ironic-conductors-support-3bf27e8b2f0299ba.yaml new file mode 100644 index 000000000..e2aea13a2 --- /dev/null +++ b/releasenotes/notes/ironic-conductors-support-3bf27e8b2f0299ba.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Support for Ironic Conductor API.