Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/c7n/resources/glue.py: 63%
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
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
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 return super(DescribeTable, self).get_query(capture_parent_id=True)
374 def augment(self, resources):
375 result = []
376 for parent_id, r in resources:
377 r['DatabaseName'] = parent_id
378 result.append(r)
379 return result
382@GlueTable.action_registry.register('delete')
383class DeleteTable(BaseAction):
385 schema = type_schema('delete')
386 permissions = ('glue:DeleteTable',)
388 def process(self, resources):
389 client = local_session(self.manager.session_factory).client('glue')
390 for r in resources:
391 try:
392 client.delete_table(DatabaseName=r['DatabaseName'], Name=r['Name'])
393 except client.exceptions.EntityNotFoundException:
394 continue
397@resources.register('glue-classifier')
398class GlueClassifier(QueryResourceManager):
400 class resource_type(TypeInfo):
401 service = 'glue'
402 enum_spec = ('get_classifiers', 'Classifiers', None)
403 id = name = 'Name'
404 date = 'CreationTime'
405 arn_type = 'classifier'
406 config_type = cfn_type = 'AWS::Glue::Classifier'
409@GlueClassifier.action_registry.register('delete')
410class DeleteClassifier(BaseAction):
412 schema = type_schema('delete')
413 permissions = ('glue:DeleteClassifier',)
415 def process(self, resources):
416 client = local_session(self.manager.session_factory).client('glue')
417 for r in resources:
418 # Extract the classifier from the resource, see below
419 # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/glue.html#Glue.Client.get_classifier
420 classifier = list(r.values())[0]
421 try:
422 client.delete_classifier(Name=classifier['Name'])
423 except client.exceptions.EntityNotFoundException:
424 continue
427@resources.register('glue-ml-transform')
428class GlueMLTransform(QueryResourceManager):
430 class resource_type(TypeInfo):
431 service = 'glue'
432 enum_spec = ('get_ml_transforms', 'Transforms', None)
433 name = 'Name'
434 id = 'TransformId'
435 arn_type = 'mlTransform'
436 universal_taggable = object()
437 config_type = cfn_type = 'AWS::Glue::MLTransform'
439 source_mapping = {'describe': query.DescribeWithResourceTags,
440 'config': query.ConfigSource}
442 def get_permissions(self):
443 return ('glue:GetMLTransforms',)
446@GlueMLTransform.action_registry.register('delete')
447class DeleteMLTransform(BaseAction):
449 schema = type_schema('delete')
450 permissions = ('glue:DeleteMLTransform',)
452 def process(self, resources):
453 client = local_session(self.manager.session_factory).client('glue')
454 for r in resources:
455 try:
456 client.delete_ml_transform(TransformId=r['TransformId'])
457 except client.exceptions.EntityNotFoundException:
458 continue
461@resources.register('glue-security-configuration')
462class GlueSecurityConfiguration(QueryResourceManager):
464 class resource_type(TypeInfo):
465 service = 'glue'
466 enum_spec = ('get_security_configurations', 'SecurityConfigurations', None)
467 id = name = 'Name'
468 arn_type = 'securityConfiguration'
469 date = 'CreatedTimeStamp'
470 cfn_type = 'AWS::Glue::SecurityConfiguration'
473@GlueSecurityConfiguration.filter_registry.register('kms-key')
474class KmsFilter(KmsRelatedFilter):
476 schema = type_schema(
477 'kms-key',
478 rinherit=ValueFilter.schema,
479 **{'key-type': {'type': 'string', 'enum': [
480 's3', 'cloudwatch', 'job-bookmarks', 'all']},
481 'match-resource': {'type': 'boolean'},
482 'operator': {'enum': ['and', 'or']}})
484 RelatedIdsExpression = ''
486 def __init__(self, data, manager=None):
487 super().__init__(data, manager)
488 key_type_to_related_ids = {
489 's3': 'EncryptionConfiguration.S3Encryption[].KmsKeyArn',
490 'cloudwatch': 'EncryptionConfiguration.CloudWatchEncryption.KmsKeyArn',
491 'job-bookmarks': 'EncryptionConfiguration.JobBookmarksEncryption.KmsKeyArn',
492 'all': 'EncryptionConfiguration.*[][].KmsKeyArn'
493 }
494 key_type = self.data.get('key_type', 'all')
495 self.RelatedIdsExpression = key_type_to_related_ids[key_type]
498@GlueSecurityConfiguration.action_registry.register('delete')
499class DeleteSecurityConfiguration(BaseAction):
501 schema = type_schema('delete')
502 permissions = ('glue:DeleteSecurityConfiguration',)
504 def process(self, resources):
505 client = local_session(self.manager.session_factory).client('glue')
506 for r in resources:
507 try:
508 client.delete_security_configuration(Name=r['Name'])
509 except client.exceptions.EntityNotFoundException:
510 continue
513@resources.register('glue-trigger')
514class GlueTrigger(QueryResourceManager):
516 class resource_type(TypeInfo):
517 service = 'glue'
518 enum_spec = ('get_triggers', 'Triggers', None)
519 id = name = 'Name'
520 arn_type = 'trigger'
521 universal_taggable = object()
522 cfn_type = 'AWS::Glue::Trigger'
524 augment = universal_augment
527@GlueTrigger.action_registry.register('delete')
528class DeleteTrigger(BaseAction):
530 schema = type_schema('delete')
531 permissions = ('glue:DeleteTrigger',)
533 def process(self, resources):
534 client = local_session(self.manager.session_factory).client('glue')
535 for r in resources:
536 try:
537 client.delete_trigger(Name=r['Name'])
538 except client.exceptions.EntityNotFoundException:
539 continue
542@resources.register('glue-workflow')
543class GlueWorkflow(QueryResourceManager):
545 class resource_type(TypeInfo):
546 service = 'glue'
547 enum_spec = ('list_workflows', 'Workflows', None)
548 detail_spec = ('get_workflow', 'Name', None, 'Workflow')
549 id = name = 'Name'
550 arn_type = 'workflow'
551 universal_taggable = object()
552 cfn_type = 'AWS::Glue::Workflow'
554 def augment(self, resources):
555 return universal_augment(
556 self, super(GlueWorkflow, self).augment(resources))
559@GlueWorkflow.action_registry.register('delete')
560class DeleteWorkflow(BaseAction):
562 schema = type_schema('delete')
563 permissions = ('glue:DeleteWorkflow',)
565 def process(self, resources):
566 client = local_session(self.manager.session_factory).client('glue')
567 for r in resources:
568 try:
569 client.delete_workflow(Name=r['Name'])
570 except client.exceptions.EntityNotFoundException:
571 continue
574@GlueWorkflow.filter_registry.register('security-config')
575class GlueWorkflowSecurityConfigFilter(SecurityConfigFilter):
576 RelatedIdsExpression = 'SecurityConfiguration'
579@resources.register('glue-catalog')
580class GlueDataCatalog(ResourceManager):
582 filter_registry = FilterRegistry('glue-catalog.filters')
583 action_registry = ActionRegistry('glue-catalog.actions')
584 retry = staticmethod(QueryResourceManager.retry)
586 class resource_type(query.TypeInfo):
587 service = 'glue'
588 arn_type = 'catalog'
589 id = name = 'CatalogId'
590 cfn_type = 'AWS::Glue::DataCatalogEncryptionSettings'
592 @classmethod
593 def get_permissions(cls):
594 return ('glue:GetDataCatalogEncryptionSettings',)
596 @classmethod
597 def has_arn(cls):
598 return True
600 def get_model(self):
601 return self.resource_type
603 def _get_catalog_encryption_settings(self):
604 client = utils.local_session(self.session_factory).client('glue')
605 settings = client.get_data_catalog_encryption_settings()
606 settings['CatalogId'] = self.config.account_id
607 settings.pop('ResponseMetadata', None)
608 return [settings]
610 def resources(self):
611 return self.filter_resources(self._get_catalog_encryption_settings())
613 def get_resources(self, resource_ids):
614 return [{'CatalogId': self.config.account_id}]
617@GlueDataCatalog.filter_registry.register('kms-key')
618class GlueCatalogKmsFilter(KmsRelatedFilter):
620 schema = type_schema(
621 'kms-key',
622 rinherit=ValueFilter.schema,
623 **{'key-type': {'type': 'string', 'enum': [
624 'EncryptionAtRest', 'ConnectionPasswordEncryption']},
625 'required': ['key-type'],
626 'match-resource': {'type': 'boolean'},
627 'operator': {'enum': ['and', 'or']}})
629 permissions = ('glue:GetDataCatalogEncryptionSettings',)
631 RelatedIdsExpression = ''
633 def __init__(self, data, manager=None):
634 super().__init__(data, manager)
635 key_type_to_related_ids = {
636 'EncryptionAtRest': 'DataCatalogEncryptionSettings.EncryptionAtRest.SseAwsKmsKeyId',
637 'ConnectionPasswordEncryption':
638 'DataCatalogEncryptionSettings.ConnectionPasswordEncryption.AwsKmsKeyId'
639 }
640 self.RelatedIdsExpression = key_type_to_related_ids.get(self.data.get('key-type'))
643@GlueDataCatalog.action_registry.register('set-encryption')
644class GlueDataCatalogEncryption(BaseAction):
645 """Modifies glue data catalog encryption based on specified parameter
646 As per docs, we can enable catalog encryption or only password encryption,
647 not both
649 :example:
651 .. code-block:: yaml
653 policies:
654 - name: data-catalog-encryption
655 resource: glue-catalog
656 filters:
657 - type: value
658 key: DataCatalogEncryptionSettings.EncryptionAtRest.CatalogEncryptionMode
659 value: DISABLED
660 op: eq
661 actions:
662 - type: set-encryption
663 attributes:
664 EncryptionAtRest:
665 CatalogEncryptionMode: SSE-KMS
666 SseAwsKmsKeyId: alias/aws/glue
667 """
669 schema = type_schema(
670 'set-encryption',
671 required=['attributes'],
672 attributes={
673 'type': 'object',
674 'additionalProperties': False,
675 'properties': {
676 'EncryptionAtRest': {
677 'type': 'object',
678 'additionalProperties': False,
679 'required': ['CatalogEncryptionMode'],
680 'properties': {
681 'CatalogEncryptionMode': {'enum': ['DISABLED', 'SSE-KMS']},
682 'SseAwsKmsKeyId': {'type': 'string'}
683 }
684 },
685 'ConnectionPasswordEncryption': {
686 'type': 'object',
687 'additionalProperties': False,
688 'required': ['ReturnConnectionPasswordEncrypted'],
689 'properties': {
690 'ReturnConnectionPasswordEncrypted': {'type': 'boolean'},
691 'AwsKmsKeyId': {'type': 'string'}
692 }
693 }
694 }
695 }
696 )
698 permissions = ('glue:PutDataCatalogEncryptionSettings',)
700 def process(self, resources):
701 client = local_session(self.manager.session_factory).client('glue')
702 self.process_catalog_encryption(client, resources)
704 def process_catalog_encryption(self, client, resources):
705 # there is one glue data catalog per account
706 if 'DataCatalogEncryptionSettings' not in resources[0]:
707 resources = self.manager.resources()
708 enc_config = resources[0]['DataCatalogEncryptionSettings']
709 updated_config = {**enc_config, **self.data['attributes']}
710 if enc_config == updated_config:
711 return
712 client.put_data_catalog_encryption_settings(
713 DataCatalogEncryptionSettings=updated_config)
716@GlueDataCatalog.filter_registry.register('glue-security-config')
717class GlueCatalogEncryptionFilter(GlueCatalogEncryptionEnabled):
718 """Filter glue catalog by its glue encryption status and KMS key
720 :example:
722 .. code-block:: yaml
724 policies:
725 - name: glue-catalog-security-config
726 resource: aws.glue-catalog
727 filters:
728 - type: glue-security-config
729 SseAwsKmsKeyId: alias/aws/glue
731 """
734@GlueDataCatalog.filter_registry.register('cross-account')
735class GlueCatalogCrossAccount(CrossAccountAccessFilter):
736 """Filter glue catalog if it has cross account permissions
738 :example:
740 .. code-block:: yaml
742 policies:
743 - name: catalog-cross-account
744 resource: aws.glue-catalog
745 filters:
746 - type: cross-account
748 """
749 permissions = ('glue:GetResourcePolicy',)
750 policy_annotation = "c7n:AccessPolicy"
752 def get_resource_policy(self, r):
753 client = local_session(self.manager.session_factory).client('glue')
754 if self.policy_annotation in r:
755 return r[self.policy_annotation]
756 try:
757 policy = client.get_resource_policy().get('PolicyInJson')
758 except client.exceptions.EntityNotFoundException:
759 policy = {}
760 r[self.policy_annotation] = policy
761 return policy
764@GlueDataCatalog.action_registry.register('remove-statements')
765class RemovePolicyStatement(RemovePolicyBase):
766 """Action to remove policy statements from Glue Data Catalog
768 :example:
770 .. code-block:: yaml
772 policies:
773 - name: remove-glue-catalog-cross-account
774 resource: aws.glue-catalog
775 filters:
776 - type: cross-account
777 actions:
778 - type: remove-statements
779 statement_ids: matched
780 """
781 permissions = ('glue:PutResourcePolicy',)
782 policy_annotation = "c7n:AccessPolicy"
784 def validate(self):
785 for f in self.manager.iter_filters():
786 if isinstance(f, GlueCatalogCrossAccount):
787 return self
788 raise PolicyValidationError(
789 '`remove-statements` may only be used in '
790 'conjunction with `cross-account` filter on %s' % (self.manager.data,))
792 def process(self, resources):
793 resource = resources[0]
794 client = local_session(self.manager.session_factory).client('glue')
795 if resource.get(self.policy_annotation):
796 p = json.loads(resource[self.policy_annotation])
797 statements, found = self.process_policy(
798 p, resource, CrossAccountAccessFilter.annotation_key)
799 if not found:
800 return
801 if statements:
802 client.put_resource_policy(PolicyInJson=json.dumps(p))
803 else:
804 client.delete_resource_policy()