Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions storage/api/Storage.Samples.Tests/DeleteBucketIpFilterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// 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.

using Google.Cloud.Storage.V1;
using System.Linq;
using Xunit;

[Collection(nameof(StorageFixture))]
public class DeleteBucketIpFilterTest
{
private readonly StorageFixture _fixture;

public DeleteBucketIpFilterTest(StorageFixture fixture)
{
_fixture = fixture;
}

[Fact]
public void TestDeleteBucketIpFilter()
{
var deleteSample = new DeleteBucketIpFilterSample();
var storage = StorageClient.Create();
var bucketName = _fixture.GenerateBucketName();
var ipFilteredBucket = _fixture.CreateBucket(bucketName, multiVersion: false, ipFilter: true, registerForDeletion: true);
string targetPublicIp = "0.0.0.0/0";
string targetVpc = $"projects/{_fixture.ProjectId}/global/networks/default";
deleteSample.DeleteBucketIpFilter(bucketName, targetPublicIp, targetVpc);
var updatedBucket = storage.GetBucket(bucketName);
Assert.NotNull(updatedBucket.IpFilter);
Assert.NotNull(updatedBucket.IpFilter.PublicNetworkSource);
Assert.DoesNotContain(targetPublicIp, updatedBucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges);
Assert.False(updatedBucket.IpFilter?.VpcNetworkSources?.Any(v => v.Network == targetVpc) ?? false);
}
}
67 changes: 67 additions & 0 deletions storage/api/Storage.Samples.Tests/DisableBucketIpFilterTest.cs
Original file line number Diff line number Diff line change
@@ -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.

using Google;
using Google.Apis.Storage.v1.Data;
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;

[Collection(nameof(StorageFixture))]
public class DisableBucketIpFilterTest
{
private readonly StorageFixture _fixture;

public DisableBucketIpFilterTest(StorageFixture fixture)
{
_fixture = fixture;
}

[Fact]
public void TestDisableBucketIpFilter()
{
var disableSample = new DisableBucketIpFilterSample();
var enableSample = new EnableBucketIpFilterSample();
var projectId = _fixture.ProjectId;
var bucketName = _fixture.GenerateBucketName();
_fixture.CreateBucket(bucketName, multiVersion: false, ipFilter: true, registerForDeletion: true);
var newPublicRange = "0.0.0.0/0";
var ipFilterEnabledBucket = enableSample.EnableBucketIpFilter(projectId, bucketName, publicRange: newPublicRange);
Bucket unfilteredBucket = null;
bool isPropagationBlocked;

try
{
unfilteredBucket = disableSample.DisableBucketIpFilter(ipFilterEnabledBucket.Name);
isPropagationBlocked = false;
}
catch (GoogleApiException ex) when (ex.HttpStatusCode == HttpStatusCode.Forbidden)
{
isPropagationBlocked = true;
}

if (isPropagationBlocked)
{
Assert.True(isPropagationBlocked, "IP filtering prevented access (403 Forbidden).");
return;
}

Assert.NotNull(unfilteredBucket.IpFilter);
Assert.Equal("Disabled", unfilteredBucket.IpFilter.Mode);
Assert.NotNull(unfilteredBucket.IpFilter.PublicNetworkSource?.AllowedIpCidrRanges);
Assert.Contains("203.0.113.0/24", unfilteredBucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges);
}
}
50 changes: 50 additions & 0 deletions storage/api/Storage.Samples.Tests/EnableBucketIpFilterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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.

using System.Linq;
using Xunit;

[Collection(nameof(StorageFixture))]
public class EnableBucketIpFilterTest
{
private readonly StorageFixture _fixture;

public EnableBucketIpFilterTest(StorageFixture fixture)
{
_fixture = fixture;
}

[Fact]
public void TestEnableBucketIpFilter()
{
var updateSample = new EnableBucketIpFilterSample();
var bucketName = _fixture.GenerateBucketName();
var projectId = _fixture.ProjectId;
string newPublicRange = "0.0.0.0/0";
string newVpcRange = "0.0.0.0/0";
_fixture.CreateBucket(bucketName, multiVersion: false, ipFilter: false, registerForDeletion: true);
var updatedBucket = updateSample.EnableBucketIpFilter(projectId, bucketName, newPublicRange, newVpcRange);
Assert.NotNull(updatedBucket.IpFilter);
Assert.Equal("Enabled", updatedBucket.IpFilter.Mode);
var publicRanges = updatedBucket.IpFilter.PublicNetworkSource?.AllowedIpCidrRanges;
Assert.NotNull(publicRanges);
Assert.Contains(newPublicRange, publicRanges);
var vpcNetwork = updatedBucket.IpFilter.VpcNetworkSources?
.FirstOrDefault(v => v.Network == $"projects/{projectId}/global/networks/default");
Assert.NotNull(vpcNetwork);
var vpcRanges = vpcNetwork.AllowedIpCidrRanges;
Assert.NotNull(vpcRanges);
Assert.Contains(newVpcRange, vpcRanges);
}
}
43 changes: 43 additions & 0 deletions storage/api/Storage.Samples.Tests/GetBucketIpFilterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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.

using Xunit;

[Collection(nameof(StorageFixture))]
public class GetBucketIpFilterTest
{
private readonly StorageFixture _fixture;

public GetBucketIpFilterTest(StorageFixture fixture)
{
_fixture = fixture;
}

[Fact]
public void TestGetBucketIpFilter()
{
var getIpFilter = new GetBucketIpFilterSample();
var bucketName = _fixture.GenerateBucketName();
_fixture.CreateBucket(bucketName, multiVersion: false, ipFilter: true, registerForDeletion: true);
var bucketIpFilter = getIpFilter.GetBucketIpFilter(bucketName);
Assert.NotNull(bucketIpFilter);
Assert.Equal("Disabled", bucketIpFilter.Mode);
Assert.False(bucketIpFilter.AllowAllServiceAgentAccess);
Assert.False(bucketIpFilter.AllowCrossOrgVpcs);
Assert.NotNull(bucketIpFilter.PublicNetworkSource);
Assert.NotNull(bucketIpFilter.PublicNetworkSource.AllowedIpCidrRanges);
Assert.Contains("203.0.113.0/24", bucketIpFilter.PublicNetworkSource.AllowedIpCidrRanges);
Assert.NotNull(bucketIpFilter.VpcNetworkSources);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// 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.

using System.Linq;
using Xunit;

[Collection(nameof(StorageFixture))]
public class ListBucketsWithIpFilterStatusTest
{
private readonly StorageFixture _fixture;

public ListBucketsWithIpFilterStatusTest(StorageFixture fixture)
{
_fixture = fixture;
}

[Fact]
public void TestListBucketsWithIpFilterStatus()
{
var listBucketsWithIpFilter = new ListBucketsWithIpFilterStatusSample();
var bucketName = _fixture.GenerateBucketName();
_fixture.CreateBucket(bucketName, multiVersion: false, ipFilter: true, registerForDeletion: true);
var buckets = listBucketsWithIpFilter.ListBucketsWithIpFilterStatus(_fixture.ProjectId);
var targetBucket = buckets.FirstOrDefault(b => b.Name == bucketName);
Assert.NotNull(targetBucket);
Assert.Equal("Disabled", targetBucket.IpFilter?.Mode);
}
}
28 changes: 27 additions & 1 deletion storage/api/Storage.Samples.Tests/StorageFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public void CreateBucket(string bucketName, string location = null, AutoclassDat
TempBucketNames.Add(bucketName);
}

internal Bucket CreateBucket(string name, bool multiVersion, bool softDelete = false, bool registerForDeletion = true)
internal Bucket CreateBucket(string name, bool multiVersion, bool softDelete = false, bool registerForDeletion = true, bool ipFilter = false)
{
var bucket = Client.CreateBucket(ProjectId,
new Bucket
Expand All @@ -227,6 +227,32 @@ internal Bucket CreateBucket(string name, bool multiVersion, bool softDelete = f
Versioning = new Bucket.VersioningData { Enabled = multiVersion },
// The minimum allowed for soft delete is 7 days.
SoftDeletePolicy = softDelete ? new Bucket.SoftDeletePolicyData { RetentionDurationSeconds = (int) TimeSpan.FromDays(7).TotalSeconds } : null,
IpFilter = ipFilter ? new Bucket.IpFilterData
{
Mode = "Disabled",
PublicNetworkSource = new Bucket.IpFilterData.PublicNetworkSourceData
{
AllowedIpCidrRanges = new List<string>
{
"203.0.113.0/24",
"198.51.100.10/32",
"0.0.0.0/0"
}
},
VpcNetworkSources = new List<Bucket.IpFilterData.VpcNetworkSourcesData>
{
new Bucket.IpFilterData.VpcNetworkSourcesData
{
Network = $"projects/{ProjectId}/global/networks/default",
AllowedIpCidrRanges = new List<string>
{
"0.0.0.0/0"
}
}
},
AllowAllServiceAgentAccess = false,
AllowCrossOrgVpcs = false
} : null
});
SleepAfterBucketCreateUpdateDelete();
if (registerForDeletion)
Expand Down
86 changes: 86 additions & 0 deletions storage/api/Storage.Samples/DeleteBucketIpFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// 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.

// [START storage_delete_ip_filtering_rules]

using Google.Cloud.Storage.V1;
using System;
using System.Linq;

public class DeleteBucketIpFilterSample
{
/// <summary>
/// Delete specific IP filter rules or VPC network sources from the bucket.
/// </summary>
/// <param name="bucketName">The name of the bucket.</param>
/// <param name="publicRangeToDelete">The public CIDR range to delete (e.g., "1.2.3.4/32").</param>
/// <param name="vpcNetworkToDelete">The name of the VPC network source to delete (e.g., "projects/my-project/global/networks/my-vpc").</param>
public void DeleteBucketIpFilter(
string bucketName = "your-unique-bucket-name",
string publicRangeToDelete = null,
string vpcNetworkToDelete = null)
{
var storage = StorageClient.Create();
var bucket = storage.GetBucket(bucketName);
bool updated = false;

if (bucket.IpFilter == null)
{
Console.WriteLine($"Bucket {bucketName} has no IP Filter Configuration.");
return;
}

if (!string.IsNullOrEmpty(publicRangeToDelete) &&
bucket.IpFilter.PublicNetworkSource?.AllowedIpCidrRanges != null)
{
bool removedPublic = bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges.Remove(publicRangeToDelete);
if (removedPublic)
{
Console.WriteLine($"Removed Public CIDR Range {publicRangeToDelete} from the Bucket {bucketName}.");
updated = true;
}
else
{
Console.WriteLine($"Public CIDR Range {publicRangeToDelete} not found in the Bucket {bucketName} Configuration.");
}
}

if (!string.IsNullOrEmpty(vpcNetworkToDelete) && bucket.IpFilter.VpcNetworkSources != null)
{
var vpcToRemove = bucket.IpFilter.VpcNetworkSources
.FirstOrDefault(v => v.Network == vpcNetworkToDelete);

if (vpcToRemove != null)
{
bucket.IpFilter.VpcNetworkSources.Remove(vpcToRemove);
Console.WriteLine($"Removed VPC Network Source {vpcNetworkToDelete} from the Bucket {bucketName}.");
updated = true;
}
else
{
Console.WriteLine($"VPC Network {vpcNetworkToDelete} not found in the Bucket {bucketName} Configuration.");
}
}

if (updated)
{
storage.UpdateBucket(bucket);
}
else
{
Console.WriteLine("No changes were made to the Bucket's IP filters.");
}
}
}
// [END storage_delete_ip_filtering_rules]
Loading