Feat/ip list get#423
Merged
Merged
Conversation
Adds an IMS-authenticated self-service command that fetches the Adobe I/O Runtime egress IP allowlist from the ip-list-service. - `aio runtime ip-list get` [--region <r>] [--accept-terms --contact-email <e>] [--json] - First-use terms acceptance flow (interactive via inquirer, or non-interactive via flags), mirroring the action-level surface - Hits the runtime host directly to sidestep the CloudFront 503 masking that would otherwise hide the 403 TERMS_REQUIRED response (see ACNA-4547) - Pure-JS helpers are exported for unit tests; 28 Jest tests cover flag validation, terms gating, retry-after-accept, interactive decline, JSON mode, region filtering, and server-error surfacing - No regressions across the existing 822 plugin tests (total 850 passing)
The ip-list-service `get-ip-list` action returns `regions[region]` as a
flat array of CIDR strings, not a nested `{ cidrs: [...] }` object. The
human formatter in v1 assumed the latter and rendered "0 CIDRs" for
every region on the first real end-to-end Stage run.
- Normalize both shapes in formatHumanOutput; array form is the primary
wire format, nested form is tolerated as defense-in-depth
- Update the IP_LIST_OK test fixture to match the actual Stage response
- Add a regression test for the legacy nested shape
- Verified end-to-end against Stage:
`aio runtime ip-list get` → 4 regions, 3 CIDRs each
`aio runtime ip-list get --region emea` → just emea
`aio runtime ip-list get --region mars` → client-side validation error
Matches the server-side cross-org refactor
(OneAdobe/ip-list-service#9): the service no longer runs under the
require-adobe-auth gateway wrapper, so there's no point attaching
Authorization / x-gw-ims-org-id headers to every request. Instead
we POST `{token, imsOrgId, surface, [region]}` to both endpoints
and the in-action auth helper validates the token + org membership.
This lets the CLI serve authenticated users from any Adobe org, not
just whichever org happens to own the service's App Builder workspace.
Unit tests updated to assert the new wire shape + guard against
regressions where the old header-based auth sneaks back in.
Verified end-to-end against Stage:
$ aio runtime ip-list get
Adobe I/O Runtime egress IPs
... (real CIDRs) ...
inquirer v9 went ESM-first; its CJS build exposes the public API under
`.default` instead of at the module root, so `require('inquirer').prompt`
was undefined and the interactive acceptance path crashed with
"inquirer.prompt is not a function" before ever reaching stdin.
Normalize with `require('inquirer').default || require('inquirer')` so
the command keeps working against inquirer v8 (flat export) and v12
(default-wrapped). Tighten the test's module mock to expose the same
jest.fn() under both the flat and `.default` shapes so assertions stay
agnostic to the inquirer major version.
…rompt vs flag
When the user runs:
aio runtime ip-list get
...and gets the TERMS_REQUIRED 403, the command prompts them via
inquirer and posts `acceptanceMode: "interactive"` to the service.
When the user runs:
aio runtime ip-list get --accept-terms --contact-email ...
...no prompt fires, so the command posts `acceptanceMode:
"programmatic"` instead.
The service records this verbatim on the terms_acceptance document so
the admin dashboard can tell a human-attested acceptance from a
scripted one. Tests assert both paths send the right mode alongside
the existing contactEmail / surface / token / imsOrgId payload.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
purplecabbage
approved these changes
May 28, 2026
purplecabbage
left a comment
Member
There was a problem hiding this comment.
I added a few minor nits, questions really.
| ] | ||
|
|
||
| IndexCommand.examples = [ | ||
| '$ aio runtime ip-list get', |
Member
There was a problem hiding this comment.
Why do we need a get subcommand? Are there plans for set, delete, search? We have an alias already for aio rt ip-list ... why do we need the get?
Contributor
Author
There was a problem hiding this comment.
Hey @pru55e11 what's your take on collapsing the subcommand from aio rt ip-list get( the actual fetch command ) --> aio rt ip-list
If we want to have additional subcommands like aio rt ip-list status or aio rt ip-list reset etc in the future then we can keep the verb. If not, Jesse is right
purplecabbage
approved these changes
May 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR adds a new sub command
aio runtime ip-list get, that fetches the Adobe I/O Runtime egress IP allowlist from an IMS-authenticated backend service. Supports per-region filtering (--region), structured --json output, and an interactive or programmatic (--accept-terms --contact-email) terms-acceptance flow on first use.Related Issue
Motivation and Context
Customers running App Builder / I/O Runtime workloads behind corporate egress firewalls need a self-service way to retrieve the current set of outbound IP addresses for their network allowlists. Today this information is only available via support tickets. Hence exposing it through the standard aio CLI removes that round-trip and provides a scriptable source of truth.
How Has This Been Tested?
added new unit tests and verified via npm test
manually tested the workflow against the backend using different IMS orgs by
aio plugins linkthe local cloned repoScreenshots (if appropriate):
Types of changes
Checklist: