1# Copyright The Cloud Custodian Authors.
2# SPDX-License-Identifier: Apache-2.0
3from c7n.utils import type_schema
4from c7n_gcp.actions import MethodAction
5from c7n_gcp.provider import resources
6from c7n_gcp.query import QueryResourceManager, TypeInfo
7from c7n_gcp.filters import IamPolicyFilter
8
9
10@resources.register('bucket')
11class Bucket(QueryResourceManager):
12
13 class resource_type(TypeInfo):
14 service = 'storage'
15 version = 'v1'
16 component = 'buckets'
17 scope = 'project'
18 enum_spec = ('list', 'items[]', {'projection': 'full'})
19 name = id = 'name'
20 default_report_fields = [
21 "name", "timeCreated", "location", "storageClass"]
22 asset_type = "storage.googleapis.com/Bucket"
23 scc_type = "google.cloud.storage.Bucket"
24 metric_key = 'resource.labels.bucket_name'
25 urn_component = "bucket"
26
27 @staticmethod
28 def get(client, resource_info):
29 # pull mode passes the bucket name in the info using bucket_name.
30 # gcp-scc mode passes in the full resourceName
31 if not (bucket_name := resource_info.get("bucket_name")):
32 # There is no nice way to return no resource, so if there is no
33 # resourceName in the info, we will raise a KeyError.
34 prefix = "//storage.googleapis.com/"
35 bucket_name = resource_info["resourceName"].removeprefix(prefix)
36
37 return client.execute_command("get", {"bucket": bucket_name})
38
39
40@Bucket.filter_registry.register('iam-policy')
41class BucketIamPolicyFilter(IamPolicyFilter):
42 """
43 Overrides the base implementation to process bucket resources correctly.
44 """
45 permissions = ('storage.buckets.getIamPolicy',)
46
47 def _verb_arguments(self, resource):
48 verb_arguments = {{"bucket": resource["name"]}}
49 return verb_arguments
50
51
52@Bucket.action_registry.register('set-uniform-access')
53class BucketLevelAccess(MethodAction):
54 '''Uniform access disables object ACLs on a bucket.
55
56 Enabling this means only bucket policies (and organization bucket
57 policies) govern access to a bucket.
58
59 When enabled, users can only specify bucket level IAM policies
60 and not Object level ACL's.
61
62 Example Policy:
63
64 .. code-block:: yaml
65
66 policies:
67 - name: enforce-uniform-bucket-level-access
68 resource: gcp.bucket
69 filters:
70 - iamConfiguration.uniformBucketLevelAccess.enable: false
71 actions:
72 - type: set-uniform-access
73 # The following is also the default
74 state: true
75 '''
76
77 schema = type_schema('set-uniform-access', state={'type': 'boolean'})
78 method_spec = {'op': 'patch'}
79 method_perm = 'update'
80
81 # the google docs and example on this api appear to broken.
82 # https://cloud.google.com/storage/docs/using-uniform-bucket-level-access#rest-apis
83 #
84 # instead we observe the behavior gsutil interaction to effect the same.
85 # the key seems to be the undocumented projection parameter
86 #
87 def get_resource_params(self, model, resource):
88 enabled = self.data.get('state', True)
89 return {'bucket': resource['name'],
90 'fields': 'iamConfiguration',
91 'projection': 'noAcl', # not documented but
92 'body': {'iamConfiguration': {'uniformBucketLevelAccess': {'enabled': enabled}}}}