Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added provider.profile support #575

Merged
merged 4 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [7.0.3] - 2023-05-05

### Fixed
- Managing of the Serverless `provider.profile` parameter from the serverless.yml.

## [7.0.2] - 2023-03-24

### Fixed
- Manage the Serverless `provider.region` parameter from the serverless.yml.
- Managing of the Serverless `provider.region` parameter from the serverless.yml.

## [7.0.1] - 2023-03-23

### Fixed
- Manage the Serverless `region` parameter.
- Managing of the Serverless `region` parameter.

## [7.0.0] - 2023-03-22

Expand Down
1,819 changes: 948 additions & 871 deletions package-lock.json

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "serverless-domain-manager",
"version": "7.0.2",
"version": "7.0.3",
"engines": {
"node": ">=14"
},
Expand Down Expand Up @@ -49,33 +49,33 @@
},
"devDependencies": {
"@types/mocha": "^10.0.1",
"@types/node": "^18.15.7",
"@types/shelljs": "^0.8.11",
"@types/node": "^18.16.3",
"@types/shelljs": "^0.8.12",
"aws-sdk-client-mock": "^2.1.1",
"chai": "^4.3.7",
"chai-spies": "^1.0.0",
"mocha": "^10.2.0",
"mocha-param": "^2.0.1",
"nyc": "^15.1.0",
"randomstring": "^1.2.3",
"serverless": "^3.28.1",
"serverless": "^3.30.1",
"serverless-plugin-split-stacks": "^1.12.0",
"shelljs": "^0.8.5",
"ts-node": "^10.9.1",
"tslint": "^6.1.3",
"typescript": "^5.0.2"
"typescript": "^5.0.4"
},
"dependencies": {
"@aws-sdk/client-acm": "^3.298.0",
"@aws-sdk/client-api-gateway": "^3.298.0",
"@aws-sdk/client-apigatewayv2": "^3.298.0",
"@aws-sdk/client-cloudformation": "^3.298.0",
"@aws-sdk/client-route-53": "^3.298.0",
"@aws-sdk/client-s3": "^3.298.0",
"@aws-sdk/config-resolver": "^3.296.0",
"@aws-sdk/credential-providers": "^3.298.0",
"@aws-sdk/node-config-provider": "^3.296.0",
"@aws-sdk/smithy-client": "^3.296.0"
"@aws-sdk/client-acm": "^3.326.0",
"@aws-sdk/client-api-gateway": "^3.326.0",
"@aws-sdk/client-apigatewayv2": "^3.326.0",
"@aws-sdk/client-cloudformation": "^3.326.0",
"@aws-sdk/client-route-53": "^3.326.0",
"@aws-sdk/client-s3": "^3.326.0",
"@aws-sdk/config-resolver": "^3.310.0",
"@aws-sdk/credential-providers": "^3.326.0",
"@aws-sdk/node-config-provider": "^3.310.0",
"@aws-sdk/smithy-client": "^3.325.0"
},
"peerDependencies": {
"serverless": "^2.60 || ^3.0.0"
Expand Down
7 changes: 5 additions & 2 deletions src/aws/acm-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ const certStatuses = ["PENDING_VALIDATION", "ISSUED", "INACTIVE"];
class ACMWrapper {
public acm: ACMClient;

constructor(endpointType: string) {
constructor(credentials: any, endpointType: string) {
const isEdge = endpointType === Globals.endpointTypes.edge;
this.acm = new ACMClient({region: isEdge ? Globals.defaultRegion : Globals.getRegion()});
this.acm = new ACMClient({
credentials,
region: isEdge ? Globals.defaultRegion : Globals.getRegion()
});
}

public async getCertArn(domain: DomainConfig): Promise<string> {
Expand Down
7 changes: 5 additions & 2 deletions src/aws/api-gateway-v1-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ import APIGatewayBase = require("../models/apigateway-base");
import Logging from "../logging";

class APIGatewayV1Wrapper extends APIGatewayBase {
constructor() {
constructor(credentials?: any,) {
super();
this.apiGateway = new APIGatewayClient({region: Globals.getRegion()});
this.apiGateway = new APIGatewayClient({
credentials,
region: Globals.getRegion()
});
}

public async createCustomDomain(domain: DomainConfig): Promise<DomainInfo> {
Expand Down
7 changes: 5 additions & 2 deletions src/aws/api-gateway-v2-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ import Logging from "../logging";

class APIGatewayV2Wrapper extends APIGatewayBase {

constructor() {
constructor(credentials?: any) {
super();
this.apiGateway = new ApiGatewayV2Client({region: Globals.getRegion()});
this.apiGateway = new ApiGatewayV2Client({
credentials,
region: Globals.getRegion()
});
}

/**
Expand Down
7 changes: 5 additions & 2 deletions src/aws/cloud-formation-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ class CloudFormationWrapper {
public cloudFormation: CloudFormationClient;
public stackName: string;

constructor() {
constructor(credentials?: any) {
const defaultStackName = Globals.serverless.service.service + "-" + Globals.getBaseStage();
this.cloudFormation = new CloudFormationClient({region: Globals.getRegion()});
this.stackName = Globals.serverless.service.provider.stackName || defaultStackName;
this.cloudFormation = new CloudFormationClient({
credentials,
region: Globals.getRegion()
});
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/aws/route53-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Route53Wrapper {
public route53: Route53Client;

constructor(credentials?: any, region?: string) {
// not null and not undefined
if (credentials) {
this.route53 = new Route53Client({
credentials,
Expand Down
7 changes: 5 additions & 2 deletions src/aws/s3-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import Globals from "../globals";
class S3Wrapper {
public s3: S3Client;

constructor() {
this.s3 = new S3Client({region: Globals.getRegion()});
constructor(credentials?: any) {
this.s3 = new S3Client({
credentials,
region: Globals.getRegion()
});
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export default class Globals {
public static options: ServerlessOptions;
public static v3Utils: ServerlessUtils;

public static currentRegion: string;
public static nodeRegion: string;
public static credentials: any;

public static defaultRegion = "us-east-1";
public static defaultBasePath = "(none)";
Expand Down Expand Up @@ -66,7 +67,7 @@ export default class Globals {

public static getRegion() {
const slsRegion = Globals.options.region || Globals.serverless.service.provider.region;
return slsRegion || Globals.currentRegion || Globals.defaultRegion;
return slsRegion || Globals.nodeRegion || Globals.defaultRegion;
}

public static async getProfileCreds(profile: string) {
Expand Down
29 changes: 20 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class ServerlessCustomDomain {
// Validate the domain configurations
this.validateDomainConfigs();
// setup AWS resources
await this.initAWSCredentials();
await this.initAWSRegion();
await this.initAWSResources();

Expand Down Expand Up @@ -166,22 +167,32 @@ class ServerlessCustomDomain {
}

/**
* Init AWS current region
* Init AWS credentials based on sls `provider.profile`
*/
public async initAWSCredentials(): Promise<void> {
const slsProfile = Globals.serverless.service.provider.profile;
Globals.credentials = slsProfile ? await Globals.getProfileCreds(slsProfile) : null;
}

/**
* Init AWS current region based on Node options
*/
public async initAWSRegion(): Promise<void> {
if (!Globals.options.region) {
Globals.currentRegion = await loadConfig(NODE_REGION_CONFIG_OPTIONS, NODE_REGION_CONFIG_FILE_OPTIONS)();
try {
Globals.nodeRegion = await loadConfig(NODE_REGION_CONFIG_OPTIONS, NODE_REGION_CONFIG_FILE_OPTIONS)();
} catch (err) {
Logging.logInfo("Node region was not found.");
}
}

/**
* Setup AWS resources
*/
public async initAWSResources(): Promise<void> {
this.apiGatewayV1Wrapper = new APIGatewayV1Wrapper();
this.apiGatewayV2Wrapper = new APIGatewayV2Wrapper();
this.cloudFormationWrapper = new CloudFormationWrapper();
this.s3Wrapper = new S3Wrapper();
this.apiGatewayV1Wrapper = new APIGatewayV1Wrapper(Globals.credentials);
this.apiGatewayV2Wrapper = new APIGatewayV2Wrapper(Globals.credentials);
this.cloudFormationWrapper = new CloudFormationWrapper(Globals.credentials);
this.s3Wrapper = new S3Wrapper(Globals.credentials);
}

public getApiGateway(domain: DomainConfig): APIGatewayBase {
Expand Down Expand Up @@ -220,11 +231,11 @@ class ServerlessCustomDomain {
*/
public async createDomain(domain: DomainConfig): Promise<void> {
const creationProgress = Globals.v3Utils && Globals.v3Utils.progress.get(`create-${domain.givenDomainName}`);
const route53Creds = domain.route53Profile ? await Globals.getProfileCreds(domain.route53Profile) : Globals.credentials;

const apiGateway = this.getApiGateway(domain);
const route53Creds = domain.route53Profile ? await Globals.getProfileCreds(domain.route53Profile) : null;
const route53 = new Route53Wrapper(route53Creds, domain.route53Region);
const acm = new ACMWrapper(domain.endpointType);
const acm = new ACMWrapper(Globals.credentials, domain.endpointType);

domain.domainInfo = await apiGateway.getCustomDomain(domain);

Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface ServerlessInstance {
provider: {
stage: string
region?: string
profile?: string
stackName: string
compiledCloudFormationTemplate: {
Outputs: any,
Expand Down
2 changes: 1 addition & 1 deletion test/integration-tests/test-utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ async function createTempDir(tempDir, folderName) {
* @returns {Promise<void>}
*/
function slsCreateDomain(tempDir, debug: boolean = false) {
return exec(`cd ${tempDir} && npx serverless create_domain --stage test --region us-east-1` + (debug ? " --verbose" : ""));
return exec(`cd ${tempDir} && npx serverless create_domain` + (debug ? " --verbose" : ""));
}

/**
Expand Down
18 changes: 9 additions & 9 deletions test/unit-tests/aws/acm-wrapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,22 @@ const certTestData = {

describe("ACM Wrapper checks", () => {
it("Initialization edge", async () => {
const acmWrapper = new ACMWrapper(Globals.endpointTypes.edge);
const acmWrapper = new ACMWrapper(null, Globals.endpointTypes.edge);
const actualResult = await acmWrapper.acm.config.region();
expect(actualResult).to.equal(Globals.defaultRegion);
});

it("Initialization regional", async () => {
const acmWrapper = new ACMWrapper(Globals.endpointTypes.regional);
const acmWrapper = new ACMWrapper(null, Globals.endpointTypes.regional);
const actualResult = await acmWrapper.acm.config.region();
expect(actualResult).to.equal(Globals.currentRegion);
expect(actualResult).to.equal(Globals.nodeRegion);
});

it("getCertArn by certificate name", async () => {
const ACMCMock = mockClient(ACMClient);
ACMCMock.on(ListCertificatesCommand).resolves(certTestData);

const acmWrapper = new ACMWrapper(Globals.endpointTypes.regional);
const acmWrapper = new ACMWrapper(null, Globals.endpointTypes.regional);
const dc = new DomainConfig(getDomainConfig({
certificateName: "cert_name"
}));
Expand All @@ -52,7 +52,7 @@ describe("ACM Wrapper checks", () => {
const ACMCMock = mockClient(ACMClient);
ACMCMock.on(ListCertificatesCommand).resolves(certTestData);

const acmWrapper = new ACMWrapper(Globals.endpointTypes.regional);
const acmWrapper = new ACMWrapper(null, Globals.endpointTypes.regional);
const dc = new DomainConfig(getDomainConfig({
domainName: "test_domain",
}));
Expand All @@ -66,7 +66,7 @@ describe("ACM Wrapper checks", () => {
ACMCMock.on(ListCertificatesCommand).resolves(certTestData);

const certificateName = "not_existing_certificate"
const acmWrapper = new ACMWrapper(Globals.endpointTypes.regional);
const acmWrapper = new ACMWrapper(null, Globals.endpointTypes.regional);
const dc = new DomainConfig(getDomainConfig({certificateName}));

let errored = false;
Expand All @@ -92,7 +92,7 @@ describe("ACM Wrapper checks", () => {
}]
});

const acmWrapper = new ACMWrapper(Globals.endpointTypes.regional);
const acmWrapper = new ACMWrapper(null, Globals.endpointTypes.regional);
const dc = new DomainConfig(getDomainConfig({
domainName: "sub.test_domain",
}));
Expand All @@ -106,7 +106,7 @@ describe("ACM Wrapper checks", () => {
ACMCMock.on(ListCertificatesCommand).resolves(certTestData);

const domainName = "not_existing_domain"
const acmWrapper = new ACMWrapper(Globals.endpointTypes.regional);
const acmWrapper = new ACMWrapper(null, Globals.endpointTypes.regional);
const dc = new DomainConfig(getDomainConfig({domainName}));

let errored = false;
Expand All @@ -123,7 +123,7 @@ describe("ACM Wrapper checks", () => {
const ACMCMock = mockClient(ACMClient);
ACMCMock.on(ListCertificatesCommand).rejects();

const acmWrapper = new ACMWrapper(Globals.endpointTypes.regional);
const acmWrapper = new ACMWrapper(null, Globals.endpointTypes.regional);
const dc = new DomainConfig(getDomainConfig({
domainName: "test_domain",
}));
Expand Down
2 changes: 1 addition & 1 deletion test/unit-tests/aws/api-gateway-v1-wrapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe("API Gateway V1 wrapper checks", () => {
it("Initialization", async () => {
const apiGatewayV1Wrapper = new APIGatewayV1Wrapper();
const actualResult = await apiGatewayV1Wrapper.apiGateway.config.region();
expect(actualResult).to.equal(Globals.currentRegion);
expect(actualResult).to.equal(Globals.nodeRegion);
});

describe("Custom domain", () => {
Expand Down
2 changes: 1 addition & 1 deletion test/unit-tests/aws/api-gateway-v2-wrapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe("API Gateway V2 wrapper checks", () => {
it("Initialization", async () => {
const apiGatewayV2Wrapper = new APIGatewayV2Wrapper();
const actualResult = await apiGatewayV2Wrapper.apiGateway.config.region();
expect(actualResult).to.equal(Globals.currentRegion);
expect(actualResult).to.equal(Globals.nodeRegion);
});

describe("Custom domain", () => {
Expand Down
2 changes: 1 addition & 1 deletion test/unit-tests/aws/cloud-formation-wrapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe("Cloud Formation wrapper checks", () => {
it("Initialization", async () => {
const cloudFormationWrapper = new CloudFormationWrapper();
const actualResult = await cloudFormationWrapper.cloudFormation.config.region();
expect(actualResult).to.equal(Globals.currentRegion);
expect(actualResult).to.equal(Globals.nodeRegion);
expect(cloudFormationWrapper.stackName).to.equal(Globals.serverless.service.provider.stackName);
});

Expand Down
2 changes: 1 addition & 1 deletion test/unit-tests/aws/route53-wrapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe("Route53 wrapper checks", () => {
it("Initialization", async () => {
const route53Wrapper = new Route53Wrapper();
const actualResult = await route53Wrapper.route53.config.region();
expect(actualResult).to.equal(Globals.currentRegion);
expect(actualResult).to.equal(Globals.nodeRegion);
});

it("Initialization profile", async () => {
Expand Down
2 changes: 1 addition & 1 deletion test/unit-tests/aws/s3-wrapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe("S3 wrapper checks", () => {
it("Initialization", async () => {
const s3Wrapper = new S3Wrapper();
const actualResult = await s3Wrapper.s3.config.region();
expect(actualResult).to.equal(Globals.currentRegion);
expect(actualResult).to.equal(Globals.nodeRegion);
});

it("Assert TlS cert object exists", async () => {
Expand Down
2 changes: 1 addition & 1 deletion test/unit-tests/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const getV3Utils = () => {
}
}

Globals.currentRegion = "test_region";
Globals.nodeRegion = "test_region";
Globals.options = {
stage: "test"
};
Expand Down