Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/c7n/resources/glue.py: 63%
441 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 json
4from botocore.exceptions import ClientError
5from concurrent.futures import as_completed
6from c7n.manager import resources, ResourceManager
7from c7n.query import QueryResourceManager, TypeInfo
8from c7n.utils import local_session, chunks, type_schema
9from c7n.actions import BaseAction, ActionRegistry, RemovePolicyBase
10from c7n.exceptions import PolicyValidationError
11from c7n.filters.vpc import SubnetFilter, SecurityGroupFilter
12from c7n.filters.related import RelatedResourceFilter
13from c7n.tags import universal_augment
14from c7n.filters import ValueFilter, FilterRegistry, CrossAccountAccessFilter
15from c7n import query, utils
16from c7n.resources.account import GlueCatalogEncryptionEnabled
17from c7n.filters.kms import KmsRelatedFilter
20@resources.register('glue-connection')
21class GlueConnection(QueryResourceManager):
23 class resource_type(TypeInfo):
24 service = 'glue'
25 enum_spec = ('get_connections', 'ConnectionList', {'HidePassword': True})
26 id = name = 'Name'
27 date = 'CreationTime'
28 arn_type = "connection"
29 cfn_type = 'AWS::Glue::Connection'
30 universal_taggable = object()
32 augment = universal_augment
35@GlueConnection.filter_registry.register('subnet')
36class ConnectionSubnetFilter(SubnetFilter):
38 RelatedIdsExpression = 'PhysicalConnectionRequirements.SubnetId'
41@GlueConnection.filter_registry.register('security-group')
42class ConnectionSecurityGroupFilter(SecurityGroupFilter):
44 RelatedIdsExpression = 'PhysicalConnectionRequirements.' \
45 'SecurityGroupIdList[]'
48@GlueConnection.action_registry.register('delete')
49class DeleteConnection(BaseAction):
50 """Delete a connection from the data catalog
52 :example:
54 .. code-block:: yaml
56 policies:
57 - name: delete-jdbc-connections
58 resource: glue-connection
59 filters:
60 - ConnectionType: JDBC
61 actions:
62 - type: delete
63 """
64 schema = type_schema('delete')
65 permissions = ('glue:DeleteConnection',)
67 def delete_connection(self, r):
68 client = local_session(self.manager.session_factory).client('glue')
69 try:
70 client.delete_connection(ConnectionName=r['Name'])
71 except ClientError as e:
72 if e.response['Error']['Code'] != 'EntityNotFoundException':
73 raise
75 def process(self, resources):
76 with self.executor_factory(max_workers=2) as w:
77 list(w.map(self.delete_connection, resources))
80@resources.register('glue-dev-endpoint')
81class GlueDevEndpoint(QueryResourceManager):
83 class resource_type(TypeInfo):
84 service = 'glue'
85 enum_spec = ('get_dev_endpoints', 'DevEndpoints', None)
86 id = name = 'EndpointName'
87 date = 'CreatedTimestamp'
88 arn_type = "devEndpoint"
89 universal_taggable = True
90 cfn_type = 'AWS::Glue::DevEndpoint'
92 augment = universal_augment
95@GlueDevEndpoint.filter_registry.register('subnet')
96class EndpointSubnetFilter(SubnetFilter):
98 RelatedIdsExpression = 'SubnetId'
101@GlueDevEndpoint.action_registry.register('delete')
102class DeleteDevEndpoint(BaseAction):
103 """Deletes public Glue Dev Endpoints
105 :example:
107 .. code-block:: yaml
109 policies:
110 - name: delete-public-dev-endpoints
111 resource: glue-dev-endpoint
112 filters:
113 - PublicAddress: present
114 actions:
115 - type: delete
116 """
117 schema = type_schema('delete')
118 permissions = ('glue:DeleteDevEndpoint',)
120 def delete_dev_endpoint(self, client, endpoint_set):
121 for e in endpoint_set:
122 try:
123 client.delete_dev_endpoint(EndpointName=e['EndpointName'])
124 except client.exceptions.AlreadyExistsException:
125 pass
127 def process(self, resources):
128 futures = []
129 client = local_session(self.manager.session_factory).client('glue')
130 with self.executor_factory(max_workers=2) as w:
131 for endpoint_set in chunks(resources, size=5):
132 futures.append(w.submit(self.delete_dev_endpoint, client, endpoint_set))
133 for f in as_completed(futures):
134 if f.exception():
135 self.log.error(
136 "Exception deleting glue dev endpoint \n %s",
137 f.exception())
140@resources.register('glue-job')
141class GlueJob(QueryResourceManager):
143 class resource_type(TypeInfo):
144 service = 'glue'
145 enum_spec = ('get_jobs', 'Jobs', None)
146 id = name = 'Name'
147 date = 'CreatedOn'
148 arn_type = 'job'
149 universal_taggable = True
150 cfn_type = 'AWS::Glue::Job'
152 permissions = ('glue:GetJobs',)
153 augment = universal_augment
156@GlueJob.action_registry.register('delete')
157class DeleteJob(BaseAction):
159 schema = type_schema('delete')
160 permissions = ('glue:DeleteJob',)
162 def process(self, resources):
163 client = local_session(self.manager.session_factory).client('glue')
164 for r in resources:
165 try:
166 client.delete_job(JobName=r['Name'])
167 except client.exceptions.EntityNotFoundException:
168 continue
171@GlueJob.action_registry.register('toggle-metrics')
172class GlueJobToggleMetrics(BaseAction):
173 """Enable or disable CloudWatch metrics for a Glue job
175 :example:
177 .. code-block:: yaml
179 policies:
180 - name: gluejob-enable-metrics
181 resource: glue-job
182 filters:
183 - type: value
184 key: 'DefaultArguments."--enable-metrics"'
185 value: absent
186 actions:
187 - type: toggle-metrics
188 enabled: true
189 """
190 schema = type_schema(
191 'toggle-metrics',
192 enabled={'type': 'boolean'},
193 required=['enabled'],
194 )
195 permissions = ('glue:UpdateJob',)
197 def prepare_params(self, r):
198 client = local_session(self.manager.session_factory).client('glue')
199 update_keys = client.meta._service_model.shape_for('JobUpdate').members
200 want_keys = set(r).intersection(update_keys) - {'AllocatedCapacity'}
201 params = {k: r[k] for k in want_keys}
203 # Can't specify MaxCapacity when updating/creating a job if
204 # job configuration includes WorkerType or NumberOfWorkers
205 if 'WorkerType' in params or 'NumberOfWorkers' in params:
206 del params['MaxCapacity']
208 # Can't specify Timeout when updating Ray jobs.
209 # Removing Timeout preserves default setting.
210 if params['Command']['Name'] == 'glueray':
211 del params['Timeout']
213 if self.data.get('enabled'):
214 if 'DefaultArguments' not in params:
215 params['DefaultArguments'] = {}
216 params["DefaultArguments"]["--enable-metrics"] = ""
217 else:
218 if 'DefaultArguments' in params and \
219 '--enable-metrics' in params['DefaultArguments']:
220 del params["DefaultArguments"]["--enable-metrics"]
222 return params
224 def process(self, resources):
225 client = local_session(self.manager.session_factory).client('glue')
227 for r in resources:
228 try:
229 job_name = r["Name"]
230 updated_resource = self.prepare_params(r)
231 client.update_job(JobName=job_name, JobUpdate=updated_resource)
232 except Exception as e:
233 self.log.error('Error updating glue job: {}'.format(e))
236@resources.register('glue-crawler')
237class GlueCrawler(QueryResourceManager):
239 class resource_type(TypeInfo):
240 service = 'glue'
241 enum_spec = ('get_crawlers', 'Crawlers', None)
242 id = name = 'Name'
243 date = 'CreatedOn'
244 arn_type = 'crawler'
245 state_key = 'State'
246 universal_taggable = True
247 cfn_type = 'AWS::Glue::Crawler'
249 augment = universal_augment
252class SecurityConfigFilter(RelatedResourceFilter):
253 """Filters glue crawlers with security configurations
255 :example:
257 .. code-block:: yaml
259 policies:
260 - name: need-kms-cloudwatch
261 resource: glue-crawler
262 filters:
263 - type: security-config
264 key: EncryptionConfiguration.CloudWatchEncryption.CloudWatchEncryptionMode
265 op: ne
266 value: SSE-KMS
268 To find resources missing any security configuration all set `missing: true` on the filter.
269 """
271 RelatedResource = "c7n.resources.glue.GlueSecurityConfiguration"
272 AnnotationKey = "matched-security-config"
273 RelatedIdsExpression = None
275 schema = type_schema(
276 'security-config',
277 missing={'type': 'boolean', 'default': False},
278 rinherit=ValueFilter.schema)
280 def validate(self):
281 if self.data.get('missing'):
282 return self
283 else:
284 return super(SecurityConfigFilter, self).validate()
286 def process(self, resources, event=None):
287 if self.data.get('missing'):
288 return [r for r in resources if self.RelatedIdsExpression not in r]
289 return super(SecurityConfigFilter, self).process(resources, event=None)
292@GlueDevEndpoint.filter_registry.register('security-config')
293class DevEndpointSecurityConfigFilter(SecurityConfigFilter):
294 RelatedIdsExpression = 'SecurityConfiguration'
297@GlueJob.filter_registry.register('security-config')
298class GlueJobSecurityConfigFilter(SecurityConfigFilter):
299 RelatedIdsExpression = 'SecurityConfiguration'
302@GlueCrawler.filter_registry.register('security-config')
303class GlueCrawlerSecurityConfigFilter(SecurityConfigFilter):
305 RelatedIdsExpression = 'CrawlerSecurityConfiguration'
308@GlueCrawler.action_registry.register('delete')
309class DeleteCrawler(BaseAction):
311 schema = type_schema('delete')
312 permissions = ('glue:DeleteCrawler',)
313 valid_origin_states = ('READY', 'FAILED')
315 def process(self, resources):
316 resources = self.filter_resources(resources, 'State', self.valid_origin_states)
318 client = local_session(self.manager.session_factory).client('glue')
319 for r in resources:
320 try:
321 client.delete_crawler(Name=r['Name'])
322 except client.exceptions.EntityNotFoundException:
323 continue
326@resources.register('glue-database')
327class GlueDatabase(QueryResourceManager):
329 class resource_type(TypeInfo):
330 service = 'glue'
331 enum_spec = ('get_databases', 'DatabaseList', None)
332 id = name = 'Name'
333 date = 'CreatedOn'
334 arn_type = 'database'
335 state_key = 'State'
336 cfn_type = 'AWS::Glue::Database'
339@GlueDatabase.action_registry.register('delete')
340class DeleteDatabase(BaseAction):
342 schema = type_schema('delete')
343 permissions = ('glue:DeleteDatabase',)
345 def process(self, resources):
346 client = local_session(self.manager.session_factory).client('glue')
347 for r in resources:
348 try:
349 client.delete_database(Name=r['Name'])
350 except client.exceptions.EntityNotFoundException:
351 continue
354@resources.register('glue-table')
355class GlueTable(query.ChildResourceManager):
357 child_source = 'describe-table'
359 class resource_type(TypeInfo):
360 service = 'glue'
361 parent_spec = ('glue-database', 'DatabaseName', None)
362 enum_spec = ('get_tables', 'TableList', None)
363 id = name = 'Name'
364 date = 'CreatedOn'
365 arn_type = 'table'
368@query.sources.register('describe-table')
369class DescribeTable(query.ChildDescribeSource):
371 def get_query(self):
372 query = super(DescribeTable, self).get_query()
373 query.capture_parent_id = True
374 return query
376 def augment(self, resources):
377 result = []
378 for parent_id, r in resources:
379 r['DatabaseName'] = parent_id
380 result.append(r)
381 return result
384@GlueTable.action_registry.register('delete')
385class DeleteTable(BaseAction):
387 schema = type_schema('delete')
388 permissions = ('glue:DeleteTable',)
390 def process(self, resources):
391 client = local_session(self.manager.session_factory).client('glue')
392 for r in resources:
393 try:
394 client.delete_table(DatabaseName=r['DatabaseName'], Name=r['Name'])
395 except client.exceptions.EntityNotFoundException:
396 continue
399@resources.register('glue-classifier')
400class GlueClassifier(QueryResourceManager):
402 class resource_type(TypeInfo):
403 service = 'glue'
404 enum_spec = ('get_classifiers', 'Classifiers', None)
405 id = name = 'Name'
406 date = 'CreationTime'
407 arn_type = 'classifier'
408 config_type = cfn_type = 'AWS::Glue::Classifier'
411@GlueClassifier.action_registry.register('delete')
412class DeleteClassifier(BaseAction):
414 schema = type_schema('delete')
415 permissions = ('glue:DeleteClassifier',)
417 def process(self, resources):
418 client = local_session(self.manager.session_factory).client('glue')
419 for r in resources:
420 # Extract the classifier from the resource, see below
421 # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/glue.html#Glue.Client.get_classifier
422 classifier = list(r.values())[0]
423 try:
424 client.delete_classifier(Name=classifier['Name'])
425 except client.exceptions.EntityNotFoundException:
426 continue
429@resources.register('glue-ml-transform')
430class GlueMLTransform(QueryResourceManager):
432 class resource_type(TypeInfo):
433 service = 'glue'
434 enum_spec = ('get_ml_transforms', 'Transforms', None)
435 name = 'Name'
436 id = 'TransformId'
437 arn_type = 'mlTransform'
438 universal_taggable = object()
439 config_type = cfn_type = 'AWS::Glue::MLTransform'
441 source_mapping = {'describe': query.DescribeWithResourceTags,
442 'config': query.ConfigSource}
444 def get_permissions(self):
445 return ('glue:GetMLTransforms',)
448@GlueMLTransform.action_registry.register('delete')
449class DeleteMLTransform(BaseAction):
451 schema = type_schema('delete')
452 permissions = ('glue:DeleteMLTransform',)
454 def process(self, resources):
455 client = local_session(self.manager.session_factory).client('glue')
456 for r in resources:
457 try:
458 client.delete_ml_transform(TransformId=r['TransformId'])
459 except client.exceptions.EntityNotFoundException:
460 continue
463@resources.register('glue-security-configuration')
464class GlueSecurityConfiguration(QueryResourceManager):
466 class resource_type(TypeInfo):
467 service = 'glue'
468 enum_spec = ('get_security_configurations', 'SecurityConfigurations', None)
469 id = name = 'Name'
470 arn_type = 'securityConfiguration'
471 date = 'CreatedTimeStamp'
472 cfn_type = 'AWS::Glue::SecurityConfiguration'
475@GlueSecurityConfiguration.filter_registry.register('kms-key')
476class KmsFilter(KmsRelatedFilter):
478 schema = type_schema(
479 'kms-key',
480 rinherit=ValueFilter.schema,
481 **{'key-type': {'type': 'string', 'enum': [
482 's3', 'cloudwatch', 'job-bookmarks', 'all']},
483 'match-resource': {'type': 'boolean'},
484 'operator': {'enum': ['and', 'or']}})
486 RelatedIdsExpression = ''
488 def __init__(self, data, manager=None):
489 super().__init__(data, manager)
490 key_type_to_related_ids = {
491 's3': 'EncryptionConfiguration.S3Encryption[].KmsKeyArn',
492 'cloudwatch': 'EncryptionConfiguration.CloudWatchEncryption.KmsKeyArn',
493 'job-bookmarks': 'EncryptionConfiguration.JobBookmarksEncryption.KmsKeyArn',
494 'all': 'EncryptionConfiguration.*[][].KmsKeyArn'
495 }
496 key_type = self.data.get('key_type', 'all')
497 self.RelatedIdsExpression = key_type_to_related_ids[key_type]
500@GlueSecurityConfiguration.action_registry.register('delete')
501class DeleteSecurityConfiguration(BaseAction):
503 schema = type_schema('delete')
504 permissions = ('glue:DeleteSecurityConfiguration',)
506 def process(self, resources):
507 client = local_session(self.manager.session_factory).client('glue')
508 for r in resources:
509 try:
510 client.delete_security_configuration(Name=r['Name'])
511 except client.exceptions.EntityNotFoundException:
512 continue
515@resources.register('glue-trigger')
516class GlueTrigger(QueryResourceManager):
518 class resource_type(TypeInfo):
519 service = 'glue'
520 enum_spec = ('get_triggers', 'Triggers', None)
521 id = name = 'Name'
522 arn_type = 'trigger'
523 universal_taggable = object()
524 cfn_type = 'AWS::Glue::Trigger'
526 augment = universal_augment
529@GlueTrigger.action_registry.register('delete')
530class DeleteTrigger(BaseAction):
532 schema = type_schema('delete')
533 permissions = ('glue:DeleteTrigger',)
535 def process(self, resources):
536 client = local_session(self.manager.session_factory).client('glue')
537 for r in resources:
538 try:
539 client.delete_trigger(Name=r['Name'])
540 except client.exceptions.EntityNotFoundException:
541 continue
544@resources.register('glue-workflow')
545class GlueWorkflow(QueryResourceManager):
547 class resource_type(TypeInfo):
548 service = 'glue'
549 enum_spec = ('list_workflows', 'Workflows', None)
550 detail_spec = ('get_workflow', 'Name', None, 'Workflow')
551 id = name = 'Name'
552 arn_type = 'workflow'
553 universal_taggable = object()
554 cfn_type = 'AWS::Glue::Workflow'
556 def augment(self, resources):
557 return universal_augment(
558 self, super(GlueWorkflow, self).augment(resources))
561@GlueWorkflow.action_registry.register('delete')
562class DeleteWorkflow(BaseAction):
564 schema = type_schema('delete')
565 permissions = ('glue:DeleteWorkflow',)
567 def process(self, resources):
568 client = local_session(self.manager.session_factory).client('glue')
569 for r in resources:
570 try:
571 client.delete_workflow(Name=r['Name'])
572 except client.exceptions.EntityNotFoundException:
573 continue
576@GlueWorkflow.filter_registry.register('security-config')
577class GlueWorkflowSecurityConfigFilter(SecurityConfigFilter):
578 RelatedIdsExpression = 'SecurityConfiguration'
581@resources.register('glue-catalog')
582class GlueDataCatalog(ResourceManager):
584 filter_registry = FilterRegistry('glue-catalog.filters')
585 action_registry = ActionRegistry('glue-catalog.actions')
586 retry = staticmethod(QueryResourceManager.retry)
588 class resource_type(query.TypeInfo):
589 service = 'glue'
590 arn_type = 'catalog'
591 id = name = 'CatalogId'
592 cfn_type = 'AWS::Glue::DataCatalogEncryptionSettings'
594 @classmethod
595 def get_permissions(cls):
596 return ('glue:GetDataCatalogEncryptionSettings',)
598 @classmethod
599 def has_arn(cls):
600 return True
602 def get_model(self):
603 return self.resource_type
605 def _get_catalog_encryption_settings(self):
606 client = utils.local_session(self.session_factory).client('glue')
607 settings = client.get_data_catalog_encryption_settings()
608 settings['CatalogId'] = self.config.account_id
609 settings.pop('ResponseMetadata', None)
610 return [settings]
612 def resources(self):
613 return self.filter_resources(self._get_catalog_encryption_settings())
615 def get_resources(self, resource_ids):
616 return [{'CatalogId': self.config.account_id}]
619@GlueDataCatalog.filter_registry.register('kms-key')
620class GlueCatalogKmsFilter(KmsRelatedFilter):
622 schema = type_schema(
623 'kms-key',
624 rinherit=ValueFilter.schema,
625 **{'key-type': {'type': 'string', 'enum': [
626 'EncryptionAtRest', 'ConnectionPasswordEncryption']},
627 'required': ['key-type'],
628 'match-resource': {'type': 'boolean'},
629 'operator': {'enum': ['and', 'or']}})
631 permissions = ('glue:GetDataCatalogEncryptionSettings',)
633 RelatedIdsExpression = ''
635 def __init__(self, data, manager=None):
636 super().__init__(data, manager)
637 key_type_to_related_ids = {
638 'EncryptionAtRest': 'DataCatalogEncryptionSettings.EncryptionAtRest.SseAwsKmsKeyId',
639 'ConnectionPasswordEncryption':
640 'DataCatalogEncryptionSettings.ConnectionPasswordEncryption.AwsKmsKeyId'
641 }
642 self.RelatedIdsExpression = key_type_to_related_ids.get(self.data.get('key-type'))
645@GlueDataCatalog.action_registry.register('set-encryption')
646class GlueDataCatalogEncryption(BaseAction):
647 """Modifies glue data catalog encryption based on specified parameter
648 As per docs, we can enable catalog encryption or only password encryption,
649 not both
651 :example:
653 .. code-block:: yaml
655 policies:
656 - name: data-catalog-encryption
657 resource: glue-catalog
658 filters:
659 - type: value
660 key: DataCatalogEncryptionSettings.EncryptionAtRest.CatalogEncryptionMode
661 value: DISABLED
662 op: eq
663 actions:
664 - type: set-encryption
665 attributes:
666 EncryptionAtRest:
667 CatalogEncryptionMode: SSE-KMS
668 SseAwsKmsKeyId: alias/aws/glue
669 """
671 schema = type_schema(
672 'set-encryption',
673 required=['attributes'],
674 attributes={
675 'type': 'object',
676 'additionalProperties': False,
677 'properties': {
678 'EncryptionAtRest': {
679 'type': 'object',
680 'additionalProperties': False,
681 'required': ['CatalogEncryptionMode'],
682 'properties': {
683 'CatalogEncryptionMode': {'enum': ['DISABLED', 'SSE-KMS']},
684 'SseAwsKmsKeyId': {'type': 'string'}
685 }
686 },
687 'ConnectionPasswordEncryption': {
688 'type': 'object',
689 'additionalProperties': False,
690 'required': ['ReturnConnectionPasswordEncrypted'],
691 'properties': {
692 'ReturnConnectionPasswordEncrypted': {'type': 'boolean'},
693 'AwsKmsKeyId': {'type': 'string'}
694 }
695 }
696 }
697 }
698 )
700 permissions = ('glue:PutDataCatalogEncryptionSettings',)
702 def process(self, resources):
703 client = local_session(self.manager.session_factory).client('glue')
704 self.process_catalog_encryption(client, resources)
706 def process_catalog_encryption(self, client, resources):
707 # there is one glue data catalog per account
708 if 'DataCatalogEncryptionSettings' not in resources[0]:
709 resources = self.manager.resources()
710 enc_config = resources[0]['DataCatalogEncryptionSettings']
711 updated_config = {**enc_config, **self.data['attributes']}
712 if enc_config == updated_config:
713 return
714 client.put_data_catalog_encryption_settings(
715 DataCatalogEncryptionSettings=updated_config)
718@GlueDataCatalog.filter_registry.register('glue-security-config')
719class GlueCatalogEncryptionFilter(GlueCatalogEncryptionEnabled):
720 """Filter glue catalog by its glue encryption status and KMS key
722 :example:
724 .. code-block:: yaml
726 policies:
727 - name: glue-catalog-security-config
728 resource: aws.glue-catalog
729 filters:
730 - type: glue-security-config
731 SseAwsKmsKeyId: alias/aws/glue
733 """
736@GlueDataCatalog.filter_registry.register('cross-account')
737class GlueCatalogCrossAccount(CrossAccountAccessFilter):
738 """Filter glue catalog if it has cross account permissions
740 :example:
742 .. code-block:: yaml
744 policies:
745 - name: catalog-cross-account
746 resource: aws.glue-catalog
747 filters:
748 - type: cross-account
750 """
751 permissions = ('glue:GetResourcePolicy',)
752 policy_annotation = "c7n:AccessPolicy"
754 def get_resource_policy(self, r):
755 client = local_session(self.manager.session_factory).client('glue')
756 if self.policy_annotation in r:
757 return r[self.policy_annotation]
758 try:
759 policy = client.get_resource_policy().get('PolicyInJson')
760 except client.exceptions.EntityNotFoundException:
761 policy = {}
762 r[self.policy_annotation] = policy
763 return policy
766@GlueDataCatalog.action_registry.register('remove-statements')
767class RemovePolicyStatement(RemovePolicyBase):
768 """Action to remove policy statements from Glue Data Catalog
770 :example:
772 .. code-block:: yaml
774 policies:
775 - name: remove-glue-catalog-cross-account
776 resource: aws.glue-catalog
777 filters:
778 - type: cross-account
779 actions:
780 - type: remove-statements
781 statement_ids: matched
782 """
783 permissions = ('glue:PutResourcePolicy',)
784 policy_annotation = "c7n:AccessPolicy"
786 def validate(self):
787 for f in self.manager.iter_filters():
788 if isinstance(f, GlueCatalogCrossAccount):
789 return self
790 raise PolicyValidationError(
791 '`remove-statements` may only be used in '
792 'conjunction with `cross-account` filter on %s' % (self.manager.data,))
794 def process(self, resources):
795 resource = resources[0]
796 client = local_session(self.manager.session_factory).client('glue')
797 if resource.get(self.policy_annotation):
798 p = json.loads(resource[self.policy_annotation])
799 statements, found = self.process_policy(
800 p, resource, CrossAccountAccessFilter.annotation_key)
801 if not found:
802 return
803 if statements:
804 client.put_resource_policy(PolicyInJson=json.dumps(p))
805 else:
806 client.delete_resource_policy()