diff --git a/linode_api4/objects/linode.py b/linode_api4/objects/linode.py index 44e946b7c..f09e8ce34 100644 --- a/linode_api4/objects/linode.py +++ b/linode_api4/objects/linode.py @@ -790,6 +790,42 @@ class UpgradeInterfacesResult(JSONObject): ) +@dataclass +class InstanceBackupSchedule(JSONObject): + """ + InstanceBackupSchedule represents when automatic backups of a Linode Instance are taken. + """ + + include_none_values = True + + day: Optional[str] = None + window: Optional[str] = None + + +@dataclass +class InstanceBackupsOptions(JSONObject): + """ + InstanceBackupsOptions is used to update the backup settings of a Linode Instance. + """ + + enabled: bool = False + schedule: Optional[InstanceBackupSchedule] = None + + +@dataclass +class InstanceBackups(JSONObject): + """ + InstanceBackups represents the backup settings and status of a Linode Instance. + """ + + put_class = InstanceBackupsOptions + + enabled: bool = False + available: bool = False + schedule: Optional[InstanceBackupSchedule] = None + last_successful: Optional[str] = None + + class Instance(Base): """ A Linode Instance. @@ -811,7 +847,7 @@ class Instance(Base): "disks": Property(derived_class=Disk), "configs": Property(derived_class=Config), "type": Property(slug_relationship=Type), - "backups": Property(mutable=True), + "backups": Property(mutable=True, json_object=InstanceBackups), "ipv4": Property(unordered=True), "ipv6": Property(), "hypervisor": Property(), diff --git a/test/fixtures/linode_instances.json b/test/fixtures/linode_instances.json index 08cbe80c8..9f3b5bbc7 100644 --- a/test/fixtures/linode_instances.json +++ b/test/fixtures/linode_instances.json @@ -19,6 +19,8 @@ "label": "linode123", "backups": { "enabled": true, + "available": true, + "last_successful": "2018-01-01T00:01:01", "schedule": { "window": "W02", "day": "Scheduling" diff --git a/test/unit/objects/linode_test.py b/test/unit/objects/linode_test.py index 6e22e6fe6..eafbac328 100644 --- a/test/unit/objects/linode_test.py +++ b/test/unit/objects/linode_test.py @@ -26,6 +26,8 @@ Disk, Image, Instance, + InstanceBackups, + InstanceBackupSchedule, StackScript, Type, VPCSubnet, @@ -59,6 +61,14 @@ def test_get_linode(self): self.assertEqual(linode.lke_cluster_id, None) self.assertEqual(linode.maintenance_policy, "linode/migrate") + self.assertIsInstance(linode.backups, InstanceBackups) + self.assertTrue(linode.backups.enabled) + self.assertTrue(linode.backups.available) + self.assertEqual(linode.backups.last_successful, "2018-01-01T00:01:01") + self.assertIsInstance(linode.backups.schedule, InstanceBackupSchedule) + self.assertEqual(linode.backups.schedule.day, "Scheduling") + self.assertEqual(linode.backups.schedule.window, "W02") + json = linode._raw_json self.assertIsNotNone(json) self.assertEqual(json["id"], 123) @@ -229,6 +239,22 @@ def test_update_linode(self): }, ) + def test_update_linode_backups_disabled(self): + """ + Tests that an unset backup schedule is sent as explicit nulls + """ + with self.mock_put("linode/instances/456") as m: + linode = self.client.load(Instance, 456) + linode.save() + + self.assertEqual( + m.call_data["backups"], + { + "enabled": False, + "schedule": {"day": None, "window": None}, + }, + ) + def test_delete_linode(self): """ Tests that deleting a Linode creates the correct api request