Skip to content

Commit e46e21f

Browse files
authored
[aws][feat] Add dynamodb continuous backup (#2090)
1 parent 9245b9d commit e46e21f

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

plugins/aws/fix_plugin_aws/resource/dynamodb.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import ClassVar, Dict, List, Optional, Type, Any
33
from attrs import define, field
44
from fix_plugin_aws.aws_client import AwsClient
5-
from fix_plugin_aws.resource.base import AwsApiSpec, AwsResource, GraphBuilder
5+
from fix_plugin_aws.resource.base import AwsApiSpec, AwsResource, GraphBuilder, parse_json
66
from fix_plugin_aws.resource.kinesis import AwsKinesisStream
77
from fix_plugin_aws.resource.kms import AwsKmsKey
88
from fix_plugin_aws.utils import ToDict
@@ -328,6 +328,30 @@ class AwsDynamoDbArchivalSummary:
328328
archival_backup_arn: Optional[str] = field(default=None)
329329

330330

331+
@define(eq=False, slots=False)
332+
class AwsDynamoDbPointInTimeRecovery:
333+
kind: ClassVar[str] = "aws_dynamo_db_point_in_time_recovery"
334+
mapping: ClassVar[Dict[str, Bender]] = {
335+
"status": S("PointInTimeRecoveryStatus"),
336+
"earliest_restorable_date_time": S("EarliestRestorableDateTime"),
337+
"latest_restorable_date_time": S("LatestRestorableDateTime"),
338+
}
339+
status: Optional[str] = field(default=None, metadata={"description": "The current state of point in time recovery: ENABLED - Point in time recovery is enabled. DISABLED - Point in time recovery is disabled."}) # fmt: skip
340+
earliest_restorable_date_time: Optional[datetime] = field(default=None, metadata={"description": "Specifies the earliest point in time you can restore your table to. You can restore your table to any point in time during the last 35 days."}) # fmt: skip
341+
latest_restorable_date_time: Optional[datetime] = field(default=None, metadata={"description": "LatestRestorableDateTime is typically 5 minutes before the current time."}) # fmt: skip
342+
343+
344+
@define(eq=False, slots=False)
345+
class AwsDynamoDbContinuousBackup:
346+
kind: ClassVar[str] = "aws_dynamo_db_continuous_backup"
347+
mapping: ClassVar[Dict[str, Bender]] = {
348+
"status": S("ContinuousBackupsStatus"),
349+
"point_in_time_recovery": S("PointInTimeRecoveryDescription") >> Bend(AwsDynamoDbPointInTimeRecovery.mapping),
350+
}
351+
status: Optional[str] = field(default=None, metadata={"description": "ContinuousBackupsStatus can be one of the following states: ENABLED, DISABLED"}) # fmt: skip
352+
point_in_time_recovery: Optional[AwsDynamoDbPointInTimeRecovery] = field(default=None, metadata={"description": "The description of the point in time recovery settings applied to the table."}) # fmt: skip
353+
354+
331355
@define(eq=False, slots=False)
332356
class AwsDynamoDbTable(DynamoDbTaggable, AwsResource):
333357
kind: ClassVar[str] = "aws_dynamodb_table"
@@ -390,26 +414,37 @@ class AwsDynamoDbTable(DynamoDbTaggable, AwsResource):
390414
dynamodb_sse_description: Optional[AwsDynamoDbSSEDescription] = field(default=None)
391415
dynamodb_archival_summary: Optional[AwsDynamoDbArchivalSummary] = field(default=None)
392416
dynamodb_table_class_summary: Optional[AwsDynamoDbTableClassSummary] = field(default=None)
417+
dynamodb_continuous_backup: Optional[AwsDynamoDbContinuousBackup] = field(default=None)
393418

394419
@classmethod
395420
def called_collect_apis(cls) -> List[AwsApiSpec]:
396421
return [
397422
cls.api_spec,
398423
AwsApiSpec(service_name, "describe-table"),
399424
AwsApiSpec(service_name, "list-tags-of-resource"),
425+
AwsApiSpec(service_name, "describe-continuous-backups"),
400426
]
401427

402428
@classmethod
403429
def collect(cls: Type[AwsResource], json: List[Json], builder: GraphBuilder) -> List[AwsResource]:
404430
instances = []
405431

432+
def add_backup_description(table: AwsDynamoDbTable) -> None:
433+
if continuous_backup := builder.client.get(
434+
service_name, "describe-continuous-backups", "ContinuousBackupsDescription", TableName=table.name
435+
):
436+
table.dynamodb_continuous_backup = parse_json(
437+
continuous_backup, AwsDynamoDbContinuousBackup, builder, AwsDynamoDbContinuousBackup.mapping
438+
)
439+
406440
def add_instance(table: str) -> None:
407441
table_description = builder.client.get(service_name, "describe-table", "Table", TableName=table)
408442
if table_description is not None:
409443
if instance := cls.from_api(table_description, builder):
410444
instances.append(instance)
411445
builder.add_node(instance, table_description)
412446
builder.submit_work(service_name, add_tags, instance)
447+
builder.submit_work(service_name, add_backup_description, instance)
413448

414449
def add_tags(table: AwsDynamoDbTable) -> None:
415450
tags = builder.client.list(service_name, "list-tags-of-resource", "Tags", ResourceArn=table.arn)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"ContinuousBackupsDescription": {
3+
"ContinuousBackupsStatus": "DISABLED",
4+
"PointInTimeRecoveryDescription": {
5+
"PointInTimeRecoveryStatus": "DISABLED",
6+
"EarliestRestorableDateTime": "2024-05-28T08:58:20Z",
7+
"LatestRestorableDateTime": "2024-05-28T08:58:20Z"
8+
}
9+
}
10+
}

plugins/aws/tools/aws_model_gen.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ def default_imports() -> str:
936936

937937
if __name__ == "__main__":
938938
"""print some test data"""
939-
print(json.dumps(create_test_response("ssm", "list-resource-compliance-summaries"), indent=2))
939+
print(json.dumps(create_test_response("dynamodb", "describe-continuous-backups"), indent=2))
940940

941941
"""print the class models"""
942942
# print(default_imports())

0 commit comments

Comments
 (0)