From 0a11a0c5e8aa703f4f985c77b326523879fb4c8d Mon Sep 17 00:00:00 2001 From: Denis Yuen Date: Tue, 20 May 2025 16:48:56 -0400 Subject: [PATCH 1/5] test with node 22 --- checkUrlExists/template.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkUrlExists/template.yaml b/checkUrlExists/template.yaml index cf57d63..b4c485f 100644 --- a/checkUrlExists/template.yaml +++ b/checkUrlExists/template.yaml @@ -16,7 +16,7 @@ Resources: Properties: CodeUri: lambda/ Handler: index.lambdaHandler - Runtime: nodejs18.x + Runtime: nodejs22.x Events: Lambda: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api From db7d7186e528ea2a05e9cdd24f3101a8746c780e Mon Sep 17 00:00:00 2001 From: Denis Yuen Date: Fri, 23 May 2025 11:25:32 -0400 Subject: [PATCH 2/5] remove cloudfront edge lambda --- edge-lambda-for-s3/README.md | 1 - edge-lambda-for-s3/deployment/index.js | 123 ------------------ .../edge-lambda-for-s3-404s.yaml | 15 --- 3 files changed, 139 deletions(-) delete mode 100644 edge-lambda-for-s3/README.md delete mode 100644 edge-lambda-for-s3/deployment/index.js delete mode 100644 edge-lambda-for-s3/edge-lambda-for-s3-404s.yaml diff --git a/edge-lambda-for-s3/README.md b/edge-lambda-for-s3/README.md deleted file mode 100644 index 5744f86..0000000 --- a/edge-lambda-for-s3/README.md +++ /dev/null @@ -1 +0,0 @@ -This lambda handles 404 responses from an AWS CloudFront distribution of ui2 diff --git a/edge-lambda-for-s3/deployment/index.js b/edge-lambda-for-s3/deployment/index.js deleted file mode 100644 index aa7c023..0000000 --- a/edge-lambda-for-s3/deployment/index.js +++ /dev/null @@ -1,123 +0,0 @@ -"use strict"; - -const http = require("https"); - -const indexPage = "index.html"; - -exports.handler = async (event, context, callback) => { - const cf = event.Records[0].cf; - const request = cf.request; - const response = cf.response; - const statusCode = response.status; - - // Only replace 403 and 404 requests typically received - // when loading a page for a SPA that uses client-side routing - const doReplace = - request.method === "GET" && (statusCode == "403" || statusCode == "404"); - - const result = doReplace - ? await generateResponseAndLog(cf, request, indexPage) - : response; - - if (response.headers["via"]) { - result.headers["via"] = response.headers["via"]; - } - if (response.headers["transfer-encoding"]) { - result.headers["transfer-encoding"] = response.headers["transfer-encoding"]; - } - - callback(null, result); -}; - -async function generateResponseAndLog(cf, request, indexPage) { - const domain = cf.config.distributionDomainName; - const indexPath = `/${indexPage}`; - - const response = await generateResponse(domain, indexPath); - - return response; -} - -async function generateResponse(domain, path) { - try { - // Load HTML index from the CloudFront cache - const s3Response = await httpGet({ hostname: domain, path: path }); - - const headers = s3Response.headers; - - return { - status: "200", - headers: wrapAndFilterHeaders(headers), - body: s3Response.body, - }; - } catch (error) { - return { - status: "500", - headers: { - "content-type": [{ value: "text/plain" }], - }, - body: "An error occurred loading the page", - }; - } -} - -function httpGet(params) { - return new Promise((resolve, reject) => { - http - .get(params, (resp) => { - console.log( - `Fetching ${params.hostname}${params.path}, status code : ${resp.statusCode}` - ); - let result = { - headers: resp.headers, - body: "", - }; - resp.on("data", (chunk) => { - result.body += chunk; - }); - resp.on("end", () => { - resolve(result); - }); - }) - .on("error", (err) => { - console.log( - `Couldn't fetch ${params.hostname}${params.path} : ${err.message}` - ); - reject(err, null); - }); - }); -} - -// Cloudfront requires header values to be wrapped in an array -function wrapAndFilterHeaders(headers) { - const allowedHeaders = [ - "content-type", - "content-length", - "last-modified", - "date", - "etag", - ]; - - const responseHeaders = {}; - - if (!headers) { - return responseHeaders; - } - - for (var propName in headers) { - // only include allowed headers - if (allowedHeaders.includes(propName.toLowerCase())) { - var header = headers[propName]; - - if (Array.isArray(header)) { - // assume already 'wrapped' format - responseHeaders[propName] = header; - } else { - // fix to required format - responseHeaders[propName] = [{ value: header }]; - } - } - } - - return responseHeaders; -} diff --git a/edge-lambda-for-s3/edge-lambda-for-s3-404s.yaml b/edge-lambda-for-s3/edge-lambda-for-s3-404s.yaml deleted file mode 100644 index bda94e5..0000000 --- a/edge-lambda-for-s3/edge-lambda-for-s3-404s.yaml +++ /dev/null @@ -1,15 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: 'Supports deployment of Dockstore via CloudFront, processing 404s' -Resources: - edgelambdafors3404s: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs10.x - CodeUri: . - Description: 'Supports deployment of Dockstore via CloudFront, processing 404s' - MemorySize: 128 - Timeout: 3 - Role: >- - arn:aws:iam::312767926603:role/service-role/edge-lambda-for-s3-404s-role-t2r9lwiv From 07dc7782b980becfe3a7e97b0a66e5a8a228af9d Mon Sep 17 00:00:00 2001 From: Denis Yuen Date: Fri, 23 May 2025 11:25:50 -0400 Subject: [PATCH 3/5] remove poc lambda for cloudwatch to slack --- webhook-testing/README.md | 1 - webhook-testing/deployment/index.js | 179 ------------------ .../deployment/output-template.yaml | 37 ---- webhook-testing/deployment/package.json | 8 - webhook-testing/deployment/template.yaml | 37 ---- webhook-testing/webhook-testing.yaml | 34 ---- 6 files changed, 296 deletions(-) delete mode 100644 webhook-testing/README.md delete mode 100644 webhook-testing/deployment/index.js delete mode 100644 webhook-testing/deployment/output-template.yaml delete mode 100644 webhook-testing/deployment/package.json delete mode 100644 webhook-testing/deployment/template.yaml delete mode 100644 webhook-testing/webhook-testing.yaml diff --git a/webhook-testing/README.md b/webhook-testing/README.md deleted file mode 100644 index 6eb5504..0000000 --- a/webhook-testing/README.md +++ /dev/null @@ -1 +0,0 @@ -This lambda is a poc for relaying GitHub app webhooks into Slack diff --git a/webhook-testing/deployment/index.js b/webhook-testing/deployment/index.js deleted file mode 100644 index 2071fa7..0000000 --- a/webhook-testing/deployment/index.js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; - -/** - * Follow these steps to configure the webhook in Slack: - * - * 1. Navigate to https://.slack.com/services/new - * - * 2. Search for and select "Incoming WebHooks". - * - * 3. Choose the default channel where messages will be sent and click "Add Incoming WebHooks Integration". - * - * 4. Copy the webhook URL from the setup instructions and use it in the next section. - * - * - * To encrypt your secrets use the following steps: - * - * 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - * - * 2. Click the "Enable Encryption Helpers" checkbox - * - * 3. Paste into the kmsEncryptedHookUrl environment variable and click encrypt - * - * Note: You must exclude the protocol from the URL (e.g. "hooks.slack.com/services/abc123"). - * - * 4. Give your function's role permission for the kms:Decrypt action. - * Example: - -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "Stmt1443036478000", - "Effect": "Allow", - "Action": [ - "kms:Decrypt" - ], - "Resource": [ - "" - ] - } - ] -} - - */ - -const AWS = require("aws-sdk"); -const url = require("url"); -const https = require("https"); -const crypto = require("crypto"); - -// Verification function to check if it is actually GitHub who is POSTing here -const verifyGitHub = (req) => { - console.log(req); - if (!req.headers["User-Agent"].includes("GitHub-Hookshot")) { - return false; - } - // Compare their hmac signature to our hmac signature - // (hmac = hash-based message authentication code) - const theirSignature = req.headers["X-Hub-Signature"]; - const payload = req.body; - console.log(payload); - const secret = process.env.SECRET_TOKEN; - const ourSignature = `sha1=${crypto - .createHmac("sha1", secret) - .update(payload) - .digest("hex")}`; - return crypto.timingSafeEqual( - Buffer.from(theirSignature), - Buffer.from(ourSignature) - ); -}; - -// The base-64 encoded, encrypted key (CiphertextBlob) stored in the kmsEncryptedHookUrl environment variable -const kmsEncryptedHookUrl = process.env.kmsEncryptedHookUrl; -// The Slack channel to send a message to stored in the slackChannel environment variable -const slackChannel = process.env.slackChannel; -let hookUrl; - -function postMessage(message, callback) { - const body = JSON.stringify(message); - const options = url.parse(hookUrl); - options.method = "POST"; - options.headers = { - "Content-Type": "application/json", - "Content-Length": Buffer.byteLength(body), - }; - - const postReq = https.request(options, (res) => { - const chunks = []; - res.setEncoding("utf8"); - res.on("data", (chunk) => chunks.push(chunk)); - res.on("end", () => { - if (callback) { - callback({ - body: chunks.join(""), - statusCode: res.statusCode, - statusMessage: res.statusMessage, - }); - } - }); - return res; - }); - - postReq.write(body); - postReq.end(); -} - -function processEvent(event, callback) { - if (!verifyGitHub(event)) { - callback(null, { - statusCode: 403, - body: "something is wrong, github secret does not match", - }); - return; - } - - const body = JSON.parse(event.body); - - const repository = body.repository.full_name; - const refType = body.ref_type; - const ref = body.ref; - - if (typeof ref === "undefined") { - callback(null, { - statusCode: 204, - body: "this is not an event type we handle", - }); - return; - } - - const slackMessage = { - channel: slackChannel, - text: `${repository} created a new ${refType} called ${ref}`, - }; - - postMessage(slackMessage, (response) => { - if (response.statusCode < 400) { - console.info("Message posted successfully"); - callback(null); - } else if (response.statusCode < 500) { - console.error( - `Error posting message to Slack API: ${response.statusCode} - ${response.statusMessage}` - ); - callback(null); // Don't retry because the error is due to a problem with the request - } else { - // Let Lambda retry - callback( - `Server error when processing message: ${response.statusCode} - ${response.statusMessage}` - ); - } - }); - - callback(null, { statusCode: 200, body: "results" }); -} - -exports.handler = (event, context, callback) => { - if (hookUrl) { - // Container reuse, simply process the event with the key in memory - processEvent(event, callback); - } else if ( - kmsEncryptedHookUrl && - kmsEncryptedHookUrl !== "" - ) { - const encryptedBuf = new Buffer(kmsEncryptedHookUrl, "base64"); - const cipherText = { CiphertextBlob: encryptedBuf }; - - const kms = new AWS.KMS(); - kms.decrypt(cipherText, (err, data) => { - if (err) { - console.log("Decrypt error:", err); - return callback(err); - } - hookUrl = `https://${data.Plaintext.toString("ascii")}`; - processEvent(event, callback); - }); - } else { - callback("Hook URL has not been set."); - } -}; diff --git a/webhook-testing/deployment/output-template.yaml b/webhook-testing/deployment/output-template.yaml deleted file mode 100644 index 7c9313f..0000000 --- a/webhook-testing/deployment/output-template.yaml +++ /dev/null @@ -1,37 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Description: An Amazon SNS trigger that sends CloudWatch alarm notifications to Slack. -Parameters: - KeyIdParameter: - Type: String - kmsEncryptedHookUrlParameter: - Type: String - slackChannelParameter: - Type: String -Resources: - SNSTopic1: - Type: AWS::SNS::Topic - cloudwatchalarmtoslack: - Properties: - CodeUri: s3://aws-sar-publishing/376e2767f8cf796f8f7a36e41cb5ae7e - Description: An Amazon SNS trigger that sends CloudWatch alarm notifications - to Slack. - Environment: - Variables: - kmsEncryptedHookUrl: kmsEncryptedHookUrlParameter - slackChannel: slackChannelParameter - Events: - SNS1: - Properties: - Topic: - Ref: SNSTopic1 - Type: SNS - Handler: index.handler - MemorySize: 128 - Policies: - - KMSDecryptPolicy: - KeyId: - Ref: KeyIdParameter - Runtime: nodejs8.10 - Timeout: 3 - Type: AWS::Serverless::Function -Transform: AWS::Serverless-2016-10-31 diff --git a/webhook-testing/deployment/package.json b/webhook-testing/deployment/package.json deleted file mode 100644 index 02d6a7d..0000000 --- a/webhook-testing/deployment/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/webhook-testing/deployment/template.yaml b/webhook-testing/deployment/template.yaml deleted file mode 100644 index dd316e1..0000000 --- a/webhook-testing/deployment/template.yaml +++ /dev/null @@ -1,37 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon SNS trigger that sends CloudWatch alarm notifications to Slack. -Parameters: - KeyIdParameter: - Type: String - slackChannelParameter: - Type: String - kmsEncryptedHookUrlParameter: - Type: String -Resources: - cloudwatchalarmtoslack: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon SNS trigger that sends CloudWatch alarm notifications to - Slack. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter - Events: - SNS1: - Type: SNS - Properties: - Topic: - Ref: SNSTopic1 - Environment: - Variables: - slackChannel: slackChannelParameter - kmsEncryptedHookUrl: kmsEncryptedHookUrlParameter - SNSTopic1: - Type: 'AWS::SNS::Topic' diff --git a/webhook-testing/webhook-testing.yaml b/webhook-testing/webhook-testing.yaml deleted file mode 100644 index 8b91364..0000000 --- a/webhook-testing/webhook-testing.yaml +++ /dev/null @@ -1,34 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An undefined trigger that sends GitHub App notifications to Slack. -Resources: - webhooktesting: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: An undefined trigger that sends GitHub App notifications to Slack. - MemorySize: 128 - Timeout: 3 - Role: >- - arn:aws:iam::312767926603:role/serverlessrepo-cloudwatch-cloudwatchalarmtoslackRo-1MWUBBKPY1IYG - Events: - Api1: - Type: Api - Properties: - Path: /helloworld - Method: ANY - Api2: - Type: Api - Properties: - Path: /foobar - Method: ANY - Environment: - Variables: - SECRET_TOKEN: - kmsEncryptedHookUrl: >- - AQICAHicSBs6aaXy8Lb+IjLRg6DV8EoauPSVsU5VmBT+1qT9lQHKPbWX5JBpfWlEh2zlYjcHAAAApzCBpAYJKoZIhvcNAQcGoIGWMIGTAgEAMIGNBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDNtuoG7RbaBP332pFwIBEIBgqMNMDsjI3Thu1pVmjMVFNZ8fo81XwU2mDyN2VxOayuJDHpdnItbj2KIFYn4AXLSF/JSjikYjik2QX79+Pm1XFo01zN46+vWOav989cJFh0MMQsRku9+aO3ksinrz5VYB - slackChannel: dockstore-testing - KmsKeyArn: >- - arn:aws:kms:us-east-1:312767926603:key/0a1d7811-1366-448c-a31d-ce61effcbf92 From b4a8fafdbfcc3ad5b792bcd83e92da53e0e73439 Mon Sep 17 00:00:00 2001 From: Denis Yuen Date: Fri, 23 May 2025 11:47:20 -0400 Subject: [PATCH 4/5] remove testing --- .circleci/config.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0539e3a..8d46d24 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,12 +29,6 @@ jobs: - create_zip_upload_to_s3: lambdaFolder: "cloud-watch-to-slack-testing/deployment" s3BucketFolder: "cloudWatchToSlackTesting" - - create_zip_upload_to_s3: - lambdaFolder: "edge-lambda-for-s3/deployment" - s3BucketFolder: "edgeLambdaForS3404s" - - create_zip_upload_to_s3: - lambdaFolder: "webhook-testing/deployment" - s3BucketFolder: "webhookTesting" # Make this a separate job because AWS SAM needs to run in # the container specified in the template.yml From bfb164f2f73450202839fa9cfeefc3a76757ddc8 Mon Sep 17 00:00:00 2001 From: Denis Yuen Date: Fri, 23 May 2025 15:34:25 -0400 Subject: [PATCH 5/5] hookup test for checkurl --- .github/workflows/maven.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 7688806..460aa33 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -49,5 +49,9 @@ jobs: python -m pytest tests/unit -v pylint cwl_pack_function pylint tests - - + - name: Test checkurl with SAM CLI build and invoke + working-directory: ./checkUrlExists + run: | + sam build --use-container + sam local invoke LambdaFunction -e events/event.json &> output.txt + grep "statusCode\": 200" output.txt