dns: Add support for TLDs

- Add DNS TLD resource to the SDK
- Implement proxy methods: create_tld(), find_tld(), get_tld(),
  update_tld(), delete_tld(), tlds()

Change-Id: I9e61ac2e7984e7594dea701adee1415db5093bf6
Signed-off-by: chjung99 <cksgh1168@gmail.com>
Co-authored-by: Kim Yubin <garmalhy1@gmail.com>
Co-authored-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
chjung99
2024-08-31 14:50:15 +09:00
committed by Stephen Finucane
parent 271813050b
commit 633c73018e
9 changed files with 315 additions and 0 deletions

View File

@@ -51,6 +51,13 @@ FloatingIP Operations
:noindex:
:members: floating_ips, get_floating_ip, update_floating_ip
TLD Operations
^^^^^^^^^^^^^^
.. autoclass:: openstack.dns.v2._proxy.Proxy
:noindex:
:members: create_tld, delete_tld, get_tld, find_tld, tlds
Zone Transfer Operations
^^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -10,6 +10,7 @@ DNS Resources
v2/zone_import
v2/zone_share
v2/floating_ip
v2/tld
v2/recordset
v2/limit
v2/service_status

View File

@@ -0,0 +1,12 @@
openstack.dns.v2.tld
==============================
.. automodule:: openstack.dns.v2.tld
The TLD Class
--------------
The ``DNS`` class inherits from :class:`~openstack.resource.Resource`.
.. autoclass:: openstack.dns.v2.tld.TLD
:members:

View File

@@ -17,6 +17,7 @@ from openstack.dns.v2 import floating_ip as _fip
from openstack.dns.v2 import limit as _limit
from openstack.dns.v2 import recordset as _rs
from openstack.dns.v2 import service_status as _svc_status
from openstack.dns.v2 import tld as _tld
from openstack.dns.v2 import tsigkey as _tsigkey
from openstack.dns.v2 import zone as _zone
from openstack.dns.v2 import zone_export as _zone_export
@@ -42,6 +43,7 @@ class Proxy(proxy.Proxy):
"zone_nameserver": _zone_nameserver.ZoneNameserver,
"zone_share": _zone_share.ZoneShare,
"zone_transfer_request": _zone_transfer.ZoneTransferRequest,
"tld": _tld.TLD,
}
# ======== Zones ========
@@ -717,6 +719,87 @@ class Proxy(proxy.Proxy):
"""
return self._get(_svc_status.ServiceStatus, service)
# ======== TLDs ========
def tlds(self, **query):
"""Retrieve a generator of tlds
:param dict query: Optional query parameters to be sent to limit the
resources being returned.
* `name`: TLD Name field.
:returns: A generator of tld
:class:`~openstack.dns.v2.tld.TLD` instances.
"""
return self._list(_tld.TLD, **query)
def create_tld(self, **attrs):
"""Create a new tld from attributes
:param dict attrs: Keyword arguments which will be used to create
a :class:`~openstack.dns.v2.tld.TLD`,
comprised of the properties on the TLD class.
:returns: The results of TLD creation.
:rtype: :class:`~openstack.dns.v2.tld.TLD`
"""
return self._create(_tld.TLD, prepend_key=False, **attrs)
def get_tld(self, tld):
"""Get a tld
:param tld: The value can be the ID of a tld
or a :class:`~openstack.dns.v2.tld.TLD` instance.
:returns: tld instance.
:rtype: :class:`~openstack.dns.v2.tld.TLD`
"""
return self._get(_tld.TLD, tld)
def delete_tld(self, tld, ignore_missing=True):
"""Delete a tld
:param tld: The value can be the ID of a tld
or a :class:`~openstack.dns.v2.tld.TLD` instance.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.NotFoundException` will be raised when
the tld does not exist.
When set to ``True``, no exception will be set when attempting to
delete a nonexistent tld.
:returns: TLD been deleted
:rtype: :class:`~openstack.dns.v2.tld.TLD`
"""
return self._delete(
_tld.TLD,
tld,
ignore_missing=ignore_missing,
)
def update_tld(self, tld, **attrs):
"""Update tld attributes
:param tld: The id or an instance of
:class:`~openstack.dns.v2.tld.TLD`.
:param dict attrs: attributes for update on
:class:`~openstack.dns.v2.tld.TLD`.
:rtype: :class:`~openstack.dns.v2.tld.TLD`
"""
return self._update(_tld.TLD, tld, **attrs)
def find_tld(self, name_or_id, ignore_missing=True):
"""Find a single tld
:param name_or_id: The name or ID of a tld
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.NotFoundException` will be raised
when the tld does not exist.
When set to ``True``, no exception will be set when attempting
to delete a nonexistent tld.
:returns: :class:`~openstack.dns.v2.tld.TLD`
"""
return self._find(_tld.TLD, name_or_id, ignore_missing=ignore_missing)
# ========== Utilities ==========
def wait_for_status(
self,

49
openstack/dns/v2/tld.py Normal file
View File

@@ -0,0 +1,49 @@
# 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 TLD(_base.Resource):
"""DNS TLD Resource"""
resources_key = "tlds"
base_path = "/tlds"
# capabilities
allow_create = True
allow_fetch = True
allow_commit = True
allow_delete = True
allow_list = True
commit_method = "PATCH"
_query_mapping = resource.QueryParameters(
"name",
"description",
"limit",
"marker",
)
#: TLD name
name = resource.Body("name")
#: TLD description
description = resource.Body("description")
#: Timestamp when the tld was created
created_at = resource.Body("created_at")
#: Timestamp when the tld was last updated
updated_at = resource.Body("updated_at")
#: Links contains a `self` pertaining to this tld or a `next` pertaining
#: to next page
links = resource.Body("links", type=dict)

View File

@@ -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.dns.v2 import tld as _tld
from openstack.tests.functional import base
class TestTLD(base.BaseFunctionalTest):
def setUp(self):
super().setUp()
self.require_service('dns')
self.tld_name = 'xyz'
self.tld_description = 'The xyz TLD'
def test_tld(self):
# create the tld
tld = self.operator_cloud.dns.create_tld(
name=self.tld_name, description=self.tld_description
)
self.assertIsInstance(tld, _tld.TLD)
self.assertEqual(self.tld_description, tld.description)
self.addCleanup(self.operator_cloud.dns.delete_tld, tld)
# update the tld
tld = self.operator_cloud.dns.update_tld(
tld, description=self.tld_description
)
self.assertIsInstance(tld, _tld.TLD)
self.assertEqual(self.tld_description, tld.description)
# retrieve details of the (updated) tld by ID
tld = self.operator_cloud.dns.get_tld(tld.id)
self.assertIsInstance(tld, _tld.TLD)
self.assertEqual(self.tld_description, tld.description)
# retrieve details of the (updated) tld by name
tld = self.operator_cloud.dns.find_tld(tld.name)
self.assertIsInstance(tld, _tld.TLD)
self.assertEqual(self.tld_description, tld.description)
# list all tlds
tlds = list(self.operator_cloud.dns.tlds())
self.assertIsInstance(tlds[0], _tld.TLD)
self.assertIn(
self.tld_name, {x.name for x in self.operator_cloud.dns.tlds()}
)

View File

@@ -15,6 +15,7 @@ from openstack.dns.v2 import blacklist
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 tld
from openstack.dns.v2 import tsigkey
from openstack.dns.v2 import zone
from openstack.dns.v2 import zone_export
@@ -393,3 +394,33 @@ class TestDnsBlacklist(TestDnsProxy):
def test_blacklists(self):
self.verify_list(self.proxy.blacklists, blacklist.Blacklist)
class TestDnsTLD(TestDnsProxy):
def test_tld_create(self):
self.verify_create(
self.proxy.create_tld,
tld.TLD,
method_kwargs={"name": "id"},
expected_kwargs={"name": "id", "prepend_key": False},
)
def test_tld_delete(self):
self.verify_delete(
self.proxy.delete_tld,
tld.TLD,
True,
expected_kwargs={"ignore_missing": True},
)
def test_tld_find(self):
self.verify_find(self.proxy.find_tld, tld.TLD)
def test_tld_get(self):
self.verify_get(self.proxy.get_tld, tld.TLD)
def test_tlds(self):
self.verify_list(self.proxy.tlds, tld.TLD)
def test_tld_update(self):
self.verify_update(self.proxy.update_tld, tld.TLD)

View File

@@ -0,0 +1,66 @@
# 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 unittest import mock
from keystoneauth1 import adapter
from openstack.dns.v2 import tld
from openstack.tests.unit import base
IDENTIFIER = "NAME"
EXAMPLE = {
"id": IDENTIFIER,
"name": "com",
"description": "tld description",
}
class TestTLD(base.TestCase):
def setUp(self):
super().setUp()
self.resp = mock.Mock()
self.resp.body = None
self.resp.json = mock.Mock(return_value=self.resp.body)
self.resp.status_code = 200
self.sess = mock.Mock(spec=adapter.Adapter)
self.sess.post = mock.Mock(return_value=self.resp)
self.sess.default_microversion = None
def test_basic(self):
sot = tld.TLD()
self.assertEqual(None, sot.resource_key)
self.assertEqual("tlds", sot.resources_key)
self.assertEqual("/tlds", sot.base_path)
self.assertTrue(sot.allow_list)
self.assertTrue(sot.allow_create)
self.assertTrue(sot.allow_fetch)
self.assertTrue(sot.allow_commit)
self.assertTrue(sot.allow_delete)
self.assertEqual("PATCH", sot.commit_method)
self.assertDictEqual(
{
"description": "description",
"name": "name",
"limit": "limit",
"marker": "marker",
},
sot._query_mapping._mapping,
)
def test_make_it(self):
sot = tld.TLD(**EXAMPLE)
self.assertEqual(IDENTIFIER, sot.id)
self.assertEqual(EXAMPLE["description"], sot.description)
self.assertEqual(EXAMPLE["name"], sot.name)

View File

@@ -0,0 +1,5 @@
---
features:
- |
Adds support for `dns tld
<https://docs.openstack.org/api-ref/dns/dns-api-v2-index.html#tld>`_ service.