Skip to content

ESD-1647: Close input-mode divergences across buy and update commands#536

Open
Phil-Browne wants to merge 9 commits into
mainfrom
esd-1647-input-mode-parity
Open

ESD-1647: Close input-mode divergences across buy and update commands#536
Phil-Browne wants to merge 9 commits into
mainfrom
esd-1647-input-mode-parity

Conversation

@Phil-Browne

Copy link
Copy Markdown
Contributor

Brings interactive, flag, and JSON input modes to parity across eight buy/update commands so each validates, resolves, and gates inputs the same way regardless of mode.

  • nat gateway buy: reject empty tag keys on the flags path (JSON already did)
  • managed account buy: validate required fields (accountName, accountRef) in the JSON path
  • vxc buy: resolve partner-port UIDs to product UIDs in the JSON path, matching the flags path
  • mve update: gate the name update on an explicit flag/JSON change instead of a non-empty check
  • ix update: require at least one field before issuing the update
  • vxc update (interactive): reject an update where nothing changed, or where the new name is left empty
  • nat gateway update: keep the current promo code and service level reference when left blank, instead of relying on server-side omitempty
  • partners search (interactive): normalize the output-format input (case, whitespace, unsupported values falling back to table)

Full validation (go build ./... && go test ./... && golangci-lint run) passes cleanly.

Bring interactive, flag, and JSON input modes to parity across eight
commands so each validates, resolves, and gates inputs the same way
regardless of mode.

- nat gateway: reject empty tag keys on flag paths (already done on JSON)
- managed account: validate required fields in the JSON path
- vxc buy: resolve partner-port UIDs in the JSON path like the flags path
- mve update: gate the name update on an explicit flag/JSON change, not a
  non-empty check
- ix update: require at least one field before issuing the update
- vxc update prompts: reject an update where nothing changed or the new
  name is empty
- nat gateway update: keep the current promo code and service level
  reference when left blank, instead of relying on server-side omitempty
- partners search: normalize the interactive output-format input (case,
  whitespace, unsupported values falling back to table)
Copilot AI review requested due to automatic review settings July 10, 2026 20:00
@Phil-Browne Phil-Browne requested review from a team and penzeliz-megaport as code owners July 10, 2026 20:00
@Phil-Browne Phil-Browne requested a review from mega-alex July 10, 2026 20:00
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.11765% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.18%. Comparing base (9ba6a3b) to head (19e467f).
⚠️ Report is 14 commits behind head on main.

Files with missing lines Patch % Lines
internal/commands/vxc/vxc_inputs.go 92.59% 2 Missing and 2 partials ⚠️
...nternal/commands/nat_gateway/nat_gateway_inputs.go 77.77% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #536      +/-   ##
==========================================
+ Coverage   78.57%   79.18%   +0.61%     
==========================================
  Files         192      193       +1     
  Lines       18522    18647     +125     
==========================================
+ Hits        14553    14765     +212     
+ Misses       2904     2805      -99     
- Partials     1065     1077      +12     
Files with missing lines Coverage Δ
internal/commands/ix/ix_inputs.go 98.23% <100.00%> (+0.06%) ⬆️
...commands/managed_account/managed_account_inputs.go 100.00% <100.00%> (ø)
internal/commands/mve/mve_inputs.go 86.14% <100.00%> (+0.10%) ⬆️
...ternal/commands/nat_gateway/nat_gateway_actions.go 81.98% <100.00%> (+0.19%) ⬆️
internal/commands/partners/partners_actions.go 70.37% <100.00%> (+0.75%) ⬆️
internal/commands/vxc/vxc_actions.go 82.68% <100.00%> (+0.12%) ⬆️
internal/commands/vxc/vxc_prompts.go 48.76% <100.00%> (+15.54%) ⬆️
...nternal/commands/nat_gateway/nat_gateway_inputs.go 96.95% <77.77%> (+0.06%) ⬆️
internal/commands/vxc/vxc_inputs.go 78.40% <92.59%> (+0.98%) ⬆️

... and 17 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

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.

Pull request overview

This PR tightens input validation and behavior consistency across interactive, flag, and JSON input modes for several “buy”/“update” commands, aiming to ensure the same requests are accepted/rejected regardless of how the user supplies input.

Changes:

  • Align VXC behavior across modes: interactive update now rejects no-op/empty-name updates, and JSON buy now resolves partner-port identifiers similarly to flags mode.
  • Harden update/build inputs: require at least one field for IX updates; reject explicit empty names for MVE updates; require core fields for managed-account buy via JSON.
  • Normalize interactive output/metadata inputs: partners search output-format prompt now supports more formats and normalizes user input; NAT gateway flags now reject empty tag keys and update defaults preserve promo/SLR when left blank.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
internal/commands/vxc/vxc_prompts.go Reject empty name and no-op updates in interactive VXC update flow.
internal/commands/vxc/vxc_prompts_test.go Update prompt-builder tests to cover new error cases and no-op rejection.
internal/commands/vxc/vxc_inputs.go Add JSON-path partner-port UID resolution and thread ctx/service into JSON builder.
internal/commands/vxc/vxc_inputs_test.go Update JSON builder call sites and add partner-port resolution test coverage.
internal/commands/vxc/vxc_actions.go Wire ctx/service through to the JSON VXC request builder.
internal/commands/partners/partners_actions.go Expand/normalize interactive output-format selection for partner search.
internal/commands/partners/partners_actions_test.go Add tests asserting output-format normalization behavior.
internal/commands/nat_gateway/nat_gateway_inputs.go Reject empty resource-tag keys in NAT gateway flag paths.
internal/commands/nat_gateway/nat_gateway_additional_test.go Add tests for promo/SLR default inheritance behavior in updates.
internal/commands/nat_gateway/nat_gateway_actions.go Preserve promo code and service level reference when left blank during update merges.
internal/commands/mve/mve_inputs.go Gate name updates on presence/Changed and reject explicit empty names in JSON/flags paths.
internal/commands/mve/mve_inputs_test.go Add tests for explicit empty-name rejection in MVE updates.
internal/commands/managed_account/managed_account_inputs.go Enforce required fields for managed-account buy via JSON.
internal/commands/managed_account/managed_account_inputs_test.go Update JSON tests to expect required-field failures.
internal/commands/ix/ix_test.go Update IX update JSON tests to require at least one recognized field.
internal/commands/ix/ix_inputs.go Reject IX update JSON bodies that don’t change any supported field.

Comment thread internal/commands/vxc/vxc_inputs.go
…dd coverage

Copilot review on PR #536 flagged that JSON-mode buy could send an empty
B-End productUID when the partner config type doesn't support UID lookup
(e.g. AWS), since ValidateVXCRequest only requires it when partnerConfig
is nil. Match flags mode, which always requires a resolved UID.

Also fills in patch coverage gaps flagged by Codecov: empty tag key
rejection on both NAT gateway flag paths, the remaining VXC update
prompt fields, and the new VXC JSON partner-port resolution branches.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Comment thread internal/commands/managed_account/managed_account_inputs.go
Copilot review on PR #536 noted the JSON-mode required-fields error used
flag names (account-name/account-ref) instead of the JSON keys
(accountName/accountRef), which is confusing when the input is a JSON
body or file rather than flags.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Comment thread internal/commands/vxc/vxc_inputs.go
Copilot review on PR #536 noted that resolvePartnerPortUID could run
before vxcName/rateLimit/term were even parsed, wasting an API call on
malformed JSON that would fail validation anyway. Move the rateLimit/
term whole-number checks (and vxcName parsing) ahead of the lookup so
malformed JSON fails fast without the network round-trip.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Comment thread internal/commands/vxc/vxc_inputs.go
Copilot review on PR #536 pointed out that vxcName/rateLimit/term
presence wasn't enforced before resolvePartnerPortUID, so a JSON body
missing these fields but relying on a partner config for portUid or
productUID would still trigger a network lookup and only fail later in
ValidateVXCRequest. Added a requireBuyFields check called immediately
before both the A-End and B-End lookups.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 6 comments.

Comment thread internal/commands/nat_gateway/nat_gateway_inputs.go
Comment thread internal/commands/nat_gateway/nat_gateway_inputs.go
Comment thread internal/commands/mve/mve_inputs.go
Comment thread internal/commands/mve/mve_inputs.go
Comment thread internal/commands/vxc/vxc_prompts.go
Comment thread internal/commands/vxc/vxc_prompts_test.go
…e errors

nat_gateway's flags create/update paths and its JSON update path returned
plain errors for an empty resource tag key, exiting general (1) instead of
usage, unlike the JSON create path and every other resource's tag validation.

mve's update paths and vxc's update prompt returned a plain error for an
explicitly empty name instead of a validation.ValidationError, so they also
exited general instead of usage, unlike the vxc buy prompt's equivalent check.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Comment thread internal/commands/ix/ix_inputs.go
buildUpdateIXRequestFromJSON returned utils.ReadJSONInput and json.Unmarshal
errors unwrapped, so a missing --json-file got classified as an API error
(the "failed to read" pattern) instead of usage, unlike buildIXRequestFromJSON.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Comment thread internal/commands/nat_gateway/nat_gateway_inputs.go
Comment thread internal/commands/nat_gateway/nat_gateway_inputs.go
"failed to parse resource tags JSON" doesn't match classifyError's
exact "failed to parse JSON" usage pattern, so it fell through to the
broader API-error pattern and returned the wrong exit code. Wrap the
read and unmarshal errors explicitly, same as the empty-tag-key check
right below them.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated no new comments.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated no new comments.

@penzeliz-megaport

Copy link
Copy Markdown
Collaborator

Two issues.

  1. The managed-account flags path skips the required-field check that JSON enforces. buildManagedAccountRequestFromFlags (managed_account_inputs.go:27-38) builds the request with no validation, while buildManagedAccountRequestFromJSON (L46) rejects empty accountName/accountRef, and CreateManagedAccount doesn't validate after either builder. So managed-account buy --account-name Foo (blank --account-ref) ships to the API, while the equivalent JSON is rejected locally. That's the exact flags-vs-JSON divergence this PR closes elsewhere. Add the check to the flags builder, or validate req once after it's built.

  2. mergeUpdateDefaults (nat_gateway_actions.go:366-370) re-inherits PromoCode and ServiceLevelReference from the original when blank, so every unrelated NAT-gateway update (e.g. a speed change) re-sends the original PromoCode instead of omitting it. Harmless for ServiceLevelReference; for PromoCode it's a regression risk if re-submitting an already-applied code re-triggers discount logic or is rejected server-side. Confirm the GET returns PromoCode and that re-sending it is idempotent, otherwise keep PromoCode on the omitempty path.

buildManagedAccountRequestFromFlags built the request with no
validation while buildManagedAccountRequestFromJSON rejected empty
accountName/accountRef, letting managed-account buy --account-name Foo
(blank --account-ref) ship to the API. Add the same check to the flags
builder.
@Phil-Browne

Copy link
Copy Markdown
Contributor Author
  1. Fixed in 19e467f: buildManagedAccountRequestFromFlags now rejects empty accountName/accountRef with the same error and usage-error wrapping as the JSON builder.

  2. Verified against staging: created a NAT gateway design with a promo code, confirmed via the SDK that GET returns PromoCode populated, then ran an unrelated update (name change only, promo code untouched). The PUT returned 200 with no error and the promo code was unchanged afterward. Resending the inherited value is idempotent, so keeping current mergeUpdateDefaults behavior.

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.

3 participants