Skip to content

samples(Storage): Add samples and tests for Bucket IP filter#22

Open
mahendra-google wants to merge 25 commits into
mainfrom
bucket-ip-filter
Open

samples(Storage): Add samples and tests for Bucket IP filter#22
mahendra-google wants to merge 25 commits into
mainfrom
bucket-ip-filter

Conversation

@mahendra-google
Copy link
Copy Markdown
Owner

@mahendra-google mahendra-google commented May 11, 2026

This PR Introduces code samples and integration tests for the full Bucket IP Filter lifecycle.

Operations Covered are :

Create / Update / Delete: Management of IP filter rule sets.

Get / List: Retrieval of configuration metadata.

Disable / Bypass: Logic for pausing filters or configuring administrative overrides.

- Added CreateBucketWithIpFilterSample for bucket security configuration.
- Added ListBucketIpFiltersSample to demonstrate filter retrieval.
- Included integration tests to verify IP filter logic.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces new C# code samples and corresponding tests for Google Cloud Storage bucket IP filter configurations, including functionality to create buckets with specific IP CIDR ranges and retrieve those settings. Feedback indicates that the ListBucketIpFilterTest needs to register created buckets for cleanup and include a sleep call to ensure consistency. Additionally, the XML documentation in ListBucketIpFilter.cs requires correction to properly nest the tag outside of the

block.

var listIpFilter = new ListBucketIpFiltersSample();

var bucketName = _fixture.GenerateBucketName();
createIpFilter.CreateBucketWithIpFilter(_fixture.ProjectId, bucketName);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The bucket created in this test is not registered for cleanup in _fixture.TempBucketNames, which will lead to orphaned buckets in the test project. Additionally, a call to SleepAfterBucketCreateUpdateDelete() is missing after bucket creation to ensure eventual consistency and avoid rate limiting issues, consistent with other tests in this suite.

        var bucket = createIpFilter.CreateBucketWithIpFilter(_fixture.ProjectId, bucketName);
        _fixture.SleepAfterBucketCreateUpdateDelete();
        _fixture.TempBucketNames.Add(bucket.Name);

Comment on lines +21 to +24
/// <summary>
/// Retrieves the IP Filter configuration for the bucket.
/// <param name="bucketName">The name of the bucket.</param>
/// </summary>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The <param> tag is incorrectly nested inside the <summary> tag. According to standard C# XML documentation practices, <param> should be a top-level tag within the documentation comment.

/// <summary>
/// Retrieves the IP Filter configuration for the bucket.
/// </summary>
/// <param name="bucketName">The name of the bucket.</param>

@mahendra-google
Copy link
Copy Markdown
Owner Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive set of C# code samples and unit tests for managing Google Cloud Storage Bucket IP filters, covering operations such as creation, retrieval, listing, updating, disabling, and bypassing filter rules. The review feedback highlights several areas for improvement: specifically, adding defensive null checks in the delete and update samples to prevent potential NullReferenceException errors, replacing hardcoded VPC network names with placeholders for better sample consistency, and refining console output to ensure VPC network details are printed correctly instead of their type names.

Comment on lines +31 to +34
var bucket = storage.GetBucket(bucketName);
bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges.Remove(ipAddress);
storage.UpdateBucket(bucket);
Console.WriteLine($"IP Address ({ipAddress}) from Allowed CIDR Ranges has been deleted from the bucket: {bucketName}");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The code lacks defensive checks for IpFilter, PublicNetworkSource, and AllowedIpCidrRanges. If any of these are null, a NullReferenceException will occur. It is safer to verify these are not null before attempting to remove the IP address.

        var bucket = storage.GetBucket(bucketName);
        if (bucket.IpFilter?.PublicNetworkSource?.AllowedIpCidrRanges == null)
        {
            Console.WriteLine($"Bucket {bucketName} has no IP Filter CIDR ranges to delete.");
            return;
        }
        bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges.Remove(ipAddress);
        storage.UpdateBucket(bucket);
        Console.WriteLine($"IP Address ({ipAddress}) from Allowed CIDR Ranges has been deleted from the bucket: {bucketName}");

Comment on lines +46 to +49
if (bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges == null)
{
bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges = new List<string>();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If bucket.IpFilter is not null but PublicNetworkSource is null, accessing bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges will throw a NullReferenceException. An additional check for PublicNetworkSource is recommended.

        if (bucket.IpFilter.PublicNetworkSource == null)
        {
            bucket.IpFilter.PublicNetworkSource = new Bucket.IpFilterData.PublicNetworkSourceData();
        }
        if (bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges == null)
        {
            bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges = new List<string>();
        }

{
new Bucket.IpFilterData.VpcNetworkSourcesData
{
Network = $"projects/{projectId}/global/networks/my-vpc-network",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The VPC network name is hardcoded as 'my-vpc-network'. For consistency with other parameters in this sample (like projectId and bucketName), it should use a placeholder or a variable.

                             Network = $"projects/{projectId}/global/networks/your-vpc-network",

Comment on lines +55 to +58
foreach (var vpcNetwork in bucket.IpFilter.VpcNetworkSources)
{
Console.WriteLine($"- {vpcNetwork}");
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Printing the vpcNetwork object directly will likely output the type name instead of the network path. It is better to print the Network property and its associated CIDR ranges to provide useful output.

            foreach (var vpcNetwork in bucket.IpFilter.VpcNetworkSources)
            {
                Console.WriteLine($"- Network: {vpcNetwork.Network}");
                if (vpcNetwork.AllowedIpCidrRanges != null)
                {
                    Console.WriteLine($"  Allowed CIDR Ranges: {string.Join(", ", vpcNetwork.AllowedIpCidrRanges)}");
                }
            }

Updated the start and end region tags for the listbuckets with ip filter
code samples
…ateBucketIpFilter

Updates the UpdateBucketIpFilter method signature to accept projectId and vpcNetwork parameters instead of relying on a hardcoded string. This allows users to pass in actual configuration values and use dynamic string interpolation.

Updates the test accordingly
@mahendra-google
Copy link
Copy Markdown
Owner Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several C# sample classes and integration tests for managing Google Cloud Storage bucket IP filtering, including creating, updating, retrieving, listing, disabling, and deleting IP filter configurations. The feedback suggests materializing the lazy enumerable in the bucket listing sample to avoid redundant API calls, and adding checks to prevent duplicate IP ranges from being added to the public and VPC CIDR lists during updates.

public IEnumerable<Bucket> ListBucketWithIpFilter(string projectId = "your-project-id")
{
var storage = StorageClient.Create();
IEnumerable<Bucket> buckets = storage.ListBuckets(projectId).Where(b => b.IpFilter != null);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The storage.ListBuckets(projectId) method returns a lazy enumerable that performs remote API calls. Because buckets is iterated once in the foreach loop and then returned to the caller (who iterates it again, e.g., in the integration test via FirstOrDefault), this causes multiple redundant API calls to Google Cloud Storage.\n\nMaterializing the query using .ToList() avoids this double-enumeration performance penalty.

        var buckets = storage.ListBuckets(projectId).Where(b => b.IpFilter != null).ToList();

Comment on lines +57 to +61
if (bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges == null)
{
bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges = new List<string>();
}
bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges.Add(publicRange);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To prevent adding duplicate IP ranges to the allowed public CIDR ranges list, check if the range already exists before adding it.

        if (bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges == null)\n        {\n            bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges = new List<string>();\n        }\n        if (!bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges.Contains(publicRange))\n        {\n            bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges.Add(publicRange);\n        }

Comment on lines +71 to +78
if (existingVpcNetwork != null)
{
if (existingVpcNetwork.AllowedIpCidrRanges == null)
{
existingVpcNetwork.AllowedIpCidrRanges = new List<string>();
}
existingVpcNetwork.AllowedIpCidrRanges.Add(vpcRange);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To prevent adding duplicate IP ranges to the allowed VPC CIDR ranges list, check if the range already exists before adding it.

        if (existingVpcNetwork != null)\n        {\n            if (existingVpcNetwork.AllowedIpCidrRanges == null)\n            {\n                existingVpcNetwork.AllowedIpCidrRanges = new List<string>();\n            }\n            if (!existingVpcNetwork.AllowedIpCidrRanges.Contains(vpcRange))\n            {\n                existingVpcNetwork.AllowedIpCidrRanges.Add(vpcRange);\n            }\n        }

@mahendra-google
Copy link
Copy Markdown
Owner Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several new code samples and corresponding unit tests demonstrating Google Cloud Storage IP filtering capabilities, including creating, updating, getting, listing, disabling, deleting, and bypassing IP filters on buckets. The feedback highlights a duplicate region tag conflict in UpdateBucketIpFilter.cs and a logical/performance issue in ListBucketsWithIpFilter.cs where deferred execution of bucket listing leads to redundant API calls and incorrect filtering.

// See the License for the specific language governing permissions and
// limitations under the License.

// [START storage_enable_ip_filtering]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The region tag storage_enable_ip_filtering is already used in CreateBucketWithIpFilter.cs. Reusing the same region tag in multiple files within the same language/directory will cause conflicts and build failures in the Google Cloud documentation publishing pipeline. Please use a unique region tag for this sample, such as storage_update_bucket_ip_filtering.

// [START storage_update_bucket_ip_filtering]

return updatedBucket;
}
}
// [END storage_enable_ip_filtering]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Please update the closing region tag to match the unique region tag storage_update_bucket_ip_filtering.

// [END storage_update_bucket_ip_filtering]

public IEnumerable<Bucket> ListBucketWithIpFilter(string projectId = "your-project-id")
{
var storage = StorageClient.Create();
IEnumerable<Bucket> buckets = storage.ListBuckets(projectId).Where(b => b.IpFilter != null);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The method's XML documentation states it "Lists all buckets including their IP filtering status", and line 38 attempts to handle the case where IpFilter is null by falling back to "Not Configured". However, the .Where(b => b.IpFilter != null) filter on line 32 excludes all buckets without an IP filter, making the fallback unreachable and failing to list all buckets.\n\nAdditionally, storage.ListBuckets(projectId) returns a deferred PagedEnumerable. By not materializing it, iterating over buckets in the foreach loop and then returning it for the caller (or tests) to iterate again will trigger redundant API calls to GCS. Materializing it with .ToList() resolves both issues.

        List<Bucket> buckets = storage.ListBuckets(projectId).ToList();

@mahendra-google
Copy link
Copy Markdown
Owner Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces sample code and corresponding tests for managing IP filtering configurations on Google Cloud Storage buckets, including creating, updating, disabling, getting, listing, and deleting IP filter rules, as well as bypassing filters for service agents and cross-org VPCs. The review feedback highlights potential runtime issues where directly modifying collections returned by the client library (such as AllowedIpCidrRanges and VpcNetworkSources) could throw a NotSupportedException if they are read-only or arrays. Additionally, it is recommended to avoid eagerly loading all buckets into memory with .ToList() when listing buckets to prevent performance degradation in projects with a large number of buckets.

Comment on lines +38 to +43
bool removed = bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges.Remove(ipAddress);
if (!removed)
{
Console.WriteLine($"IP Address ({ipAddress}) was not found in the Allowed CIDR ranges.");
return;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Modifying the AllowedIpCidrRanges collection directly using .Remove() can throw a NotSupportedException if the underlying collection returned by the client library is read-only or an array. It is safer to copy the collection to a new List<string>, perform the removal, and then reassign it.

        var ranges = new List<string>(bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges);
        if (!ranges.Remove(ipAddress))
        {
            Console.WriteLine($"IP Address ({ipAddress}) was not found in the Allowed CIDR ranges.");
            return;
        }
        bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges = ranges;

Comment on lines +40 to +88
if (bucket.IpFilter == null)
{
bucket.IpFilter = new Bucket.IpFilterData
{
Mode = "Enabled",
PublicNetworkSource = new Bucket.IpFilterData.PublicNetworkSourceData
{
AllowedIpCidrRanges = new List<string>()
},
VpcNetworkSources = new List<Bucket.IpFilterData.VpcNetworkSourcesData>()
};
}

if (bucket.IpFilter.PublicNetworkSource == null)
{
bucket.IpFilter.PublicNetworkSource = new Bucket.IpFilterData.PublicNetworkSourceData();
}
if (bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges == null)
{
bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges = new List<string>();
}
if (!bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges.Contains(publicRange))
{
bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges.Add(publicRange);
}
if (bucket.IpFilter.VpcNetworkSources == null)
{
bucket.IpFilter.VpcNetworkSources = new List<Bucket.IpFilterData.VpcNetworkSourcesData>();
}

string networkName = $"projects/{projectId}/global/networks/{vpcNetwork}";
var existingVpcNetwork = bucket.IpFilter.VpcNetworkSources.FirstOrDefault(v => v.Network == networkName);

if (existingVpcNetwork != null)
{
existingVpcNetwork.AllowedIpCidrRanges ??= new List<string>();
if (!existingVpcNetwork.AllowedIpCidrRanges.Contains(vpcRange))
{
existingVpcNetwork.AllowedIpCidrRanges.Add(vpcRange);
}
}
else
{
bucket.IpFilter.VpcNetworkSources.Add(new Bucket.IpFilterData.VpcNetworkSourcesData
{
Network = networkName,
AllowedIpCidrRanges = new List<string> { vpcRange }
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Directly modifying or adding items to the AllowedIpCidrRanges and VpcNetworkSources collections can throw a NotSupportedException if the underlying collections returned by the client library are read-only or arrays.

Additionally, the initialization and update logic can be simplified and made much more robust by using the null-coalescing assignment operator (??=) and copying the collections to new lists before modification.

        bucket.IpFilter ??= new Bucket.IpFilterData { Mode = "Enabled" };
        bucket.IpFilter.PublicNetworkSource ??= new Bucket.IpFilterData.PublicNetworkSourceData();

        var publicRanges = bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges?.ToList() ?? new List<string>();
        if (!publicRanges.Contains(publicRange))
        {
            publicRanges.Add(publicRange);
            bucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges = publicRanges;
        }

        var vpcSources = bucket.IpFilter.VpcNetworkSources?.ToList() ?? new List<Bucket.IpFilterData.VpcNetworkSourcesData>();
        string networkName = $"projects/{projectId}/global/networks/{vpcNetwork}";
        var existingVpcNetwork = vpcSources.FirstOrDefault(v => v.Network == networkName);

        if (existingVpcNetwork != null)
        {
            var vpcRanges = existingVpcNetwork.AllowedIpCidrRanges?.ToList() ?? new List<string>();
            if (!vpcRanges.Contains(vpcRange))
            {
                vpcRanges.Add(vpcRange);
                existingVpcNetwork.AllowedIpCidrRanges = vpcRanges;
            }
        }
        else
        {
            vpcSources.Add(new Bucket.IpFilterData.VpcNetworkSourcesData
            {
                Network = networkName,
                AllowedIpCidrRanges = new List<string> { vpcRange }
            });
        }
        bucket.IpFilter.VpcNetworkSources = vpcSources;

public IEnumerable<Bucket> ListBucketsWithIpFilterStatus(string projectId = "your-project-id")
{
var storage = StorageClient.Create();
IEnumerable<Bucket> buckets = storage.ListBuckets(projectId).ToList();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Calling .ToList() eagerly loads all buckets in the project into memory. If the project contains a large number of buckets, this can cause significant performance degradation and high memory usage. Since the method returns IEnumerable<Bucket> and only iterates over them, you can stream the buckets lazily by removing .ToList().

        var buckets = storage.ListBuckets(projectId);

@mahendra-google
Copy link
Copy Markdown
Owner Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces new sample classes and corresponding unit tests for managing IP filtering configurations on Google Cloud Storage buckets, including enabling, disabling, retrieving, listing, and deleting IP filter rules. The review feedback correctly identifies a critical bug in EnableBucketIpFilter where the bucket's IP filter mode is not updated to "Enabled" if an IP filter configuration already exists. Additionally, the feedback points out that the unit test EnableBucketIpFilterTest incorrectly asserts the mode to be "Disabled" to match this buggy behavior, and both should be updated to correctly handle and assert the "Enabled" state.

Comment on lines +40 to +51
if (bucket.IpFilter == null)
{
bucket.IpFilter = new Bucket.IpFilterData
{
Mode = "Enabled",
PublicNetworkSource = new Bucket.IpFilterData.PublicNetworkSourceData
{
AllowedIpCidrRanges = new List<string>()
},
VpcNetworkSources = new List<Bucket.IpFilterData.VpcNetworkSourcesData>()
};
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

In EnableBucketIpFilter, if bucket.IpFilter is already non-null (for example, if it was previously configured but disabled), the Mode is never updated to "Enabled". This means the method will fail to actually enable IP filtering for buckets that already have an existing IP filter configuration. Setting bucket.IpFilter.Mode = \"Enabled\" unconditionally (after ensuring bucket.IpFilter is initialized) fixes this issue.

        if (bucket.IpFilter == null)
        {
            bucket.IpFilter = new Bucket.IpFilterData
            {
                PublicNetworkSource = new Bucket.IpFilterData.PublicNetworkSourceData
                {
                    AllowedIpCidrRanges = new List<string>()
                },
                VpcNetworkSources = new List<Bucket.IpFilterData.VpcNetworkSourcesData>()
            };
        }
        bucket.IpFilter.Mode = "Enabled";

Comment on lines +37 to +39
var updatedBucket = updateSample.EnableBucketIpFilter(projectId, bucketName, newPublicRange, newVpcRange);
Assert.NotNull(updatedBucket.IpFilter);
Assert.Equal("Disabled", updatedBucket.IpFilter.Mode);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The test currently asserts that the bucket's IP filter mode is "Disabled" after calling EnableBucketIpFilter. This assertion was likely adjusted to match the buggy behavior of the sample implementation. Once the sample is fixed to correctly set the mode to "Enabled", this assertion should be updated to expect "Enabled".

        var updatedBucket = updateSample.EnableBucketIpFilter(projectId, bucketName, newPublicRange, newVpcRange);
        Assert.NotNull(updatedBucket.IpFilter);
        Assert.Equal("Enabled", updatedBucket.IpFilter.Mode);

@mahendra-google
Copy link
Copy Markdown
Owner Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces new C# samples and integration tests for managing IP filtering configurations on Google Cloud Storage buckets, including enabling, disabling, retrieving, listing, and deleting IP filter rules. The review feedback suggests two key improvements: removing .ToList() in ListBucketsWithIpFilterStatus to leverage lazy loading and avoid high memory consumption, and using conditional access defensively on updatedBucket.IpFilter in EnableBucketIpFilter to prevent potential NullReferenceExceptions.

public IEnumerable<Bucket> ListBucketsWithIpFilterStatus(string projectId = "your-project-id")
{
var storage = StorageClient.Create();
IEnumerable<Bucket> buckets = storage.ListBuckets(projectId).ToList();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Calling .ToList() on the result of ListBuckets eagerly loads all buckets in the project into memory. For projects with a large number of buckets, this can lead to high memory consumption and performance degradation. Since the method returns IEnumerable<Bucket> and only iterates over them, you can safely remove .ToList() to leverage lazy loading.

        var buckets = storage.ListBuckets(projectId);

Comment on lines +96 to +102
var currentPublicRanges = updatedBucket.IpFilter.PublicNetworkSource?.AllowedIpCidrRanges != null
? string.Join(", ", updatedBucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges)
: "None";

var currentVpcRanges = updatedBucket.IpFilter.VpcNetworkSources != null && updatedBucket.IpFilter.VpcNetworkSources.Any()
? string.Join(", ", updatedBucket.IpFilter.VpcNetworkSources.SelectMany(v => v.AllowedIpCidrRanges ?? new List<string>()))
: "None";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To prevent a potential NullReferenceException, use conditional access (?.) on updatedBucket.IpFilter when retrieving the current public and VPC network ranges. Although IpFilter was just enabled, defensive programming is recommended for sample code to handle unexpected API responses gracefully.

        var currentPublicRanges = updatedBucket.IpFilter?.PublicNetworkSource?.AllowedIpCidrRanges != null
            ? string.Join(", ", updatedBucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges)
            : "None";

        var currentVpcRanges = updatedBucket.IpFilter?.VpcNetworkSources != null && updatedBucket.IpFilter.VpcNetworkSources.Any()
            ? string.Join(", ", updatedBucket.IpFilter.VpcNetworkSources.SelectMany(v => v.AllowedIpCidrRanges ?? new List<string>()))
            : "None";

@mahendra-google
Copy link
Copy Markdown
Owner Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several new C# samples and tests for managing IP filtering configurations on Google Cloud Storage buckets, including enabling, disabling, getting, listing, and deleting IP filter rules. The StorageFixture test helper was also updated to support IP filter configurations. The review feedback suggests defensively using the null-conditional operator (?.) when accessing updatedBucket.IpFilter in both EnableBucketIpFilter.cs and DisableBucketIpFilter.cs to prevent potential NullReferenceExceptions if the server returns a bucket with a null IP filter configuration.

Comment on lines +96 to +102
var currentPublicRanges = updatedBucket.IpFilter.PublicNetworkSource?.AllowedIpCidrRanges != null
? string.Join(", ", updatedBucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges)
: "None";

var currentVpcRanges = updatedBucket.IpFilter.VpcNetworkSources != null && updatedBucket.IpFilter.VpcNetworkSources.Any()
? string.Join(", ", updatedBucket.IpFilter.VpcNetworkSources.SelectMany(v => v.AllowedIpCidrRanges ?? new List<string>()))
: "None";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Defensively use the null-conditional operator (?.) when accessing updatedBucket.IpFilter to prevent a potential NullReferenceException if the server returns a bucket with a null IpFilter configuration.

        var currentPublicRanges = updatedBucket.IpFilter?.PublicNetworkSource?.AllowedIpCidrRanges != null
            ? string.Join(", ", updatedBucket.IpFilter.PublicNetworkSource.AllowedIpCidrRanges)
            : "None";

        var currentVpcRanges = updatedBucket.IpFilter?.VpcNetworkSources != null && updatedBucket.IpFilter.VpcNetworkSources.Any()
            ? string.Join(", ", updatedBucket.IpFilter.VpcNetworkSources.SelectMany(v => v.AllowedIpCidrRanges ?? new List<string>()))
            : "None";

Comment on lines +36 to +38
var updatedBucket = storage.UpdateBucket(bucket);
Console.WriteLine($"IP filtering has been {updatedBucket.IpFilter.Mode} for the Bucket: {bucketName}");
return updatedBucket;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Defensively use the null-conditional operator (?.) when accessing updatedBucket.IpFilter to prevent a potential NullReferenceException if the server returns a bucket with a null IpFilter configuration.

            var updatedBucket = storage.UpdateBucket(bucket);
            Console.WriteLine($"IP filtering has been {updatedBucket.IpFilter?.Mode ?? "Disabled"} for the Bucket: {bucketName}");
            return updatedBucket;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant