Skip to content

feat(alicloud): aggregate cloudfw policies and assets via DescribeAss…#105

Open
j3ttt wants to merge 2 commits intoantgroup:mainfrom
j3ttt:codex/alicloud-cloudfw-internet-boundary-assets
Open

feat(alicloud): aggregate cloudfw policies and assets via DescribeAss…#105
j3ttt wants to merge 2 commits intoantgroup:mainfrom
j3ttt:codex/alicloud-cloudfw-internet-boundary-assets

Conversation

@j3ttt
Copy link
Collaborator

@j3ttt j3ttt commented Feb 26, 2026

…etList

Thank you for your contribution to CloudRec!

What About:

  • Server (java)
  • Collector (go)
  • Rule (opa)

Description:

Explain the purpose of the PR.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @j3ttt, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the Alicloud Cloud Firewall collector by enabling the aggregation of both firewall policies and their associated assets. The changes streamline the data collection process by consolidating related information into a single, comprehensive data structure, providing a more complete view of Cloud Firewall instances.

Highlights

  • Enhanced Cloud Firewall Data Collection: The Alicloud Cloud Firewall collector has been updated to aggregate both firewall policies and associated assets into a single data structure, improving data completeness for each instance.
  • New Asset Listing Functionality: A new describeAssetList function was introduced to specifically retrieve Internet boundary firewall assets using the DescribeAssetList API, which is then integrated into the main instance detail collection.
  • Refactored Data Aggregation: The GetInstanceDetail function now initializes a Detail struct to hold both collected assets and policies, appending policies to a slice within this struct rather than sending them individually. The Detail struct itself was updated to support this new aggregated data model.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • collector/alicloud/collector/cloudfw/cloudfw_instance.go
    • Modified GetInstanceDetail to initialize a Detail struct for aggregating assets and policies.
    • Added a call to a new describeAssetList function to collect Internet boundary firewall assets.
    • Updated the policy collection loop to append policies to the Policies slice within the Detail struct.
    • Changed the termination condition for policy collection from cancel() and return nil to break.
    • Modified the Detail struct to include Policies (a slice of policy objects) and Assets (a slice of asset objects).
    • Introduced a new function describeAssetList to paginate and collect firewall assets using the DescribeAssetList API.
Activity
  • No specific activity (comments, reviews, or progress updates) has been recorded for this pull request since its creation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@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 refactors the Cloud Firewall collector to aggregate policies and assets before sending them to the results channel. This is a positive change that improves data cohesion and reduces channel communication overhead. The introduction of the describeAssetList function for fetching assets with proper pagination is well-implemented. Additionally, this PR fixes a pre-existing bug that caused policy collection to terminate prematurely. I've identified one issue regarding an incorrect string comparison used for pagination that could lead to erroneous behavior.

Comment on lines 78 to 80
if bd.TotalCount == nil || strconv.Itoa(count) >= *bd.TotalCount {
cancel()
return nil
break
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The string comparison strconv.Itoa(count) >= *bd.TotalCount is incorrect and can lead to bugs. For example, in string comparison, "9" > "10" is true. You should convert *bd.TotalCount to an integer before comparing it with count. This is already handled correctly in the new describeAssetList function where TotalCount is an integer type.

                if bd.TotalCount == nil {
                    break
                }
                totalCount, err := strconv.Atoi(*bd.TotalCount)
                if err != nil {
                    log.CtxLogger(ctx).Warn("failed to parse TotalCount", zap.String("totalCount", *bd.TotalCount), zap.Error(err))
                    break
                }
                if count >= totalCount {
                    break
                }

@j3ttt
Copy link
Collaborator Author

j3ttt commented Feb 26, 2026

/gemini review

@j3ttt
Copy link
Collaborator Author

j3ttt commented Feb 26, 2026

@gemini-code-assist /gemini review

Copy link
Contributor

@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 refactors the Alicloud CloudFW collector to aggregate policies and assets before sending them, which is a good improvement over streaming individual items. The implementation introduces a new function describeAssetList and modifies GetInstanceDetail to support this aggregation. The changes are logical and align with the goal of the pull request. I have identified a few areas for improvement regarding code clarity, robustness against context cancellation, and consistency in API rate limiting.

Comment on lines +112 to +135
for {
request := &cloudfw20171207.DescribeAssetListRequest{
CurrentPage: tea.String(strconv.Itoa(page)),
PageSize: tea.String(strconv.Itoa(pageSize)),
}

resp, err := cli.DescribeAssetListWithOptions(request, collector.RuntimeObject)
if err != nil {
log.CtxLogger(ctx).Warn("describe asset list error", zap.Error(err))
return assets
}
if resp == nil || resp.Body == nil {
return assets
}

assets = append(assets, resp.Body.Assets...)
collected += int32(len(resp.Body.Assets))

if resp.Body.TotalCount == nil || collected >= *resp.Body.TotalCount || len(resp.Body.Assets) == 0 {
return assets
}

page += 1
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The pagination loop in describeAssetList doesn't check for context cancellation. If the context is cancelled (e.g., due to a timeout), this loop will continue to run until all pages are fetched. This can lead to goroutines not terminating promptly and holding up resources. It's important to check for ctx.Done() in each iteration, similar to the pattern used in GetInstanceDetail.

	for {
		select {
		case <-ctx.Done():
			log.CtxLogger(ctx).Warn("context cancelled during asset list description")
			return assets
		default:
			request := &cloudfw20171207.DescribeAssetListRequest{
				CurrentPage: tea.String(strconv.Itoa(page)),
				PageSize:    tea.String(strconv.Itoa(pageSize)),
			}

			resp, err := cli.DescribeAssetListWithOptions(request, collector.RuntimeObject)
			if err != nil {
				log.CtxLogger(ctx).Warn("describe asset list error", zap.Error(err))
				return assets
			}
			if resp == nil || resp.Body == nil {
				return assets
			}

			assets = append(assets, resp.Body.Assets...)
			collected += int32(len(resp.Body.Assets))

			if resp.Body.TotalCount == nil || collected >= *resp.Body.TotalCount || len(resp.Body.Assets) == 0 {
				return assets
			}

			page += 1
		}
	}

return assets
}

page += 1
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The loop in GetInstanceDetail includes a 1-second sleep (time.Sleep(1 * time.Second)) on line 92, presumably for rate limiting. However, this pagination loop in describeAssetList lacks a similar delay. This inconsistency could lead to hitting API rate limits when fetching assets. For consistency and to prevent potential issues, I recommend adding a similar sleep in this loop.

		page += 1
		time.Sleep(1 * time.Second)

Copy link
Contributor

@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 refactors the Alicloud CloudFW collector to aggregate policies and assets before sending them to the results channel. This is a good architectural improvement over sending each item individually. The change also correctly fixes a pagination logic bug that would have prevented collecting policies for all firewall directions. I have a few suggestions to improve the implementation further, mainly regarding context handling in the new pagination loop, removing some redundant code, and using constants for magic numbers.

pageSize := 50
var collected int32 = 0

for {
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The for loop in describeAssetList does not check for context cancellation. If this function takes a long time to run (e.g., due to a large number of assets requiring many pages of API calls), it will not honor the timeout or cancellation signal from the parent context. This can lead to goroutine leaks and unresponsive behavior. Please add a select block to check ctx.Done() at the beginning of each loop iteration, similar to the pattern used in GetInstanceDetail.

Suggested change
for {
for {
select {
case <-ctx.Done():
log.CtxLogger(ctx).Warn("describeAssetList context cancelled")
return assets
default:
}

@@ -67,15 +73,18 @@ func GetInstanceDetail(ctx context.Context, cancel context.CancelFunc, service s
bd := resp.Body
count += len(bd.Policys)
req.PageSize = tea.String(strconv.Itoa(size))
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This line is redundant. The req object is re-initialized at the beginning of each loop iteration on line 62. Modifying it here has no effect on subsequent iterations and can be safely removed for clarity.

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