Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync(integration): sync aws-lambda-okta-webhook from @indentapis/integrations #1

Merged
merged 1 commit into from Jun 8, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md

This file was deleted.

27 changes: 27 additions & 0 deletions main.tf
@@ -0,0 +1,27 @@
terraform {
backend {
encrypt = true
artifactBucket = "indent-artifacts-us-west-2"
region = "us-west-2"
key = "indent/terraform.tfstate"
}
}

module "okta" {
source = "git::https://github.com/indentapis/integrations//terraform/modules/indent_runtime_aws_lambda"
name = "idt-okta-webhook"
indent_webhook_secret = "var.indent_webhook_secret"
artifact {
artifactBucket = "indent-artifacts-us-west-2"
functionKey = "webhooks/aws/lambda/okta-v0.0.1-canary-function.zip"
depsKey = "webhooks/aws/lambda/okta-v0.0.1-canary-deps.zip"
}
env {
OKTA_DOMAIN = var.okta_domain
OKTA_TOKEN = var.okta_token
OKTA_SLACK_APP_ID = var.okta_slack_app_id
OKTA_CLIENT_ID = var.okta_client_id
OKTA_PRIVATE_KEY = var.okta_private_key
}
}

5 changes: 5 additions & 0 deletions outputs.tf
@@ -0,0 +1,5 @@
output "idt-okta-webhook-url" {
value = "module.idt-okta-webhook-url.function_url"
description = "The URL of the deployed Lambda"
}

31 changes: 31 additions & 0 deletions package.json
@@ -0,0 +1,31 @@
{
"name": "@indent/template-example-webhook",
"version": "0.0.0",
"description": "A Node.js starter for Terraform on AWS with Indent and example integration.",
"main": "index.js",
"private": true,
"scripts": {
"build:src": "tsc",
"build:deps": "npm install --production && ./scripts/build-layers.sh",
"build:function": "npm install && npm run build:src && ./scripts/build-function.sh",
"build": "npm run build:deps && npm run build:function"
},
"author": "Indent Inc <open@indent.com>",
"license": "Apache-2.0",
"repository": {
"type": "git"
},
"devDependencies": {
"@types/aws-lambda": "^8.10.39",
"@types/node": "^13.9.8",
"@types/node-fetch": "^2.5.5",
"ts-loader": "^6.2.2"
},
"dependencies": {
"@indent/integration-okta": "canary",
"@indent/runtime-aws-lambda": "canary",
"@indent/webhook": "latest",
"typescript": "^3.8.3",
"@indent/types": "latest"
}
}
11 changes: 11 additions & 0 deletions scripts/build-function.sh
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -x
set -e

ROOT_DIR="$(pwd)"

OUTPUT_DIR="$(pwd)/dist"

cd $ROOT_DIR/lib

zip -q -r $OUTPUT_DIR/function.zip .
17 changes: 17 additions & 0 deletions scripts/build-layers.sh
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -x
set -e

ROOT_DIR="$(pwd)"

OUTPUT_DIR="$(pwd)/dist"

LAYER_DIR=$OUTPUT_DIR/layers/nodejs

mkdir -p $LAYER_DIR

cp -LR node_modules $LAYER_DIR

cd $OUTPUT_DIR/layers

zip -q -r layers.zip nodejs
30 changes: 30 additions & 0 deletions scripts/catalog.ts
@@ -0,0 +1,30 @@
import { CatalogueItem } from './utils'

export const catalogue: CatalogueItem[] = [
{
name: 'pagerduty',
environmentVariables: ['PAGERDUTY_KEY'],
integrations: ['PagerdutyDecisionIntegration'],
source:
'git::https://github.com/indentapis/integrations//terraform/modules/indent_runtime_aws_lambda',
artifactBucket: 'indent-artifacts-us-west-2',
functionKey: 'webhooks/aws/lambda/pagerduty-v0.0.1-canary-function.zip',
depsKey: 'webhooks/aws/lambda/pagerduty-v0.0.1-canary-deps.zip',
},
{
name: 'okta',
integrations: ['OktaGroupIntegration', 'OktaUserIntegration'],
environmentVariables: [
'OKTA_DOMAIN',
'OKTA_TOKEN',
'OKTA_SLACK_APP_ID',
'OKTA_CLIENT_ID',
'OKTA_PRIVATE_KEY',
],
source:
'git::https://github.com/indentapis/integrations//terraform/modules/indent_runtime_aws_lambda',
artifactBucket: 'indent-artifacts-us-west-2',
functionKey: 'webhooks/aws/lambda/okta-v0.0.1-canary-function.zip',
depsKey: 'webhooks/aws/lambda/okta-v0.0.1-canary-deps.zip',
},
]
46 changes: 46 additions & 0 deletions scripts/download.sh
@@ -0,0 +1,46 @@
#!/bin/bash -e

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kodjoz we might want to uninclude this


tmpLoc="$(mktemp)"

# Download file and ensure that checksum matches.
function main() {
trap cleanup EXIT
local url="${1}"
local dst="${2}"
local checksum="${3}"

if [[ -z ${url} || -z ${dst} ]]; then
echo "URL and Destination must be provided like: ${0} <url> <dst> [checksum]"
exit 3
elif [[ -f ${dst} ]]; then
# check if already have copy
check ${checksum} ${dst} && exit 0
fi

echo "Downloading ${url}..."
curl -L -o ${tmpLoc} "${url}"

echo "Checking checksum of ${dst}"
check ${checksum} ${tmpLoc} || (echo "Failed checksum!" && exit 2)
echo "Checksum passed!"

mkdir -p $(dirname ${dst})
mv ${tmpLoc} ${dst}
}

function check() {
local checksum="${1}"
local target="${2}"

if [[ -z ${checksum} ]]; then
return false
fi

echo "${checksum} ${target}" | sha256sum --check --status
}

function cleanup() {
rm -f ${tmpLoc}
}

main "$@"
120 changes: 120 additions & 0 deletions scripts/index.ts
@@ -0,0 +1,120 @@
import { arg, TerraformGenerator } from 'terraform-generator'
import { catalogue } from './catalog'
import { CatalogueItem } from './utils'

const WEBHOOK_DIR =
process.env.WEBHOOK_DIR || 'tmp/examples/aws-lambda-example-webhook'

const generateTfVars = (environmentVariables: string[]) => {
const tfg = new TerraformGenerator()

tfg.variable('aws_region', {
type: 'string',
default: '',
})

tfg.variable('aws_profile', {
type: 'string',
default: '',
})

tfg.variable('indent_webhook_secret', {
type: 'string',
sensitive: true,
})

// please help - map didn't work
for (let v = 0; v < environmentVariables.length; v += 1) {
tfg.variable(`${environmentVariables[v]}`, {
type: 'string',
default: '',
sensitive: true,
})
}

tfg.write({ dir: WEBHOOK_DIR, format: true, tfFilename: 'variables' })
}

const generateTfOutput = (name: string) => {
const tfg = new TerraformGenerator()

tfg.output(`idt-${name}-webhook-url`, {
value: `module.idt-${name}-webhook-url.function_url`,
description: 'The URL of the deployed Lambda',
})

tfg.write({ dir: WEBHOOK_DIR, format: true, tfFilename: 'outputs' })
}

const generateTfMain = ({
name,
source,
artifactBucket,
functionKey,
depsKey,
envVars,
}: {
name: string
source: string
artifactBucket: string
functionKey: string
depsKey: string
envVars: string[]
}) => {
const tfg = new TerraformGenerator({
backend: {
encrypt: true,
artifactBucket,
region: 'us-west-2',
key: 'indent/terraform.tfstate',
},
})

let mappedVars = {}

envVars.forEach((e: string) => {
mappedVars[e] = arg(`var.${e.toLowerCase()}`)
})

tfg.module(name, {
source,
name: `idt-${name}-webhook`,
indent_webhook_secret: 'var.indent_webhook_secret',
artifact: {
artifactBucket,
functionKey,
depsKey,
},
env: { ...mappedVars },
})

tfg.write({ dir: WEBHOOK_DIR, format: true, tfFilename: 'main' })
}

const generateFiles = (data: CatalogueItem[]) => {
const integration = data.filter((d: CatalogueItem) => {
return WEBHOOK_DIR.toLowerCase().includes(d.name.toLowerCase())
})

const {
name,
source,
environmentVariables,
artifactBucket,
functionKey,
depsKey,
} = integration[0]

generateTfMain({
name,
source,
envVars: environmentVariables,
artifactBucket,
functionKey,
depsKey,
})
generateTfOutput(name)
generateTfVars(environmentVariables)
}

generateFiles(catalogue)
22 changes: 22 additions & 0 deletions scripts/package.json
@@ -0,0 +1,22 @@
{
"name": "@indent/utils",
"version": "0.0.1",
"description": "Scripts to automatically generate Indent example webhoks",
"main": "index.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "npx ts-node ./index.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"terraform-generator": "^5.2.0",
"ts-node": "^10.7.0",
"typescript": "^4.6.4",
"yarn": "^1.22.18"
},
"devDependencies": {
"@types/node": "^17.0.35"
}
}
17 changes: 17 additions & 0 deletions scripts/tsconfig.json
@@ -0,0 +1,17 @@
{
"exclude": ["node_modules"],
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"sourceMap": true,
"target": "esnext",
"outDir": "lib",
"resolveJsonModule": true
},
"include": ["./*"]
}
9 changes: 9 additions & 0 deletions scripts/utils.ts
@@ -0,0 +1,9 @@
export interface CatalogueItem {
name: string
integrations: string[]
environmentVariables: string[]
source: string
artifactBucket: string
functionKey: string
depsKey: string
}
40 changes: 40 additions & 0 deletions scripts/writeIntegration.ts
@@ -0,0 +1,40 @@
import { readFile, writeFile } from 'fs/promises'
import { join } from 'path'
import { catalogue } from './catalog'

const currentItem = catalogue.filter((item) =>
process.env.WEBHOOK_DIR.toLowerCase().includes(item.name)
)

const path = join(process.env.WEBHOOK_DIR, 'src', 'index.ts')

const { integrations, name } = currentItem[0]

const writeIntegration = async ({
functionNames,
integrationName,
path,
}: {
functionNames: string[]
integrationName: string
path: string
}) => {
try {
const data = await await readFile(path, 'utf8')
const newIntegration = data
.replace('ExampleIntegration', functionNames.join(', '))
.replace(
'@indent/integration-example',
`@indent/integration-${integrationName}`
)
.replace(
'[new ExampleIntegration()]',
`[${functionNames.map((i) => `new ${i}()`).join(', ')}]`
)
await writeFile(path, newIntegration, 'utf8')
} catch (err) {
console.log(err)
}
}

writeIntegration({ functionNames: integrations, integrationName: name, path })