Skip to content

Commit add3c01

Browse files
authored
feat: support HNS enablement in bucket metadata (#1278)
* feat: support HNS enablement in bucket metadata * update docstrings
1 parent c52e882 commit add3c01

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

google/cloud/storage/bucket.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2957,6 +2957,35 @@ def object_retention_mode(self):
29572957
if object_retention is not None:
29582958
return object_retention.get("mode")
29592959

2960+
@property
2961+
def hierarchical_namespace_enabled(self):
2962+
"""Whether hierarchical namespace is enabled for this bucket.
2963+
2964+
:setter: Update whether hierarchical namespace is enabled for this bucket.
2965+
:getter: Query whether hierarchical namespace is enabled for this bucket.
2966+
2967+
:rtype: bool
2968+
:returns: True if enabled, else False.
2969+
"""
2970+
hns = self._properties.get("hierarchicalNamespace", {})
2971+
return hns.get("enabled")
2972+
2973+
@hierarchical_namespace_enabled.setter
2974+
def hierarchical_namespace_enabled(self, value):
2975+
"""Enable or disable hierarchical namespace at the bucket-level.
2976+
2977+
:type value: convertible to boolean
2978+
:param value: If true, enable hierarchical namespace for this bucket.
2979+
If false, disable hierarchical namespace for this bucket.
2980+
2981+
.. note::
2982+
To enable hierarchical namespace, you must set it at bucket creation time.
2983+
Currently, hierarchical namespace configuration cannot be changed after bucket creation.
2984+
"""
2985+
hns = self._properties.get("hierarchicalNamespace", {})
2986+
hns["enabled"] = bool(value)
2987+
self._patch_property("hierarchicalNamespace", hns)
2988+
29602989
def configure_website(self, main_page_suffix=None, not_found_page=None):
29612990
"""Configure website-related properties.
29622991

tests/system/test_bucket.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,3 +1236,32 @@ def test_soft_delete_policy(
12361236
bucket.soft_delete_policy.retention_duration_seconds = new_duration_secs
12371237
bucket.patch()
12381238
assert bucket.soft_delete_policy.retention_duration_seconds == new_duration_secs
1239+
1240+
1241+
def test_new_bucket_with_hierarchical_namespace(
1242+
storage_client,
1243+
buckets_to_delete,
1244+
):
1245+
# Test new bucket without specifying hierarchical namespace
1246+
bucket_name = _helpers.unique_name("new-wo-hns")
1247+
bucket_obj = storage_client.bucket(bucket_name)
1248+
bucket = storage_client.create_bucket(bucket_obj)
1249+
buckets_to_delete.append(bucket)
1250+
assert bucket.hierarchical_namespace_enabled is None
1251+
1252+
# Test new bucket with hierarchical namespace disabled
1253+
bucket_name = _helpers.unique_name("new-hns-disabled")
1254+
bucket_obj = storage_client.bucket(bucket_name)
1255+
bucket_obj.hierarchical_namespace_enabled = False
1256+
bucket = storage_client.create_bucket(bucket_obj)
1257+
buckets_to_delete.append(bucket)
1258+
assert bucket.hierarchical_namespace_enabled is False
1259+
1260+
# Test new bucket with hierarchical namespace enabled
1261+
bucket_name = _helpers.unique_name("new-hns-enabled")
1262+
bucket_obj = storage_client.bucket(bucket_name)
1263+
bucket_obj.hierarchical_namespace_enabled = True
1264+
bucket_obj.iam_configuration.uniform_bucket_level_access_enabled = True
1265+
bucket = storage_client.create_bucket(bucket_obj)
1266+
buckets_to_delete.append(bucket)
1267+
assert bucket.hierarchical_namespace_enabled is True

tests/unit/test_bucket.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3163,6 +3163,19 @@ def test_soft_delete_policy_setter(self):
31633163
self.assertTrue("softDeletePolicy" in bucket._changes)
31643164
self.assertEqual(bucket.soft_delete_policy.retention_duration_seconds, seconds)
31653165

3166+
def test_hierarchical_namespace_enabled_getter_and_setter(self):
3167+
# Test hierarchical_namespace configuration unset
3168+
bucket = self._make_one()
3169+
self.assertIsNone(bucket.hierarchical_namespace_enabled)
3170+
3171+
# Test hierarchical_namespace configuration explicitly set
3172+
properties = {"hierarchicalNamespace": {"enabled": True}}
3173+
bucket = self._make_one(properties=properties)
3174+
self.assertTrue(bucket.hierarchical_namespace_enabled)
3175+
bucket.hierarchical_namespace_enabled = False
3176+
self.assertIn("hierarchicalNamespace", bucket._changes)
3177+
self.assertFalse(bucket.hierarchical_namespace_enabled)
3178+
31663179
def test_configure_website_defaults(self):
31673180
NAME = "name"
31683181
UNSET = {"website": {"mainPageSuffix": None, "notFoundPage": None}}

0 commit comments

Comments
 (0)