Skip to content

Commit 761734b

Browse files
Support for dbaas v2 (#479)
## 📝 Description **What does this PR do and why is this change necessary?** Adds new fields for dbaas 2 as well as a mehod for forking. ## ✔️ How to Test **How do I run the relevant unit/integration tests?** ```bash RUN_DB_FORK_TESTS=yes make testint TEST_SUITE=database ``` the tests are still very long so i left the skips in --------- Co-authored-by: ykim-1 <ykim@akamai.com> Co-authored-by: Youjung Kim <126618609+ykim-akamai@users.noreply.github.com>
1 parent d3de874 commit 761734b

File tree

5 files changed

+290
-255
lines changed

5 files changed

+290
-255
lines changed

.github/workflows/e2e-test-pr.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ on:
22
pull_request:
33
workflow_dispatch:
44
inputs:
5+
run_db_fork_tests:
6+
description: 'Set this parameter to "true" to run fork database related test cases'
7+
required: false
8+
default: 'false'
9+
type: choice
10+
options:
11+
- 'true'
12+
- 'false'
13+
run_db_tests:
14+
description: 'Set this parameter to "true" to run database related test cases'
15+
required: false
16+
default: 'false'
17+
type: choice
18+
options:
19+
- 'true'
20+
- 'false'
521
test_suite:
622
description: 'Enter specific test suite. E.g. domain, linode_client'
723
required: false
@@ -80,7 +96,7 @@ jobs:
8096
run: |
8197
timestamp=$(date +'%Y%m%d%H%M')
8298
report_filename="${timestamp}_sdk_test_report.xml"
83-
make test-int TEST_ARGS="--junitxml=${report_filename}" TEST_SUITE="${{ github.event.inputs.test_suite }}"
99+
make test-int RUN_DB_FORK_TESTS=${{ github.event.inputs.run_db_fork_tests }} RUN_DB_TESTS=${{ github.event.inputs.run_db_tests }} TEST_ARGS="--junitxml=${report_filename}" TEST_SUITE="${{ github.event.inputs.test_suite }}"
84100
env:
85101
LINODE_TOKEN: ${{ secrets.LINODE_TOKEN }}
86102

.github/workflows/e2e-test.yml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,25 @@ name: Integration Tests
33
on:
44
workflow_dispatch:
55
inputs:
6+
run_db_fork_tests:
7+
description: 'Set this parameter to "true" to run fork database related test cases'
8+
required: false
9+
default: 'false'
10+
type: choice
11+
options:
12+
- 'true'
13+
- 'false'
14+
run_db_tests:
15+
description: 'Set this parameter to "true" to run database related test cases'
16+
required: false
17+
default: 'false'
18+
type: choice
19+
options:
20+
- 'true'
21+
- 'false'
22+
test_suite:
23+
description: 'Enter specific test suite. E.g. domain, linode_client'
24+
required: false
625
use_minimal_test_account:
726
description: 'Indicate whether to use a minimal test account with limited resources for testing. Defaults to "false"'
827
required: false
@@ -72,7 +91,7 @@ jobs:
7291
run: |
7392
timestamp=$(date +'%Y%m%d%H%M')
7493
report_filename="${timestamp}_sdk_test_report.xml"
75-
make test-int TEST_ARGS="--junitxml=${report_filename}"
94+
make test-int RUN_DB_FORK_TESTS=${{ github.event.inputs.run_db_fork_tests }} RUN_DB_TESTS=${{ github.event.inputs.run_db_tests }} TEST_SUITE="${{ github.event.inputs.test_suite }}" TEST_ARGS="--junitxml=${report_filename}"
7695
env:
7796
LINODE_TOKEN: ${{ env.LINODE_TOKEN }}
7897

linode_api4/groups/database.py

Lines changed: 125 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
from linode_api4.errors import UnexpectedResponseError
22
from linode_api4.groups import Group
33
from linode_api4.objects import (
4-
Base,
54
Database,
65
DatabaseEngine,
76
DatabaseType,
87
MySQLDatabase,
98
PostgreSQLDatabase,
9+
drop_null_keys,
1010
)
11+
from linode_api4.objects.base import _flatten_request_body_recursive
1112

1213

1314
class DatabaseGroup(Group):
@@ -126,13 +127,71 @@ def mysql_create(self, label, region, engine, ltype, **kwargs):
126127

127128
params = {
128129
"label": label,
129-
"region": region.id if issubclass(type(region), Base) else region,
130-
"engine": engine.id if issubclass(type(engine), Base) else engine,
131-
"type": ltype.id if issubclass(type(ltype), Base) else ltype,
130+
"region": region,
131+
"engine": engine,
132+
"type": ltype,
132133
}
133134
params.update(kwargs)
134135

135-
result = self.client.post("/databases/mysql/instances", data=params)
136+
result = self.client.post(
137+
"/databases/mysql/instances",
138+
data=_flatten_request_body_recursive(drop_null_keys(params)),
139+
)
140+
141+
if "id" not in result:
142+
raise UnexpectedResponseError(
143+
"Unexpected response when creating MySQL Database", json=result
144+
)
145+
146+
d = MySQLDatabase(self.client, result["id"], result)
147+
return d
148+
149+
def mysql_fork(self, source, restore_time, **kwargs):
150+
"""
151+
Forks an :any:`MySQLDatabase` on this account with
152+
the given restore_time. label, region, engine, and ltype are optional.
153+
For example::
154+
155+
client = LinodeClient(TOKEN)
156+
157+
db_to_fork = client.database.mysql_instances()[0]
158+
159+
new_fork = client.database.mysql_fork(
160+
db_to_fork.id,
161+
db_to_fork.updated,
162+
label="new-fresh-label"
163+
)
164+
165+
API Documentation: https://techdocs.akamai.com/linode-api/reference/post-databases-mysql-instances
166+
167+
:param source: The id of the source database
168+
:type source: int
169+
:param restore_time: The timestamp for the fork
170+
:type restore_time: datetime
171+
:param label: The name for this cluster
172+
:type label: str
173+
:param region: The region to deploy this cluster in
174+
:type region: str | Region
175+
:param engine: The engine to deploy this cluster with
176+
:type engine: str | Engine
177+
:param ltype: The Linode Type to use for this cluster
178+
:type ltype: str | Type
179+
"""
180+
181+
params = {
182+
"fork": {
183+
"source": source,
184+
"restore_time": restore_time.strftime("%Y-%m-%dT%H:%M:%S"),
185+
}
186+
}
187+
if "ltype" in kwargs:
188+
params["type"] = kwargs["ltype"]
189+
params.update(kwargs)
190+
191+
result = self.client.post(
192+
"/databases/mysql/instances",
193+
data=_flatten_request_body_recursive(drop_null_keys(params)),
194+
)
136195

137196
if "id" not in result:
138197
raise UnexpectedResponseError(
@@ -191,14 +250,71 @@ def postgresql_create(self, label, region, engine, ltype, **kwargs):
191250

192251
params = {
193252
"label": label,
194-
"region": region.id if issubclass(type(region), Base) else region,
195-
"engine": engine.id if issubclass(type(engine), Base) else engine,
196-
"type": ltype.id if issubclass(type(ltype), Base) else ltype,
253+
"region": region,
254+
"engine": engine,
255+
"type": ltype,
256+
}
257+
params.update(kwargs)
258+
259+
result = self.client.post(
260+
"/databases/postgresql/instances",
261+
data=_flatten_request_body_recursive(drop_null_keys(params)),
262+
)
263+
264+
if "id" not in result:
265+
raise UnexpectedResponseError(
266+
"Unexpected response when creating PostgreSQL Database",
267+
json=result,
268+
)
269+
270+
d = PostgreSQLDatabase(self.client, result["id"], result)
271+
return d
272+
273+
def postgresql_fork(self, source, restore_time, **kwargs):
274+
"""
275+
Forks an :any:`PostgreSQLDatabase` on this account with
276+
the given restore_time. label, region, engine, and ltype are optional.
277+
For example::
278+
279+
client = LinodeClient(TOKEN)
280+
281+
db_to_fork = client.database.postgresql_instances()[0]
282+
283+
new_fork = client.database.postgresql_fork(
284+
db_to_fork.id,
285+
db_to_fork.updated,
286+
label="new-fresh-label"
287+
)
288+
289+
API Documentation: https://techdocs.akamai.com/linode-api/reference/post-databases-postgresql-instances
290+
291+
:param source: The id of the source database
292+
:type source: int
293+
:param restore_time: The timestamp for the fork
294+
:type restore_time: datetime
295+
:param label: The name for this cluster
296+
:type label: str
297+
:param region: The region to deploy this cluster in
298+
:type region: str | Region
299+
:param engine: The engine to deploy this cluster with
300+
:type engine: str | Engine
301+
:param ltype: The Linode Type to use for this cluster
302+
:type ltype: str | Type
303+
"""
304+
305+
params = {
306+
"fork": {
307+
"source": source,
308+
"restore_time": restore_time.strftime("%Y-%m-%dT%H:%M:%S"),
309+
}
197310
}
311+
if "ltype" in kwargs:
312+
params["type"] = kwargs["ltype"]
198313
params.update(kwargs)
199314

200315
result = self.client.post(
201-
"/databases/postgresql/instances", data=params
316+
"/databases/postgresql/instances",
317+
data=_flatten_request_body_recursive(drop_null_keys(params)),
202318
)
203319

204320
if "id" not in result:

linode_api4/objects/database.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class MySQLDatabase(Base):
131131
"label": Property(mutable=True),
132132
"allow_list": Property(mutable=True, unordered=True),
133133
"backups": Property(derived_class=MySQLDatabaseBackup),
134-
"cluster_size": Property(),
134+
"cluster_size": Property(mutable=True),
135135
"created": Property(is_datetime=True),
136136
"encrypted": Property(),
137137
"engine": Property(),
@@ -141,7 +141,9 @@ class MySQLDatabase(Base):
141141
"replication_type": Property(),
142142
"ssl_connection": Property(),
143143
"status": Property(volatile=True),
144-
"type": Property(),
144+
"type": Property(mutable=True),
145+
"fork": Property(),
146+
"oldest_restore_time": Property(is_datetime=True),
145147
"updated": Property(volatile=True, is_datetime=True),
146148
"updates": Property(mutable=True),
147149
"version": Property(),
@@ -264,7 +266,7 @@ class PostgreSQLDatabase(Base):
264266
"label": Property(mutable=True),
265267
"allow_list": Property(mutable=True, unordered=True),
266268
"backups": Property(derived_class=PostgreSQLDatabaseBackup),
267-
"cluster_size": Property(),
269+
"cluster_size": Property(mutable=True),
268270
"created": Property(is_datetime=True),
269271
"encrypted": Property(),
270272
"engine": Property(),
@@ -275,7 +277,9 @@ class PostgreSQLDatabase(Base):
275277
"replication_type": Property(),
276278
"ssl_connection": Property(),
277279
"status": Property(volatile=True),
278-
"type": Property(),
280+
"type": Property(mutable=True),
281+
"fork": Property(),
282+
"oldest_restore_time": Property(is_datetime=True),
279283
"updated": Property(volatile=True, is_datetime=True),
280284
"updates": Property(mutable=True),
281285
"version": Property(),
@@ -414,6 +418,7 @@ class Database(Base):
414418
"region": Property(),
415419
"status": Property(),
416420
"type": Property(),
421+
"fork": Property(),
417422
"updated": Property(),
418423
"updates": Property(),
419424
"version": Property(),

0 commit comments

Comments
 (0)