From ab33d806540c2a968ec5eb38db3db09f684dcf98 Mon Sep 17 00:00:00 2001 From: Alex Ellis <alexellis2@gmail.com> Date: Mon, 5 Mar 2018 15:15:35 +0000 Subject: [PATCH] Convert apikeyprotected-secret to apikey-secret with proper Golang template Signed-off-by: Alex Ellis <alexellis2@gmail.com> --- sample-functions/README.md | 6 ++--- sample-functions/apikey-secret.yml | 9 +++++++ sample-functions/apikey-secret/README.md | 31 +++++++++++++++++++++++ sample-functions/apikey-secret/handler.go | 28 ++++++++++++++++++++ sample-functions/stack.yml | 8 +++--- 5 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 sample-functions/apikey-secret.yml create mode 100644 sample-functions/apikey-secret/README.md create mode 100644 sample-functions/apikey-secret/handler.go diff --git a/sample-functions/README.md b/sample-functions/README.md index abcaa4eb..2d5c17e5 100644 --- a/sample-functions/README.md +++ b/sample-functions/README.md @@ -17,10 +17,10 @@ For examples of hello-world in different programming languages see inside the Ba Here is a list of some of the sample functions included this repository. -| Name | Details | -|------------------------|----------------------------------------- | +| Name | Details | +|--------------------------|----------------------------------------- | | AlpineFunction | BusyBox - a useful base image with busybox utilities pre-installed | -| ApiKeyProtected-Secrets | Example in Golang showing how to read a secret from a HTTP header and validate with a Swarm/Kubernetes secret | +| apikey-secret | Example in Golang showing how to read a secret from a HTTP header and validate with a Swarm/Kubernetes secret | | CaptainsIntent | Alexa skill - find the count of Docker Captains | | ChangeColorIntent | Alexa skill - change the colour of IoT-connected lights | | echo | Uses `cat` from BusyBox to provide an echo function | diff --git a/sample-functions/apikey-secret.yml b/sample-functions/apikey-secret.yml new file mode 100644 index 00000000..26cf8abb --- /dev/null +++ b/sample-functions/apikey-secret.yml @@ -0,0 +1,9 @@ +provider: + name: faas + gateway: http://localhost:8080 + +functions: + apikey-secret: + lang: go + handler: ./apikey-secret + image: apikey-secret diff --git a/sample-functions/apikey-secret/README.md b/sample-functions/apikey-secret/README.md new file mode 100644 index 00000000..32c8d8dc --- /dev/null +++ b/sample-functions/apikey-secret/README.md @@ -0,0 +1,31 @@ +### Sample: apikey-secret + +This function returns access denied, or unlocked depending on whether your header for X-Api-Key matches a secret in the cluster called `secret_api_key`. + +See the [secure secret management guide](../guide/secure_secret_management.md) for more information on secrets. + +## Trying the sample: + +``` + +$ docker secret remove secret_api_key # make sure we delete any existing secret + +# Create a secret with Swarm +$ echo "secret_value_goes_here" | docker secret create secret_api_key + +# Deploy this sample with Docker Swarm and attach the secret to it + +$ cd faas/sample-functions/ +$ faas-cli deploy --filter apikey-secret --secret secret_api_key + +# Now invoke the function with a good value: + +$ echo -n | faas invoke --header "X-Api-Key=secret_value_goes_here" apikey-secret +You unlocked the function. + +# Now invoke with a bad value: + +echo -n | faas invoke --header "X-Api-Key=wrong_secret_value_goes_here" apikey-secret +Access was denied. + +``` \ No newline at end of file diff --git a/sample-functions/apikey-secret/handler.go b/sample-functions/apikey-secret/handler.go new file mode 100644 index 00000000..03ef6bba --- /dev/null +++ b/sample-functions/apikey-secret/handler.go @@ -0,0 +1,28 @@ +package function + +import ( + "io/ioutil" + "log" + "os" + "strings" +) + +// Handle a serverless request +func Handle(req []byte) string { + + key := os.Getenv("Http_X_Api_Key") // converted via the Header: X-Api-Key + + secretBytes, err := ioutil.ReadFile("/run/secrets/secret_api_key") // You must create a secret ahead of time named `secret_api_key` + if err != nil { + log.Fatal(err) + } + + secret := strings.TrimSpace(string(secretBytes)) + + message := "Access was denied." + if key == secret { + message = "You unlocked the function." + } + + return message +} diff --git a/sample-functions/stack.yml b/sample-functions/stack.yml index ca7ff9b1..973a6188 100644 --- a/sample-functions/stack.yml +++ b/sample-functions/stack.yml @@ -10,10 +10,10 @@ functions: environment: fprocess: "cat" - apikeyprotected: - lang: dockerfile - handler: ./AlpineFunction - image: functions/api-key-protected:latest + apikey-secret: + lang: go + handler: ./apikey-secret + image: functions/apikey-secret:0.1 captainsintent: lang: dockerfile -- GitLab