-
Notifications
You must be signed in to change notification settings - Fork 0
samples(Storage): Add samples and tests for Bucket IP filter #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| // 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 async Task 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); | ||
| string dynamicIp = await GetPublicIpAsync(); | ||
| var newPublicRange = $"{dynamicIp}/32"; | ||
| var ipFilterEnabledBucket = enableSample.EnableBucketIpFilter(projectId, bucketName, publicRange: newPublicRange); | ||
| Bucket unfilteredBucket = null; | ||
| int maxRetries = 6; | ||
| int delayMilliseconds = 5000; | ||
| bool isPropagationBlocked = false; | ||
|
|
||
| for (int i = 0; i < maxRetries; i++) | ||
| { | ||
| try | ||
| { | ||
| unfilteredBucket = disableSample.DisableBucketIpFilter(ipFilterEnabledBucket.Name); | ||
| isPropagationBlocked = false; | ||
| break; | ||
| } | ||
| catch (GoogleApiException ex) when (ex.HttpStatusCode == HttpStatusCode.Forbidden) | ||
| { | ||
| isPropagationBlocked = true; | ||
| if (i < maxRetries - 1) | ||
| { | ||
| await Task.Delay(delayMilliseconds); | ||
| } | ||
| } | ||
| } | ||
| if (isPropagationBlocked) | ||
| { | ||
| Assert.True(isPropagationBlocked, "Firewall propagation timeout encountered."); | ||
| return; | ||
| } | ||
|
Comment on lines
+66
to
+70
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The assertion Assert.False(isPropagationBlocked, "Firewall propagation timeout encountered."); |
||
|
|
||
| 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); | ||
| } | ||
|
|
||
| private async Task<string> GetPublicIpAsync() | ||
| { | ||
| string[] ipServices = new[] | ||
| { | ||
| "https://api.ipify.org", | ||
| "https://icanhazip.com", | ||
| "https://ifconfig.me/ip", | ||
| "https://ident.me" | ||
| }; | ||
|
|
||
| using (var client = new HttpClient()) | ||
| { | ||
| client.Timeout = TimeSpan.FromSeconds(3); | ||
|
|
||
| foreach (var service in ipServices) | ||
| { | ||
| try | ||
| { | ||
| string ip = (await client.GetStringAsync(service)).Trim(); | ||
| if (IPAddress.TryParse(ip, out _)) | ||
| { | ||
| return ip; | ||
| } | ||
| } | ||
| catch (Exception) | ||
| { | ||
| // Log or ignore, try the next service | ||
| } | ||
| } | ||
| } | ||
| throw new InvalidOperationException("Failed to resolve public IP from all fallback services."); | ||
| } | ||
| } | ||
| 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 = "192.0.2.0/24"; | ||
| string newVpcRange = "10.0.0.0/24"; | ||
| _fixture.CreateBucket(bucketName, multiVersion: false, ipFilter: false, registerForDeletion: true); | ||
| var updatedBucket = updateSample.EnableBucketIpFilter(projectId, bucketName); | ||
| 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); | ||
| } | ||
| } |
| 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); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If
updatedBucket.IpFilterorupdatedBucket.IpFilter.PublicNetworkSourceis null, the test will fail with aNullReferenceExceptioninstead of a clear assertion failure. Adding explicitAssert.NotNullchecks improves test clarity and diagnostic messages.