Skip to content

Commit 239ccac

Browse files
committed
add dns recordset osc
1 parent 3fcf1c6 commit 239ccac

8 files changed

Lines changed: 654 additions & 5 deletions

File tree

doc/source/cli/dns.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,15 @@ For help on a specific `dns` command, enter:
1414
.. _dns_zone:
1515

1616
Zone operations
17-
-------------------
17+
---------------
1818

1919
.. autoprogram-cliff:: openstack.dns.v2
2020
:command: dns zone *
21+
22+
.. _dns_rs:
23+
24+
Recordset operations
25+
--------------------
26+
27+
.. autoprogram-cliff:: openstack.dns.v2
28+
:command: dns recordset *
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
# Licensed under the Apache License, Version 2.0 (the 'License'); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
#
13+
'''DNS Recordset v2 action implementations'''
14+
import logging
15+
16+
from osc_lib import utils
17+
from osc_lib.command import command
18+
19+
from otcextensions.i18n import _
20+
from otcextensions.common import sdk_utils
21+
22+
LOG = logging.getLogger(__name__)
23+
24+
RS_TYPES = ['A', 'AAAA', 'MX', 'TXT', 'CNAME', 'NS', 'SRV', 'PTR', 'CAA']
25+
26+
27+
_formatters = {
28+
}
29+
30+
31+
def _get_columns(item):
32+
column_map = {
33+
}
34+
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
35+
36+
37+
class ListRS(command.Lister):
38+
_description = _('List recordsets.')
39+
columns = (
40+
'id', 'name', 'type', 'status', 'description'
41+
)
42+
43+
def get_parser(self, prog_name):
44+
parser = super(ListRS, self).get_parser(prog_name)
45+
parser.add_argument(
46+
'--zone',
47+
metavar='<zone>',
48+
help=_('UUID or name of the zone. Recordsets of all zones '
49+
'will be returned if not given.')
50+
)
51+
return parser
52+
53+
def take_action(self, parsed_args):
54+
client = self.app.client_manager.dns
55+
56+
zone = None
57+
58+
if parsed_args.zone:
59+
60+
zone = client.find_zone(parsed_args.zone, ignore_missing=False)
61+
62+
data = client.recordsets(zone=zone)
63+
64+
table = (self.columns,
65+
(utils.get_item_properties(
66+
s, self.columns, formatters=_formatters
67+
) for s in data))
68+
return table
69+
70+
71+
class ShowRS(command.ShowOne):
72+
_description = _('Show the recordset details')
73+
74+
def get_parser(self, prog_name):
75+
parser = super(ShowRS, self).get_parser(prog_name)
76+
77+
parser.add_argument(
78+
'zone',
79+
metavar='<zone>',
80+
help=_('UUID or name of the zone.')
81+
)
82+
83+
parser.add_argument(
84+
'recordset',
85+
metavar='<id>',
86+
help=_('UUID of the recordset.')
87+
)
88+
89+
return parser
90+
91+
def take_action(self, parsed_args):
92+
93+
client = self.app.client_manager.dns
94+
95+
zone = client.find_zone(
96+
parsed_args.zone,
97+
)
98+
99+
obj = client.get_recordset(zone=zone, recordset=parsed_args.recordset)
100+
101+
display_columns, columns = _get_columns(obj)
102+
data = utils.get_item_properties(obj, columns)
103+
104+
return (display_columns, data)
105+
106+
107+
class DeleteRS(command.Command):
108+
_description = _('Delete Recordset')
109+
110+
def get_parser(self, prog_name):
111+
parser = super(DeleteRS, self).get_parser(prog_name)
112+
113+
parser.add_argument(
114+
'zone',
115+
metavar='<zone>',
116+
help=_('UUID or name of the zone.')
117+
)
118+
119+
parser.add_argument(
120+
'--recordset',
121+
metavar='<id>',
122+
required=True,
123+
action='append',
124+
help=_('UUID of the recordset.')
125+
)
126+
127+
return parser
128+
129+
def take_action(self, parsed_args):
130+
if parsed_args.zone:
131+
client = self.app.client_manager.dns
132+
zone = client.find_zone(parsed_args.zone, ignore_missing=False)
133+
for rs in parsed_args.recordset:
134+
client.delete_recordset(
135+
recordset=rs, zone=zone, ignore_missing=False)
136+
137+
138+
class CreateRS(command.ShowOne):
139+
_description = _('Create recordset')
140+
141+
def get_parser(self, prog_name):
142+
parser = super(CreateRS, self).get_parser(prog_name)
143+
144+
parser.add_argument(
145+
'--zone',
146+
metavar='<zone>',
147+
required=True,
148+
help=_('UUID or name of the zone.')
149+
)
150+
parser.add_argument(
151+
'--name',
152+
metavar='<name>',
153+
required=True,
154+
help=_('DNS Name for the zone.')
155+
)
156+
parser.add_argument(
157+
'--description',
158+
metavar='<description>',
159+
help=_('Description for this zone.')
160+
)
161+
parser.add_argument(
162+
'--type',
163+
metavar='{' + ','.join(RS_TYPES) + '}',
164+
type=lambda s: s.upper(),
165+
choices=RS_TYPES,
166+
help=_('Recordset type.')
167+
)
168+
parser.add_argument(
169+
'--ttl',
170+
metavar='<300-2147483647>',
171+
type=int,
172+
# NOTE: py2 does not support such big int, skip unless py3-only
173+
# choices=range(300, 2147483647),
174+
help=_('TTL (Time to Live) for the zone.')
175+
)
176+
parser.add_argument(
177+
'--record',
178+
metavar='<value>',
179+
action='append',
180+
help=_('Record set value, which varies depending on the record '
181+
'set type. For example, the value of an `AAAA` record set '
182+
'is the IPv6 address list mapped to the domain name. ')
183+
)
184+
185+
return parser
186+
187+
def take_action(self, parsed_args):
188+
189+
client = self.app.client_manager.dns
190+
191+
attrs = {'records': []}
192+
193+
zone = client.find_zone(parsed_args.zone, ignore_missing=False)
194+
195+
if parsed_args.name:
196+
attrs['name'] = parsed_args.name
197+
if parsed_args.description:
198+
attrs['description'] = parsed_args.description
199+
if parsed_args.type:
200+
attrs['type'] = parsed_args.type
201+
if parsed_args.ttl:
202+
attrs['ttl'] = parsed_args.ttl
203+
for rec in parsed_args.record:
204+
attrs['records'].append(rec)
205+
206+
obj = client.create_recordset(
207+
zone=zone,
208+
**attrs
209+
)
210+
211+
display_columns, columns = _get_columns(obj)
212+
data = utils.get_item_properties(obj, columns)
213+
214+
return (display_columns, data)
215+
216+
217+
class SetRS(command.ShowOne):
218+
_description = _('Update a Recordset')
219+
220+
def get_parser(self, prog_name):
221+
parser = super(SetRS, self).get_parser(prog_name)
222+
223+
parser.add_argument(
224+
'zone',
225+
metavar='<zone>',
226+
help=_('UUID or name of the zone.')
227+
)
228+
parser.add_argument(
229+
'recordset',
230+
metavar='<UUID>',
231+
help=_('UUID of the recordset.')
232+
)
233+
parser.add_argument(
234+
'--description',
235+
metavar='<description>',
236+
help=_('Description for this zone.')
237+
)
238+
parser.add_argument(
239+
'--ttl',
240+
metavar='<300-2147483647>',
241+
type=int,
242+
# NOTE: py2 does not support such big int, skip unless py3-only
243+
# choices=range(300, 2147483647),
244+
help=_('TTL (Time to Live) for the zone.')
245+
)
246+
parser.add_argument(
247+
'--record',
248+
metavar='<value>',
249+
action='append',
250+
help=_('Record set value, which varies depending on the record '
251+
'set type. For example, the value of an `AAAA` record set '
252+
'is the IPv6 address list mapped to the domain name. ')
253+
)
254+
255+
return parser
256+
257+
def take_action(self, parsed_args):
258+
259+
client = self.app.client_manager.dns
260+
261+
attrs = {'records': []}
262+
263+
if parsed_args.description:
264+
attrs['description'] = parsed_args.description
265+
if parsed_args.ttl:
266+
attrs['ttl'] = parsed_args.ttl
267+
268+
zone = client.find_zone(parsed_args.zone, ignore_missing=False)
269+
270+
if parsed_args.ttl:
271+
attrs['zone_id'] = zone.id
272+
273+
for rec in parsed_args.record:
274+
attrs['records'].append(rec)
275+
276+
obj = client.update_recordset(
277+
**attrs
278+
)
279+
280+
display_columns, columns = _get_columns(obj)
281+
data = utils.get_item_properties(obj, columns)
282+
283+
return (display_columns, data)

otcextensions/sdk/dns/v2/_proxy.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,14 @@ def get_recordset(self, zone, recordset):
193193
:rtype: :class:`~otcextensions.sdk.dns.v2.recordset.Recordset`
194194
"""
195195
zone = self._get_resource(_zone.Zone, zone)
196-
return self._get(_rs.ZoneRecordset, zone_id=zone.id)
196+
return self._get(_rs.ZoneRecordset, recordset, zone_id=zone.id)
197197

198-
def delete_recordset(self, recordset, ignore_missing=True):
198+
def delete_recordset(self, recordset, zone=None, ignore_missing=True):
199199
"""Delete a zone
200200
201+
:param recordset: The value can be the ID of a recordset
202+
or a :class:`~otcextensions.sdk.dns.v2.recordset.Recordset`
203+
instance.
201204
:param zone: The value can be the ID of a zone
202205
or a :class:`~otcextensions.sdk.dns.v2.zone.Zone` instance.
203206
:param bool ignore_missing: When set to ``False``
@@ -208,6 +211,10 @@ def delete_recordset(self, recordset, ignore_missing=True):
208211
:returns: Recordset instance been deleted
209212
:rtype: :class:`~otcextensions.sdk.dns.v2.recordset.Recordset`
210213
"""
214+
if zone:
215+
zone = self._get_resource(_zone.Zone, zone)
216+
recordset = self._get(
217+
_rs.ZoneRecordset, recordset, zone_id=zone.id)
211218
return self._delete(_rs.ZoneRecordset, recordset,
212219
ignore_missing=ignore_missing)
213220

otcextensions/sdk/dns/v2/recordset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class ZoneRecordset(sdk_resource.Resource):
4848
is_default = resource.Body('default', type=bool)
4949
#: Links contains a `self` pertaining to this zone or a `next` pertaining
5050
#: to next page
51-
links = resource.Body('links', type=dict)
51+
# links = resource.Body('links', type=dict)
5252
#: Recordset name
5353
name = resource.Body('name')
5454
#: ID of the project which the recordset belongs to

otcextensions/tests/unit/osclient/dns/v2/fakes.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from otcextensions.sdk.dns.v2 import zone
2525
from otcextensions.sdk.dns.v2 import nameserver
26+
from otcextensions.sdk.dns.v2 import recordset
2627

2728

2829
def gen_data(data, columns):
@@ -82,3 +83,21 @@ def generate(cls):
8283
}
8384
obj = nameserver.NameServer.existing(**object_info)
8485
return obj
86+
87+
88+
class FakeRecordset(test_base.Fake):
89+
"""Fake one or more recordset"""
90+
91+
@classmethod
92+
def generate(cls):
93+
object_info = {
94+
'zone_id': 'id-' + uuid.uuid4().hex,
95+
'name': uuid.uuid4().hex,
96+
'description': uuid.uuid4().hex,
97+
'status': uuid.uuid4().hex,
98+
'ttl': random.randint(1, 600),
99+
'type': random.choice(['A', 'AAAA', 'SRV']),
100+
'records': list(random.randint(1, 600) for i in range(0, 5))
101+
}
102+
obj = recordset.Recordset.existing(**object_info)
103+
return obj

0 commit comments

Comments
 (0)