aws-cfn-constructor
Version:
Constructor for AWS CloudFormation resources using AWS CDK
273 lines (272 loc) • 8.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.setPrincipal = exports.streamToBuffer = exports.loadJsonFile = exports.initialSetting = exports.extractTags = exports.extractDataFromArn = exports.delay = exports.checkAwsArnPattern = exports.createId = exports.changePartForArn = void 0;
const crypto_1 = require("crypto");
const fs_1 = require("fs");
// Response
const response_1 = require("../models/response");
/**
* Change the part for aws arn
* @param arn arn for resource
* @param type part type
* @param content content
* @returns changed arn
*/
function changePartForArn(arn, type, content) {
// Split the arn
const split = arn.split(":");
// Return by output type
switch (type) {
case "partition":
split[1] = content;
break;
case "service":
split[2] = content;
break;
case "region":
split[3] = content;
break;
case "account":
split[4] = content;
break;
case "resource":
split[5] = content;
break;
default:
break;
}
// Join to array
return split.join(":");
}
exports.changePartForArn = changePartForArn;
/**
* Create the logical id for resource to be used aws cdk
* @param content content to create hash value
* @returns created id
*/
function createId(content) {
return `TOV${(0, crypto_1.createHash)("sha256").update(content).digest("hex")}`;
}
exports.createId = createId;
/**
* Check if it matches the arn format.
* @param target the target of comparison
* @returns comparsion result
*/
function checkAwsArnPattern(target) {
// Set the regex for arn pattern
const arnPattern = new RegExp("^arn:([^:\n]*):([^:\n]*):([^:\n]*):([^:\n]*):(([^:\/\n]*)[:\/])?(.*)$");
// Check pattern
return arnPattern.test(target);
}
exports.checkAwsArnPattern = checkAwsArnPattern;
/**
* Delay process
* @param ms delay time
* @returns none
*/
async function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
exports.delay = delay;
/**
* Extract the data from arn
* @description https://docs.aws.amazon.com/ko_kr/general/latest/gr/aws-arns-and-namespaces.html
* @param arn arn for resource
* @param type output type [partition|service|region|accout|resource]
* @returns output data
*/
function extractDataFromArn(arn, type) {
// Split the arn
const split = arn.split(":");
const service = split[2];
// Return by output type
switch (type) {
case "partition":
return split[1];
case "service":
return split[2];
case "region":
return split[3];
case "account":
return split[4];
case "resource":
if (service === "cognito-idp" || service === "dynamodb") {
const temp = split[5].split("/");
return temp[1];
}
else if (service === "iam") {
const temp = split[5].split("/");
return temp.length > 1 ? temp[temp.length - 1] : split[5];
}
else if (service === "lambda") {
return split[6];
}
else {
return split[5];
}
case "qualifier":
if (service === "lambda") {
return split[7] !== undefined ? split[7] : "";
}
else {
return "";
}
default:
return "";
}
}
exports.extractDataFromArn = extractDataFromArn;
/**
* Extract a list of tag based on input data
* @param tags content of tags
* @returns a list of tag
*/
function extractTags(tags) {
// Check the input parameter type
const type = Object.prototype.toString.call(tags);
//
if (type === "Object") {
return Object.entries(tags).map((elem) => { return { key: elem.key, value: elem.value }; });
}
else if (type === "Array") {
return tags.map((elem) => {
return {
key: elem.Key !== undefined ? elem.Key : elem.key,
vallue: elem.Value !== undefined ? elem.Value : elem.value
};
});
}
else {
return [];
}
}
exports.extractTags = extractTags;
/**
* Initial setting
* @param envPath environment file path
*/
function initialSetting(envPath) {
// Load a configuration data
const env = loadJsonFile(envPath);
// Set the environment various
process.env.ASSUME_ROLE_ARN = env.ASSUME_ROLE_ARN;
process.env.ORIGIN_ACCOUNT = env.ORIGIN_ACCOUNT;
process.env.ORIGIN_REGION = env.ORIGIN_REGION;
process.env.TARGET_ACCOUNT = env.TARGET_ACCOUNT;
process.env.TARGET_REGION = env.TARGET_REGION;
// Catch error
if (!process.env.ORIGIN_ACCOUNT || !process.env.ORIGIN_REGION || !process.env.TARGET_ACCOUNT || !process.env.TARGET_REGION) {
(0, response_1.catchError)(response_1.CODE.ERROR.COMMON.INVALIED_ENV, true);
}
}
exports.initialSetting = initialSetting;
/**
* Load a json data (configuration)
* @param filePath file path
* @returns loaded data
*/
function loadJsonFile(filePath) {
try {
// Read a file ata
const data = (0, fs_1.readFileSync)(filePath).toString();
// Transform to json and return data
return JSON.parse(data);
}
catch (err) {
// Print error message
if (typeof err === "string" || err instanceof Error) {
console.error(`[ERROR] ${err}`);
}
// Exit
process.exit(1);
}
}
exports.loadJsonFile = loadJsonFile;
/**
* Stream to string
* @param steam readable stream
* @returns converted string
*/
async function streamToBuffer(steam) {
return new Promise((resolve, reject) => {
const chunks = [];
steam.on("data", chunk => chunks.push(chunk));
steam.on("error", err => reject(err));
steam.on("end", () => resolve(Buffer.concat(chunks)));
});
}
exports.streamToBuffer = streamToBuffer;
/**
* Set a principal content in policy
* @param value principal content
* @returns changed content
*/
function _setPrincipal(value) {
// Set a default pattern for account number
const accountNumberPattern = new RegExp("^[0-9]{12}");
// Check a value format (if it match a format for aws arn)
if (checkAwsArnPattern(value)) {
// Extract an account number and service type from arn
const account = extractDataFromArn(value, "account");
// Change an account number in arn
if (account === process.env.ORIGIN_ACCOUNT) {
return changePartForArn(value, "account", process.env.TARGET_ACCOUNT);
}
else {
return value;
}
}
else if (accountNumberPattern.test(value)) { // if it match a format for aws account number
if (value === process.env.ORIGIN_ACCOUNT) {
return process.env.TARGET_ACCOUNT;
}
else {
return value;
}
}
else {
return value;
}
}
/**
* Set a principal content
* @param principal principal content
* @returns changed content
*/
function setPrincipal(principal) {
try {
const result = {};
// Process
for (const key of Object.keys(principal)) {
// Extract a value by key
const value = principal[key];
// Anaysis a principal
if (key === "AWS" || key === "Faderated") {
// If value type is array
if (Object.prototype.toString.call(value) === "Array") {
result[key] = value.map((elem) => _setPrincipal(elem));
}
else { // value type is string
result[key] = _setPrincipal(value);
}
}
else { // "CanonicalUser" or "Service"
// If value type is array
if (Object.prototype.toString.call(value) === "Array") {
result[key] = value.map((elem) => elem);
}
else { // value type is string
result[key] = value;
}
}
}
// Return
return result;
}
catch (err) {
console.error(`[ERROR] Failed to set the principals in policy\n-> ${err}`);
process.exit(1);
}
}
exports.setPrincipal = setPrincipal;