-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: browsing deployed templates + refactoring
- Loading branch information
1 parent
47c442e
commit 19d0d38
Showing
4 changed files
with
162 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
const program = require("commander"); | ||
const template = require("../../shared/template"); | ||
const Vis = require("../../graph/Vis"); | ||
const draw = require("../../graph/MxGenerator"); | ||
const AWS = require("aws-sdk"); | ||
const cloudFormation = new AWS.CloudFormation(); | ||
const inquirer = require("inquirer"); | ||
const prompt = inquirer.createPromptModule(); | ||
const YAML = require("yaml-cfn"); | ||
const jsonUtil = require("../../resources/JsonUtil"); | ||
|
||
require("@mhlabs/aws-sdk-sso"); | ||
program | ||
.command("browse") | ||
.alias("b") | ||
.option("-o --output [output]", "Output format. draw.io or html") | ||
.option("--output-file [outputFile]", "Output file. Only used when using draw.io output. Defaults to <stack-name>.drawio") | ||
.option("-p --profile [profile]", "AWS CLI profile") | ||
.description("Browses and generates diagrams from your deployed templates") | ||
.action(async (cmd) => { | ||
initAuth(cmd); | ||
let nextToken = null; | ||
const stackList = []; | ||
do { | ||
const response = await cloudFormation | ||
.listStacks({ | ||
NextToken: nextToken, | ||
StackStatusFilter: ["CREATE_COMPLETE", "UPDATE_COMPLETE"], | ||
}) | ||
.promise(); | ||
stackList.push(...response.StackSummaries.map((p) => p.StackName)); | ||
nextToken = response.NextToken; | ||
} while (nextToken); | ||
while (true) { | ||
const stack = await prompt({ | ||
name: "stackName", | ||
type: "list", | ||
choices: stackList.sort(), | ||
}); | ||
const templateBody = ( | ||
await cloudFormation | ||
.getTemplate({ StackName: stack.stackName }) | ||
.promise() | ||
).TemplateBody; | ||
const isJson = jsonUtil.isJson(templateBody); | ||
const parser = isJson ? JSON.parse : YAML.yamlParse; | ||
|
||
const template = parser(templateBody); | ||
if (cmd.output === "html") { | ||
await Vis.renderTemplate( | ||
template, | ||
template.isJson, | ||
cmd.outputPath, | ||
false | ||
); | ||
} else { | ||
cmd.outputFile = cmd.outputFile || stack.stackName + ".drawio" | ||
await draw.generate(cmd, template); | ||
} | ||
} | ||
}); | ||
|
||
function initAuth(cmd) { | ||
process.env.AWS_PROFILE = cmd.profile || process.env.AWS_PROFILE || "default"; | ||
process.env.AWS_REGION = cmd.region || process.env.AWS_REGION; | ||
AWS.config.credentialProvider.providers.unshift( | ||
new AWS.SingleSignOnCredentials() | ||
); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
const program = require("commander"); | ||
const mxGenerator = require("../../graph/MxGenerator"); | ||
|
||
let ciMode = false; | ||
|
||
program | ||
.command("draw.io") | ||
.alias("d") | ||
.option( | ||
"-t, --template-file [templateFile]", | ||
"Path to template", | ||
"template.yaml" | ||
) | ||
.option( | ||
"-c, --ci-mode", | ||
"Disable interactivity", | ||
false | ||
) | ||
.option("-o, --output-file [outputFile]", "Output file", "template.drawio") | ||
.description("Generates a draw.io diagram from a CloudFormation template") | ||
.action(async (cmd) => { | ||
await mxGenerator.generate(cmd); | ||
}); | ||
|
||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
const program = require("commander"); | ||
const template = require("../../shared/template"); | ||
const path = require("path"); | ||
const tempDirectory = require("temp-dir"); | ||
const Vis = require("../../graph/Vis"); | ||
const YAML = require("yaml-cfn"); | ||
|
||
program | ||
.command("html") | ||
.alias("h") | ||
.option( | ||
"-t, --template-file [templateFile]", | ||
"Path to template", | ||
"template.yaml" | ||
) | ||
.option( | ||
"-c, --ci-mode", | ||
"Disable interactivity", | ||
false | ||
) | ||
.option( | ||
"-o, --output-path [outputPath]", | ||
"Output file", | ||
`${path.join(tempDirectory, "cfn-diagram")}` | ||
) | ||
.description("Generates a vis.js diagram from a CloudFormation template") | ||
.action(async (cmd) => { | ||
ciMode = cmd.ciMode; | ||
const templateObj = template.get(cmd); | ||
await Vis.renderTemplate(templateObj.template, template.isJson, cmd.outputPath, ciMode); | ||
}); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
const fs = require("fs"); | ||
const YAML = require("yaml-cfn"); | ||
const jsonUtil = require("../resources/JsonUtil"); | ||
|
||
function get(cmd) { | ||
let templateString = ""; | ||
try { | ||
templateString = fs.readFileSync(cmd.templateFile); | ||
} catch { | ||
console.log( | ||
`Can't find ${cmd.templateFile}. Specify location with -t flag, for example 'cfn-dia html -t mytemplate.yaml'` | ||
); | ||
process.exit(1); | ||
} | ||
|
||
const isJson = jsonUtil.isJson(templateString); | ||
const parser = isJson ? JSON.parse : YAML.yamlParse; | ||
|
||
const template = parser(templateString); | ||
Object.keys(template.Resources) | ||
.filter((p) => template.Resources[p].Type === "AWS::CloudFormation::Stack") | ||
.map((p) => { | ||
const res = template.Resources[p]; | ||
if (typeof res.Properties.TemplateURL === "string" && !res.Properties.TemplateURL.startsWith("s3://")) { | ||
templateString = fs.readFileSync(res.Properties.TemplateURL); | ||
const isJson = jsonUtil.isJson(templateString); | ||
const parser = isJson ? JSON.parse : YAML.yamlParse; | ||
template.Resources[p].Template = parser(templateString); | ||
} | ||
}); | ||
return { isJson, template }; | ||
} | ||
|
||
|
||
module.exports = { | ||
get | ||
} |