Skip to content
This repository was archived by the owner on Sep 9, 2026. It is now read-only.

Expose available IP count in public pools CLI & add describe for publicipattachment - #650

Merged
openshift-merge-bot[bot] merged 2 commits into
osac-project:mainfrom
SiddarthR56:namelookup
Jun 5, 2026
Merged

openshift-merge-bot[bot] merged 2 commits into
osac-project:mainfrom
SiddarthR56:namelookup

Conversation

@SiddarthR56

@SiddarthR56 SiddarthR56 commented Jun 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add a status field with available count to the public PublicIPPool proto, allowing tenants to see how many IPs are free for allocation
Display an "AVAILABLE" column in osac get publicippool table output and detail view
Add osac describe publicipattachment command for inspecting attachment details by ID or name

Changes

Proto (proto/public/osac/public/v1/public_ip_pool_type.proto):

  • Added PublicIPPoolStatus message with available field (field number 6, matching private proto)
  • Added status field to the public PublicIPPool message

CLI — get publicippool (internal/cmd/cli/get/publicippool/get_publicippool_cmd.go):

  • Added "AVAILABLE" column to the list table view
  • Added "Available:" row to the single-pool detail view

CLI — describe publicipattachment (new):

  • Added internal/cmd/cli/describe/publicipattachment/describe_publicipattachment_cmd.go
  • Registered in internal/cmd/cli/describe/describe_cmd.go
  • Resolves by ID or name, renders: ID, Name, Public IP, Compute Instance, Public IP Address, State, Message

Naming rationale
Public CLI uses "AVAILABLE" (standalone column, consistent with AWS AvailableIpAddressCount)
Private rendering table keeps "FREE" (alongside TOTAL/ALLOCATED, consistent with kubectl-view-allocations)

Testing

$ ./osac get publicippools
ID                                    NAME     CIDRS            IP-FAMILY  AVAILABLE
019dfd63-044e-7400-b353-541a809fa401  pool1  192.168.99.0/24  IPV4       253

$ ./osac describe publicipattachment attachment1
ID:                 019e5fee-0742-78b7-8c4a-e2501f44783a
Name:               attachment1
Public IP:          019728a4-3f5c-7def-8abc-1234567890ab
Compute Instance:   01972f1b-a4e9-7c82-9def-abcdef123456
Public IP Address:  192.168.1.42
State:              READY
Message:            -

Summary by CodeRabbit

  • New Features
    • Pool availability metrics are now visible in CLI and API outputs for better resource management. List views include an additional availability count column alongside other pool information for quick reference. Detailed pool views display comprehensive capacity and status information. This enhancement provides operators with improved visibility into resource allocation, pool readiness, and available capacity.

Assisted-by: Cursor/Claude
@openshift-ci
openshift-ci Bot requested review from akshaynadkarni and trewest June 5, 2026 18:45
@coderabbitai

coderabbitai Bot commented Jun 5, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@SiddarthR56, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 32 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: afc7ff30-049f-458f-af9b-59ae4e4e8d80

📥 Commits

Reviewing files that changed from the base of the PR and between d8924a5 and d02bbd7.

📒 Files selected for processing (4)
  • internal/cmd/cli/describe/describe_cmd.go
  • internal/cmd/cli/describe/publicipattachment/describe_publicipattachment_cmd.go
  • internal/cmd/cli/describe/publicipattachment/describe_publicipattachment_suite_test.go
  • internal/cmd/cli/describe/publicipattachment/describe_publicipattachment_test.go

Walkthrough

This PR exposes public IP pool availability capacity through a new PublicIPPoolStatus message in the proto contract, and extends the CLI output to display available pool counts in both list and detail views.

Changes

Pool Availability Exposure

Layer / File(s) Summary
Pool availability contract and status schema
proto/public/osac/public/v1/public_ip_pool_type.proto
PublicIPPoolStatus message introduced with output-only available int64 field; added as read-only status field to PublicIPPool. Documentation updated to promise pools are "ready and have available capacity."
CLI pool availability display
internal/cmd/cli/get/publicippool/get_publicippool_cmd.go
Pool list table rendered with new AVAILABLE column header and available count per row; pool detail view now displays an Available field from status.

Sequence Diagram

Not applicable—straightforward schema extension and CLI consumption without multi-component interaction flows.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • eranco74
  • larsks
  • tzvatot

Poem

🏊 Pools now whisper of their capacity,
A status field holds truth with clarity,
The CLI sings availability's song—
Ready, waiting, for right allocations to belong. 📊


⚠️ Security & Risk Note: The status field marked as output-only protects against accidental tenant writes and properly constrains capacity information to read-only. The proto contract correctly guards against state corruption. No elevated risk introduced.

🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title mentions adding available IP count to CLI and describing publicipattachment, but the changeset only shows changes to publicippool CLI and proto definitions—no publicipattachment changes are evident. Revise the title to accurately reflect the actual changes: focus on exposing available IP count in public pools, removing the unrelated publicipattachment reference.
✅ Passed checks (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Hardcoded-Secrets ✅ Passed No hardcoded secrets found. Changes only add pool availability fields to CLI output and protobuf definitions with standard string literals and legitimate data structures.
No-Weak-Crypto ✅ Passed No weak cryptographic algorithms, custom crypto implementations, or insecure secret comparisons detected. Changes only add availability field display to IP pool CLI/API output.
No-Injection-Vectors ✅ Passed No injection vectors detected. Code safely formats int64 availability data from trusted gRPC API responses using proper format specifiers without concatenation.
Container-Privileges ✅ Passed PR contains no container privilege escalation indicators: no privileged mode, hostPID/Network/IPC, SYS_ADMIN, or allowPrivilegeEscalation settings found; containers run as non-root user 1001.
No-Sensitive-Data-In-Logs ✅ Passed PR adds non-sensitive capacity metric (IP count) to CLI output. No passwords, tokens, API keys, PII, or customer data exposed in logs or error messages.
Ai-Attribution ✅ Passed AI tool usage (Cursor/Claude) properly attributed with Assisted-by trailer in commit; Co-Authored-By not misused.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/cmd/cli/get/publicippool/get_publicippool_cmd.go (1)

107-123: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Major: propagate CLI write/flush failures instead of silently succeeding
renderPoolTable / renderPoolDetail ignore the error returns from fmt.Fprintln, fmt.Fprintf, and writer.Flush(), so osac get publicippool can output partial/empty tables on broken pipes/terminal write failures while still returning success.

Suggested fix
-		renderPoolTable(c.console, resp.GetItems())
-		return nil
+		if err := renderPoolTable(c.console, resp.GetItems()); err != nil {
+			return err
+		}
+		return nil
@@
-	renderPoolDetail(c.console, pool)
-	return nil
+	return renderPoolDetail(c.console, pool)
 }
 
 // renderPoolTable writes a compact table of pools — used when listing all pools.
-func renderPoolTable(w *terminal.Console, pools []*publicv1.PublicIPPool) {
+func renderPoolTable(w *terminal.Console, pools []*publicv1.PublicIPPool) error {
 	writer := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0)
-	fmt.Fprintln(writer, "ID\tNAME\tCIDRS\tIP-FAMILY\tAVAILABLE")
+	if _, err := fmt.Fprintln(writer, "ID\tNAME\tCIDRS\tIP-FAMILY\tAVAILABLE"); err != nil {
+		return err
+	}
 	for _, p := range pools {
@@
 		ipFamily := strings.TrimPrefix(p.GetSpec().GetIpFamily().String(), "IP_FAMILY_")
 		available := fmt.Sprintf("%d", p.GetStatus().GetAvailable())
-		fmt.Fprintf(writer, "%s\t%s\t%s\t%s\t%s\n", p.GetId(), name, cidrs, ipFamily, available)
+		if _, err := fmt.Fprintf(writer, "%s\t%s\t%s\t%s\t%s\n", p.GetId(), name, cidrs, ipFamily, available); err != nil {
+			return err
+		}
 	}
-	writer.Flush()
+	return writer.Flush()
 }
 
 // renderPoolDetail writes a detailed key-value view of a single pool — used when getting by name/id.
-func renderPoolDetail(w *terminal.Console, p *publicv1.PublicIPPool) {
+func renderPoolDetail(w *terminal.Console, p *publicv1.PublicIPPool) error {
 	writer := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0)
@@
-	fmt.Fprintf(writer, "ID:\t%s\n", p.GetId())
-	fmt.Fprintf(writer, "Name:\t%s\n", name)
-	fmt.Fprintf(writer, "CIDRs:\t%s\n", cidrs)
-	fmt.Fprintf(writer, "IP Family:\t%s\n", ipFamily)
-	fmt.Fprintf(writer, "Available:\t%d\n", p.GetStatus().GetAvailable())
-	writer.Flush()
+	if _, err := fmt.Fprintf(writer, "ID:\t%s\n", p.GetId()); err != nil {
+		return err
+	}
+	if _, err := fmt.Fprintf(writer, "Name:\t%s\n", name); err != nil {
+		return err
+	}
+	if _, err := fmt.Fprintf(writer, "CIDRs:\t%s\n", cidrs); err != nil {
+		return err
+	}
+	if _, err := fmt.Fprintf(writer, "IP Family:\t%s\n", ipFamily); err != nil {
+		return err
+	}
+	if _, err := fmt.Fprintf(writer, "Available:\t%d\n", p.GetStatus().GetAvailable()); err != nil {
+		return err
+	}
+	return writer.Flush()
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/cmd/cli/get/publicippool/get_publicippool_cmd.go` around lines 107 -
123, renderPoolTable (and similarly renderPoolDetail) currently ignore errors
from fmt.Fprintln/fmt.Fprintf and writer.Flush, causing commands to return
success on write failures; change renderPoolTable to return error, check and
propagate the error returned by each fmt.Fprintln/fmt.Fprintf call and by
writer.Flush(), and update callers to handle/return that error; reference
function renderPoolTable, the tabwriter.Writer variable "writer", and the calls
to fmt.Fprintln, fmt.Fprintf, and writer.Flush to locate where to add error
checks and returns.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@internal/cmd/cli/get/publicippool/get_publicippool_cmd.go`:
- Around line 107-123: renderPoolTable (and similarly renderPoolDetail)
currently ignore errors from fmt.Fprintln/fmt.Fprintf and writer.Flush, causing
commands to return success on write failures; change renderPoolTable to return
error, check and propagate the error returned by each fmt.Fprintln/fmt.Fprintf
call and by writer.Flush(), and update callers to handle/return that error;
reference function renderPoolTable, the tabwriter.Writer variable "writer", and
the calls to fmt.Fprintln, fmt.Fprintf, and writer.Flush to locate where to add
error checks and returns.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: f0b88748-ea82-424e-9f53-7a08363c7c34

📥 Commits

Reviewing files that changed from the base of the PR and between b50cc75 and d8924a5.

⛔ Files ignored due to path filters (2)
  • internal/api/osac/public/v1/public_ip_pool_type.pb.go is excluded by !**/*.pb.go
  • internal/api/osac/public/v1/public_ip_pool_type_protoopaque.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (2)
  • internal/cmd/cli/get/publicippool/get_publicippool_cmd.go
  • proto/public/osac/public/v1/public_ip_pool_type.proto

@SiddarthR56 SiddarthR56 changed the title Add Available field to publicippools cli Expose available IP count in public pools CLI & add describe for publicipattachment Jun 5, 2026
@openshift-ci

openshift-ci Bot commented Jun 5, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jhernand, SiddarthR56

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved label Jun 5, 2026
result.AddCommand(cluster.Cmd())
result.AddCommand(computeinstance.Cmd())
result.AddCommand(publicip.Cmd())
result.AddCommand(publicipattachment.Cmd())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do you think we should add publicipattachment to the alias table and subcommands assertion in describe_cmd_test.go? Something like:

  • Entry("publicipattachment", publicipattachment.Cmd, "publicipattachments") in the alias table
  • "publicipattachment" to the ContainElements list

}
ipFamily := strings.TrimPrefix(p.GetSpec().GetIpFamily().String(), "IP_FAMILY_")
fmt.Fprintf(writer, "%s\t%s\t%s\t%s\n", p.GetId(), name, cidrs, ipFamily)
available := fmt.Sprintf("%d", p.GetStatus().GetAvailable())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Will this return 0 instead of - when a pool has no status? That could be misleading since 0 suggests no IPs are available rather than status not being populated yet. Same thing for line 146.

Maybe we should do something like this for consistency with the other columns?

available := "-"
if p.GetStatus() \!= nil {
    available = fmt.Sprintf("%d", p.GetStatus().GetAvailable())
}

WDYT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The status will never be nil for pools exposed via the public API (the server only returns pools that are READY with available > 0). That said, I can add a defensive guard if you'd prefer.

// Capacity information for a PublicIPPool exposed to tenants.
message PublicIPPoolStatus {
// Number of IP addresses available for new allocations from this pool.
int64 available = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Curious: you're using field number 6 here, is this intentional to match the private proto's field numbering?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, intentional — matches the private proto's field number for readability.

@openshift-merge-bot
openshift-merge-bot Bot merged commit 74e26c5 into osac-project:main Jun 5, 2026
13 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants