Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
9537eeb
support environment variables for template and include sns client
Dec 11, 2020
b4ec562
send job result to sns
Dec 11, 2020
35a4ec2
fix serverless provider to work with environment service
Dec 14, 2020
80ec644
get the inputs working from env vars
Jan 5, 2021
69cfb75
fix the parsing of the provider environment var
Jan 5, 2021
4dec79f
some debuggin around the cdk provider config
Jan 5, 2021
4b1cf82
properly parse provider config from env vars
Jan 5, 2021
19a2870
try json parse of provider config items
Jan 5, 2021
052d9aa
switch to just using a flat provider config
Jan 5, 2021
c4893f2
another attempt
Jan 6, 2021
ab1df3a
some more debugging and hardcoded defaults
Jan 6, 2021
3b8332c
fix cdk construct config
Jan 6, 2021
5dde3f2
send stack outputs to sns
Jan 8, 2021
398bbbf
fix hardcoded provider
Jan 11, 2021
93b3514
report hardcoded provider result
Jan 11, 2021
77efa01
handle package import names in cdk
Jan 13, 2021
c5199dd
some require stuff
Jan 13, 2021
7d0a664
explicitly state node modules
Jan 13, 2021
728ce18
print stack env
Jan 14, 2021
7984209
send passed build result from cdk provider
Jan 14, 2021
477199a
force deploy stack on cdk provider
Feb 22, 2021
6b0328d
fix serverless inputs reference
Mar 8, 2021
dd25ecf
previous commit but built now
Mar 8, 2021
58cf769
attempt to do lookups correctly in cdk provider
Mar 23, 2021
c8ce0be
experiment with using contextproviders
Mar 23, 2021
0aa48b7
increase cdk verbosity
Mar 23, 2021
0a0689d
write context to disk after resolving context
Mar 23, 2021
a88ed7e
print out cdk.context.json
Mar 23, 2021
4664408
try to make a new assembly
Mar 23, 2021
d9e412e
loop on contextprovider lookups
Mar 23, 2021
54a1451
retry synth after each context update
Mar 23, 2021
012cb3b
actually store the synthesized template after providing missing context
Mar 23, 2021
5779631
force new synth
Mar 23, 2021
739f804
try passing context to app
Mar 23, 2021
e8233c1
take a closer look at the assembly each time
Mar 23, 2021
858d605
I think this finally works
Mar 24, 2021
f3eb6a9
go back to using default legacy synthesizer
Mar 24, 2021
9e78964
remove unnecessary code from trying to get lookups to work
Mar 25, 2021
3876829
increase cdk verbosity again
Mar 29, 2021
7b04fb1
write cdk.context.json if it doesn't exist
Mar 30, 2021
5dae128
re-add default synthesizer code
Mar 30, 2021
195c119
reload config before synthesizing app
Mar 30, 2021
d58648b
try to recreate app each time the synthesizer is called
Mar 30, 2021
0ccc29a
Merge pull request #5 from DaySmart/cdk-provider-lookup
chrisdettloff Apr 8, 2021
3ea1b89
update serverless provider to stop using deprecated yaml.safeDump
Apr 8, 2021
8e88500
downgrade serverless to v1
Apr 9, 2021
47f0402
add support for serverless v2 and use projects version of serverless …
Apr 19, 2021
69030a2
remove serverless framework version from class name
Apr 19, 2021
d223b72
Merge pull request #6 from DaySmart/serverless-v2-support
Apr 20, 2021
c9f6d96
expand scope of error handling for reporting deployment status to fra…
Apr 30, 2021
a133521
Merge pull request #7 from DaySmart/expand-frank-exception-handling
May 5, 2021
635547b
handle cross account in cdk provider
Jul 20, 2021
6bb041f
fix account object ref
Jul 21, 2021
2e38d49
send account object to cdk provider
Jul 21, 2021
06af9e9
some debug logging
Jul 21, 2021
c2b59ca
fix awscredentials reference
Jul 21, 2021
6b5cd98
setup cross account credentials provider correctly
Jul 21, 2021
4da2d73
implement cross account in serverless provider
Jul 21, 2021
4b2b011
try implementing custom aws creds for serverless v2
Jul 21, 2021
db79706
Merge pull request #8 from DaySmart/cross-account-support
Jul 28, 2021
1fc8260
support cross account credentials in serverless framework provider fo…
Aug 16, 2021
9f38ddf
use profiles for cross account creds in serverless framework provider
Aug 16, 2021
d90fd10
fix credentials command
Aug 16, 2021
ae476fc
add provider to sls config command
Aug 16, 2021
fdbcf48
log some stuff
Aug 16, 2021
c427e38
catch sls config error
Aug 16, 2021
01fda42
add stage to sls config command
Aug 16, 2021
c5946c9
change profile to aws-profile
Aug 16, 2021
e66dc8c
clean up serverless provider
Aug 16, 2021
51a09ca
Merge pull request #9 from DaySmart/serverless-cross-account
Aug 20, 2021
e383be1
unflatten componenent inputs from env vars
Aug 25, 2021
be51782
remove safe unflatten
Aug 25, 2021
d2d2a74
fix unflatten logic
Aug 25, 2021
e7a99b6
Merge pull request #10 from DaySmart/unflatten-component-inpus
Aug 27, 2021
fa2d61d
fix region ref for serverless provider
Sep 13, 2021
ce58cb6
Merge branch 'env-service-refactor' of github.com:DaySmart/deployer i…
Sep 13, 2021
a988c28
added Remove function
TaylorGarpow Jan 21, 2022
5926bc5
attempt to fix the sudden breaking of cdk deploys when the change set…
Jan 24, 2022
d0822dc
fix serverless 2 provider
Feb 7, 2022
b89e45a
add deleted status
TaylorGarpow Feb 8, 2022
31575f6
add support for serverless framework v3
Feb 8, 2022
c0beef5
Merge pull request #12 from DaySmart/serverless-provider-v3
TaylorGarpow Feb 8, 2022
e8e9f52
support resolving secret values from inputs
Feb 22, 2022
3d7b3b4
bump version of aws-cdk
Feb 22, 2022
b03e1e5
drop aws-cdk version back down
Feb 22, 2022
83ab05c
remove function
TaylorGarpow Feb 28, 2022
0556996
install chalk
TaylorGarpow Feb 28, 2022
83a8e9b
Merge branch 'env-service-refactor' into env-remove
TaylorGarpow Feb 28, 2022
59ad909
serverless version
TaylorGarpow Feb 28, 2022
e0181df
change to command
TaylorGarpow Feb 28, 2022
ce33633
output for remove
TaylorGarpow Feb 28, 2022
7c71b98
Merge pull request #13 from DaySmart/env-remove
TaylorGarpow Mar 2, 2022
171c7f1
allow custom packages as providers
Apr 18, 2022
1d12547
print error
Apr 18, 2022
21eff6b
fix invocation of custom provider constructor
Apr 19, 2022
bdb26e9
fix exception for custom providers
Apr 19, 2022
ffb00b9
publish results for custom provider
Apr 19, 2022
2b3e2c6
fix the serverless v3 provider by resolving vars
May 10, 2022
8b8119e
fix imports for serverless v3 provider
May 10, 2022
b8d842f
some debugging of sls v3 provider
May 10, 2022
c3cfe8c
attempt to generate commandschema
May 10, 2022
5690849
pass command schema
May 10, 2022
e2724d2
another try add resolving vars
May 10, 2022
0940b1f
another try add resolving vars
May 10, 2022
c085330
another try add resolving vars
May 10, 2022
56af885
remove infinite loop
May 10, 2022
b2a857d
remove infinite loop
May 10, 2022
0a2c54c
try to resolve more vars
May 10, 2022
f032e44
try to resolve more vars
May 10, 2022
e74f021
for serverless 3 resolve variables that depend on the sls instance
May 10, 2022
04c8ddf
clean up serverless v3 provider
May 10, 2022
e9e5bf7
clean up serverless v3 provider
May 10, 2022
eb8f57a
try skipping the post init variable resolution to see if it fixes the…
May 11, 2022
6f060e1
some extra debugging to fix sls v3 provider
May 12, 2022
93cb83f
try to resolve sls instance specific vars again
May 12, 2022
292817b
log variablesMeta after resolving instance dependent vars
May 12, 2022
2c683f0
improve var meta logging
May 12, 2022
3cdb397
improve var meta logging
May 12, 2022
57bc954
try marking env as a fulfilled source and try to resolve vars again
May 12, 2022
7a0880f
increase retry count to 10 for cdk pulling down AWS credentials
May 19, 2022
c5fb5c6
Merge pull request #14 from DaySmart/custom-packages
Jun 2, 2022
59a0bc2
don't import cdk provider unless required to workaround the construct…
Jun 9, 2022
e50a228
implement remove for custom providers
Jul 6, 2022
0625447
Merge pull request #15 from DaySmart/implement-remove-custom-providers
Jul 6, 2022
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
8 changes: 5 additions & 3 deletions bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ const minimist = require('minimist');
const run = async () => {
const args = minimist(process.argv);
// process.argv.forEach(arg => delete process.argv[process.argv.indexOf(arg)]);
process.argv = process.argv.slice(0, 2);
const file = args._[3];
const command = args._[2];
if (process.argv.length > 2) {
process.argv = process.argv.slice(0, 2);
}
const file = (args._.length > 3) ? args._[3] : undefined;
const command = (args._.length > 2) ? args._[2] : 'deploy';
const deploy = new deployer(command, file);
await deploy.run();
};
Expand Down
9 changes: 6 additions & 3 deletions bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ const minimist = require('minimist');
const run = async () => {
const args = minimist(process.argv);
// process.argv.forEach(arg => delete process.argv[process.argv.indexOf(arg)]);
process.argv = process.argv.slice(0, 2);
const file = args._[3];
const command = args._[2];
if(process.argv.length > 2) {
process.argv = process.argv.slice(0, 2);
}

const file = (args._.length > 3) ? args._[3] : undefined;
const command = (args._.length > 2) ? args._[2] : 'deploy';
const deploy = new deployer(command, file);
await deploy.run();
}
Expand Down
272 changes: 244 additions & 28 deletions lib/deployer.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const parseYaml = require('./utils/parseYaml');
const cdk_1 = require("./providers/cdk");
const serverless_1 = require("./providers/serverless");
const HardCoded = require('./providers/hardcoded');
const DsicollectionDynamicEnvironment = require('./providers/dsicollectionDynamicEnvironment');
const environmentService = require('./service/environmentService');
const snsClient = require('./service/snsClient');
const unflatten = require('flat').unflatten;
const AWS = require('aws-sdk');
class Deployer {
constructor(command, file) {
this.publish = true;
this.file = file;
this.command = command;
this.component = this.parseComponentTemplate(this.file);
this.command = process.env.PROVIDER_METHOD || command;
if (this.file) {
this.component = this.parseComponentTemplate(this.file);
}
else {
this.component = this.parseEnvironmentVariables();
this.deploymentGuid = process.env.DEPLOYMENT_GUID;
this.jobRunGuid = process.env.JOB_RUN_GUID;
}
console.log(this.component);
}
async run() {
try {
await this.resolveSecrets();
}
catch (err) {
console.error('Error on resolving secrets', err);
}
if (this.command === 'deploy') {
await this.deploy();
}
else if (this.command === 'destroy') {
await this.destroy();
else if (this.command === 'remove') {
await this.remove();
}
else {
console.error(`The command ${this.command} is not implemented`);
this.publishResultToFrankenstack();
throw `The command ${this.command} is not implemented`;
}
}
async deploy() {
Expand All @@ -30,37 +47,236 @@ class Deployer {
if (this.component.provider instanceof String) {
providerType = this.component.provider;
}
else {
else if (this.component.provider.name) {
providerType = this.component.provider.name;
}
switch (providerType) {
case 'serverless-framework':
provider = new serverless_1.ServerlessV1(this.component);
break;
case 'hardcoded':
provider = new HardCoded(this.component);
break;
case 'dsicollection-dynamic-environment':
provider = new DsicollectionDynamicEnvironment(this.component);
break;
case 'cdk':
provider = new cdk_1.CDK(this.component.name, this.component.env, this.component.provider.config, this.component.input);
break;
default:
throw (`The provider ${providerType} is not implemented!`);
}
const deployResp = await provider.deploy();
else if (this.component.provider.Name) {
providerType = this.component.provider.Name;
}
let deployResp = {};
try {
switch (providerType) {
case 'serverless-framework':
provider = new serverless_1.Serverless(this.component);
break;
case 'hardcoded':
provider = new HardCoded(this.component);
break;
case 'dsicollection-dynamic-environment':
provider = new DsicollectionDynamicEnvironment(this.component);
break;
case 'cdk':
const cdk = require('./providers/cdk');
provider = new cdk.CDK(this.component.name, this.component.env, this.component.provider.config, this.component.inputs, this.component.provider.account);
break;
default:
try {
const { createRequireFromPath } = require('module');
const requireUtil = createRequireFromPath(process.cwd() + '/node_modules');
const providerPackage = requireUtil(providerType);
const providerConfig = {
componentProvider: {
name: this.component.provider.name,
config: Object.entries(this.component.provider.config).map(config => {
return { key: config[0], value: config[1] };
}),
account: this.component.provider.account
},
environment: this.component.env,
componentName: this.component.name,
deploymentGuid: this.deploymentGuid,
jobRunGuid: this.jobRunGuid,
jobRunFinishedTopicArn: process.env.JOB_RUN_FINISHED_TOPIC_ARN,
inputs: Object.entries(this.component.inputs).map(input => {
return { key: input[0], value: input[1] };
})
};
const providerClass = Object.keys(providerPackage)[0];
provider = new providerPackage[providerClass](providerConfig);
this.publish = false;
}
catch (err) {
console.error(err);
throw (`The provider ${providerType} is not implemented!`);
}
}
deployResp = await provider.deploy();
}
catch (err) {
throw err;
}
finally {
if (this.publish) {
await this.publishResultToFrankenstack(deployResp);
}
else {
await provider.sendResponse();
}
if (deployResp && deployResp.exception) {
throw deployResp.exception;
}
}
// Store the component in the environment service with it's outputs
if (deployResp.outputs) {
await deployResp.outputs.forEach((output) => {
environmentService.putComponentOutput(this.component.env, this.component.name, output.key, output.value);
// if(deployResp.outputs) {
// await deployResp.outputs.forEach((output: any) => {
// environmentService.putComponentOutput(this.component.env, this.component.name, output.key, output.value)
// });
// }
}
async publishResultToFrankenstack(result) {
if (this.jobRunGuid && this.deploymentGuid) {
var status = 'Failed';
var outputs = [];
if (result) {
if (result.result) {
if (this.command === 'remove') {
status = 'Deleted';
}
else {
status = 'Success';
}
}
outputs = result.outputs || [];
}
await snsClient.publishJobRunFinishedMessage({
deploymentGuid: this.deploymentGuid,
env: this.component.env,
jobRunGuid: this.jobRunGuid,
name: this.component.name,
status: status,
outputs: JSON.stringify(outputs)
});
}
}
async destroy() {
async remove() {
let provider;
let providerType;
if (this.component.provider instanceof String) {
providerType = this.component.provider;
}
else if (this.component.provider.name) {
providerType = this.component.provider.name;
}
else if (this.component.provider.Name) {
providerType = this.component.provider.Name;
}
let deployResp = {};
try {
switch (providerType) {
case 'serverless-framework':
provider = new serverless_1.Serverless(this.component);
break;
case 'hardcoded':
provider = new HardCoded(this.component);
break;
case 'dsicollection-dynamic-environment':
provider = new DsicollectionDynamicEnvironment(this.component);
break;
case 'cdk':
const cdk = require('./providers/cdk');
provider = new cdk.CDK(this.component.name, this.component.env, this.component.provider.config, this.component.inputs, this.component.provider.account);
break;
default:
try {
const { createRequireFromPath } = require('module');
const requireUtil = createRequireFromPath(process.cwd() + '/node_modules');
const providerPackage = requireUtil(providerType);
const providerConfig = {
componentProvider: {
name: this.component.provider.name,
config: Object.entries(this.component.provider.config).map(config => {
return { key: config[0], value: config[1] };
}),
account: this.component.provider.account
},
environment: this.component.env,
componentName: this.component.name,
deploymentGuid: this.deploymentGuid,
jobRunGuid: this.jobRunGuid,
jobRunFinishedTopicArn: process.env.JOB_RUN_FINISHED_TOPIC_ARN,
inputs: Object.entries(this.component.inputs).map(input => {
return { key: input[0], value: input[1] };
})
};
const providerClass = Object.keys(providerPackage)[0];
provider = new providerPackage[providerClass](providerConfig);
this.publish = false;
}
catch (err) {
console.error(err);
throw (`The provider ${providerType} is not implemented!`);
}
}
deployResp = await provider.remove();
}
catch (err) {
throw err;
}
finally {
if (this.publish) {
await this.publishResultToFrankenstack(deployResp);
}
else {
await provider.sendResponse();
}
if (deployResp && deployResp.exception) {
throw deployResp.exception;
}
}
}
parseEnvironmentVariables() {
let provider;
try {
const rawProvider = JSON.parse(process.env.COMPONENT_PROVIDER);
console.log(rawProvider);
provider = {
name: rawProvider.Name,
config: (rawProvider.Config) ? rawProvider.Config.reduce((obj, item) => {
return Object.assign(Object.assign({}, obj), { [item.Key]: item.Value });
}, {}) : undefined,
account: (rawProvider.Account) ? rawProvider.Account : undefined
};
}
catch (err) {
provider = process.env.COMPONENT_PROVIDER;
}
return {
env: process.env.COMPONENT_ENVIRONMENT,
name: process.env.COMPONENT_NAME,
provider: provider,
inputs: (process.env.COMPONENT_INPUTS)
? unflatten(JSON.parse(process.env.COMPONENT_INPUTS).reduce((obj, item) => {
return Object.assign(Object.assign({}, obj), { [item.Key]: item.Value });
}, {}))
: undefined
};
}
parseComponentTemplate(file) {
return parseYaml(file);
}
async resolveSecrets() {
const ssm = new AWS.SSM();
if (!this.component.inputs) {
return;
}
for (var key of Object.keys(this.component.inputs)) {
if (this.component.inputs[key].startsWith('ssm:')) {
console.log(`Resolving secret value for: ${this.component.inputs[key]}`);
const paramName = this.component.inputs[key].replace('ssm:', '');
const param = await ssm.getParameter({
Name: paramName,
WithDecryption: true
}).promise();
if (param.Parameter && param.Parameter.Value) {
this.component.inputs[key] = param.Parameter.Value;
}
else {
const result = { status: false };
await this.publishResultToFrankenstack(result);
throw `Failed to resolve secret value for paramater: ${paramName}`;
}
}
}
}
}
module.exports = Deployer;
Loading