Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/c7n/resources/rdsparamgroup.py: 65%
127 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
« 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
3import logging
5from botocore.exceptions import ClientError
7from c7n.actions import ActionRegistry, BaseAction
8from c7n.filters import FilterRegistry
9from c7n.manager import resources
10from c7n.query import QueryResourceManager, TypeInfo
11from c7n.utils import (type_schema, local_session, chunks)
12from c7n.tags import universal_augment
14log = logging.getLogger('custodian.rds-param-group')
16pg_filters = FilterRegistry('rds-param-group.filters')
17pg_actions = ActionRegistry('rds-param-group.actions')
20@resources.register('rds-param-group')
21class RDSParamGroup(QueryResourceManager):
22 """Resource manager for RDS parameter groups.
23 """
25 class resource_type(TypeInfo):
27 service = 'rds'
28 arn_type = 'pg'
29 enum_spec = ('describe_db_parameter_groups', 'DBParameterGroups', None)
30 name = id = 'DBParameterGroupName'
31 arn = 'DBParameterGroupArn'
32 dimension = 'DBParameterGroupName'
33 permissions_enum = ('rds:DescribeDBParameterGroups',)
34 cfn_type = 'AWS::RDS::DBParameterGroup'
35 universal_taggable = object()
37 augment = universal_augment
39 filter_registry = pg_filters
40 action_registry = pg_actions
43pg_cluster_filters = FilterRegistry('rds-cluster-param-group.filters')
44pg_cluster_actions = ActionRegistry('rds-cluster-param-group.actions')
47@resources.register('rds-cluster-param-group')
48class RDSClusterParamGroup(QueryResourceManager):
49 """ Resource manager for RDS cluster parameter groups.
50 """
52 class resource_type(TypeInfo):
54 service = 'rds'
55 arn_type = 'cluster-pg'
56 arn = 'DBClusterParameterGroupArn'
57 enum_spec = ('describe_db_cluster_parameter_groups', 'DBClusterParameterGroups', None)
58 name = id = 'DBClusterParameterGroupName'
59 dimension = 'DBClusterParameterGroupName'
60 permissions_enum = ('rds:DescribeDBClusterParameterGroups',)
61 cfn_type = 'AWS::RDS::DBClusterParameterGroup'
62 universal_taggable = object()
64 augment = universal_augment
66 filter_registry = pg_cluster_filters
67 action_registry = pg_cluster_actions
70class PGMixin:
72 def get_pg_name(self, pg):
73 return pg['DBParameterGroupName']
76class PGClusterMixin:
78 def get_pg_name(self, pg):
79 return pg['DBClusterParameterGroupName']
82class Copy(BaseAction):
84 schema = type_schema(
85 'copy',
86 **{
87 'required': ['name'],
88 'name': {'type': 'string'},
89 'description': {'type': 'string'},
90 }
91 )
93 def process(self, param_groups):
94 client = local_session(self.manager.session_factory).client('rds')
96 for param_group in param_groups:
97 name = self.get_pg_name(param_group)
98 copy_name = self.data.get('name')
99 copy_desc = self.data.get('description', 'Copy of {}'.format(name))
100 self.do_copy(client, name, copy_name, copy_desc)
101 self.log.info('Copied RDS parameter group %s to %s', name, copy_name)
104@pg_actions.register('copy')
105class PGCopy(PGMixin, Copy):
106 """ Action to copy an RDS parameter group.
108 :example:
110 .. code-block:: yaml
112 policies:
113 - name: rds-param-group-copy
114 resource: rds-param-group
115 filters:
116 - DBParameterGroupName: original_pg_name
117 actions:
118 - type: copy
119 name: copy_name
120 """
122 permissions = ('rds:CopyDBParameterGroup',)
124 def do_copy(self, client, name, copy_name, desc):
125 client.copy_db_parameter_group(
126 SourceDBParameterGroupIdentifier=name,
127 TargetDBParameterGroupIdentifier=copy_name,
128 TargetDBParameterGroupDescription=desc
129 )
132@pg_cluster_actions.register('copy')
133class PGClusterCopy(PGClusterMixin, Copy):
134 """ Action to copy an RDS cluster parameter group.
136 :example:
138 .. code-block:: yaml
140 policies:
141 - name: rds-cluster-param-group-copy
142 resource: rds-cluster-param-group
143 filters:
144 - DBClusterParameterGroupName: original_cluster_pg_name
145 actions:
146 - type: copy
147 name: copy_name
148 """
150 permissions = ('rds:CopyDBClusterParameterGroup',)
152 def do_copy(self, client, name, copy_name, desc):
153 client.copy_db_cluster_parameter_group(
154 SourceDBClusterParameterGroupIdentifier=name,
155 TargetDBClusterParameterGroupIdentifier=copy_name,
156 TargetDBClusterParameterGroupDescription=desc
157 )
160class Delete(BaseAction):
162 schema = type_schema('delete')
164 def process(self, param_groups):
165 client = local_session(self.manager.session_factory).client('rds')
167 for param_group in param_groups:
168 name = self.get_pg_name(param_group)
169 try:
170 self.do_delete(client, name)
171 except ClientError as e:
172 if e.response['Error']['Code'] == 'DBParameterGroupNotFoundFault':
173 self.log.warning('RDS parameter group %s already deleted', name)
174 continue
175 raise
176 self.log.info('Deleted RDS parameter group: %s', name)
179@pg_actions.register('delete')
180class PGDelete(PGMixin, Delete):
181 """Action to delete an RDS parameter group
183 :example:
185 .. code-block:: yaml
187 policies:
188 - name: rds-param-group-delete
189 resource: rds-param-group
190 filters:
191 - DBParameterGroupName: pg_name
192 actions:
193 - type: delete
194 """
196 permissions = ('rds:DeleteDBParameterGroup',)
198 def do_delete(self, client, name):
199 client.delete_db_parameter_group(DBParameterGroupName=name)
202@pg_cluster_actions.register('delete')
203class PGClusterDelete(PGClusterMixin, Delete):
204 """Action to delete an RDS cluster parameter group
206 :example:
208 .. code-block:: yaml
210 policies:
211 - name: rds-cluster-param-group-delete
212 resource: rds-cluster-param-group
213 filters:
214 - DBClusterParameterGroupName: cluster_pg_name
215 actions:
216 - type: delete
217 """
219 permissions = ('rds:DeleteDBClusterParameterGroup',)
221 def do_delete(self, client, name):
222 client.delete_db_cluster_parameter_group(DBClusterParameterGroupName=name)
225class Modify(BaseAction):
227 schema = type_schema(
228 'modify',
229 **{
230 'required': ['params'],
231 'params': {
232 'type': 'array',
233 'items': {
234 'type': 'object',
235 'required': ['name', 'value'],
236 'name': {'type': 'string'},
237 'value': {'type': 'string'},
238 'apply-method': {'type': 'string', 'enum': ['immediate', 'pending-reboot']}
239 },
240 },
241 }
242 )
244 def process(self, param_groups):
245 client = local_session(self.manager.session_factory).client('rds')
247 params = []
248 for param in self.data.get('params', []):
249 params.append({
250 'ParameterName': param['name'],
251 'ParameterValue': param['value'],
252 'ApplyMethod': param.get('apply-method', 'immediate'),
253 })
255 for param_group in param_groups:
256 name = self.get_pg_name(param_group)
258 # Fetch the existing parameters for this DB, so we only try to change the ones that are
259 # different.
260 cur_params = self.get_current_params(client, name)
261 changed_params = []
262 for param in params:
263 param_name = param['ParameterName']
264 if (param_name not in cur_params or
265 cur_params[param_name]['ParameterValue'] != param['ParameterValue']):
266 changed_params.append(param)
268 # Can only do 20 elements at a time per docs, so if we have more than that we will
269 # break it into multiple requests:
270 # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.modify_db_parameter_group
271 for param_set in chunks(changed_params, 5):
272 self.do_modify(client, name, param_set)
274 self.log.info('Modified RDS parameter group %s (%i parameters changed, %i unchanged)',
275 name, len(changed_params), len(params) - len(changed_params))
278@pg_actions.register('modify')
279class PGModify(PGMixin, Modify):
280 """Action to modify an RDS parameter group
282 :example:
284 .. code-block:: yaml
286 policies:
287 - name: rds-param-group-modify
288 resource: rds-param-group
289 filters:
290 - DBParameterGroupName: pg_name
291 actions:
292 - type: modify
293 params:
294 - name: autocommit
295 value: "1"
296 - name: max_connections
297 value: "100"
298 """
300 permissions = ('rds:DescribeDBParameters', 'rds:ModifyDBParameterGroup')
302 def get_current_params(self, client, name):
303 params = client.describe_db_parameters(DBParameterGroupName=name)
304 return {x['ParameterName']: {
305 'ParameterValue': x.get('ParameterValue'),
306 'ApplyMethod': x['ApplyMethod']}
307 for x in params.get('Parameters', [])}
309 def do_modify(self, client, name, params):
310 client.modify_db_parameter_group(DBParameterGroupName=name, Parameters=params)
313@pg_cluster_actions.register('modify')
314class PGClusterModify(PGClusterMixin, Modify):
315 """Action to modify an RDS cluster parameter group
317 :example:
319 .. code-block:: yaml
321 policies:
322 - name: rds-cluster-param-group-modify
323 resource: rds-cluster-param-group
324 filters:
325 - DBClusterParameterGroupName: cluster_pg_name
326 actions:
327 - type: modify
328 params:
329 - name: lower_case_table_names
330 value: "1"
331 - name: master_verify_checksum
332 value: "1"
333 """
335 permissions = ('rds:DescribeDBClusterParameters', 'rds:ModifyDBClusterParameterGroup')
337 def get_current_params(self, client, name):
338 params = client.describe_db_cluster_parameters(DBClusterParameterGroupName=name)
339 return {x['ParameterName']: {
340 'ParameterValue': x.get('ParameterValue'),
341 'ApplyMethod': x['ApplyMethod']}
342 for x in params.get('Parameters', [])}
344 def do_modify(self, client, name, params):
345 client.modify_db_cluster_parameter_group(
346 DBClusterParameterGroupName=name,
347 Parameters=params
348 )