Skip to content

Commit

Permalink
chore(util-endpoints): add utility to read service specific endpoints (
Browse files Browse the repository at this point in the history
  • Loading branch information
trivikr authored Oct 5, 2023
1 parent 9712aa7 commit 8376b3e
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/util-endpoints/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "*",
"@smithy/node-config-provider": "^2.0.13",
"tslib": "^2.5.0"
},
"engines": {
Expand Down
91 changes: 91 additions & 0 deletions packages/util-endpoints/src/getEndpointUrlConfig.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { getEndpointUrlConfig } from "./getEndpointUrlConfig";

const ENV_ENDPOINT_URL = "AWS_ENDPOINT_URL";
const CONFIG_ENDPOINT_URL = "endpoint_url";

describe(getEndpointUrlConfig.name, () => {
const serviceId = "mockServiceId";
const endpointUrlConfig = getEndpointUrlConfig(serviceId);

const mockEndpoint = "https://mock-endpoint.com";
const ORIGINAL_ENV = process.env;

beforeEach(() => {
process.env = {};
});

afterEach(() => {
process.env = ORIGINAL_ENV;
});

describe("environmentVariableSelector", () => {
beforeEach(() => {
process.env[ENV_ENDPOINT_URL] = mockEndpoint;
});

it.each([
["foo", `${ENV_ENDPOINT_URL}_FOO`],
["foobar", `${ENV_ENDPOINT_URL}_FOOBAR`],
["foo bar", `${ENV_ENDPOINT_URL}_FOO_BAR`],
])("returns endpoint for '%s' from environment variable %s", (serviceId, envKey) => {
const serviceMockEndpoint = `${mockEndpoint}/${envKey}`;
process.env[envKey] = serviceMockEndpoint;

const endpointUrlConfig = getEndpointUrlConfig(serviceId);
expect(endpointUrlConfig.environmentVariableSelector(process.env)).toEqual(serviceMockEndpoint);
});

it(`returns endpoint from environment variable ${ENV_ENDPOINT_URL}`, () => {
expect(endpointUrlConfig.environmentVariableSelector(process.env)).toEqual(mockEndpoint);
});

it("returns undefined, if endpoint not available in environment variables", () => {
process.env[ENV_ENDPOINT_URL] = undefined;
expect(endpointUrlConfig.environmentVariableSelector(process.env)).toBeUndefined();
});
});

describe("configFileSelector", () => {
const profile = { [CONFIG_ENDPOINT_URL]: mockEndpoint };

// ToDo: Enable once support for services section is added.
it.skip.each([
["foo", "foo"],
["foobar", "foobar"],
["foo bar", "foo_bar"],
])("returns endpoint for '%s' from config file '%s'", (serviceId, serviceConfigId) => {
const serviceMockEndpoint = `${mockEndpoint}/${serviceConfigId}`;
const serviceSectionName = `services ${serviceConfigId}_dev`;

const profileWithServices = {
...profile,
services: serviceSectionName,
};
const parsedIni = {
profileName: profileWithServices,
[serviceSectionName]: {
[serviceConfigId]: {
[CONFIG_ENDPOINT_URL]: serviceMockEndpoint,
},
},
};

// @ts-ignore
expect(endpointUrlConfig.environmentVariableSelector(profileWithServices, parsedIni)).toEqual(
serviceMockEndpoint
);
});

it("returns endpoint from config file, if available", () => {
expect(endpointUrlConfig.configFileSelector(profile)).toEqual(mockEndpoint);
});

it("returns undefined, if endpoint not available in config", () => {
expect(endpointUrlConfig.environmentVariableSelector({})).toBeUndefined();
});
});

it("returns undefined by default", () => {
expect(endpointUrlConfig.default).toBeUndefined();
});
});
36 changes: 36 additions & 0 deletions packages/util-endpoints/src/getEndpointUrlConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { IniSection } from "@aws-sdk/types";
import { LoadedConfigSelectors } from "@smithy/node-config-provider";

const ENV_ENDPOINT_URL = "AWS_ENDPOINT_URL";
const CONFIG_ENDPOINT_URL = "endpoint_url";

export const getEndpointUrlConfig = (serviceId: string): LoadedConfigSelectors<string | undefined> => ({
environmentVariableSelector: (env: NodeJS.ProcessEnv) => {
// The value provided by a service-specific environment variable.
const serviceEndpointUrlSections = [ENV_ENDPOINT_URL, ...serviceId.split(" ").map((w) => w.toUpperCase())];
const serviceEndpointUrl = env[serviceEndpointUrlSections.join("_")];
if (serviceEndpointUrl) return serviceEndpointUrl;

// The value provided by the global endpoint environment variable.
const endpointUrl = env[ENV_ENDPOINT_URL];
if (endpointUrl) return endpointUrl;

return undefined;
},

configFileSelector: (profile: IniSection) => {
// The value provided by a service-specific parameter from a services definition section
// referenced in a profile in the shared configuration file.

// ToDo: profile is selected one. It does not have access to other 'services' section.
// The configFileSelector interface needs to be modified to pass ParsedIniData as optional second parameter.

// The value provided by the global parameter from a profile in the shared configuration file.
const endpointUrl = profile[CONFIG_ENDPOINT_URL];
if (endpointUrl) return endpointUrl;

return undefined;
},

default: undefined,
});

0 comments on commit 8376b3e

Please sign in to comment.