diff --git a/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/CreateBucketIpFilter.java b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/CreateBucketIpFilter.java new file mode 100644 index 000000000000..e6f827b60487 --- /dev/null +++ b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/CreateBucketIpFilter.java @@ -0,0 +1,57 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.storage.bucket; + +// [START storage_create_bucket_ip_filtering] +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo; +import com.google.cloud.storage.BucketInfo.IpFilter; +import com.google.cloud.storage.BucketInfo.IpFilter.PublicNetworkSource; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; +import java.util.Arrays; + +public class CreateBucketIpFilter { + public static void createBucketIpFilter( + String projectId, String bucketName, String publicCidrRange) { + // The ID of your GCP project + // String projectId = "your-project-id"; + + // The ID to give your GCS bucket + // String bucketName = "your-unique-bucket-name"; + + // The public IPv4 CIDR range to allow + // String publicCidrRange = "192.0.2.0/24"; + + Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService(); + + IpFilter ipFilter = + IpFilter.newBuilder() + .setMode("Disabled") + .setAllowAllServiceAgentAccess(true) + .setPublicNetworkSource(PublicNetworkSource.of(Arrays.asList(publicCidrRange))) + .build(); + + BucketInfo bucketInfo = BucketInfo.newBuilder(bucketName).setIpFilter(ipFilter).build(); + + Bucket bucket = storage.create(bucketInfo); + + System.out.println( + "Created bucket " + bucketName + " with IP filter mode " + bucket.getIpFilter().getMode()); + } +} +// [END storage_create_bucket_ip_filtering] diff --git a/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/DeleteBucketIpFilter.java b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/DeleteBucketIpFilter.java new file mode 100644 index 000000000000..492fb4e585b6 --- /dev/null +++ b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/DeleteBucketIpFilter.java @@ -0,0 +1,95 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.storage.bucket; + +// [START storage_delete_ip_filtering_rules] +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo.IpFilter; +import com.google.cloud.storage.BucketInfo.IpFilter.PublicNetworkSource; +import com.google.cloud.storage.BucketInfo.IpFilter.VpcNetworkSource; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class DeleteBucketIpFilter { + public static Bucket deleteBucketIpFilterRules( + String projectId, String bucketName, String publicRangeToDelete, String vpcNetworkToDelete) { + // The ID of your GCP project + // String projectId = "your-project-id"; + + // The ID of your GCS bucket + // String bucketName = "your-unique-bucket-name"; + + // The public IPv4/IPv6 CIDR range to remove + // String publicRangeToDelete = "192.0.2.0/24"; + + // The VPC network name to remove + // String vpcNetworkToDelete = "projects/my-project/global/networks/my-vpc"; + + Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService(); + Bucket bucket = storage.get(bucketName); + IpFilter ipFilter = bucket.getIpFilter(); + + if (ipFilter == null) { + System.out.println("Bucket " + bucketName + " has no IP Filter configured."); + return bucket; + } + + boolean modified = false; + List publicRanges = new ArrayList<>(); + if (ipFilter.getPublicNetworkSource() != null + && ipFilter.getPublicNetworkSource().getAllowedIpCidrRanges() != null) { + publicRanges.addAll(ipFilter.getPublicNetworkSource().getAllowedIpCidrRanges()); + } + if (publicRangeToDelete != null && publicRanges.remove(publicRangeToDelete)) { + modified = true; + } + + List vpcSources = new ArrayList<>(); + if (ipFilter.getVpcNetworkSources() != null) { + vpcSources.addAll(ipFilter.getVpcNetworkSources()); + } + if (vpcNetworkToDelete != null) { + Iterator iterator = vpcSources.iterator(); + while (iterator.hasNext()) { + VpcNetworkSource source = iterator.next(); + if (vpcNetworkToDelete.equals(source.getNetwork())) { + iterator.remove(); + modified = true; + } + } + } + + if (modified) { + IpFilter.Builder updatedIpFilterBuilder = ipFilter.toBuilder(); + updatedIpFilterBuilder.setPublicNetworkSource( + publicRanges.isEmpty() ? null : PublicNetworkSource.of(publicRanges)); + updatedIpFilterBuilder.setVpcNetworkSources(vpcSources.isEmpty() ? null : vpcSources); + + Bucket updatedBucket = + storage.update(bucket.toBuilder().setIpFilter(updatedIpFilterBuilder.build()).build()); + System.out.println("Deleted specified IP filtering rules for bucket " + bucketName); + return updatedBucket; + } else { + System.out.println("No matching IP filtering rules found to delete for bucket " + bucketName); + return bucket; + } + } +} +// [END storage_delete_ip_filtering_rules] diff --git a/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/DisableBucketIpFilter.java b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/DisableBucketIpFilter.java new file mode 100644 index 000000000000..0ddfc28427cd --- /dev/null +++ b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/DisableBucketIpFilter.java @@ -0,0 +1,48 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.storage.bucket; + +// [START storage_disable_ip_filtering] +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo.IpFilter; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; + +public class DisableBucketIpFilter { + public static Bucket disableBucketIpFilter(String projectId, String bucketName) { + // The ID of your GCP project + // String projectId = "your-project-id"; + + // The ID of your GCS bucket + // String bucketName = "your-unique-bucket-name"; + + Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService(); + Bucket bucket = storage.get(bucketName); + + if (bucket.getIpFilter() == null) { + System.out.println("Bucket " + bucketName + " has no IP Filter configured."); + return bucket; + } + + IpFilter disabledIpFilter = bucket.getIpFilter().toBuilder().setMode("Disabled").build(); + Bucket updatedBucket = storage.update(bucket.toBuilder().setIpFilter(disabledIpFilter).build()); + + System.out.println("IP filtering disabled for bucket " + bucketName); + return updatedBucket; + } +} +// [END storage_disable_ip_filtering] diff --git a/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/EnableBucketIpFilter.java b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/EnableBucketIpFilter.java new file mode 100644 index 000000000000..164de21ab24d --- /dev/null +++ b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/EnableBucketIpFilter.java @@ -0,0 +1,126 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.storage.bucket; + +// [START storage_enable_ip_filtering] +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo.IpFilter; +import com.google.cloud.storage.BucketInfo.IpFilter.PublicNetworkSource; +import com.google.cloud.storage.BucketInfo.IpFilter.VpcNetworkSource; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class EnableBucketIpFilter { + public static Bucket enableBucketIpFilter( + String projectId, + String bucketName, + String publicRange, + String vpcNetworkName, + String vpcRange) { + // The ID of your GCP project + // String projectId = "your-project-id"; + + // The ID of your GCS bucket + // String bucketName = "your-unique-bucket-name"; + + // The public IPv4/IPv6 CIDR range to allow + // String publicRange = "192.0.2.0/24"; + + // The VPC network name in the format: projects/PROJECT_ID/global/networks/NETWORK_NAME + // String vpcNetworkName = "projects/my-project/global/networks/my-vpc"; + + // The VPC IPv4/IPv6 CIDR range to allow + // String vpcRange = "10.0.0.0/24"; + + Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService(); + Bucket bucket = storage.get(bucketName); + + List publicRanges = new ArrayList<>(); + List vpcSources = new ArrayList<>(); + + IpFilter existingIpFilter = bucket.getIpFilter(); + if (existingIpFilter != null) { + if (existingIpFilter.getPublicNetworkSource() != null + && existingIpFilter.getPublicNetworkSource().getAllowedIpCidrRanges() != null) { + publicRanges.addAll(existingIpFilter.getPublicNetworkSource().getAllowedIpCidrRanges()); + } + if (existingIpFilter.getVpcNetworkSources() != null) { + vpcSources.addAll(existingIpFilter.getVpcNetworkSources()); + } + } + + if (publicRange != null && !publicRanges.contains(publicRange)) { + publicRanges.add(publicRange); + } + + if (vpcNetworkName != null && vpcRange != null) { + boolean found = false; + for (int i = 0; i < vpcSources.size(); i++) { + VpcNetworkSource vpcSource = vpcSources.get(i); + if (vpcNetworkName.equals(vpcSource.getNetwork())) { + found = true; + List ranges = new ArrayList<>(); + if (vpcSource.getAllowedIpCidrRanges() != null) { + ranges.addAll(vpcSource.getAllowedIpCidrRanges()); + } + if (!ranges.contains(vpcRange)) { + ranges.add(vpcRange); + } + vpcSources.set(i, vpcSource.toBuilder().setAllowedIpCidrRanges(ranges).build()); + break; + } + } + if (!found) { + vpcSources.add( + VpcNetworkSource.newBuilder() + .setNetwork(vpcNetworkName) + .setAllowedIpCidrRanges(Collections.singletonList(vpcRange)) + .build()); + } + } + + IpFilter.Builder ipFilterBuilder = + IpFilter.newBuilder() + .setMode("Enabled") + .setAllowAllServiceAgentAccess(true) + .setAllowCrossOrgVpcs(true); + + if (!publicRanges.isEmpty()) { + ipFilterBuilder.setPublicNetworkSource(PublicNetworkSource.of(publicRanges)); + } + if (!vpcSources.isEmpty()) { + ipFilterBuilder.setVpcNetworkSources(vpcSources); + } + + IpFilter newIpFilter = ipFilterBuilder.build(); + Bucket updatedBucket = storage.update(bucket.toBuilder().setIpFilter(newIpFilter).build()); + + System.out.println( + "Enabled IP filtering for bucket " + + bucketName + + ", allowed public CIDRs: " + + publicRanges + + ", VPC sources: " + + vpcSources); + + return updatedBucket; + } +} +// [END storage_enable_ip_filtering] diff --git a/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/GetBucketIpFilter.java b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/GetBucketIpFilter.java new file mode 100644 index 000000000000..ac4f51b239aa --- /dev/null +++ b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/GetBucketIpFilter.java @@ -0,0 +1,67 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.storage.bucket; + +// [START storage_get_ip_filtering] +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo.IpFilter; +import com.google.cloud.storage.BucketInfo.IpFilter.VpcNetworkSource; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; + +public class GetBucketIpFilter { + public static IpFilter getBucketIpFilter(String projectId, String bucketName) { + // The ID of your GCP project + // String projectId = "your-project-id"; + + // The ID of your GCS bucket + // String bucketName = "your-unique-bucket-name"; + + Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService(); + Bucket bucket = storage.get(bucketName); + IpFilter ipFilter = bucket.getIpFilter(); + + if (ipFilter == null) { + System.out.println("Bucket " + bucketName + " has no IP Filter configured."); + return null; + } + + System.out.println("IP Filter Mode: " + ipFilter.getMode()); + System.out.println( + "Allow All Service Agent Access: " + ipFilter.getAllowAllServiceAgentAccess()); + System.out.println("Allow Cross Org VPCs: " + ipFilter.getAllowCrossOrgVpcs()); + + if (ipFilter.getPublicNetworkSource() != null) { + System.out.println( + "Allowed Public CIDR Blocks: " + + ipFilter.getPublicNetworkSource().getAllowedIpCidrRanges()); + } + + if (ipFilter.getVpcNetworkSources() != null) { + for (VpcNetworkSource vpcSource : ipFilter.getVpcNetworkSources()) { + System.out.println( + "VPC Network: " + + vpcSource.getNetwork() + + ", Allowed CIDR Ranges: " + + vpcSource.getAllowedIpCidrRanges()); + } + } + + return ipFilter; + } +} +// [END storage_get_ip_filtering] diff --git a/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/ListBucketsIpFilter.java b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/ListBucketsIpFilter.java new file mode 100644 index 000000000000..681bece593cd --- /dev/null +++ b/java-storage/samples/snippets/src/main/java/com/example/storage/bucket/ListBucketsIpFilter.java @@ -0,0 +1,42 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.storage.bucket; + +// [START storage_list_buckets_ip_filtering] +import com.google.api.gax.paging.Page; +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo.IpFilter; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; + +public class ListBucketsIpFilter { + public static void listBucketsIpFilter(String projectId) { + // The ID of your GCP project + // String projectId = "your-project-id"; + + Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService(); + Page buckets = storage.list(); + + for (Bucket bucket : buckets.iterateAll()) { + IpFilter ipFilter = bucket.getIpFilter(); + String status = + (ipFilter == null || ipFilter.getMode() == null) ? "Not Configured" : ipFilter.getMode(); + System.out.println("Bucket: " + bucket.getName() + ", IP Filter Mode: " + status); + } + } +} +// [END storage_list_buckets_ip_filtering] diff --git a/java-storage/samples/snippets/src/test/java/com/example/storage/bucket/IpFilterTest.java b/java-storage/samples/snippets/src/test/java/com/example/storage/bucket/IpFilterTest.java new file mode 100644 index 000000000000..c3602bef842a --- /dev/null +++ b/java-storage/samples/snippets/src/test/java/com/example/storage/bucket/IpFilterTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.storage.bucket; + +import static com.example.storage.Env.GOOGLE_CLOUD_PROJECT; +import static com.google.common.truth.Truth.assertThat; + +import com.example.storage.TestBase; +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo; +import com.google.cloud.storage.testing.RemoteStorageHelper; +import org.junit.Test; + +public class IpFilterTest extends TestBase { + + @Test + public void testBucketIpFilterLifecycle() throws Exception { + String bucketName = RemoteStorageHelper.generateBucketName(); + String publicRange = "192.0.2.0/24"; + String vpcNetwork = "projects/" + GOOGLE_CLOUD_PROJECT + "/global/networks/default"; + String vpcRange = "10.0.0.0/24"; + + try { + // 1. Create with IP Filter + CreateBucketIpFilter.createBucketIpFilter(GOOGLE_CLOUD_PROJECT, bucketName, publicRange); + Bucket created = storage.get(bucketName); + assertThat(created.getIpFilter()).isNotNull(); + + // 2. Enable IP Filter with Public and VPC ranges + Bucket enabled = + EnableBucketIpFilter.enableBucketIpFilter( + GOOGLE_CLOUD_PROJECT, bucketName, publicRange, vpcNetwork, vpcRange); + assertThat(enabled.getIpFilter().getMode()).isEqualTo("Enabled"); + + // 3. Get IP Filter + BucketInfo.IpFilter fetched = + GetBucketIpFilter.getBucketIpFilter(GOOGLE_CLOUD_PROJECT, bucketName); + assertThat(fetched.getMode()).isEqualTo("Enabled"); + + // 4. Delete IP Filter rules + Bucket modified = + DeleteBucketIpFilter.deleteBucketIpFilterRules( + GOOGLE_CLOUD_PROJECT, bucketName, publicRange, vpcNetwork); + assertThat(modified.getIpFilter()).isNotNull(); + + // 5. Disable IP Filter + Bucket disabled = + DisableBucketIpFilter.disableBucketIpFilter(GOOGLE_CLOUD_PROJECT, bucketName); + assertThat(disabled.getIpFilter().getMode()).isEqualTo("Disabled"); + + // 6. List Buckets with IP Filter + ListBucketsIpFilter.listBucketsIpFilter(GOOGLE_CLOUD_PROJECT); + assertThat(stdOut.getCapturedOutputAsUtf8String()).contains(bucketName); + } finally { + RemoteStorageHelper.forceDelete(storage, bucketName); + } + } +}