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

Commit

Permalink
Merge pull request #24 from wascc/issue-18
Browse files Browse the repository at this point in the history
Invoke `http::OP_HANDLE_REQUEST` for events that look like HTTP requests
  • Loading branch information
ewbankkit committed Apr 21, 2020
2 parents f9cec9f + 6d0f2a8 commit 284001b
Show file tree
Hide file tree
Showing 17 changed files with 940 additions and 45 deletions.
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" }
base64 = "0.12.0"
url = "2.1.1"
thiserror = "1.0.15"
Loading

0 comments on commit 284001b

Please sign in to comment.