diff --git a/gcsfs/core.py b/gcsfs/core.py index dedf215b..ef43e49a 100644 --- a/gcsfs/core.py +++ b/gcsfs/core.py @@ -837,8 +837,8 @@ async def _mkdir( location=None, create_parents=True, enable_versioning=False, - uniform_access=False, - public_access_prevention=True, + enable_object_retention=False, + iam_configuration=None, **kwargs, ): """ @@ -846,7 +846,7 @@ async def _mkdir( If path is more than just a bucket, will create bucket if create_parents=True; otherwise is a noop. If create_parents is False and bucket does not exist, - will produce FileNotFFoundError. + will produce FileNotFoundError. Parameters ---------- @@ -854,7 +854,8 @@ async def _mkdir( bucket name. If contains '/' (i.e., looks like subdir), will have no effect because GCS doesn't have real directories. acl: string, one of bACLs - access for the bucket itself + access for the bucket itself. See: + https://cloud.google.com/storage/docs/access-control/lists#predefined-acl default_acl: str, one of ACLs default ACL for objects created in this bucket location: Optional[str] @@ -867,12 +868,19 @@ async def _mkdir( enable_versioning: bool If True, creates the bucket in question with object versioning enabled. - uniform_access: bool - If True, creates the bucket in question with uniform access - enabled. - public_access_prevention: bool - If True, creates the bucket in question with public access - prevention enabled. + enable_object_retention: bool + If True, creates the bucket in question with object retention + permanently enabled. + iam_configuration: dict + If provided, sets the IAM policy for the bucket. This argument + allows setting properties such as `{publicAccessPrevention: "enforced"}` + and `{"uniformBucketLevelAccess": {"enabled": True}}`. If passed, `acl` + and `default_acl` are explicitly ignored. + **kwargs + Additional parameters passed to the API call request body. See: + https://cloud.google.com/storage/docs/json_api/v1/buckets/insert#request-body + for all possible options. Pass nested parameters as dictionaries, e.g.: + `{"autoclass": {"enabled": True}}` """ bucket, object, generation = self.split_path(path) if bucket in ["", "/"]: @@ -885,21 +893,18 @@ async def _mkdir( return raise FileNotFoundError(bucket) - json_data = {"name": bucket, "iamConfiguration": {}} + json_data = {"name": bucket} location = location or self.default_location if location: json_data["location"] = location if enable_versioning: json_data["versioning"] = {"enabled": True} - if uniform_access: - # Cannot use ACLs with uniform access + if iam_configuration: + json_data["iamConfiguration"] = iam_configuration acl = None default_acl = None - json_data["iamConfiguration"]["uniformBucketLevelAccess"] = { - "enabled": True - } - if public_access_prevention: - json_data["iamConfiguration"]["publicAccessPrevention"] = "enforced" + if kwargs: + json_data.update(kwargs) await self._call( method="POST", @@ -907,6 +912,7 @@ async def _mkdir( predefinedAcl=acl, project=self.project, predefinedDefaultObjectAcl=default_acl, + enableObjectRetention=str(enable_object_retention).lower(), json=json_data, json_out=True, ) diff --git a/gcsfs/tests/settings.py b/gcsfs/tests/settings.py index a661417c..0e074f97 100644 --- a/gcsfs/tests/settings.py +++ b/gcsfs/tests/settings.py @@ -3,4 +3,3 @@ TEST_BUCKET = os.getenv("GCSFS_TEST_BUCKET", "gcsfs_test") TEST_PROJECT = os.getenv("GCSFS_TEST_PROJECT", "project") TEST_REQUESTER_PAYS_BUCKET = "gcsfs_test_req_pay" -TEST_CUSTOM_BUCKET = os.getenv("GCSFS_TEST_CUSTOM_BUCKET", "gcsfs_test_custom") diff --git a/gcsfs/tests/test_core.py b/gcsfs/tests/test_core.py index 6b51c018..1415d66f 100644 --- a/gcsfs/tests/test_core.py +++ b/gcsfs/tests/test_core.py @@ -24,7 +24,6 @@ TEST_BUCKET = gcsfs.tests.settings.TEST_BUCKET TEST_PROJECT = gcsfs.tests.settings.TEST_PROJECT TEST_REQUESTER_PAYS_BUCKET = gcsfs.tests.settings.TEST_REQUESTER_PAYS_BUCKET -TEST_CUSTOM_BUCKET = gcsfs.tests.settings.TEST_CUSTOM_BUCKET def test_simple(gcs): @@ -1479,16 +1478,3 @@ def test_find_maxdepth(gcs): with pytest.raises(ValueError, match="maxdepth must be at least 1"): gcs.find(f"{TEST_BUCKET}/nested", maxdepth=0) - - -def test_mkdir_options(gcs): - gcs = GCSFileSystem(endpoint_url=gcs._endpoint) - if not gcs.on_google: - pytest.skip("emulator doesn't support IAM policies.") - - gcs.mkdir(TEST_CUSTOM_BUCKET, uniform_access=True, public_access_prevention=True) - info = gcs.info(TEST_CUSTOM_BUCKET) - gcs.rm(TEST_CUSTOM_BUCKET, recursive=True) - - assert info["iamConfiguration"]["uniformBucketLevelAccess"]["enabled"] - assert info["iamConfiguration"]["publicAccessPrevention"] == "enforced"