Coverage for src/extratools_cloud/aws/cloud_control.py: 0%
19 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-16 05:54 -0700
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-16 05:54 -0700
1import json
2from collections.abc import Iterable
4import boto3
5from botocore.client import BaseClient
6from extratools_core.crudl import CRUDLDict
7from extratools_core.json import JsonDict
9from .helpers import ClientErrorHandler
11default_client: BaseClient = boto3.client("cloudcontrol")
14def get_resource_dict(
15 resource_type: str,
16 *,
17 client: BaseClient | None = None,
18) -> CRUDLDict[str, JsonDict]:
19 client = client or default_client
21 # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudcontrol.html
23 @ClientErrorHandler(
24 "ResourceNotFoundException",
25 KeyError,
26 )
27 def read_func(identifier: str) -> JsonDict:
28 return json.loads(client.get_resource(
29 TypeName=resource_type,
30 Identifier=identifier,
31 )["ResourceDescription"]["Properties"])
33 # Resource model may be treated as a special filter.
34 # It must be specified for certain resource types,
35 # yet must be unspecified for certain other resource types.
36 # https://docs.aws.amazon.com/cloudcontrolapi/latest/userguide/resource-operations-list.html#resource-operations-list-containers
37 def list_func(resource_model: JsonDict | None) -> Iterable[tuple[str, JsonDict]]:
38 paginator = client.get_paginator("list_resources")
39 for page in paginator.paginate(
40 TypeName=resource_type,
41 **({} if resource_model is None else dict(
42 ResourceModel=json.dumps(resource_model),
43 )),
44 ):
45 for resource in page.get("ResourceDescriptions", []):
46 yield (resource["Identifier"], json.loads(resource["Properties"]))
48 return CRUDLDict[str, JsonDict](
49 create_func=lambda _, desired_state: client.create_resource(
50 TypeName=resource_type,
51 DesiredState=json.dumps(desired_state),
52 ),
53 read_func=read_func,
54 update_func=lambda identifier, patch: client.update_resource(
55 TypeName=resource_type,
56 Identifier=identifier,
57 PatchDocument=json.dumps(patch),
58 ),
59 delete_func=lambda identifier: client.delete_resource(
60 TypeName=resource_type,
61 Identifier=identifier,
62 ),
63 list_func=list_func,
64 )