Skip to content

fix: update VPN and VPC API structures and improve error handling#11

Merged
ditahkk merged 4 commits into
mainfrom
issues/fix-network-bugs
Jun 11, 2026
Merged

fix: update VPN and VPC API structures and improve error handling#11
ditahkk merged 4 commits into
mainfrom
issues/fix-network-bugs

Conversation

@ditahkk

@ditahkk ditahkk commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • IP allocation accepts an optional project flag.
    • VPN customer-gateway create/update expose new IKE/ESP DH and ESP PFS flags.
    • VPN gateway/listing and create output now show ID, Public IP, and VPC ID.
  • Bug Fixes

    • Update commands only send description when explicitly changed (can clear vs omit).
    • Improved handling of API responses that return null/metadata to avoid blank or partial output.
    • Fixed username field mapping for user listing.
  • Documentation

    • Changelog and docs updated for v0.0.15.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

More reviews will be available in 27 minutes and 10 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 77186eaf-016e-414b-86a1-a8e7530498c7

📥 Commits

Reviewing files that changed from the base of the PR and between 9de2520 and 76b8971.

📒 Files selected for processing (4)
  • pkg/api/vpc/vpc.go
  • pkg/api/vpc/vpc_test.go
  • pkg/api/vpn/customergateway.go
  • pkg/api/vpn/vpn_test.go
📝 Walkthrough

Walkthrough

This PR standardizes API shapes (VPN customer gateways, VPN users, VPC VPN gateways, network, ipaddress), makes service Create/Update tolerant to metadata/null responses by falling back to GET or post-listing, and aligns CLI flags, request wiring, output, and tests with those schema changes.

Changes

API Schema Updates and CLI Command Alignment

Layer / File(s) Summary
CustomerGateway API schema and provisioning
pkg/api/vpn/customergateway.go
Rename boolean fields (ForceEncapsulation, SplitConnections, DeadPeerDetection), switch JSON tags to snake_case, add IKEDH/ESPDH/ESPPFS, add Service.Get and make Create/Update handle metadata/null responses and fallback to Get.
CustomerGateway CLI flags and wiring
internal/commands/vpn.go
Register --ike-dh, --esp-dh, --esp-pfs and wire them; construct vpn.CustomerGatewayRequest with renamed boolean fields and new DH/PFS fields for create and update.
VPN User JSON tag and response handling
pkg/api/vpn/user.go
Change User.UserName tag to username. UserService.Create only unmarshals env.Data when non-empty and not the literal \"null\".
VPC VPN gateway model, service, and CLI outputs
pkg/api/vpc/vpc.go, internal/commands/vpc.go
Make UpdateRequest.Description nullable *string; reshape VPNGateway to {ID, PublicIP, VPCID, VPCName}; Update/Create handle data:null by falling back to Get or post-list lookup; CLI list/create tables now print ID, PUBLIC IP, VPC ID.
Network Update and IP allocate project support
pkg/api/network/network.go, pkg/api/ipaddress/ipaddress.go, internal/commands/ip.go
Network.UpdateRequest.Description*string; Service.Update PUTs and conditionally returns data or falls back to Get; ipaddress.CreateRequest adds optional Project and ip allocate wires --project.
Tests updated for metadata/null flows and pointer description
pkg/api/vpn/vpn_test.go, pkg/api/vpc/vpc_test.go
TestCustomerGatewayUpdate now uses metadata-only PUT and GET fallback; TestVPCUpdate passes Description as *string.
Docs, changelog, and release notes
CHANGELOG.md, RELEASE_NOTES.md, docs/api-inventory.md, docs/command-taxonomy.md
Add v0.0.15 release notes and document schema/tag fixes, new flags, null-safe behavior, project flag, and renumber API inventory endpoints.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • ClintonChe
  • godsonten
  • ditahm6

Poem

I hopped through JSON fields with care,
Renamed the flags and sniffed the air,
If API answers come back null,
I fetch again — no output dull,
A rabbit cheers your CLI repair 🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: update VPN and VPC API structures and improve error handling' accurately describes the main changes: updates to VPN/VPC API structures (field renames, type changes, JSON tags) and improved error handling (null response fallbacks, validation logic).
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issues/fix-network-bugs

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.

Actionable comments posted: 3

🧹 Nitpick comments (1)
internal/commands/vpn.go (1)

84-103: ⚡ Quick win

New CustomerGatewayRequest fields are not exposed via CLI.

The API model now includes IKEDH, ESPDH, and ESPPFS fields (lines 41-45 in pkg/api/vpn/customergateway.go), but addCustomerGatewayFlags does not register corresponding --ike-dh, --esp-dh, or --esp-pfs flags. Users cannot set these parameters via the CLI.

If this is intentional for a phased rollout, consider adding a TODO comment. Otherwise, wire the flags:

♻️ Proposed fix to add missing DH/PFS flags
 func addCustomerGatewayFlags(cmd *cobra.Command, name, gateway, cidr, psk, ikePolicy, espPolicy *string,
 	ikeLifetime, espLifetime, ikeEncryption, ikeHash, ikeVersion, espEncryption, espHash *string,
+	ikeDH, espDH, espPFS *string,
 	forceEncap, splitConnection, dpd *bool) {
 	cmd.Flags().StringVar(name, "name", "", "Customer gateway name")
 	// ... existing flags ...
 	cmd.Flags().StringVar(espHash, "esp-hash", "", "ESP hash algorithm")
+	cmd.Flags().StringVar(ikeDH, "ike-dh", "", "IKE Diffie-Hellman group (optional)")
+	cmd.Flags().StringVar(espDH, "esp-dh", "", "ESP Diffie-Hellman group (optional)")
+	cmd.Flags().StringVar(espPFS, "esp-pfs", "", "ESP Perfect Forward Secrecy group (optional)")
 	cmd.Flags().BoolVar(forceEncap, "force-encap", false, "Force UDP encapsulation")
 	// ...
 }

Then update the request construction in both create and update commands to include these fields.

🤖 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/commands/vpn.go` around lines 84 - 103, addCustomerGatewayFlags is
missing CLI flags for the new CustomerGatewayRequest fields IKEDH, ESPDH and
ESPPFS, so users cannot set --ike-dh, --esp-dh or --esp-pfs; add StringVar flags
for each (e.g. bind variables for ikeDH, espDH, espPFS with flag names "ike-dh",
"esp-dh", "esp-pfs" and appropriate help text) in addCustomerGatewayFlags, then
update the create and update request construction code that builds
CustomerGatewayRequest to populate IKEDH, ESPDH and ESPPFS from those flag
variables (ensure you use the exact field names IKEDH, ESPDH, ESPPFS and the
same flag variable names you added).
🤖 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.

Inline comments:
In `@pkg/api/ipaddress/ipaddress.go`:
- Line 48: The CreateRequest struct gained an optional Project field but the "ip
allocate" command that builds an ipaddress.CreateRequest is not populating it;
add a new CLI flag (e.g. --project) to the "ip allocate" command, wire the flag
into the command's options parsing, and set CreateRequest.Project when
constructing ipaddress.CreateRequest; also update any related tests to pass the
project value (or add coverage for the flag) so the new field is exercised.

In `@pkg/api/network/network.go`:
- Line 127: The UpdateRequest struct's Description field is now always
serialized (json:"description") which causes CLI code that builds
network.UpdateRequest{ Name: name, Description: description } in
internal/commands/network.go to send an empty description when --description
isn't provided; either revert the struct tag to json:"description,omitempty" on
UpdateRequest.Description or change the CLI/service to only set the Description
field when the user explicitly supplies --description (e.g., populate
Description conditionally before constructing network.UpdateRequest) so existing
descriptions aren't unintentionally cleared.

In `@pkg/api/vpc/vpc.go`:
- Around line 237-244: The current fallback in the create flow calls
s.ListVPNGateways(ctx, vpcSlug) and returns gateways[0], which can return the
wrong gateway if multiple exist; instead capture the pre-create list (IDs) by
calling s.ListVPNGateways before creating, then after the create call call
s.ListVPNGateways again and diff the two lists to locate the newly added gateway
(compare by unique identifier such as gateway.ID or another stable field used in
your model), and return that matched gateway; update the logic around the create
function and the post-create listing code (the block using s.ListVPNGateways and
returning gateways[0]) to use this comparison and handle the case where no new
gateway is found by returning a clear error.

---

Nitpick comments:
In `@internal/commands/vpn.go`:
- Around line 84-103: addCustomerGatewayFlags is missing CLI flags for the new
CustomerGatewayRequest fields IKEDH, ESPDH and ESPPFS, so users cannot set
--ike-dh, --esp-dh or --esp-pfs; add StringVar flags for each (e.g. bind
variables for ikeDH, espDH, espPFS with flag names "ike-dh", "esp-dh", "esp-pfs"
and appropriate help text) in addCustomerGatewayFlags, then update the create
and update request construction code that builds CustomerGatewayRequest to
populate IKEDH, ESPDH and ESPPFS from those flag variables (ensure you use the
exact field names IKEDH, ESPDH, ESPPFS and the same flag variable names you
added).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6fc5579a-7079-420a-9011-5bff40716730

📥 Commits

Reviewing files that changed from the base of the PR and between a4f7685 and d7cfa58.

📒 Files selected for processing (7)
  • internal/commands/vpc.go
  • internal/commands/vpn.go
  • pkg/api/ipaddress/ipaddress.go
  • pkg/api/network/network.go
  • pkg/api/vpc/vpc.go
  • pkg/api/vpn/customergateway.go
  • pkg/api/vpn/user.go

Comment thread pkg/api/ipaddress/ipaddress.go
Comment thread pkg/api/network/network.go Outdated
Comment thread pkg/api/vpc/vpc.go Outdated
ditahkk added 2 commits June 10, 2026 19:30
- Enhanced API documentation for VPN, DNS, Projects, ISOs, Affinity Groups, Templates, Monitoring, Object Storage, Billing, Profile, SSH Keys, Support, Plans, Discovery, Store, and Auth endpoints.
- Added new endpoints for VPN customer gateways and updated existing ones.
- Updated command taxonomy to reflect changes in CLI commands and parameters.
- Modified network and VPC update commands to allow optional description parameter.
- Improved error handling and response validation in VPN customer gateway update logic.
- Updated tests to ensure correct behavior for new and modified API endpoints and commands.

@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.

Actionable comments posted: 2

🧹 Nitpick comments (2)
pkg/api/vpn/vpn_test.go (1)

113-123: ⚡ Quick win

Assert the fallback GET path in TestCustomerGatewayUpdate.

The GET branch currently accepts any path. Add a path assertion so fallback-route regressions are caught (not just “GET happened”).

Suggested test hardening
 	var gotBody map[string]interface{}
 	var gotPutPath string
+	var gotGetPath string
 	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		w.Header().Set("Content-Type", "application/json")
 		switch r.Method {
 		case http.MethodPut:
 			gotPutPath = r.URL.Path
 			json.NewDecoder(r.Body).Decode(&gotBody)
 			// Return metadata envelope (no VPN fields) — Update always falls back to Get.
 			json.NewEncoder(w).Encode(apiEnvelope{Status: "ok", Data: vpn.CustomerGateway{Slug: "cgw-1", Name: "updated-cgw"}})
 		case http.MethodGet:
+			gotGetPath = r.URL.Path
 			json.NewEncoder(w).Encode(apiEnvelope{Status: "ok", Data: fullCG})
 		default:
 			http.Error(w, "unexpected method", http.StatusMethodNotAllowed)
 		}
 	}))
@@
 	if gotPutPath != "/vpn-customer-gateways/cgw-1" {
 		t.Errorf("path = %q, want %q", gotPutPath, "/vpn-customer-gateways/cgw-1")
 	}
+	if gotGetPath != "/vpn-customer-gateways/cgw-1" {
+		t.Errorf("GET path = %q, want %q", gotGetPath, "/vpn-customer-gateways/cgw-1")
+	}
🤖 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 `@pkg/api/vpn/vpn_test.go` around lines 113 - 123, In
TestCustomerGatewayUpdate's fake handler switch (the r.Method cases), add an
assertion in the http.MethodGet branch to verify the incoming fallback GET path
is what you expect instead of accepting any path; for example, compute the
expected fallback path from the test fixture (e.g., using fullCG.Slug or the
same route pattern the client should call) and assert r.URL.Path == expectedPath
(use t.Fatalf or t.Errorf) so route regressions are caught; locate this change
inside the TestCustomerGatewayUpdate test where gotPutPath/gotBody and the GET
branch are defined.
pkg/api/vpc/vpc_test.go (1)

190-238: ⚡ Quick win

Cover the new update contract in this test.

TestVPCUpdate now passes a non-nil Description, but it never asserts that "description" is serialized, and it still doesn't exercise the new data:nullGet fallback in Service.Update. The changed update semantics can regress without a test failure.

🤖 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 `@pkg/api/vpc/vpc_test.go` around lines 190 - 238, Update TestVPCUpdate to
cover the new update contract: make the fake server record request sequence and
body, have the first PUT handler respond with {"status":"ok","data":null} to
trigger the Service.Update fallback to perform a GET (ensure svc.Update is the
method under test and UpdateRequest contains Description), then respond to that
GET with the full VPC JSON (the updated variable). Assert that the PUT request
body contains both "name" and "description" keys with expected values, and
assert that the test observed a subsequent GET to "/vpcs/vpc-upd-1" (i.e., that
svc.Update performed the Get fallback when data is null) as well as the returned
v.Slug check.
🤖 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.

Inline comments:
In `@pkg/api/vpc/vpc.go`:
- Around line 229-233: Remove the hard failure when the pre-create snapshot call
ListVPNGateways fails inside CreateVPNGateway: treat the call as best-effort by
capturing/logging the error and setting the pre-list variable (before) to nil or
an empty sentinel, then continue to attempt the POST/create. Ensure subsequent
logic in CreateVPNGateway checks whether the pre-list is present before using it
to diff and only requires it when the create response is null and the diff
fallback runs. Reference: ListVPNGateways, CreateVPNGateway, and the before
variable.

In `@pkg/api/vpn/customergateway.go`:
- Around line 105-107: In Create, stop swallowing JSON decode errors for
env.Data: when len(env.Data) > 0 && string(env.Data) != "null" call
json.Unmarshal into partial and check its error; if err != nil return a clear
decode/BadRequest (or wrapped) error indicating metadata JSON could not be
parsed (include err), rather than assigning to _ so failures surface immediately
(update the block around env.Data, partial in Create to validate and return on
unmarshal error).

---

Nitpick comments:
In `@pkg/api/vpc/vpc_test.go`:
- Around line 190-238: Update TestVPCUpdate to cover the new update contract:
make the fake server record request sequence and body, have the first PUT
handler respond with {"status":"ok","data":null} to trigger the Service.Update
fallback to perform a GET (ensure svc.Update is the method under test and
UpdateRequest contains Description), then respond to that GET with the full VPC
JSON (the updated variable). Assert that the PUT request body contains both
"name" and "description" keys with expected values, and assert that the test
observed a subsequent GET to "/vpcs/vpc-upd-1" (i.e., that svc.Update performed
the Get fallback when data is null) as well as the returned v.Slug check.

In `@pkg/api/vpn/vpn_test.go`:
- Around line 113-123: In TestCustomerGatewayUpdate's fake handler switch (the
r.Method cases), add an assertion in the http.MethodGet branch to verify the
incoming fallback GET path is what you expect instead of accepting any path; for
example, compute the expected fallback path from the test fixture (e.g., using
fullCG.Slug or the same route pattern the client should call) and assert
r.URL.Path == expectedPath (use t.Fatalf or t.Errorf) so route regressions are
caught; locate this change inside the TestCustomerGatewayUpdate test where
gotPutPath/gotBody and the GET branch are defined.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 05ced36c-2b3c-4953-9ceb-52505b186029

📥 Commits

Reviewing files that changed from the base of the PR and between d7cfa58 and 9de2520.

📒 Files selected for processing (13)
  • CHANGELOG.md
  • RELEASE_NOTES.md
  • docs/api-inventory.md
  • docs/command-taxonomy.md
  • internal/commands/ip.go
  • internal/commands/network.go
  • internal/commands/vpc.go
  • internal/commands/vpn.go
  • pkg/api/network/network.go
  • pkg/api/vpc/vpc.go
  • pkg/api/vpc/vpc_test.go
  • pkg/api/vpn/customergateway.go
  • pkg/api/vpn/vpn_test.go
✅ Files skipped from review due to trivial changes (3)
  • docs/command-taxonomy.md
  • RELEASE_NOTES.md
  • CHANGELOG.md

Comment thread pkg/api/vpc/vpc.go Outdated
Comment thread pkg/api/vpn/customergateway.go
@ditahkk ditahkk merged commit b250cc9 into main Jun 11, 2026
21 checks passed
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.

2 participants