Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/c7n/actions/invoke.py: 34%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

44 statements  

1# Copyright The Cloud Custodian Authors. 

2# SPDX-License-Identifier: Apache-2.0 

3 

4try: 

5 from botocore.config import Config 

6except ImportError: 

7 from c7n.config import Bag as Config # pragma: no cover 

8 

9from .core import EventAction 

10from c7n import utils 

11from c7n.manager import resources 

12from c7n.version import version as VERSION 

13from c7n.credentials import assumed_session 

14 

15 

16class LambdaInvoke(EventAction): 

17 """Invoke an arbitrary lambda 

18 

19 serialized invocation parameters 

20 

21 - resources / collection of resources 

22 - policy / policy that is invoke the lambda 

23 - action / action that is invoking the lambda 

24 - event / cloud trail event if any 

25 - version / version of custodian invoking the lambda 

26 

27 We automatically batch into sets of 250 for invocation, 

28 We try to utilize async invocation by default, this imposes 

29 some greater size limits of 128kb which means we batch 

30 invoke. 

31 

32 Example:: 

33 

34 - type: invoke-lambda 

35 function: my-function 

36 assume-role: iam-role-arn 

37 

38 Note, if you're synchronously invoking the lambda, you may also need 

39 to configure the timeout to avoid multiple invocations. The default 

40 timeout is 90s. If the lambda doesn't respond within that time, the boto 

41 sdk will invoke the lambda again with the same 

42 arguments. Alternatively, use `async: true` 

43 

44 """ 

45 schema_alias = True 

46 schema = { 

47 'type': 'object', 

48 'required': ['type', 'function'], 

49 'additionalProperties': False, 

50 'properties': { 

51 'type': {'enum': ['invoke-lambda']}, 

52 'function': {'type': 'string'}, 

53 'assume-role': {'type': 'string'}, 

54 'region': {'type': 'string'}, 

55 'async': {'type': 'boolean'}, 

56 'qualifier': {'type': 'string'}, 

57 'batch_size': {'type': 'integer'}, 

58 'timeout': {'type': 'integer'}, 

59 'vars': {'type': 'object'}, 

60 } 

61 } 

62 

63 permissions = ('lambda:InvokeFunction', 

64 'iam:ListAccountAliases',) 

65 

66 def process(self, resources, event=None): 

67 

68 config = Config(read_timeout=self.data.get( 

69 'timeout', 90), region_name=self.data.get('region', None)) 

70 session = utils.local_session(self.manager.session_factory) 

71 assumed_role = self.data.get('assume-role', '') 

72 

73 if assumed_role: 

74 self.log.debug('Assuming role: {}'.format(assumed_role)) 

75 target_session = assumed_session( 

76 role_arn=assumed_role, session_name='LambdaAssumedRoleSession', session=session) 

77 client = target_session.client('lambda', config=config) 

78 else: 

79 client = utils.local_session( 

80 self.manager.session_factory).client('lambda', config=config) 

81 

82 params = dict(FunctionName=self.data['function']) 

83 if self.data.get('qualifier'): 

84 params['Qualifier'] = self.data['Qualifier'] 

85 

86 if self.data.get('async', True): 

87 params['InvocationType'] = 'Event' 

88 

89 alias = utils.get_account_alias_from_sts( 

90 utils.local_session(self.manager.session_factory)) 

91 

92 payload = { 

93 'version': VERSION, 

94 'event': event, 

95 'account_id': self.manager.config.account_id, 

96 'account': alias, 

97 'region': self.manager.config.region, 

98 'action': self.data, 

99 'policy': self.manager.data} 

100 

101 results = [] 

102 for resource_set in utils.chunks(resources, self.data.get('batch_size', 250)): 

103 payload['resources'] = resource_set 

104 params['Payload'] = utils.dumps(payload) 

105 result = client.invoke(**params) 

106 result['Payload'] = result['Payload'].read() 

107 if isinstance(result['Payload'], bytes): 

108 result['Payload'] = result['Payload'].decode('utf-8') 

109 results.append(result) 

110 return results 

111 

112 @classmethod 

113 def register_resources(klass, registry, resource_class): 

114 if 'invoke-lambda' not in resource_class.action_registry: 

115 resource_class.action_registry.register('invoke-lambda', LambdaInvoke) 

116 

117 

118resources.subscribe(LambdaInvoke.register_resources)