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

1import json 

2from collections.abc import Iterable 

3 

4import boto3 

5from botocore.client import BaseClient 

6from extratools_core.crudl import CRUDLDict 

7from extratools_core.json import JsonDict 

8 

9from .helpers import ClientErrorHandler 

10 

11default_client: BaseClient = boto3.client("cloudcontrol") 

12 

13 

14def get_resource_dict( 

15 resource_type: str, 

16 *, 

17 client: BaseClient | None = None, 

18) -> CRUDLDict[str, JsonDict]: 

19 client = client or default_client 

20 

21 # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudcontrol.html 

22 

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"]) 

32 

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"])) 

47 

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 )