From 351bd1758c563f7346ef005038098a8afbbe110a Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Wed, 5 Aug 2026 17:43:22 +0000 Subject: [PATCH 1/5] feat(gateway): add connector read commands --- src/handlers/gateway/connector/get/index.tsx | 36 ++++++++ src/handlers/gateway/connector/index.tsx | 13 +++ src/handlers/gateway/connector/list/index.tsx | 35 ++++++++ src/handlers/gateway/connector/target.ts | 7 ++ src/handlers/gateway/gateway.test.tsx | 90 ++++++++++++++++--- src/handlers/gateway/index.tsx | 2 + 6 files changed, 172 insertions(+), 11 deletions(-) create mode 100644 src/handlers/gateway/connector/get/index.tsx create mode 100644 src/handlers/gateway/connector/index.tsx create mode 100644 src/handlers/gateway/connector/list/index.tsx create mode 100644 src/handlers/gateway/connector/target.ts diff --git a/src/handlers/gateway/connector/get/index.tsx b/src/handlers/gateway/connector/get/index.tsx new file mode 100644 index 000000000..258de21cd --- /dev/null +++ b/src/handlers/gateway/connector/get/index.tsx @@ -0,0 +1,36 @@ +import z from "zod"; +import { InputValidationError } from "../../../../errors"; +import { createHandler, flag } from "../../../../router"; +import { JsonRendererKey } from "../../../../tui"; +import type { Core } from "../../../types"; +import { coreOptsFromCtx } from "../../../utils"; +import { isConnectorTarget } from "../target"; + +export const createGetGatewayConnectorHandler = (core: Core) => + createHandler({ + name: "get", + description: "get a connector configured for an AgentCore Gateway", + flags: [ + flag("gateway-id", "the ID of the Gateway", z.string().optional()), + flag("id", "the ID of the connector-backed Gateway Target", z.string().optional()), + ], + handle: async (ctx, flags) => { + if (!flags["gateway-id"]) { + throw new InputValidationError("required option '--gateway-id ' not specified"); + } + if (!flags.id) { + throw new InputValidationError("required option '--id ' not specified"); + } + + const target = await core.gateway.getGatewayTarget( + flags["gateway-id"], + flags.id, + coreOptsFromCtx(ctx), + ); + if (!isConnectorTarget(target.targetConfiguration)) { + throw new InputValidationError(`Gateway Target "${flags.id}" is not connector-backed`); + } + + ctx.require(JsonRendererKey).renderJson(target); + }, + }); diff --git a/src/handlers/gateway/connector/index.tsx b/src/handlers/gateway/connector/index.tsx new file mode 100644 index 000000000..c4eddc556 --- /dev/null +++ b/src/handlers/gateway/connector/index.tsx @@ -0,0 +1,13 @@ +import type { AppIO } from "../../../io"; +import { Router } from "../../../router"; +import { createHelpDefault } from "../../help"; +import type { Core } from "../../types"; +import { createGetGatewayConnectorHandler } from "./get"; +import { createListGatewayConnectorsHandler } from "./list"; + +export function createGatewayConnectorHandler(core: Core, io: AppIO): Router { + return new Router("connector", "inspect connectors configured for an AgentCore Gateway") + .default(createHelpDefault(io)) + .handler(createGetGatewayConnectorHandler(core)) + .handler(createListGatewayConnectorsHandler(core)); +} diff --git a/src/handlers/gateway/connector/list/index.tsx b/src/handlers/gateway/connector/list/index.tsx new file mode 100644 index 000000000..6448b6122 --- /dev/null +++ b/src/handlers/gateway/connector/list/index.tsx @@ -0,0 +1,35 @@ +import { TargetType } from "@aws-sdk/client-bedrock-agentcore-control"; +import z from "zod"; +import { InputValidationError } from "../../../../errors"; +import { createHandler, flag } from "../../../../router"; +import { JsonRendererKey } from "../../../../tui"; +import type { Core } from "../../../types"; +import { coreOptsFromCtx } from "../../../utils"; + +export const createListGatewayConnectorsHandler = (core: Core) => + createHandler({ + name: "list", + description: "list connectors configured for an AgentCore Gateway", + flags: [ + flag("gateway-id", "the ID of the Gateway", z.string().optional()), + flag("next-token", "pagination token returned by a previous request", z.string().optional()), + flag("max-results", "maximum number of items to return", z.number().optional()), + ], + handle: async (ctx, flags) => { + if (!flags["gateway-id"]) { + throw new InputValidationError("required option '--gateway-id ' not specified"); + } + + const response = await core.gateway.listGatewayTargets( + flags["gateway-id"], + flags["next-token"], + flags["max-results"], + coreOptsFromCtx(ctx), + ); + + ctx.require(JsonRendererKey).renderJson({ + ...response, + items: response.items?.filter((target) => target.targetType === TargetType.CONNECTOR), + }); + }, + }); diff --git a/src/handlers/gateway/connector/target.ts b/src/handlers/gateway/connector/target.ts new file mode 100644 index 000000000..699b681c9 --- /dev/null +++ b/src/handlers/gateway/connector/target.ts @@ -0,0 +1,7 @@ +import type { TargetConfiguration } from "@aws-sdk/client-bedrock-agentcore-control"; + +export function isConnectorTarget(configuration: TargetConfiguration | undefined): boolean { + return ( + configuration?.mcp?.connector !== undefined || configuration?.inference?.connector !== undefined + ); +} diff --git a/src/handlers/gateway/gateway.test.tsx b/src/handlers/gateway/gateway.test.tsx index 9dc3ebe29..1dc8fe0ae 100644 --- a/src/handlers/gateway/gateway.test.tsx +++ b/src/handlers/gateway/gateway.test.tsx @@ -1,14 +1,15 @@ import { describe, expect, test } from "bun:test"; -import type { - GatewayRuleDetail, - GatewaySummary, - GetGatewayResponse, - GetGatewayRuleResponse, - GetGatewayTargetResponse, - ListGatewayRulesResponse, - ListGatewaysResponse, - ListGatewayTargetsResponse, - TargetSummary, +import { + TargetType, + type GatewayRuleDetail, + type GatewaySummary, + type GetGatewayResponse, + type GetGatewayRuleResponse, + type GetGatewayTargetResponse, + type ListGatewayRulesResponse, + type ListGatewaysResponse, + type ListGatewayTargetsResponse, + type TargetSummary, } from "@aws-sdk/client-bedrock-agentcore-control"; import { createSilentLogger, @@ -66,6 +67,7 @@ describe("gateway command hierarchy", () => { }); const gateway = root.children().find((child) => child.name() === "gateway"); const target = gateway?.children().find((child) => child.name() === "target"); + const connector = gateway?.children().find((child) => child.name() === "connector"); const rule = gateway?.children().find((child) => child.name() === "rule"); expect(gateway?.flags().map((flag) => flag.name)).not.toContain("interactive"); @@ -73,13 +75,15 @@ describe("gateway command hierarchy", () => { "get", "list", "target", + "connector", "rule", ]); expect(target?.children().map((child) => child.name())).toEqual(["get", "list"]); + expect(connector?.children().map((child) => child.name())).toEqual(["get", "list"]); expect(rule?.children().map((child) => child.name())).toEqual(["get", "list"]); }); - test.each(["gateway", "gateway target", "gateway rule"])( + test.each(["gateway", "gateway target", "gateway connector", "gateway rule"])( "prints help for bare `%s` without a Core call", async (command) => { const { core, stdout } = await run(command.split(" ")); @@ -210,6 +214,67 @@ describe("gateway reads", () => { ]); }); + test.each([ + ["MCP", { mcp: { connector: { source: { connectorId: "web-search" } } } }], + ["inference", { inference: { connector: { source: { connectorId: "openai" } } } }], + ] as const)("gets a configured %s Connector", async (_kind, targetConfiguration) => { + const core = new TestCoreClient(); + core.gateway.setGetTargetResponse({ ...targetResponse, targetConfiguration }); + + const result = await run( + ["gateway", "connector", "get", "--gateway-id", GATEWAY_ID, "--id", TARGET_ID], + core, + ); + + expect(result.core.gateway.calls).toEqual([ + { + method: "getGatewayTarget", + args: [GATEWAY_ID, TARGET_ID, { region: REGION }], + }, + ]); + expect(JSON.parse(result.stdout)).toEqual({ ...targetResponse, targetConfiguration }); + }); + + test("lists only configured Connectors and preserves the service token", async () => { + const response: ListGatewayTargetsResponse = { + items: [ + { targetId: TARGET_ID, targetType: TargetType.CONNECTOR } as TargetSummary, + { targetId: "target-2", targetType: TargetType.MCP_SERVER } as TargetSummary, + ], + nextToken: "target-page-2", + }; + const core = new TestCoreClient(); + core.gateway.setListTargetsResponse(response); + + const result = await run( + ["gateway", "connector", "list", "--gateway-id", GATEWAY_ID, "--max-results", "2"], + core, + ); + + expect(JSON.parse(result.stdout)).toEqual({ + items: [response.items![0]], + nextToken: response.nextToken, + }); + expect(result.core.gateway.calls).toEqual([ + { + method: "listGatewayTargets", + args: [GATEWAY_ID, undefined, 2, { region: REGION }], + }, + ]); + }); + + test("rejects a non-Connector Target from connector get", async () => { + const core = new TestCoreClient(); + core.gateway.setGetTargetResponse({ + ...targetResponse, + targetConfiguration: { mcp: { mcpServer: { endpoint: "https://example.test/mcp" } } }, + }); + + await expect( + run(["gateway", "connector", "get", "--gateway-id", GATEWAY_ID, "--id", TARGET_ID], core), + ).rejects.toThrow(`Gateway Target "${TARGET_ID}" is not connector-backed`); + }); + test("gets a Gateway Rule with qualified selectors", async () => { const core = new TestCoreClient(); core.gateway.setGetRuleResponse(ruleResponse); @@ -279,6 +344,9 @@ describe("gateway validation and errors", () => { ["Target get parent", ["gateway", "target", "get"], /--gateway-id/], ["Target get child", ["gateway", "target", "get", "--gateway-id", GATEWAY_ID], /--target-id/], ["Target list", ["gateway", "target", "list"], /--gateway-id/], + ["Connector get parent", ["gateway", "connector", "get"], /--gateway-id/], + ["Connector get child", ["gateway", "connector", "get", "--gateway-id", GATEWAY_ID], /--id/], + ["Connector list", ["gateway", "connector", "list"], /--gateway-id/], ["Rule get parent", ["gateway", "rule", "get"], /--gateway-id/], ["Rule get child", ["gateway", "rule", "get", "--gateway-id", GATEWAY_ID], /--rule-id/], ["Rule list", ["gateway", "rule", "list"], /--gateway-id/], diff --git a/src/handlers/gateway/index.tsx b/src/handlers/gateway/index.tsx index 0c431ca14..698e3719e 100644 --- a/src/handlers/gateway/index.tsx +++ b/src/handlers/gateway/index.tsx @@ -2,6 +2,7 @@ import type { AppIO } from "../../io"; import { Router } from "../../router"; import { createHelpDefault } from "../help"; import type { Core } from "../types"; +import { createGatewayConnectorHandler } from "./connector"; import { createGetGatewayHandler } from "./get"; import { createListGatewaysHandler } from "./list"; import { createGatewayRuleHandler } from "./rule"; @@ -13,5 +14,6 @@ export function createGatewayHandler(core: Core, io: AppIO): Router { .handler(createGetGatewayHandler(core)) .handler(createListGatewaysHandler(core)) .handler(createGatewayTargetHandler(core, io)) + .handler(createGatewayConnectorHandler(core, io)) .handler(createGatewayRuleHandler(core, io)); } From 8dc6ac6c7c76027a362a71fa4fae73aafc798a74 Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Wed, 5 Aug 2026 18:55:50 +0000 Subject: [PATCH 2/5] refactor(gateway): name connector predicate module explicitly --- src/handlers/gateway/connector/get/index.tsx | 2 +- .../gateway/connector/{target.ts => isConnectorTarget.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/handlers/gateway/connector/{target.ts => isConnectorTarget.ts} (100%) diff --git a/src/handlers/gateway/connector/get/index.tsx b/src/handlers/gateway/connector/get/index.tsx index 258de21cd..e2e28b7ee 100644 --- a/src/handlers/gateway/connector/get/index.tsx +++ b/src/handlers/gateway/connector/get/index.tsx @@ -4,7 +4,7 @@ import { createHandler, flag } from "../../../../router"; import { JsonRendererKey } from "../../../../tui"; import type { Core } from "../../../types"; import { coreOptsFromCtx } from "../../../utils"; -import { isConnectorTarget } from "../target"; +import { isConnectorTarget } from "../isConnectorTarget"; export const createGetGatewayConnectorHandler = (core: Core) => createHandler({ diff --git a/src/handlers/gateway/connector/target.ts b/src/handlers/gateway/connector/isConnectorTarget.ts similarity index 100% rename from src/handlers/gateway/connector/target.ts rename to src/handlers/gateway/connector/isConnectorTarget.ts From afcaac527bd33cb2bf738c718218ea639360e601 Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Wed, 5 Aug 2026 20:10:36 +0000 Subject: [PATCH 3/5] test(gateway): add connector golden coverage --- ...GatewayTargetCommand.137ec397ae5efe2d.json | 38 +++++++++++++++++++ ...atewayTargetsCommand.64c210a8bc459fb1.json | 30 +++++++++++++++ .../__fixtures__/connector-get.golden.json | 34 +++++++++++++++++ .../__fixtures__/connector-list.golden.json | 13 +++++++ src/handlers/gateway/connector/get/index.tsx | 8 +++- .../gateway/connector/isConnectorTarget.ts | 7 ---- src/handlers/gateway/gateway.fixture.test.tsx | 27 ++++++++++++- 7 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.137ec397ae5efe2d.json create mode 100644 src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.64c210a8bc459fb1.json create mode 100644 src/handlers/gateway/__fixtures__/connector-get.golden.json create mode 100644 src/handlers/gateway/__fixtures__/connector-list.golden.json delete mode 100644 src/handlers/gateway/connector/isConnectorTarget.ts diff --git a/src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.137ec397ae5efe2d.json b/src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.137ec397ae5efe2d.json new file mode 100644 index 000000000..a4b832f4c --- /dev/null +++ b/src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.137ec397ae5efe2d.json @@ -0,0 +1,38 @@ +{ + "gatewayArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:gateway/agentcore-cli-gateway-read-rule-fixture-lhpid2reoy", + "targetId": "HDDX5P33XN", + "createdAt": { + "$date": "2026-08-05T20:06:04.149Z" + }, + "updatedAt": { + "$date": "2026-08-05T20:06:05.163Z" + }, + "status": "FAILED", + "name": "agentcore-cli-gateway-read-connector-openai", + "targetConfiguration": { + "inference": { + "connector": { + "source": { + "connectorId": "openai" + } + } + } + }, + "credentialProviderConfigurations": [ + { + "credentialProviderType": "API_KEY", + "credentialProvider": { + "apiKeyCredentialProvider": { + "providerArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:token-vault/default/apikeycredentialprovider/agentcore-cli-gateway-read-connector", + "credentialParameterName": "Authorization", + "credentialPrefix": "Bearer", + "credentialLocation": "HEADER" + } + } + } + ], + "statusReasons": [ + "Failed to discover models from inference provider for target HDDX5P33XN. Error: Inference list-models call to https://api.openai.com/v1/models failed with HTTP 401: {\n \"error\": {\n \"message\": \"Incorrect API key provided: agentcor****************************-key. You can find your API key at https://platform.openai.com/account/api-keys.\",\n \"type\": \"invalid_request_error\",\n \"param\": null,\n \"code\": \"invalid_api_key\"\n }\n}" + ], + "description": "AgentCore CLI persistent Gateway Connector read fixture" +} \ No newline at end of file diff --git a/src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.64c210a8bc459fb1.json b/src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.64c210a8bc459fb1.json new file mode 100644 index 000000000..0252cc433 --- /dev/null +++ b/src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.64c210a8bc459fb1.json @@ -0,0 +1,30 @@ +{ + "items": [ + { + "targetId": "HDDX5P33XN", + "name": "agentcore-cli-gateway-read-connector-openai", + "status": "FAILED", + "createdAt": { + "$date": "2026-08-05T20:06:04.149Z" + }, + "updatedAt": { + "$date": "2026-08-05T20:06:05.163Z" + }, + "description": "AgentCore CLI persistent Gateway Connector read fixture", + "targetType": "CONNECTOR" + }, + { + "targetId": "O4HB9LXPLC", + "name": "agentcore-cli-gateway-read-http-target", + "status": "READY", + "createdAt": { + "$date": "2026-07-30T00:13:31.109Z" + }, + "updatedAt": { + "$date": "2026-07-30T00:13:31.778Z" + }, + "description": "AgentCore CLI persistent HTTP Gateway Target fixture", + "targetType": "PASSTHROUGH" + } + ] +} \ No newline at end of file diff --git a/src/handlers/gateway/__fixtures__/connector-get.golden.json b/src/handlers/gateway/__fixtures__/connector-get.golden.json new file mode 100644 index 000000000..09210063a --- /dev/null +++ b/src/handlers/gateway/__fixtures__/connector-get.golden.json @@ -0,0 +1,34 @@ +{ + "gatewayArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:gateway/agentcore-cli-gateway-read-rule-fixture-lhpid2reoy", + "targetId": "HDDX5P33XN", + "createdAt": "2026-08-05T20:06:04.149Z", + "updatedAt": "2026-08-05T20:06:05.163Z", + "status": "FAILED", + "name": "agentcore-cli-gateway-read-connector-openai", + "targetConfiguration": { + "inference": { + "connector": { + "source": { + "connectorId": "openai" + } + } + } + }, + "credentialProviderConfigurations": [ + { + "credentialProviderType": "API_KEY", + "credentialProvider": { + "apiKeyCredentialProvider": { + "providerArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:token-vault/default/apikeycredentialprovider/agentcore-cli-gateway-read-connector", + "credentialParameterName": "Authorization", + "credentialPrefix": "Bearer", + "credentialLocation": "HEADER" + } + } + } + ], + "statusReasons": [ + "Failed to discover models from inference provider for target HDDX5P33XN. Error: Inference list-models call to https://api.openai.com/v1/models failed with HTTP 401: {\n \"error\": {\n \"message\": \"Incorrect API key provided: agentcor****************************-key. You can find your API key at https://platform.openai.com/account/api-keys.\",\n \"type\": \"invalid_request_error\",\n \"param\": null,\n \"code\": \"invalid_api_key\"\n }\n}" + ], + "description": "AgentCore CLI persistent Gateway Connector read fixture" +} \ No newline at end of file diff --git a/src/handlers/gateway/__fixtures__/connector-list.golden.json b/src/handlers/gateway/__fixtures__/connector-list.golden.json new file mode 100644 index 000000000..a9947895b --- /dev/null +++ b/src/handlers/gateway/__fixtures__/connector-list.golden.json @@ -0,0 +1,13 @@ +{ + "items": [ + { + "targetId": "HDDX5P33XN", + "name": "agentcore-cli-gateway-read-connector-openai", + "status": "FAILED", + "createdAt": "2026-08-05T20:06:04.149Z", + "updatedAt": "2026-08-05T20:06:05.163Z", + "description": "AgentCore CLI persistent Gateway Connector read fixture", + "targetType": "CONNECTOR" + } + ] +} \ No newline at end of file diff --git a/src/handlers/gateway/connector/get/index.tsx b/src/handlers/gateway/connector/get/index.tsx index e2e28b7ee..5932fcddb 100644 --- a/src/handlers/gateway/connector/get/index.tsx +++ b/src/handlers/gateway/connector/get/index.tsx @@ -1,10 +1,16 @@ +import type { TargetConfiguration } from "@aws-sdk/client-bedrock-agentcore-control"; import z from "zod"; import { InputValidationError } from "../../../../errors"; import { createHandler, flag } from "../../../../router"; import { JsonRendererKey } from "../../../../tui"; import type { Core } from "../../../types"; import { coreOptsFromCtx } from "../../../utils"; -import { isConnectorTarget } from "../isConnectorTarget"; + +function isConnectorTarget(configuration: TargetConfiguration | undefined): boolean { + return ( + configuration?.mcp?.connector !== undefined || configuration?.inference?.connector !== undefined + ); +} export const createGetGatewayConnectorHandler = (core: Core) => createHandler({ diff --git a/src/handlers/gateway/connector/isConnectorTarget.ts b/src/handlers/gateway/connector/isConnectorTarget.ts deleted file mode 100644 index 699b681c9..000000000 --- a/src/handlers/gateway/connector/isConnectorTarget.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { TargetConfiguration } from "@aws-sdk/client-bedrock-agentcore-control"; - -export function isConnectorTarget(configuration: TargetConfiguration | undefined): boolean { - return ( - configuration?.mcp?.connector !== undefined || configuration?.inference?.connector !== undefined - ); -} diff --git a/src/handlers/gateway/gateway.fixture.test.tsx b/src/handlers/gateway/gateway.fixture.test.tsx index 139bcdec8..586d0df69 100644 --- a/src/handlers/gateway/gateway.fixture.test.tsx +++ b/src/handlers/gateway/gateway.fixture.test.tsx @@ -16,10 +16,11 @@ const GATEWAY_ID = "agentcore-cli-gateway-read-fixture-a-l6opkbe2kd"; const TARGET_ID = "KALJACI9HO"; const RULE_GATEWAY_ID = "agentcore-cli-gateway-read-rule-fixture-lhpid2reoy"; const RULE_ID = "d396c3f4-4591-41b3-a4d5-816e03c32419"; +const CONNECTOR_ID = "HDDX5P33XN"; // Account 685197708687 owns the persistent read-only fixture graph: -// two listable Gateways, two MCP Targets under GATEWAY_ID, and two Rules under -// RULE_GATEWAY_ID. Record with: +// listable Gateways, two MCP Targets under GATEWAY_ID, and one HTTP Target, one +// connector Target, and two Rules under RULE_GATEWAY_ID. Record with: // AWS_PROFILE=e2e-test RECORD=1 bun test src/handlers/gateway/gateway.fixture.test.tsx function createFixtureCore(): CoreClient { const { createControlClient, createDataClient, createIamClient } = fixtureFactories(FIXTURES); @@ -112,6 +113,28 @@ describe("Gateway fixture-backed reads", () => { expect(JSON.parse(page2).items).toHaveLength(1); }); + test("gets a Gateway Connector", async () => { + const stdout = await run([ + "gateway", + "connector", + "get", + "--gateway-id", + RULE_GATEWAY_ID, + "--id", + CONNECTOR_ID, + ]); + matchGolden(FIXTURES, "connector-get.golden.json", stdout); + expect(JSON.parse(stdout).targetId).toBe(CONNECTOR_ID); + }); + + test("lists Gateway Connectors", async () => { + const stdout = await run(["gateway", "connector", "list", "--gateway-id", RULE_GATEWAY_ID]); + matchGolden(FIXTURES, "connector-list.golden.json", stdout); + expect(JSON.parse(stdout).items.map(({ targetId }: { targetId: string }) => targetId)).toEqual([ + CONNECTOR_ID, + ]); + }); + test("gets a Gateway Rule", async () => { const stdout = await run([ "gateway", From 8aca33f32afb02851cacf3a11b19af3bdb473e4f Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Wed, 5 Aug 2026 20:24:02 +0000 Subject: [PATCH 4/5] test(gateway): use ready connector fixture --- ...GatewayTargetCommand.137ec397ae5efe2d.json | 38 ------------------- ...GatewayTargetCommand.5c220cde576e6df6.json | 38 +++++++++++++++++++ ...atewayTargetsCommand.34041f83759ffb99.json | 20 ++++++++++ ...atewayTargetsCommand.64c210a8bc459fb1.json | 30 --------------- .../__fixtures__/connector-get.golden.json | 18 ++++----- .../__fixtures__/connector-list.golden.json | 11 +++--- src/handlers/gateway/gateway.fixture.test.tsx | 30 +++++++-------- 7 files changed, 87 insertions(+), 98 deletions(-) delete mode 100644 src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.137ec397ae5efe2d.json create mode 100644 src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.5c220cde576e6df6.json create mode 100644 src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.34041f83759ffb99.json delete mode 100644 src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.64c210a8bc459fb1.json diff --git a/src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.137ec397ae5efe2d.json b/src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.137ec397ae5efe2d.json deleted file mode 100644 index a4b832f4c..000000000 --- a/src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.137ec397ae5efe2d.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "gatewayArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:gateway/agentcore-cli-gateway-read-rule-fixture-lhpid2reoy", - "targetId": "HDDX5P33XN", - "createdAt": { - "$date": "2026-08-05T20:06:04.149Z" - }, - "updatedAt": { - "$date": "2026-08-05T20:06:05.163Z" - }, - "status": "FAILED", - "name": "agentcore-cli-gateway-read-connector-openai", - "targetConfiguration": { - "inference": { - "connector": { - "source": { - "connectorId": "openai" - } - } - } - }, - "credentialProviderConfigurations": [ - { - "credentialProviderType": "API_KEY", - "credentialProvider": { - "apiKeyCredentialProvider": { - "providerArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:token-vault/default/apikeycredentialprovider/agentcore-cli-gateway-read-connector", - "credentialParameterName": "Authorization", - "credentialPrefix": "Bearer", - "credentialLocation": "HEADER" - } - } - } - ], - "statusReasons": [ - "Failed to discover models from inference provider for target HDDX5P33XN. Error: Inference list-models call to https://api.openai.com/v1/models failed with HTTP 401: {\n \"error\": {\n \"message\": \"Incorrect API key provided: agentcor****************************-key. You can find your API key at https://platform.openai.com/account/api-keys.\",\n \"type\": \"invalid_request_error\",\n \"param\": null,\n \"code\": \"invalid_api_key\"\n }\n}" - ], - "description": "AgentCore CLI persistent Gateway Connector read fixture" -} \ No newline at end of file diff --git a/src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.5c220cde576e6df6.json b/src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.5c220cde576e6df6.json new file mode 100644 index 000000000..2e860a0c3 --- /dev/null +++ b/src/handlers/gateway/__fixtures__/GetGatewayTargetCommand.5c220cde576e6df6.json @@ -0,0 +1,38 @@ +{ + "gatewayArn": "arn:aws:bedrock-agentcore:us-east-1:685197708687:gateway/agentcore-cli-gateway-read-connector-gkzcxxkc5e", + "targetId": "Z3FQ0H8JCK", + "createdAt": { + "$date": "2026-08-05T20:20:45.351Z" + }, + "updatedAt": { + "$date": "2026-08-05T20:20:51.210Z" + }, + "status": "READY", + "name": "agentcore-cli-gateway-read-connector-openai", + "targetConfiguration": { + "inference": { + "connector": { + "source": { + "connectorId": "openai" + } + } + } + }, + "credentialProviderConfigurations": [ + { + "credentialProviderType": "API_KEY", + "credentialProvider": { + "apiKeyCredentialProvider": { + "providerArn": "arn:aws:bedrock-agentcore:us-east-1:685197708687:token-vault/default/apikeycredentialprovider/DONOTDELETEe2eOAI", + "credentialParameterName": "Authorization", + "credentialPrefix": "Bearer", + "credentialLocation": "HEADER" + } + } + } + ], + "description": "AgentCore CLI persistent READY Gateway Connector Target fixture", + "lastSynchronizedAt": { + "$date": "2026-08-05T20:20:51.000Z" + } +} \ No newline at end of file diff --git a/src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.34041f83759ffb99.json b/src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.34041f83759ffb99.json new file mode 100644 index 000000000..cfc4c7480 --- /dev/null +++ b/src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.34041f83759ffb99.json @@ -0,0 +1,20 @@ +{ + "items": [ + { + "targetId": "Z3FQ0H8JCK", + "name": "agentcore-cli-gateway-read-connector-openai", + "status": "READY", + "createdAt": { + "$date": "2026-08-05T20:20:45.351Z" + }, + "updatedAt": { + "$date": "2026-08-05T20:20:51.210Z" + }, + "description": "AgentCore CLI persistent READY Gateway Connector Target fixture", + "lastSynchronizedAt": { + "$date": "2026-08-05T20:20:51.000Z" + }, + "targetType": "CONNECTOR" + } + ] +} \ No newline at end of file diff --git a/src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.64c210a8bc459fb1.json b/src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.64c210a8bc459fb1.json deleted file mode 100644 index 0252cc433..000000000 --- a/src/handlers/gateway/__fixtures__/ListGatewayTargetsCommand.64c210a8bc459fb1.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "items": [ - { - "targetId": "HDDX5P33XN", - "name": "agentcore-cli-gateway-read-connector-openai", - "status": "FAILED", - "createdAt": { - "$date": "2026-08-05T20:06:04.149Z" - }, - "updatedAt": { - "$date": "2026-08-05T20:06:05.163Z" - }, - "description": "AgentCore CLI persistent Gateway Connector read fixture", - "targetType": "CONNECTOR" - }, - { - "targetId": "O4HB9LXPLC", - "name": "agentcore-cli-gateway-read-http-target", - "status": "READY", - "createdAt": { - "$date": "2026-07-30T00:13:31.109Z" - }, - "updatedAt": { - "$date": "2026-07-30T00:13:31.778Z" - }, - "description": "AgentCore CLI persistent HTTP Gateway Target fixture", - "targetType": "PASSTHROUGH" - } - ] -} \ No newline at end of file diff --git a/src/handlers/gateway/__fixtures__/connector-get.golden.json b/src/handlers/gateway/__fixtures__/connector-get.golden.json index 09210063a..efafebd65 100644 --- a/src/handlers/gateway/__fixtures__/connector-get.golden.json +++ b/src/handlers/gateway/__fixtures__/connector-get.golden.json @@ -1,9 +1,9 @@ { - "gatewayArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:gateway/agentcore-cli-gateway-read-rule-fixture-lhpid2reoy", - "targetId": "HDDX5P33XN", - "createdAt": "2026-08-05T20:06:04.149Z", - "updatedAt": "2026-08-05T20:06:05.163Z", - "status": "FAILED", + "gatewayArn": "arn:aws:bedrock-agentcore:us-east-1:685197708687:gateway/agentcore-cli-gateway-read-connector-gkzcxxkc5e", + "targetId": "Z3FQ0H8JCK", + "createdAt": "2026-08-05T20:20:45.351Z", + "updatedAt": "2026-08-05T20:20:51.210Z", + "status": "READY", "name": "agentcore-cli-gateway-read-connector-openai", "targetConfiguration": { "inference": { @@ -19,7 +19,7 @@ "credentialProviderType": "API_KEY", "credentialProvider": { "apiKeyCredentialProvider": { - "providerArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:token-vault/default/apikeycredentialprovider/agentcore-cli-gateway-read-connector", + "providerArn": "arn:aws:bedrock-agentcore:us-east-1:685197708687:token-vault/default/apikeycredentialprovider/DONOTDELETEe2eOAI", "credentialParameterName": "Authorization", "credentialPrefix": "Bearer", "credentialLocation": "HEADER" @@ -27,8 +27,6 @@ } } ], - "statusReasons": [ - "Failed to discover models from inference provider for target HDDX5P33XN. Error: Inference list-models call to https://api.openai.com/v1/models failed with HTTP 401: {\n \"error\": {\n \"message\": \"Incorrect API key provided: agentcor****************************-key. You can find your API key at https://platform.openai.com/account/api-keys.\",\n \"type\": \"invalid_request_error\",\n \"param\": null,\n \"code\": \"invalid_api_key\"\n }\n}" - ], - "description": "AgentCore CLI persistent Gateway Connector read fixture" + "description": "AgentCore CLI persistent READY Gateway Connector Target fixture", + "lastSynchronizedAt": "2026-08-05T20:20:51.000Z" } \ No newline at end of file diff --git a/src/handlers/gateway/__fixtures__/connector-list.golden.json b/src/handlers/gateway/__fixtures__/connector-list.golden.json index a9947895b..e984ee9f8 100644 --- a/src/handlers/gateway/__fixtures__/connector-list.golden.json +++ b/src/handlers/gateway/__fixtures__/connector-list.golden.json @@ -1,12 +1,13 @@ { "items": [ { - "targetId": "HDDX5P33XN", + "targetId": "Z3FQ0H8JCK", "name": "agentcore-cli-gateway-read-connector-openai", - "status": "FAILED", - "createdAt": "2026-08-05T20:06:04.149Z", - "updatedAt": "2026-08-05T20:06:05.163Z", - "description": "AgentCore CLI persistent Gateway Connector read fixture", + "status": "READY", + "createdAt": "2026-08-05T20:20:45.351Z", + "updatedAt": "2026-08-05T20:20:51.210Z", + "description": "AgentCore CLI persistent READY Gateway Connector Target fixture", + "lastSynchronizedAt": "2026-08-05T20:20:51.000Z", "targetType": "CONNECTOR" } ] diff --git a/src/handlers/gateway/gateway.fixture.test.tsx b/src/handlers/gateway/gateway.fixture.test.tsx index 586d0df69..10d646316 100644 --- a/src/handlers/gateway/gateway.fixture.test.tsx +++ b/src/handlers/gateway/gateway.fixture.test.tsx @@ -11,16 +11,18 @@ import { import { createRootHandler } from "../index"; const REGION = "us-west-2"; +const CONNECTOR_REGION = "us-east-1"; const FIXTURES = join(import.meta.dir, "__fixtures__"); const GATEWAY_ID = "agentcore-cli-gateway-read-fixture-a-l6opkbe2kd"; const TARGET_ID = "KALJACI9HO"; const RULE_GATEWAY_ID = "agentcore-cli-gateway-read-rule-fixture-lhpid2reoy"; const RULE_ID = "d396c3f4-4591-41b3-a4d5-816e03c32419"; -const CONNECTOR_ID = "HDDX5P33XN"; +const CONNECTOR_GATEWAY_ID = "agentcore-cli-gateway-read-connector-gkzcxxkc5e"; +const CONNECTOR_ID = "Z3FQ0H8JCK"; // Account 685197708687 owns the persistent read-only fixture graph: -// listable Gateways, two MCP Targets under GATEWAY_ID, and one HTTP Target, one -// connector Target, and two Rules under RULE_GATEWAY_ID. Record with: +// listable Gateways and Targets in REGION, plus one READY connector Target under +// CONNECTOR_GATEWAY_ID in CONNECTOR_REGION. Record with: // AWS_PROFILE=e2e-test RECORD=1 bun test src/handlers/gateway/gateway.fixture.test.tsx function createFixtureCore(): CoreClient { const { createControlClient, createDataClient, createIamClient } = fixtureFactories(FIXTURES); @@ -32,14 +34,14 @@ function createFixtureCore(): CoreClient { }); } -async function run(args: string[]): Promise { +async function run(args: string[], region = REGION): Promise { const io = testIO(); const root = createRootHandler(createFixtureCore(), { io: io.io, logger: createSilentLogger(), globalConfigAccessor: new TestGlobalConfigAccessor(), }); - await root.route(["node", "agentcore", ...args, "--region", REGION]); + await root.route(["node", "agentcore", ...args, "--region", region]); return io.stdout(); } @@ -114,21 +116,19 @@ describe("Gateway fixture-backed reads", () => { }); test("gets a Gateway Connector", async () => { - const stdout = await run([ - "gateway", - "connector", - "get", - "--gateway-id", - RULE_GATEWAY_ID, - "--id", - CONNECTOR_ID, - ]); + const stdout = await run( + ["gateway", "connector", "get", "--gateway-id", CONNECTOR_GATEWAY_ID, "--id", CONNECTOR_ID], + CONNECTOR_REGION, + ); matchGolden(FIXTURES, "connector-get.golden.json", stdout); expect(JSON.parse(stdout).targetId).toBe(CONNECTOR_ID); }); test("lists Gateway Connectors", async () => { - const stdout = await run(["gateway", "connector", "list", "--gateway-id", RULE_GATEWAY_ID]); + const stdout = await run( + ["gateway", "connector", "list", "--gateway-id", CONNECTOR_GATEWAY_ID], + CONNECTOR_REGION, + ); matchGolden(FIXTURES, "connector-list.golden.json", stdout); expect(JSON.parse(stdout).items.map(({ targetId }: { targetId: string }) => targetId)).toEqual([ CONNECTOR_ID, From dd0fb3201ad91b083bd2150eba0271a06ccc5998 Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Thu, 6 Aug 2026 14:52:26 +0000 Subject: [PATCH 5/5] test(gateway): identify read fixtures by profile --- src/handlers/gateway/gateway.fixture.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handlers/gateway/gateway.fixture.test.tsx b/src/handlers/gateway/gateway.fixture.test.tsx index 10d646316..e45bdf14a 100644 --- a/src/handlers/gateway/gateway.fixture.test.tsx +++ b/src/handlers/gateway/gateway.fixture.test.tsx @@ -20,7 +20,7 @@ const RULE_ID = "d396c3f4-4591-41b3-a4d5-816e03c32419"; const CONNECTOR_GATEWAY_ID = "agentcore-cli-gateway-read-connector-gkzcxxkc5e"; const CONNECTOR_ID = "Z3FQ0H8JCK"; -// Account 685197708687 owns the persistent read-only fixture graph: +// The e2e-test profile owns the persistent read-only fixture graph: // listable Gateways and Targets in REGION, plus one READY connector Target under // CONNECTOR_GATEWAY_ID in CONNECTOR_REGION. Record with: // AWS_PROFILE=e2e-test RECORD=1 bun test src/handlers/gateway/gateway.fixture.test.tsx