Skip to content

Commit 0b0939b

Browse files
vineet-pruthigtema
authored andcommitted
Rds v3 (#50)
* Adding RDS v3 implementation
1 parent 3b56141 commit 0b0939b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+5970
-30
lines changed

doc/source/enforcer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def get_proxy_methods():
4343
"otcextensions.sdk.kms.v1._proxy",
4444
"otcextensions.sdk.obs.v1._proxy",
4545
"otcextensions.sdk.rds.v1._proxy",
46+
"otcextensions.sdk.rds.v3._proxy",
4647
"otcextensions.sdk.volume_backup.v2._proxy"
4748
]
4849

File renamed without changes.

doc/source/user/proxies/rds_v3.rst

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
Database RDS API
2+
================
3+
4+
For details on how to use database, see :doc:`/user/guides/rds`
5+
6+
.. automodule:: otcextensions.sdk.rds.v3._proxy
7+
8+
The Database Class
9+
------------------
10+
11+
The database high-level interface is available through the ``rds`` member of a
12+
:class:`~openstack.connection.Connection` object. The ``rds`` member will only
13+
be added if the ``otcextensions.sdk.register_otc_extensions(conn)`` method is
14+
called.
15+
16+
Datastore Operations
17+
^^^^^^^^^^^^^^^^^^^^
18+
19+
.. autoclass:: otcextensions.sdk.rds.v3._proxy.Proxy
20+
21+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.datastore_versions
22+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.get_datastore_version
23+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.datastore_types
24+
25+
Flavor Operations
26+
^^^^^^^^^^^^^^^^^
27+
28+
.. autoclass:: otcextensions.sdk.rds.v3._proxy.Proxy
29+
30+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.get_flavor
31+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.flavors
32+
33+
Instance Operations
34+
^^^^^^^^^^^^^^^^^^^
35+
36+
.. autoclass:: otcextensions.sdk.rds.v3._proxy.Proxy
37+
38+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.create_instance
39+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.update_instance
40+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.delete_instance
41+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.get_instance
42+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.find_instance
43+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.instances
44+
45+
46+
Backup Operations
47+
^^^^^^^^^^^^^^^^^
48+
49+
.. autoclass:: otcextensions.sdk.rds.v3._proxy.Proxy
50+
51+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.backups
52+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.create_backup
53+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.delete_backup
54+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.get_backup_policy
55+
.. automethod:: otcextensions.sdk.rds.v3._proxy.Proxy.set_backup_policy

doc/source/user/resources/rds/index.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ RDS Resources
77
v1/configuration
88
v1/flavor
99
v1/instance
10+
v3/configuration
11+
v3/flavor
12+
v3/instance
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
otcextensions.sdk.rds.v3.configuration
2+
======================================
3+
4+
.. automodule:: otcextensions.sdk.rds.v3.configuration
5+
6+
The Configuration Class
7+
-----------------------
8+
9+
The ``Configuration`` class inherits from
10+
:class:`~otcextensions.sdk.sdk_resource.Resource`.
11+
12+
.. autoclass:: otcextensions.sdk.rds.v3.configuration.ConfigurationGroup
13+
:members:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
otcextensions.sdk.rds.v3.flavor
2+
===============================
3+
4+
.. automodule:: otcextensions.sdk.rds.v3.flavor
5+
6+
The Flavor Class
7+
----------------
8+
9+
The ``Flavor`` class inherits from
10+
:class:`~otcextensions.sdk.sdk_resource.Resource`.
11+
12+
.. autoclass:: otcextensions.sdk.rds.v3.flavor.Flavor
13+
:members:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
otcextensions.sdk.rds.v3.instance
2+
=================================
3+
4+
.. automodule:: otcextensions.sdk.rds.v3.instance
5+
6+
The Instance Class
7+
------------------
8+
9+
The ``Instance`` class inherits from
10+
:class:`~otcextensions.sdk.sdk_resource.Resource`.
11+
12+
.. autoclass:: otcextensions.sdk.rds.v3.instance.Instance
13+
:members:

otcextensions/osclient/rds/client.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,20 @@
1212
#
1313
import logging
1414

15-
from otcextensions import sdk
15+
from osc_lib import utils
1616

17+
from otcextensions import sdk
18+
from otcextensions.i18n import _
1719

1820
LOG = logging.getLogger(__name__)
1921

20-
DEFAULT_API_VERSION = '1.0'
22+
DEFAULT_API_VERSION = '3'
2123
API_VERSION_OPTION = 'os_rds_api_version'
2224
API_NAME = "rds"
2325
API_VERSIONS = {
2426
"1.0": "openstack.connection.Connection",
2527
"1": "openstack.connection.Connection",
28+
"3": "openstack.connection.Connection"
2629
}
2730

2831

@@ -42,4 +45,11 @@ def make_client(instance):
4245

4346
def build_option_parser(parser):
4447
"""Hook to add global options"""
48+
parser.add_argument(
49+
'--os-rds-api-version',
50+
metavar='<rds-api-version>',
51+
default=utils.env('OS_RDS_API_VERSION'),
52+
help=_("RDS API version, default=%s "
53+
"(Env: OS_RDS_API_VERSION)") % DEFAULT_API_VERSION
54+
)
4555
return parser

otcextensions/osclient/rds/v3/__init__.py

Whitespace-only changes.
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
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+
"""Backup v3 action implementations"""
14+
15+
from osc_lib import utils
16+
from osc_lib.command import command
17+
18+
from otcextensions.common import sdk_utils
19+
from otcextensions.i18n import _
20+
21+
22+
BACKUP_TYPE_CHOICES = ['auto', 'manual', 'fragment', 'incremental']
23+
24+
25+
_formatters = {
26+
}
27+
28+
29+
def _get_columns(item):
30+
column_map = {}
31+
hidden = ['location']
32+
return sdk_utils.get_osc_show_columns_for_sdk_resource(
33+
item, column_map, hidden)
34+
35+
36+
class ListBackup(command.Lister):
37+
_description = _("List database backups")
38+
column_headers = (
39+
'ID', 'Name', 'Type', 'Instance Id', 'Size (KB)'
40+
)
41+
42+
columns = (
43+
'id', 'name', 'type', 'instance_id', 'size'
44+
)
45+
46+
def get_parser(self, prog_name):
47+
parser = super(ListBackup, self).get_parser(prog_name)
48+
parser.add_argument(
49+
'instance',
50+
metavar='<instance>',
51+
help=_('Specify instance ID or Name to get backup list'),
52+
)
53+
parser.add_argument(
54+
'--backup-id',
55+
metavar='<backup_id>',
56+
help=_('Specify the backup ID.'),
57+
)
58+
parser.add_argument(
59+
'--backup-type',
60+
metavar='{' + ','.join(BACKUP_TYPE_CHOICES) + '}',
61+
choices=BACKUP_TYPE_CHOICES,
62+
type=lambda s: s.lower(),
63+
help=_('Specify the backup type.'),
64+
)
65+
parser.add_argument(
66+
'--offset',
67+
metavar='<offset>',
68+
type=int,
69+
help=_('Specify the index position.'),
70+
)
71+
parser.add_argument(
72+
'--limit',
73+
metavar='<limit>',
74+
type=int,
75+
help=_('Specify the limit of resources to be queried.'),
76+
)
77+
# parser.add_argument(
78+
# '--begin-time',
79+
# metavar='<begin_time>',
80+
# help=_('Specify the start time for obtaining the backup list.'),
81+
# )
82+
# parser.add_argument(
83+
# '--end-time',
84+
# metavar='<end_time>',
85+
# help=_('Specify the end time for obtaining the backup list.'),
86+
# )
87+
88+
return parser
89+
90+
def take_action(self, parsed_args):
91+
client = self.app.client_manager.rds
92+
attrs = {}
93+
args_list = [
94+
'backup_id', 'backup_type', 'offset', 'limit'
95+
# , 'begin_time', 'end_time'
96+
]
97+
for arg in args_list:
98+
if getattr(parsed_args, arg):
99+
attrs[arg] = getattr(parsed_args, arg)
100+
if parsed_args.limit:
101+
attrs['paginated'] = False
102+
103+
instance = client.find_instance(parsed_args.instance,
104+
ignore_missing=False)
105+
106+
data = client.backups(instance=instance, **attrs)
107+
108+
return (self.column_headers, (utils.get_item_properties(
109+
s,
110+
self.columns,
111+
) for s in data))
112+
113+
114+
class CreateBackup(command.ShowOne):
115+
_description = _('Create Database backup')
116+
117+
def get_parser(self, prog_name):
118+
parser = super(CreateBackup, self).get_parser(prog_name)
119+
parser.add_argument(
120+
'name',
121+
metavar='<name>',
122+
help=_('Name for the backup'))
123+
parser.add_argument(
124+
'instance',
125+
metavar='<instance>',
126+
help=_('ID or Name of the instance to create backup from'))
127+
parser.add_argument(
128+
'--description',
129+
metavar='<description>',
130+
help=_('Description for the backup'))
131+
parser.add_argument(
132+
'--databases',
133+
metavar='<databases>',
134+
help=_(
135+
'Specifies a CSV list of self-built SQL Server'
136+
'databases that are partially backed up'
137+
'(Only SQL Server support partial backups.)'))
138+
return parser
139+
140+
def take_action(self, parsed_args):
141+
client = self.app.client_manager.rds
142+
143+
attrs = {'name': parsed_args.name}
144+
if parsed_args.description:
145+
attrs['description'] = parsed_args.description
146+
147+
instance = client.find_instance(parsed_args.instance,
148+
ignore_missing=False)
149+
150+
if (parsed_args.databases
151+
and instance.datastore['type'].lower() == 'sqlserver'):
152+
attrs['databases'] = []
153+
databases = parsed_args.databases
154+
databases = databases.split(",")
155+
for db_name in databases:
156+
attrs['databases'].append({'name': db_name})
157+
else:
158+
# Do we want to raise error otherwise?
159+
pass
160+
161+
obj = client.create_backup(instance=instance,
162+
**attrs)
163+
164+
display_columns, columns = _get_columns(obj)
165+
data = utils.get_item_properties(obj, columns,
166+
formatters=_formatters)
167+
168+
return (display_columns, data)
169+
170+
171+
class DeleteBackup(command.Command):
172+
_description = _('Delete Backup')
173+
174+
def get_parser(self, prog_name):
175+
parser = super(DeleteBackup, self).get_parser(prog_name)
176+
parser.add_argument('backup',
177+
metavar='<backup_id>',
178+
nargs='+',
179+
help=_('ID of the backup'))
180+
return parser
181+
182+
def take_action(self, parsed_args):
183+
184+
if parsed_args.backup:
185+
client = self.app.client_manager.rds
186+
for bck in parsed_args.backup:
187+
client.delete_backup(backup=bck, ignore_missing=False)
188+
189+
190+
class ListBackupDownloadLinks(command.Lister):
191+
_description = _('List Backup Download Links')
192+
193+
column_headers = ('Size (KB)', 'URL', 'Expires at')
194+
columns = ('size', 'download_link', 'expires_at')
195+
196+
def get_parser(self, prog_name):
197+
parser = super(ListBackupDownloadLinks, self).get_parser(prog_name)
198+
parser.add_argument('backup_id',
199+
metavar='<backup_id>',
200+
help=_('ID of the backup'))
201+
return parser
202+
203+
def take_action(self, parsed_args):
204+
205+
client = self.app.client_manager.rds
206+
data = client.backup_download_links(backup_id=parsed_args.backup_id)
207+
return (self.column_headers, (utils.get_item_properties(
208+
s,
209+
self.columns,
210+
formatters={}
211+
) for s in data))

0 commit comments

Comments
 (0)