Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 6 additions & 11 deletions .github/workflows/ci.yml → .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
name: CI

on: [push, pull_request]

name: Lint
on:
push:
branches: [master]
pull_request:
jobs:
build:
runs-on: 'ubuntu-latest'

runs-on: ['ubuntu-latest']
steps:

- uses: 'actions/checkout@v2'

- uses: 'actions/setup-python@v2'
with:
python-version: '3.8'

- name: yamlllint
run: |
pip install yamllint==1.35.1
yamllint module.yml && yamllint test/*.yml

- name: cfn-lint
run: |
pip install cfn-lint==1.20.1
cfn-lint -i W3002 -t module.yml && cfn-lint -i W3002 -t test/*.yml

- name: license
run: |
grep -q "LICENSE-2.0" module.yml
31 changes: 31 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Test
on:
push:
branches: [master]
pull_request:
permissions:
id-token: write
contents: read
concurrency:
group: test
cancel-in-progress: false
jobs:
build:
runs-on: ['ubuntu-latest']
steps:
- uses: 'actions/checkout@v2'
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: 'arn:aws:iam::068189904525:role/github-openid-connect'
aws-region: 'eu-west-1'
role-duration-seconds: 7200 # 2 hours
- uses: actions/setup-node@v4
with:
node-version: '18.x'
- name: test
run: |
npm ci
cd test
npm ci
CFN_PACKAGE_BUCKET_NAME=cf-templates-1a2zmgbg9ut4o-eu-west-1 npm test
cd -
95 changes: 65 additions & 30 deletions lambda-src/dashboard.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
const AWS = require('aws-sdk');
const cloudwatch = new AWS.CloudWatch({apiVersion: '2010-08-01'});
const response = require('cfn-response');
const { CloudWatchClient, PutDashboardCommand, DeleteDashboardsCommand } = require('@aws-sdk/client-cloudwatch');
const cloudwatch = new CloudWatchClient({apiVersion: '2010-08-01'});

async function cfnCustomResourceSuccess(event, physicalResourceId, optionalData) {
const response = await fetch(event.ResponseURL, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
Status: 'SUCCESS',
PhysicalResourceId: physicalResourceId,
StackId: event.StackId,
RequestId: event.RequestId,
LogicalResourceId: event.LogicalResourceId,
...(optionalData !== undefined && {Data: optionalData})
})
});
if (response.status !== 200) {
console.log('response status', response.status);
console.log('response', await response.text());
throw new Error('unexpected status code');
}
}

async function cfnCustomResourceFailed(event, physicalResourceId, optionalReason) {
const response = await fetch(event.ResponseURL, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
Status: 'FAILED',
...(optionalReason !== undefined && {Reason: optionalReason}),
PhysicalResourceId: (physicalResourceId === undefined || physicalResourceId === null) ? event.LogicalResourceId : physicalResourceId, // physicalResourceId might not be available if create fails
StackId: event.StackId,
RequestId: event.RequestId,
LogicalResourceId: event.LogicalResourceId
})
});
if (response.status !== 200) {
console.log('response status', response.status);
console.log('response', await response.text());
throw new Error('unexpected status code');
}
}

function generateDashboard(event) {
let widgets = [];
Expand Down Expand Up @@ -124,33 +167,25 @@ function generateDashboard(event) {
return dashboard;
}

exports.handler = (event, context, cb) => {
exports.handler = async (event, context, cb) => {
console.log(`Executing function with event: ${JSON.stringify(event)}`);
const error = (err) => {
console.log('Error', err);
response.send(event, context, response.FAILED);
};
if (event.RequestType === 'Delete') {
cloudwatch.deleteDashboards({DashboardNames: [event.ResourceProperties.DashboardName]}, function(err) {
if (err) {
error(err);
} else {
response.send(event, context, response.SUCCESS, {}, event.ResourceProperties.DashboardName);
}
});
} else if (event.RequestType === 'Create' || event.RequestType === 'Update') {
cloudwatch.putDashboard({
DashboardName: event.ResourceProperties.DashboardName,
DashboardBody: JSON.stringify(generateDashboard(event))
}, function(err) {
if (err) {
error(err);
} else {
console.log(`Created/Updated dashboard ${event.ResourceProperties.DashboardName}.`);
response.send(event, context, response.SUCCESS, {}, event.ResourceProperties.DashboardName);
}
});
} else {
error(new Error(`unsupported request type: ${event.RequestType}`));
try {
if (event.RequestType === 'Delete') {
await cloudwatch.send(new DeleteDashboardsCommand({DashboardNames: [event.ResourceProperties.DashboardName]}));
console.log(`Deleted dashboard ${event.ResourceProperties.DashboardName}.`);
await cfnCustomResourceSuccess(event, event.ResourceProperties.DashboardName);
} else if (event.RequestType === 'Create' || event.RequestType === 'Update') {
await cloudwatch.send(new PutDashboardCommand({
DashboardName: event.ResourceProperties.DashboardName,
DashboardBody: JSON.stringify(generateDashboard(event))
}));
console.log(`Created/Updated dashboard ${event.ResourceProperties.DashboardName}.`);
await cfnCustomResourceSuccess(event, event.ResourceProperties.DashboardName);
} else {
error(new Error(`unsupported request type: ${event.RequestType}`));
}
} catch(e) {
console.log('Error', e);
await cfnCustomResourceFailed(event, event.ResourceProperties.DashboardName, e);
}
};
11 changes: 0 additions & 11 deletions lambda-src/node_modules/cfn-response/README.md

This file was deleted.

54 changes: 0 additions & 54 deletions lambda-src/node_modules/cfn-response/index.js

This file was deleted.

7 changes: 0 additions & 7 deletions lambda-src/node_modules/cfn-response/license.txt

This file was deleted.

58 changes: 0 additions & 58 deletions lambda-src/node_modules/cfn-response/package.json

This file was deleted.

11 changes: 3 additions & 8 deletions lambda-src/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions lambda-src/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
{
"private": true,
"dependencies": {
"cfn-response": "1.0.1"
}
"private": true
}
2 changes: 1 addition & 1 deletion module.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Parameters:
DashboardName:
Description: 'The name for the dashboard'
Type: String
AllowedPattern: '^([A-Za-z0-9-_]){1,255}$'
AllowedPattern: '^[A-Za-z0-9-_]{1,255}$'
ConstraintDescription: 'Only A-Z, a-z, 0-9, -, and _ are supported. Max 255 characters.'
AlbModule:
Description: 'Optional stack name of the alb module.'
Expand Down
Loading
Loading