diff --git a/package.json b/package.json index c5bc504..ca4e270 100644 --- a/package.json +++ b/package.json @@ -39,9 +39,6 @@ "pinst": "^2.1.4", "prettier": "^2.2.1" }, - "peerDependencies": { - "serverless": "^2.4.0" - }, "engines": { "node": ">=8.10.0" }, diff --git a/src/index.js b/src/index.js index 3df1227..8605b10 100644 --- a/src/index.js +++ b/src/index.js @@ -296,6 +296,28 @@ class AlertsPlugin { } else { alertTopics[key] = topic; } + + const subscriptions = (notifications || []).reduce((memo, n) => { + const nameSuffix = n.name || ''; + const cfRef = `AwsAlerts${upperFirst(key)}${upperFirst(n.protocol)}${nameSuffix}Subscription`; + + if (memo[cfRef]) { + throw new Error('Subscription with the same protocol already exists! Use the name property to uniquely identify it'); + } + + return Object.assign(memo, { + [cfRef]: { + Type: 'AWS::SNS::Subscription', + Properties: { + TopicArn: topic, + Protocol: n.protocol, + Endpoint: n.endpoint, + }, + }, + }); + }, {}); + + this.addCfResources(subscriptions); } else { const cfRef = `AwsAlerts${ customAlarmName ? upperFirst(customAlarmName) : '' diff --git a/src/index.test.js b/src/index.test.js index 29d477a..3b68073 100644 --- a/src/index.test.js +++ b/src/index.test.js @@ -484,7 +484,7 @@ describe('#index', () => { }); }); - it('should create SNS topic with notificaitons', () => { + it('should create SNS topic with notifications', () => { const topicName = 'ok-topic'; const plugin = pluginFactory({ topics: { @@ -528,6 +528,93 @@ describe('#index', () => { }); }); + it('should create SNS subscription for existing topic', () => { + const plugin = pluginFactory({ + topics: { + ok: { + topic: { + Ref: 'AwsAlertsAlarm', + }, + notifications: [ + { + protocol: 'email', + endpoint: 'test@email.com', + }, + ], + }, + }, + }); + + const config = plugin.getConfig(); + const topics = plugin.compileAlertTopics(config); + + expect(topics).toEqual({ + ok: { + Ref: `AwsAlertsAlarm`, + }, + }); + + expect( + plugin.serverless.service.provider.compiledCloudFormationTemplate + .Resources + ).toEqual({ + AwsAlertsOkEmailSubscription: { + Type: 'AWS::SNS::Subscription', + Properties: { + TopicArn: { + Ref: 'AwsAlertsAlarm', + }, + Protocol: 'email', + Endpoint: 'test@email.com', + }, + }, + }); + }); + + it('should create SNS subscription for existing topic with a custom name suffix', () => { + const plugin = pluginFactory({ + topics: { + ok: { + topic: { + Ref: 'AwsAlertsAlarm', + }, + notifications: [ + { + name: 'Test', + protocol: 'email', + endpoint: 'test@email.com', + }, + ], + }, + }, + }); + + const config = plugin.getConfig(); + const topics = plugin.compileAlertTopics(config); + + expect(topics).toEqual({ + ok: { + Ref: `AwsAlertsAlarm`, + }, + }); + + expect( + plugin.serverless.service.provider.compiledCloudFormationTemplate + .Resources + ).toEqual({ + AwsAlertsOkEmailTestSubscription: { + Type: 'AWS::SNS::Subscription', + Properties: { + TopicArn: { + Ref: 'AwsAlertsAlarm', + }, + Protocol: 'email', + Endpoint: 'test@email.com', + }, + }, + }); + }); + it('should create SNS topic with nested definitions', () => { const plugin = pluginFactory({ topics: {