Skip to content
This repository has been archived by the owner on Aug 16, 2022. It is now read-only.

Invoke http::OP_HANDLE_REQUEST for events that look like HTTP requests #24

Merged
merged 25 commits into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3a011e2
Handle HTTP requests.
ewbankkit Apr 6, 2020
e287505
Merge branch 'master' into issue-18
ewbankkit Apr 7, 2020
0499d1e
Handle HTTP requests.
ewbankkit Apr 7, 2020
29f25e0
Dispatch ALB target group request.
ewbankkit Apr 8, 2020
fa34d97
Add API Gateway example.
ewbankkit Apr 8, 2020
027f710
Merge branch 'master' into issue-18
ewbankkit Apr 10, 2020
f7728e5
Add 'http' module for Lambda events that correspond to standard actor…
ewbankkit Apr 10, 2020
ffeb307
Add 'dispatch' module.
ewbankkit Apr 10, 2020
936c636
Add DispatcherError enum.
ewbankkit Apr 13, 2020
392751c
Use RawEventDispatcher.
ewbankkit Apr 13, 2020
0d5871f
Use HttpDispatcher.
ewbankkit Apr 13, 2020
1ba2398
Implement 'TryFrom', not 'TryInto'.
ewbankkit Apr 13, 2020
e5f2290
Dispatch ALB requests.
ewbankkit Apr 13, 2020
77daa66
Handle API Gateway proxy HTTP requests.
ewbankkit Apr 13, 2020
74ff0fb
Add Uppercase demo.
ewbankkit Apr 13, 2020
793bfc9
Merge branch 'master' into issue-18
ewbankkit Apr 15, 2020
3cf64fe
Use custom version of aws_lambda_events, including https://github.com…
ewbankkit Apr 20, 2020
3d5975c
Add support for APIGW v2 proxy request and response.
ewbankkit Apr 20, 2020
1e48629
Use API Gateway v2 quick create.
ewbankkit Apr 20, 2020
0763487
Merge branch 'master' into issue-18
ewbankkit Apr 21, 2020
19da2c8
Correct Lambda permission for APIGW quick create.
ewbankkit Apr 21, 2020
3d5f995
Log runtime version.
ewbankkit Apr 21, 2020
5fbb6f2
Log invocation body when attempting conversion to an HTTP request.
ewbankkit Apr 21, 2020
9f13140
Tweak RUST_LOG value.
ewbankkit Apr 21, 2020
6d0f2a8
README additions.
ewbankkit Apr 21, 2020
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
3 changes: 2 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Examples of using the [waSCC](https://wascc.dev/) runtime for AWS Lambda.

## Examples

* [`custom`](custom/README.md) A simple example that processes a custom lambda event
* [`custom`](custom/README.md) A simple example that processes a custom Lambda event
* [`apigw`](apigw/README.md) An example that receives an HTTP request via API Gateway
* [`sqs`](sqs/README.md) Receive an SQS message and publish a reply

## Notes
Expand Down
7 changes: 7 additions & 0 deletions examples/apigw/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.terraform/

terraform.tfstate
terraform.tfstate.backup

app.zip
output.json
9 changes: 9 additions & 0 deletions examples/apigw/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.PHONY: all apply

all: apply

apply: app.zip
terraform12 apply

app.zip: manifest.yaml actor/target/wasm32-unknown-unknown/release/uppercase.wasm
zip -j $@ $^
42 changes: 42 additions & 0 deletions examples/apigw/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# API Gateway HTTP Request Invocation

This actor is identical to the [Krustlet Uppercase](https://github.com/deislabs/krustlet/tree/master/demos/wascc/uppercase) demo,
the only change being that the actor is signed with the `awslambda:runtime` capability instead of the standard HTTP server capability.

### Build

Build the [sample waSCC actor](actor/README.md).

```console
$ cd actor
$ make release
$ cd ..
```

### Deploy

This examples uses the `wascc-slim` Lambda layer.
See [`layers`](../../layers/README/md) for instructions on building the waSCC runtime Lambda layers.

```console
$ terraform init
```

Set AWS environment variables for your authenticated session.

```console
$ make
```

### Test

```console
$ curl https://v3390lt0j2.execute-api.us-west-2.amazonaws.com/?today=tuesday
{"original":"today=tuesday","uppercased":"TODAY=TUESDAY"}
```

### Known Issues

It works on my machine!

The public key of the actor in `manifest.yaml` is the value I use and will have to be changed when you generate your own keys.
1 change: 1 addition & 0 deletions examples/apigw/actor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.keys/
22 changes: 22 additions & 0 deletions examples/apigw/actor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "uppercase"
version = "0.6.1"
authors = ["Kit Ewbank <Kit_Ewbank@hotmail.com>"]
edition = "2018"
license = "Apache-2.0"
readme = "README.md"

[lib]
crate-type = ["cdylib"]

[dependencies]
wascc-actor = "0.6.0"
log = '0.4.8'
serde = { version = "1.0.104", features = ["derive"]}
wascc-codec = "0.6.0"

[profile.release]
# Optimize for small code size
opt-level = "s"

[workspace]
49 changes: 49 additions & 0 deletions examples/apigw/actor/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
COLOR ?= always # Valid COLOR options: {always, auto, never}
CARGO = cargo --color $(COLOR)
TARGET = target/wasm32-unknown-unknown
DEBUG = $(TARGET)/debug
RELEASE = $(TARGET)/release
KEYDIR ?= .keys

.PHONY: all bench build check clean doc test update keys keys-account keys-module

all: build

bench:
@$(CARGO) bench

build:
@$(CARGO) build --target wasm32-unknown-unknown
wascap sign $(DEBUG)/uppercase.wasm $(DEBUG)/uppercase_signed.wasm --issuer $(KEYDIR)/account.nk --subject $(KEYDIR)/module.nk --cap awslambda:runtime --cap wascc:logging --name uppercase

check:
@$(CARGO) check

clean:
@$(CARGO) clean

doc:
@$(CARGO) doc

test: build
@$(CARGO) test

update:
@$(CARGO) update

release:
@$(CARGO) build --release --target wasm32-unknown-unknown
wascap sign $(RELEASE)/uppercase.wasm $(RELEASE)/uppercase.wasm --issuer $(KEYDIR)/account.nk --subject $(KEYDIR)/module.nk --cap awslambda:runtime --cap wascc:logging --name uppercase

keys: keys-account
keys: keys-module

keys-account:
@mkdir -p $(KEYDIR)
nk gen account > $(KEYDIR)/account.txt
awk '/Seed/{ print $$2 }' $(KEYDIR)/account.txt > $(KEYDIR)/account.nk

keys-module:
@mkdir -p $(KEYDIR)
nk gen module > $(KEYDIR)/module.txt
awk '/Seed/{ print $$2 }' $(KEYDIR)/module.txt > $(KEYDIR)/module.nk
38 changes: 38 additions & 0 deletions examples/apigw/actor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Sample waSCC Actor

A sample [waSCC](https://wascc.dev/) actor that uses the AWS Lambda runtime capability provider.

This actor is identical to the [Krustlet Uppercase](https://github.com/deislabs/krustlet/tree/master/demos/wascc/uppercase) demo,
the only change being that the actor is signed with the `awslambda:runtime` capability instead of the standard HTTP server capability.

## Build

#### Install [NKeys](https://github.com/encabulators/nkeys)

```console
cargo install nkeys --features "cli"
```

#### Generate Keys

```console
make keys
```

#### Add `wasm32-unknown-unknown` Compilation Target

```console
rustup target add wasm32-unknown-unknown
```

#### Install [WASCAP](https://github.com/wascc/wascap)

```console
cargo install wascap --features "cli"
```

#### Build Actor

```console
make release
```
35 changes: 35 additions & 0 deletions examples/apigw/actor/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
extern crate wascc_actor as actor;

#[macro_use]
extern crate log;
extern crate serde;
extern crate wascc_codec;

use actor::prelude::*;
use serde::Serialize;
use wascc_codec::serialize;

actor_handlers! {
codec::http::OP_HANDLE_REQUEST => uppercase,
codec::core::OP_HEALTH_REQUEST => health
}

fn uppercase(r: codec::http::Request) -> CallResult {
info!("Query String: {}", r.query_string);
let upper = UppercaseResponse {
original: r.query_string.to_string(),
uppercased: r.query_string.to_ascii_uppercase(),
};

Ok(serialize(codec::http::Response::json(upper, 200, "OK"))?)
}

fn health(_req: codec::core::HealthRequest) -> ReceiveResult {
Ok(vec![])
}

#[derive(Serialize)]
struct UppercaseResponse {
original: String,
uppercased: String,
}
135 changes: 135 additions & 0 deletions examples/apigw/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
//
// waSCC runtime for AWS Lambda example configuration.
//

terraform {
required_version = ">= 0.12.19"
}


# Build from https://github.com/terraform-providers/terraform-provider-aws/commit/df71a4fd95c0e5a9afe5b08c43a951d3a7fda0ed.
# Will be released in v2.59.0.
# provider "aws" {
# version = ">= 2.58.0"
# }

//
// Data sources for current AWS account ID, partition and region.
//

data "aws_caller_identity" "current" {}

data "aws_partition" "current" {}

data "aws_region" "current" {}

//
// API Gateway resources.
//

resource "aws_apigatewayv2_api" "example" {
name = "waSCC-example-apigw"
protocol_type = "HTTP"
target = aws_lambda_function.example.arn
}

//
// Lambda resources.
//

data "aws_lambda_layer_version" "slim" {
layer_name = "wascc-slim"
}

resource "aws_lambda_function" "example" {
filename = "${path.module}/app.zip"
source_code_hash = filebase64sha256("${path.module}/app.zip")
function_name = "waSCC-example-apigw"
role = aws_iam_role.example.arn
handler = "doesnt.matter"
runtime = "provided"
memory_size = 256
timeout = 90

layers = [data.aws_lambda_layer_version.slim.arn]

environment {
variables = {
RUST_BACKTRACE = "1"
RUST_LOG = "info,cranelift_wasm=warn,cranelift_codegen=info"
}
}
}

// See https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html#apigateway-permissions.
resource "aws_lambda_permission" "example" {
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.example.function_name
principal = "apigateway.amazonaws.com"
source_arn = "arn:${data.aws_partition.current.partition}:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:${aws_apigatewayv2_api.example.id}/*/$default"
}

//
// IAM resources.
//

resource "aws_iam_role" "example" {
name = "waSCC-example-apigw-Lambda-role"

assume_role_policy = <<EOT
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}]
}
EOT
}

resource "aws_iam_policy" "cloudwatch_logs_policy" {
name = "waSCC-example-apigw-Lambda-CloudWatchLogsPolicy"

policy = <<EOT
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:${data.aws_partition.current.partition}:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:${data.aws_partition.current.partition}:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:/aws/lambda/${aws_lambda_function.example.function_name}:*"
]
}
]
}
EOT
}

resource "aws_iam_role_policy_attachment" "cloudwatch_logs" {
role = aws_iam_role.example.name
policy_arn = aws_iam_policy.cloudwatch_logs_policy.arn
}

//
// Outputs.
//

output "FunctionName" {
value = aws_lambda_function.example.function_name
}

output "Url" {
value = aws_apigatewayv2_api.example.api_endpoint
}
5 changes: 5 additions & 0 deletions examples/apigw/manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
actors:
- uppercase.wasm
capabilities: []
bindings: []
4 changes: 4 additions & 0 deletions provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ reqwest = { version = "0.10.4", features = ["blocking", "json"] }
serde = "1.0.106"
serde_json = "1.0.51"
codec = { path = "../codec" }
aws_lambda_events = { git = "https://github.com/ewbankkit/aws-lambda-events", branch = "include-aws-lambda-go.pr-280" }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

base64 = "0.12.0"
url = "2.1.1"
thiserror = "1.0.15"
Loading