diff --git a/README.md b/README.md index b588372..97f65b7 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ npm install serverless-plugin-resource-tagging ``` ### serverless.yml -``` +```yml provider: name: XXX stackTags: @@ -34,3 +34,22 @@ AWS::ApiGateway::Stage AWS::CloudFront::Distribution AWS::Logs::LogGroup ``` + +Optionally, you can add other AWS resource types for tagging with +```yml +custom: + resourceTagging: + types: + - AWS::SNS::Topic + - AWS::IAM::Role +``` + +If you only want specific resources you define, add the `exclusive` flag +```yml +custom: + resourceTagging: + exclusive: true + types: + - AWS::SNS::Topic + - AWS::IAM::Role +``` diff --git a/index.js b/index.js index 6ade976..80b340c 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ 'use strict'; +const { get, uniq } = require('lodash'); const _ = require('underscore'); class ServerlessPlugin { @@ -33,7 +34,40 @@ class ServerlessPlugin { }; } + get log() { + const pluginId = 'resource-tagging-plugin'; + return { + info: (msg) => { + this.serverless.cli.log(`[${pluginId}] INFO ${msg}`); + }, + error: (msg) => { + this.serverless.cli.log(`[${pluginId}] ERROR ${msg}`); + }, + warn: (msg) => { + this.serverless.cli.log(`[${pluginId}] WARN ${msg}`); + }, + }; + } + + get pluginConfig() { + const { + types: userTypes = [], + exclusive = false, + } = get(this, 'serverless.service.custom.resourceTagging', {}); + + return { + types: exclusive + ? userTypes + : uniq([ + ...this.supportedTypes, + ...userTypes, + ]), + }; + } + _addTagsToResource() { + this.log.info(`config: ${JSON.stringify(this.pluginConfig, null, 2)}`); + var stackTags = []; var self = this; const template = this.serverless.service.provider.compiledCloudFormationTemplate; @@ -56,10 +90,18 @@ class ServerlessPlugin { }); } + const isValidProperties = props => { + return props && ( + Object.keys(props).length > 1 + || + !`${Object.keys(props)[0]}`.match(new RegExp('^!|Fn::', 'g')) + ); + }; + Object.keys(template.Resources).forEach(function (key) { var resourceType = template.Resources[key]['Type'] - if ((self.supportedTypes.indexOf(resourceType) !== -1) && Array.isArray(stackTags) && stackTags.length > 0) { - if (template.Resources[key]['Properties']) { + if ((self.pluginConfig.types.indexOf(resourceType) !== -1) && Array.isArray(stackTags) && stackTags.length > 0) { + if (isValidProperties(template.Resources[key]['Properties'])) { var tags = template.Resources[key]['Properties']['Tags'] if (tags) { template.Resources[key]['Properties']['Tags'] = tags.concat(stackTags.filter(obj => (self._getTagNames(tags).indexOf(obj["Key"]) === -1))) @@ -67,7 +109,7 @@ class ServerlessPlugin { template.Resources[key]['Properties']['Tags'] = stackTags } } else { - self.serverless.cli.log('Properties not available for ' + resourceType); + self.log.warn('Properties not available for ' + resourceType); } } @@ -76,10 +118,12 @@ class ServerlessPlugin { self.isApiGatewayStageAvailableInTemplate = true; } }); - self.serverless.cli.log('Updated AWS resource tags..'); + self.log.info('Updated AWS resource tags..'); } _addAPIGatewayStageTags() { + this.log.info(`config: ${JSON.stringify(this.pluginConfig, null, 2)}`); + var self = this; var stackName = this.provider.naming.getStackName(); if (!self.isApiGatewayStageAvailableInTemplate) { @@ -93,10 +137,10 @@ class ServerlessPlugin { }; promiseStack.push(self.provider.request('APIGateway', 'tagResource', apiStageParams)) }); - return Promise.all(promiseStack).then(resp => self.serverless.cli.log('Updated APIGateway resource tags..')); + return Promise.all(promiseStack).then(resp => self.log.info('Updated APIGateway resource tags..')); }); } else { - self.serverless.cli.log('APIGateway stage already available in serverless.yml. Tag update skipped.'); + self.log.info('APIGateway stage already available in serverless.yml. Tag update skipped.'); return null; } } diff --git a/package-lock.json b/package-lock.json index 2b79833..1178144 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,14 @@ { "name": "serverless-plugin-resource-tagging", - "version": "1.0.0", + "version": "1.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "user": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/user/-/user-0.0.0.tgz", diff --git a/package.json b/package.json index bee324a..044ae0c 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,8 @@ }, "homepage": "https://github.com/ilayanambi86/serverless-plugin-resource-tagging#readme", "dependencies": { - "user": "0.0.0", - "underscore": "^1.12.1" + "lodash": "^4.17.21", + "underscore": "^1.12.1", + "user": "0.0.0" } }