Skip to content

Commit 3692712

Browse files
authored
Add support to suspend and resume database (#519)
* suspend and resume db * address comment
1 parent 70169d7 commit 3692712

File tree

7 files changed

+176
-0
lines changed

7 files changed

+176
-0
lines changed

linode_api4/objects/database.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,30 @@ def invalidate(self):
265265

266266
Base.invalidate(self)
267267

268+
def suspend(self):
269+
"""
270+
Suspend a MySQL Managed Database, releasing idle resources and keeping only necessary data.
271+
272+
API documentation: https://techdocs.akamai.com/linode-api/reference/suspend-databases-mysql-instance
273+
"""
274+
self._client.post(
275+
"{}/suspend".format(MySQLDatabase.api_endpoint), model=self
276+
)
277+
278+
return self.invalidate()
279+
280+
def resume(self):
281+
"""
282+
Resume a suspended MySQL Managed Database.
283+
284+
API documentation: https://techdocs.akamai.com/linode-api/reference/resume-databases-mysql-instance
285+
"""
286+
self._client.post(
287+
"{}/resume".format(MySQLDatabase.api_endpoint), model=self
288+
)
289+
290+
return self.invalidate()
291+
268292

269293
class PostgreSQLDatabase(Base):
270294
"""
@@ -405,6 +429,30 @@ def invalidate(self):
405429

406430
Base.invalidate(self)
407431

432+
def suspend(self):
433+
"""
434+
Suspend a PostgreSQL Managed Database, releasing idle resources and keeping only necessary data.
435+
436+
API documentation: https://techdocs.akamai.com/linode-api/reference/suspend-databases-postgre-sql-instance
437+
"""
438+
self._client.post(
439+
"{}/suspend".format(PostgreSQLDatabase.api_endpoint), model=self
440+
)
441+
442+
return self.invalidate()
443+
444+
def resume(self):
445+
"""
446+
Resume a suspended PostgreSQL Managed Database.
447+
448+
API documentation: https://techdocs.akamai.com/linode-api/reference/resume-databases-postgre-sql-instance
449+
"""
450+
self._client.post(
451+
"{}/resume".format(PostgreSQLDatabase.api_endpoint), model=self
452+
)
453+
454+
return self.invalidate()
455+
408456

409457
ENGINE_TYPE_TRANSLATION = {
410458
"mysql": MySQLDatabase,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

test/integration/models/database/test_database.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,40 @@ def test_database_instance(test_linode_client, test_create_sql_db):
165165
assert str(test_create_sql_db.id) in str(dbs.lists)
166166

167167

168+
@pytest.mark.skipif(
169+
os.getenv("RUN_DB_TESTS", "").strip().lower() not in {"yes", "true"},
170+
reason="RUN_DB_TESTS environment variable must be set to 'yes' or 'true' (case insensitive)",
171+
)
172+
def test_mysql_suspend_resume(test_linode_client, test_create_sql_db):
173+
db = test_linode_client.load(MySQLDatabase, test_create_sql_db.id)
174+
175+
db.suspend()
176+
177+
wait_for_condition(
178+
10,
179+
300,
180+
get_sql_db_status,
181+
test_linode_client,
182+
test_create_sql_db.id,
183+
"suspended",
184+
)
185+
186+
assert db.status == "suspended"
187+
188+
db.resume()
189+
190+
wait_for_condition(
191+
30,
192+
600,
193+
get_sql_db_status,
194+
test_linode_client,
195+
test_create_sql_db.id,
196+
"active",
197+
)
198+
199+
assert db.status == "active"
200+
201+
168202
# ------- POSTGRESQL DB Test cases -------
169203
@pytest.mark.skipif(
170204
os.getenv("RUN_DB_TESTS", "").strip().lower() not in {"yes", "true"},
@@ -411,3 +445,37 @@ def test_reset_postgres_credentials(
411445

412446
assert db.credentials.username == "akmadmin"
413447
assert db.credentials.password != old_pass
448+
449+
450+
@pytest.mark.skipif(
451+
os.getenv("RUN_DB_TESTS", "").strip().lower() not in {"yes", "true"},
452+
reason="RUN_DB_TESTS environment variable must be set to 'yes' or 'true' (case insensitive)",
453+
)
454+
def test_postgres_suspend_resume(test_linode_client, test_create_postgres_db):
455+
db = test_linode_client.load(PostgreSQLDatabase, test_create_postgres_db.id)
456+
457+
db.suspend()
458+
459+
wait_for_condition(
460+
10,
461+
300,
462+
get_postgres_db_status,
463+
test_linode_client,
464+
test_create_postgres_db.id,
465+
"suspended",
466+
)
467+
468+
assert db.status == "suspended"
469+
470+
db.resume()
471+
472+
wait_for_condition(
473+
30,
474+
600,
475+
get_postgres_db_status,
476+
test_linode_client,
477+
test_create_postgres_db.id,
478+
"active",
479+
)
480+
481+
assert db.status == "active"

test/unit/objects/database_test.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,34 @@ def test_reset_credentials(self):
263263
m.call_url, "/databases/mysql/instances/123/credentials/reset"
264264
)
265265

266+
def test_suspend(self):
267+
"""
268+
Test MySQL Database suspend logic.
269+
"""
270+
with self.mock_post("/databases/mysql/instances/123/suspend") as m:
271+
db = MySQLDatabase(self.client, 123)
272+
273+
db.suspend()
274+
275+
self.assertEqual(m.method, "post")
276+
self.assertEqual(
277+
m.call_url, "/databases/mysql/instances/123/suspend"
278+
)
279+
280+
def test_resume(self):
281+
"""
282+
Test MySQL Database resume logic.
283+
"""
284+
with self.mock_post("/databases/mysql/instances/123/resume") as m:
285+
db = MySQLDatabase(self.client, 123)
286+
287+
db.resume()
288+
289+
self.assertEqual(m.method, "post")
290+
self.assertEqual(
291+
m.call_url, "/databases/mysql/instances/123/resume"
292+
)
293+
266294

267295
class PostgreSQLDatabaseTest(ClientBaseCase):
268296
"""
@@ -451,3 +479,31 @@ def test_reset_credentials(self):
451479
m.call_url,
452480
"/databases/postgresql/instances/123/credentials/reset",
453481
)
482+
483+
def test_suspend(self):
484+
"""
485+
Test PostgreSQL Database suspend logic.
486+
"""
487+
with self.mock_post("/databases/postgresql/instances/123/suspend") as m:
488+
db = PostgreSQLDatabase(self.client, 123)
489+
490+
db.suspend()
491+
492+
self.assertEqual(m.method, "post")
493+
self.assertEqual(
494+
m.call_url, "/databases/postgresql/instances/123/suspend"
495+
)
496+
497+
def test_resume(self):
498+
"""
499+
Test PostgreSQL Database resume logic.
500+
"""
501+
with self.mock_post("/databases/postgresql/instances/123/resume") as m:
502+
db = PostgreSQLDatabase(self.client, 123)
503+
504+
db.resume()
505+
506+
self.assertEqual(m.method, "post")
507+
self.assertEqual(
508+
m.call_url, "/databases/postgresql/instances/123/resume"
509+
)

0 commit comments

Comments
 (0)