diff --git a/linode_api4/groups/database.py b/linode_api4/groups/database.py index 9de02ac35..9546100a8 100644 --- a/linode_api4/groups/database.py +++ b/linode_api4/groups/database.py @@ -9,6 +9,7 @@ from linode_api4.objects import ( Database, DatabaseEngine, + DatabasePrivateNetwork, DatabaseType, MySQLDatabase, PostgreSQLDatabase, @@ -126,6 +127,7 @@ def mysql_create( engine, ltype, engine_config: Union[MySQLDatabaseConfigOptions, Dict[str, Any]] = None, + private_network: Union[DatabasePrivateNetwork, Dict[str, Any]] = None, **kwargs, ): """ @@ -159,6 +161,8 @@ def mysql_create( :type ltype: str or Type :param engine_config: The configuration options for this MySQL cluster :type engine_config: Dict[str, Any] or MySQLDatabaseConfigOptions + :param private_network: The private network settings to use for this cluster + :type private_network: Dict[str, Any] or DatabasePrivateNetwork """ params = { @@ -167,6 +171,7 @@ def mysql_create( "engine": engine, "type": ltype, "engine_config": engine_config, + "private_network": private_network, } params.update(kwargs) @@ -262,6 +267,7 @@ def postgresql_create( engine_config: Union[ PostgreSQLDatabaseConfigOptions, Dict[str, Any] ] = None, + private_network: Union[DatabasePrivateNetwork, Dict[str, Any]] = None, **kwargs, ): """ @@ -295,6 +301,8 @@ def postgresql_create( :type ltype: str or Type :param engine_config: The configuration options for this PostgreSQL cluster :type engine_config: Dict[str, Any] or PostgreSQLDatabaseConfigOptions + :param private_network: The private network settings to use for this cluster + :type private_network: Dict[str, Any] or DatabasePrivateNetwork """ params = { @@ -303,6 +311,7 @@ def postgresql_create( "engine": engine, "type": ltype, "engine_config": engine_config, + "private_network": private_network, } params.update(kwargs) diff --git a/linode_api4/objects/database.py b/linode_api4/objects/database.py index 39249bbf9..979990e8e 100644 --- a/linode_api4/objects/database.py +++ b/linode_api4/objects/database.py @@ -74,6 +74,18 @@ def invalidate(self): Base.invalidate(self) +@dataclass +class DatabasePrivateNetwork(JSONObject): + """ + DatabasePrivateNetwork is used to specify + a Database Cluster's private network settings during its creation. + """ + + vpc_id: Optional[int] = None + subnet_id: Optional[int] = None + public_access: Optional[bool] = None + + @deprecated( reason="Backups are not supported for non-legacy database clusters." ) @@ -304,6 +316,9 @@ class MySQLDatabase(Base): "engine_config": Property( mutable=True, json_object=MySQLDatabaseConfigOptions ), + "private_network": Property( + mutable=True, json_object=DatabasePrivateNetwork, nullable=True + ), } @property @@ -470,6 +485,9 @@ class PostgreSQLDatabase(Base): "engine_config": Property( mutable=True, json_object=PostgreSQLDatabaseConfigOptions ), + "private_network": Property( + mutable=True, json_object=DatabasePrivateNetwork, nullable=True + ), } @property @@ -636,6 +654,9 @@ class Database(Base): "updated": Property(), "updates": Property(), "version": Property(), + "private_network": Property( + json_object=DatabasePrivateNetwork, nullable=True + ), } @property diff --git a/linode_api4/objects/vpc.py b/linode_api4/objects/vpc.py index 94c0302f0..52fdacbce 100644 --- a/linode_api4/objects/vpc.py +++ b/linode_api4/objects/vpc.py @@ -21,6 +21,13 @@ class VPCSubnetLinode(JSONObject): interfaces: Optional[List[VPCSubnetLinodeInterface]] = None +@dataclass +class VPCSubnetDatabase(JSONObject): + id: int = 0 + ipv4_range: Optional[str] = None + ipv6_ranges: Optional[List[str]] = None + + class VPCSubnet(DerivedBase): """ An instance of a VPC subnet. @@ -37,6 +44,7 @@ class VPCSubnet(DerivedBase): "label": Property(mutable=True), "ipv4": Property(), "linodes": Property(json_object=VPCSubnetLinode, unordered=True), + "databases": Property(json_object=VPCSubnetDatabase, unordered=True), "created": Property(is_datetime=True), "updated": Property(is_datetime=True), } diff --git a/test/fixtures/databases_instances.json b/test/fixtures/databases_instances.json index 3b3f4d602..5e92515a5 100644 --- a/test/fixtures/databases_instances.json +++ b/test/fixtures/databases_instances.json @@ -27,7 +27,12 @@ "hour_of_day": 0, "week_of_month": null }, - "version": "8.0.26" + "version": "8.0.26", + "private_network": { + "vpc_id": 1234, + "subnet_id": 5678, + "public_access": true + } } ], "page": 1, diff --git a/test/fixtures/databases_mysql_instances.json b/test/fixtures/databases_mysql_instances.json index d6e3f2e64..e60bfe019 100644 --- a/test/fixtures/databases_mysql_instances.json +++ b/test/fixtures/databases_mysql_instances.json @@ -61,6 +61,11 @@ "tmp_table_size": 16777216, "wait_timeout": 28800 } + }, + "private_network": { + "vpc_id": 1234, + "subnet_id": 5678, + "public_access": true } } ], diff --git a/test/fixtures/databases_postgresql_instances.json b/test/fixtures/databases_postgresql_instances.json index 92d5ce945..47573aa12 100644 --- a/test/fixtures/databases_postgresql_instances.json +++ b/test/fixtures/databases_postgresql_instances.json @@ -83,6 +83,11 @@ }, "shared_buffers_percentage": 41.5, "work_mem": 4 + }, + "private_network": { + "vpc_id": 1234, + "subnet_id": 5678, + "public_access": true } } ], diff --git a/test/fixtures/vpcs_123456_subnets.json b/test/fixtures/vpcs_123456_subnets.json index 37537efb2..a24642d78 100644 --- a/test/fixtures/vpcs_123456_subnets.json +++ b/test/fixtures/vpcs_123456_subnets.json @@ -21,6 +21,15 @@ ] } ], + "databases": [ + { + "id": 12345, + "ipv4_range": "10.0.0.0/24", + "ipv6_ranges": [ + "2001:db8::/64" + ] + } + ], "created": "2018-01-01T00:01:01", "updated": "2018-01-01T00:01:01" } diff --git a/test/fixtures/vpcs_123456_subnets_789.json b/test/fixtures/vpcs_123456_subnets_789.json index 7fac495c4..43a77cd02 100644 --- a/test/fixtures/vpcs_123456_subnets_789.json +++ b/test/fixtures/vpcs_123456_subnets_789.json @@ -19,6 +19,15 @@ ] } ], + "databases": [ + { + "id": 12345, + "ipv4_range": "10.0.0.0/24", + "ipv6_ranges": [ + "2001:db8::/64" + ] + } + ], "created": "2018-01-01T00:01:01", "updated": "2018-01-01T00:01:01" } \ No newline at end of file diff --git a/test/unit/groups/database_test.py b/test/unit/groups/database_test.py index 9647fed82..5e2964c8d 100644 --- a/test/unit/groups/database_test.py +++ b/test/unit/groups/database_test.py @@ -61,6 +61,9 @@ def test_get_databases(self): self.assertEqual(dbs[0].region, "us-east") self.assertEqual(dbs[0].updates.duration, 3) self.assertEqual(dbs[0].version, "8.0.26") + self.assertEqual(dbs[0].private_network.vpc_id, 1234) + self.assertEqual(dbs[0].private_network.subnet_id, 5678) + self.assertEqual(dbs[0].private_network.public_access, True) def test_database_instance(self): """ @@ -1338,6 +1341,10 @@ def test_get_mysql_instances(self): self.assertEqual(dbs[0].engine_config.mysql.tmp_table_size, 16777216) self.assertEqual(dbs[0].engine_config.mysql.wait_timeout, 28800) + self.assertEqual(dbs[0].private_network.vpc_id, 1234) + self.assertEqual(dbs[0].private_network.subnet_id, 5678) + self.assertEqual(dbs[0].private_network.public_access, True) + def test_get_postgresql_instances(self): """ Test that postgresql instances can be retrieved properly @@ -1452,3 +1459,7 @@ def test_get_postgresql_instances(self): self.assertEqual(dbs[0].engine_config.pg.track_io_timing, "off") self.assertEqual(dbs[0].engine_config.pg.wal_sender_timeout, 60000) self.assertEqual(dbs[0].engine_config.pg.wal_writer_delay, 50) + + self.assertEqual(dbs[0].private_network.vpc_id, 1234) + self.assertEqual(dbs[0].private_network.subnet_id, 5678) + self.assertEqual(dbs[0].private_network.public_access, True) diff --git a/test/unit/objects/database_test.py b/test/unit/objects/database_test.py index c5abe3a58..535b2a336 100644 --- a/test/unit/objects/database_test.py +++ b/test/unit/objects/database_test.py @@ -2,6 +2,7 @@ from test.unit.base import ClientBaseCase from linode_api4 import ( + DatabasePrivateNetwork, MySQLDatabaseConfigMySQLOptions, MySQLDatabaseConfigOptions, PostgreSQLDatabase, @@ -41,6 +42,11 @@ def test_create(self): ), binlog_retention_period=200, ), + private_network=DatabasePrivateNetwork( + vpc_id=1234, + subnet_id=5678, + public_access=True, + ), ) except Exception as e: logger.warning( @@ -61,6 +67,12 @@ def test_create(self): m.call_data["engine_config"]["binlog_retention_period"], 200 ) + self.assertEqual(m.call_data["private_network"]["vpc_id"], 1234) + self.assertEqual(m.call_data["private_network"]["subnet_id"], 5678) + self.assertEqual( + m.call_data["private_network"]["public_access"], True + ) + def test_update(self): """ Test that the MySQL database can be updated @@ -78,6 +90,11 @@ def test_update(self): mysql=MySQLDatabaseConfigMySQLOptions(connect_timeout=20), binlog_retention_period=200, ) + db.private_network = DatabasePrivateNetwork( + vpc_id=1234, + subnet_id=5678, + public_access=True, + ) db.save() @@ -93,6 +110,12 @@ def test_update(self): m.call_data["engine_config"]["binlog_retention_period"], 200 ) + self.assertEqual(m.call_data["private_network"]["vpc_id"], 1234) + self.assertEqual(m.call_data["private_network"]["subnet_id"], 5678) + self.assertEqual( + m.call_data["private_network"]["public_access"], True + ) + def test_list_backups(self): """ Test that MySQL backups list properly @@ -259,6 +282,11 @@ def test_create(self): ), work_mem=4, ), + private_network=DatabasePrivateNetwork( + vpc_id=1234, + subnet_id=5678, + public_access=True, + ), ) except Exception: pass @@ -302,6 +330,12 @@ def test_create(self): ) self.assertEqual(m.call_data["engine_config"]["work_mem"], 4) + self.assertEqual(m.call_data["private_network"]["vpc_id"], 1234) + self.assertEqual(m.call_data["private_network"]["subnet_id"], 5678) + self.assertEqual( + m.call_data["private_network"]["public_access"], True + ) + def test_update(self): """ Test that the PostgreSQL database can be updated @@ -322,6 +356,12 @@ def test_update(self): work_mem=4, ) + db.private_network = DatabasePrivateNetwork( + vpc_id=1234, + subnet_id=5678, + public_access=True, + ) + db.save() self.assertEqual(m.method, "put") @@ -337,6 +377,12 @@ def test_update(self): ) self.assertEqual(m.call_data["engine_config"]["work_mem"], 4) + self.assertEqual(m.call_data["private_network"]["vpc_id"], 1234) + self.assertEqual(m.call_data["private_network"]["subnet_id"], 5678) + self.assertEqual( + m.call_data["private_network"]["public_access"], True + ) + def test_list_backups(self): """ Test that PostgreSQL backups list properly diff --git a/test/unit/objects/vpc_test.py b/test/unit/objects/vpc_test.py index 7888bc101..f69066aa5 100644 --- a/test/unit/objects/vpc_test.py +++ b/test/unit/objects/vpc_test.py @@ -124,6 +124,10 @@ def validate_vpc_subnet_789(self, subnet: VPCSubnet): assert subnet.created == expected_dt assert subnet.updated == expected_dt + assert subnet.databases[0].id == 12345 + assert subnet.databases[0].ipv4_range == "10.0.0.0/24" + assert subnet.databases[0].ipv6_ranges == ["2001:db8::/64"] + assert subnet.linodes[0].interfaces[0].id == 678 assert subnet.linodes[0].interfaces[0].active assert subnet.linodes[0].interfaces[0].config_id is None