From a1badd2864d7691df5fd00a8b6277342b483092d Mon Sep 17 00:00:00 2001 From: "hnn.ynh" Date: Sun, 1 Sep 2024 00:01:40 +0900 Subject: [PATCH] Add getting the status of the services in designate system The feature is specified in the DNS API docs but not supported in the SDK. - Add ServiceStatus declaration - Add methods to support - service_statuses(), get_service_status() Change-Id: Ide1f6e7bdffc949cd814171bfb7ede4e503b8ac3 --- doc/source/user/proxies/dns.rst | 7 +++ doc/source/user/resources/dns/index.rst | 1 + .../user/resources/dns/v2/service_status.rst | 13 +++++ openstack/dns/v2/_proxy.py | 22 ++++++++ openstack/dns/v2/service_status.py | 51 ++++++++++++++++++ .../functional/dns/v2/test_service_status.py | 54 +++++++++++++++++++ openstack/tests/unit/dns/v2/test_proxy.py | 13 +++++ .../tests/unit/dns/v2/test_service_status.py | 27 ++++++++++ ...d-dns-service-status-bf1e1cfd811e59a0.yaml | 4 ++ 9 files changed, 192 insertions(+) create mode 100644 doc/source/user/resources/dns/v2/service_status.rst create mode 100644 openstack/dns/v2/service_status.py create mode 100644 openstack/tests/functional/dns/v2/test_service_status.py create mode 100644 openstack/tests/unit/dns/v2/test_service_status.py create mode 100644 releasenotes/notes/add-dns-service-status-bf1e1cfd811e59a0.yaml diff --git a/doc/source/user/proxies/dns.rst b/doc/source/user/proxies/dns.rst index 8c53c5418..212651df8 100644 --- a/doc/source/user/proxies/dns.rst +++ b/doc/source/user/proxies/dns.rst @@ -68,3 +68,10 @@ Zone Share Operations :noindex: :members: create_zone_share, delete_zone_share, get_zone_share, find_zone_share, zone_shares + +Service Status Operations +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. autoclass:: openstack.dns.v2._proxy.Proxy + :noindex: + :members: service_statuses, get_service_status diff --git a/doc/source/user/resources/dns/index.rst b/doc/source/user/resources/dns/index.rst index 77860a6a0..c270c67e1 100644 --- a/doc/source/user/resources/dns/index.rst +++ b/doc/source/user/resources/dns/index.rst @@ -11,3 +11,4 @@ DNS Resources v2/zone_share v2/floating_ip v2/recordset + v2/service_status diff --git a/doc/source/user/resources/dns/v2/service_status.rst b/doc/source/user/resources/dns/v2/service_status.rst new file mode 100644 index 000000000..492f9182a --- /dev/null +++ b/doc/source/user/resources/dns/v2/service_status.rst @@ -0,0 +1,13 @@ +openstack.dns.v2.service_status +=============================== + +.. automodule:: openstack.dns.v2.service_status + +The ServiceStatus Class +----------------------- + +The ``ServiceStatus`` class inherits from +:class:`~openstack.resource.Resource`. + +.. autoclass:: openstack.dns.v2.service_status.ServiceStatus + :members: diff --git a/openstack/dns/v2/_proxy.py b/openstack/dns/v2/_proxy.py index 5b1e35d85..a5497da62 100644 --- a/openstack/dns/v2/_proxy.py +++ b/openstack/dns/v2/_proxy.py @@ -12,6 +12,7 @@ from openstack.dns.v2 import floating_ip as _fip from openstack.dns.v2 import recordset as _rs +from openstack.dns.v2 import service_status as _svc_status from openstack.dns.v2 import zone as _zone from openstack.dns.v2 import zone_export as _zone_export from openstack.dns.v2 import zone_import as _zone_import @@ -24,6 +25,7 @@ class Proxy(proxy.Proxy): _resource_registry = { "floating_ip": _fip.FloatingIP, "recordset": _rs.Recordset, + "service_status": _svc_status.ServiceStatus, "zone": _zone.Zone, "zone_export": _zone_export.ZoneExport, "zone_import": _zone_import.ZoneImport, @@ -656,6 +658,26 @@ class Proxy(proxy.Proxy): zone_id=zone_obj.id, ) + # ======== Service Statuses ======== + def service_statuses(self): + """Retrieve a generator of service statuses + + :returns: A generator of service statuses + :class:`~openstack.dns.v2.service_status.ServiceStatus` instances. + """ + return self._list(_svc_status.ServiceStatus) + + def get_service_status(self, service): + """Get a status of a service in the Designate system + + :param service: The value can be the ID of a service + or a :class:`~openstack.dns.v2.service_status.ServiceStatus` instance. + + :returns: ServiceStatus instance. + :rtype: :class:`~openstack.dns.v2.service_status.ServiceStatus` + """ + return self._get(_svc_status.ServiceStatus, service) + def _get_cleanup_dependencies(self): # DNS may depend on floating ip return {'dns': {'before': ['network']}} diff --git a/openstack/dns/v2/service_status.py b/openstack/dns/v2/service_status.py new file mode 100644 index 000000000..245817e16 --- /dev/null +++ b/openstack/dns/v2/service_status.py @@ -0,0 +1,51 @@ +# 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.dns.v2 import _base +from openstack import resource + + +class ServiceStatus(_base.Resource): + """Designate Service Statuses""" + + resources_key = 'service_statuses' + base_path = '/service_statuses' + + # capabilities + allow_create = False + allow_fetch = True + allow_commit = False + allow_delete = False + allow_list = True + + #: Capabilities for the service + capabilities = resource.Body('capabilities', type=dict) + #: Timestamp when the resource was created + created_at = resource.Body('created_at') + #: Timestamp when the last heartbeat was received + heartbeated_at = resource.Body('heartbeated_at') + #: Hostname of the host with the service instance + #: *Type: str* + hostname = resource.Body('hostname') + #: Links contains a `self` pertaining to this service status or a `next` pertaining + #: to next page + links = resource.Body('links', type=dict) + #: The name of the Designate service instance + #: *Type: str* + service_name = resource.Body('service_name') + #: Statistics for the service + stats = resource.Body('stats', type=dict) + #: The status of the resource + #: *Type: enum* + status = resource.Body('status') + #: Timestamp when the resource was last updated + updated_at = resource.Body('updated_at') diff --git a/openstack/tests/functional/dns/v2/test_service_status.py b/openstack/tests/functional/dns/v2/test_service_status.py new file mode 100644 index 000000000..562e7b69f --- /dev/null +++ b/openstack/tests/functional/dns/v2/test_service_status.py @@ -0,0 +1,54 @@ +# 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 import connection +from openstack.tests.functional import base + + +class TestServiceStatus(base.BaseFunctionalTest): + def setUp(self): + super().setUp() + self.require_service('dns') + + self.conn = connection.from_config(cloud_name=base.TEST_CLOUD_NAME) + + self.service_names = [ + "api", + "backend", + "central", + "mdns", + "producer", + "sink", + "storage", + "worker", + ] + self.service_status = ["UP", "DOWN"] + + def test_service_status(self): + service_statuses = list(self.conn.dns.service_statuses()) + if not service_statuses: + self.skipTest( + "The Service in Designate System is required for this test" + ) + + names = [f.service_name for f in service_statuses] + statuses = [f.status for f in service_statuses] + + self.assertTrue( + all(status in self.service_status for status in statuses) + ) + self.assertTrue(all(name in self.service_names for name in names)) + + # Test that we can fetch a service status + service_status = self.conn.dns.get_service_status(service_statuses[0]) + self.assertIn(service_status.service_name, self.service_names) + self.assertIn(service_status.status, self.service_status) diff --git a/openstack/tests/unit/dns/v2/test_proxy.py b/openstack/tests/unit/dns/v2/test_proxy.py index 035701ef8..97b60fe2f 100644 --- a/openstack/tests/unit/dns/v2/test_proxy.py +++ b/openstack/tests/unit/dns/v2/test_proxy.py @@ -13,6 +13,7 @@ from openstack.dns.v2 import _proxy from openstack.dns.v2 import floating_ip from openstack.dns.v2 import recordset +from openstack.dns.v2 import service_status from openstack.dns.v2 import zone from openstack.dns.v2 import zone_export from openstack.dns.v2 import zone_import @@ -311,3 +312,15 @@ class TestDnsZoneShare(TestDnsProxy): expected_args=[], expected_kwargs={'zone_id': 'zone'}, ) + + +class TestDnsServiceStatus(TestDnsProxy): + def test_service_statuses(self): + self.verify_list( + self.proxy.service_statuses, service_status.ServiceStatus + ) + + def test_service_status_get(self): + self.verify_get( + self.proxy.get_service_status, service_status.ServiceStatus + ) diff --git a/openstack/tests/unit/dns/v2/test_service_status.py b/openstack/tests/unit/dns/v2/test_service_status.py new file mode 100644 index 000000000..d2bcc7fea --- /dev/null +++ b/openstack/tests/unit/dns/v2/test_service_status.py @@ -0,0 +1,27 @@ +# 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.dns.v2 import service_status as svc_status +from openstack.tests.unit import base + + +class TestServiceStatus(base.TestCase): + def test_basic(self): + sot = svc_status.ServiceStatus() + self.assertEqual(None, sot.resource_key) + self.assertEqual('service_statuses', sot.resources_key) + self.assertEqual('/service_statuses', sot.base_path) + self.assertTrue(sot.allow_list) + self.assertFalse(sot.allow_create) + self.assertTrue(sot.allow_fetch) + self.assertFalse(sot.allow_commit) + self.assertFalse(sot.allow_delete) diff --git a/releasenotes/notes/add-dns-service-status-bf1e1cfd811e59a0.yaml b/releasenotes/notes/add-dns-service-status-bf1e1cfd811e59a0.yaml new file mode 100644 index 000000000..b10c55a6d --- /dev/null +++ b/releasenotes/notes/add-dns-service-status-bf1e1cfd811e59a0.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Add getting the status of one or all services in Designate (DNS) system.