Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/c7n/manager.py: 58%

86 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:51 +0000

1# Copyright The Cloud Custodian Authors. 

2# SPDX-License-Identifier: Apache-2.0 

3from collections import deque 

4import logging 

5 

6from c7n import cache, deprecated 

7from c7n.executor import ThreadPoolExecutor 

8from c7n.provider import clouds 

9from c7n.registry import PluginRegistry 

10from c7n.resources import load_resources 

11try: 

12 from c7n.resources.aws import AWS 

13 resources = AWS.resources 

14except ImportError: 

15 resources = PluginRegistry('resources') 

16 

17from c7n.utils import dumps 

18 

19 

20def iter_filters(filters, block_end=False): 

21 queue = deque(filters) 

22 while queue: 

23 f = queue.popleft() 

24 if f is not None and f.type in ('or', 'and', 'not'): 

25 if block_end: 

26 queue.appendleft(None) 

27 for gf in f.filters: 

28 queue.appendleft(gf) 

29 yield f 

30 

31 

32class ResourceManager: 

33 """ 

34 A Cloud Custodian resource 

35 """ 

36 

37 filter_registry = None 

38 action_registry = None 

39 executor_factory = ThreadPoolExecutor 

40 retry = None 

41 permissions = () 

42 get_client = None 

43 

44 def __init__(self, ctx, data): 

45 self.ctx = ctx 

46 self.session_factory = ctx.session_factory 

47 self.config = ctx.options 

48 self.data = data 

49 self._cache = cache.factory(self.ctx.options) 

50 self.log = logging.getLogger('custodian.resources.%s' % ( 

51 self.__class__.__name__.lower())) 

52 

53 if self.filter_registry: 

54 self.filters = self.filter_registry.parse( 

55 self.data.get('filters', []), self) 

56 if self.action_registry: 

57 self.actions = self.action_registry.parse( 

58 self.data.get('actions', []), self) 

59 

60 def format_json(self, resources, fh): 

61 return dumps(resources, fh, indent=2) 

62 

63 def match_ids(self, ids): 

64 """return ids that match this resource type's id format.""" 

65 return ids 

66 

67 @classmethod 

68 def get_permissions(cls): 

69 return () 

70 

71 def get_resources(self, resource_ids): 

72 """Retrieve a set of resources by id.""" 

73 return [] 

74 

75 def resources(self): 

76 raise NotImplementedError("") 

77 

78 def get_resource_manager(self, resource_type, data=None): 

79 """get a resource manager or a given resource type. 

80 

81 assumes the query is for the same underlying cloud provider. 

82 """ 

83 if '.' in resource_type: 

84 provider_name, resource_type = resource_type.split('.', 1) 

85 else: 

86 provider_name = self.ctx.policy.provider_name 

87 

88 # check and load 

89 load_resources(('%s.%s' % (provider_name, resource_type),)) 

90 provider_resources = clouds[provider_name].resources 

91 klass = provider_resources.get(resource_type) 

92 if klass is None: 

93 raise ValueError(resource_type) 

94 

95 # if we're already querying via config carry it forward 

96 if not data and self.source_type == 'config' and getattr( 

97 klass.get_model(), 'config_type', None): 

98 return klass(self.ctx, {'source': self.source_type}) 

99 return klass(self.ctx, data or {}) 

100 

101 def filter_resources(self, resources, event=None): 

102 original = len(resources) 

103 if event and event.get('debug', False): 

104 self.log.info( 

105 "Filtering resources using %d filters", len(self.filters)) 

106 for idx, f in enumerate(self.filters, start=1): 

107 if not resources: 

108 break 

109 rcount = len(resources) 

110 

111 with self.ctx.tracer.subsegment("filter:%s" % f.type): 

112 resources = f.process(resources, event) 

113 

114 if event and event.get('debug', False): 

115 self.log.debug( 

116 "Filter #%d applied %d->%d filter: %s", 

117 idx, rcount, len(resources), dumps(f.data, indent=None)) 

118 self.log.debug("Filtered from %d to %d %s" % ( 

119 original, len(resources), self.__class__.__name__.lower())) 

120 return resources 

121 

122 def get_model(self): 

123 """Returns the resource meta-model. 

124 """ 

125 return self.query.resolve(self.resource_type) 

126 

127 def iter_filters(self, block_end=False): 

128 return iter_filters(self.filters, block_end=block_end) 

129 

130 def validate(self): 

131 """ 

132 Validates resource definition, does NOT validate filters, actions, modes. 

133 

134 Example use case: A resource type that requires an additional query 

135 

136 :example: 

137 

138 .. code-block:: yaml 

139 

140 policies: 

141 - name: k8s-custom-resource 

142 resource: k8s.custom-namespaced-resource 

143 query: 

144 - version: v1 

145 group stable.example.com 

146 plural: crontabs 

147 """ 

148 pass 

149 

150 def get_deprecations(self): 

151 """Return any matching deprecations for the resource itself.""" 

152 return deprecated.check_deprecations(self)