Removed a bunch of old examples. (#502)

* Removed a bunch of old examples.

* moved grafana back.

* Bumping, circle didn't do build... ?
This commit is contained in:
Travis Reeder
2017-11-16 10:10:03 -08:00
committed by GitHub
parent 96cfc9f5c1
commit 64c6118313
109 changed files with 1 additions and 2222 deletions

View File

@@ -1,8 +0,0 @@
FROM fnproject/go:dev
RUN mkdir -p /go/src/github.com/Masterminds
ENV GOPATH=/go
RUN cd /go/src/github.com/Masterminds && git clone https://github.com/Masterminds/glide.git && cd glide && go build
RUN cp /go/src/github.com/Masterminds/glide/glide /bin
ENTRYPOINT ["glide"]

View File

@@ -1 +0,0 @@
/func

View File

@@ -1,5 +0,0 @@
FROM alpine
ADD func .
ENTRYPOINT ["./func"]

View File

@@ -1,144 +0,0 @@
# Blog API Example
A simple serverless blog API
## Requirements
- Remote MongoDB instance (for example heroku)
- Running Fn API
## Development
### Building image locally
```
# SET BELOW TO YOUR DOCKER HUB USERNAME
USERNAME=YOUR_DOCKER_HUB_USERNAME
# build it
docker run --rm -v "$PWD":/go/src/github.com/fnproject/hello -w /go/src/github.com/fnproject/hello fnproject/go:dev go build -o function
docker build -t $USERNAME/func-blog .
```
### Publishing to DockerHub
```
# tagging
docker run --rm -v "$PWD":/app treeder/bump patch
docker tag $USERNAME/func-blog:latest $USERNAME/func-blog:`cat VERSION`
# pushing to docker hub
docker push $USERNAME/func-blog
```
## Running it on Fn
First you need a running Fn API
### First, let's define this environment variables
```
# Set your Function server address
# Eg. 127.0.0.1:8080
FUNCAPI=YOUR_FUNCTIONS_ADDRESS
# Set your mongoDB server address
# Eg. 127.0.0.1:27017/blog
MONGODB=YOUR_MONGODB_ADDRESS
```
### Testing image
```
./test.sh
```
### Running with Fn
With this command we are going to create an application with name `blog` and also defining the app configuration `DB`.
```
curl -X POST --data '{
"app": {
"name": "blog",
"config": { "DB": "'$MONGODB'" }
}
}' http://$FUNCAPI/v1/apps
```
Now, we can create our blog routes:
- `/posts` - to create (authenticated) and list posts
- `/posts/:id` - to read post
- `/token` - to get a JWT
```
curl -X POST --data '{
"route": {
"image": "'$USERNAME'/func-blog",
"path": "/posts"
}
}' http://$FUNCAPI/v1/apps/blog/routes
```
```
curl -X POST --data '{
"route": {
"image": "'$USERNAME'/func-blog",
"path": "/posts/:id"
}
}' http://$FUNCAPI/v1/apps/blog/routes
```
```
curl -X POST --data '{
"route": {
"image": "'$USERNAME'/func-blog",
"path": "/token"
}
}' http://$FUNCAPI/v1/apps/blog/routes
```
#### Testing function
Now that we created our Fn route, let's test our routes
```
curl -X POST http://$FUNCAPI/r/blog/posts
```
This command should return `{"error":"Invalid authentication"}` because we aren't sending any token.
#### Authentication
##### Creating a blog user
First let's create our blog user. In this example an user `test` with password `test`.
```
docker run --rm -e DB=$MONGODB -e NEWUSER='{ "username": "test", "password": "test" }' $USERNAME/functions-blog
```
##### Getting authorization token
Now, to get authorized to post in our Blog API endpoints we must request a new token with a valid user.
```
curl -X POST --data '{ "username": "test", "password": "test" }' http://$FUNCAPI/r/blog/token
```
This will output a token like this:
```
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIyMDE2LTA5LTAxVDAwOjQzOjMxLjQwNjY5NTIxNy0wMzowMCIsInVzZXIiOiJ0ZXN0In0.aPKdH3QPauutFsFbSdQyF6q1hqTAas_BCbSYi5mFiSU"}
```
Let's save that token in the environment
```
BLOG_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIyMDE2LTA5LTAxVDAwOjQzOjMxLjQwNjY5NTIxNy0wMzowMCIsInVzZXIiOiJ0ZXN0In0.aPKdH3QPauutFsFbSdQyF6q1hqTAas_BCbSYi5mFiSU
```
##### Posting in your blog
curl -X POST --header "Authorization: Bearer $BLOG_TOKEN" --data '{ "title": "My New Post", "body": "Hello world!", "user": "test" }' http://$FUNCAPI/r/blog/posts

View File

@@ -1 +0,0 @@
0.0.1

View File

@@ -1,12 +0,0 @@
#!/bin/bash
set -ex
FUNCPKG=$(pwd | sed "s|$GOPATH/src/||")
# glide image to install dependencies
../build-glide.sh
docker run --rm -v "$PWD":/go/src/$FUNCPKG -w /go/src/$FUNCPKG glide up
# build image
docker run --rm -v "$PWD":/go/src/$FUNCPKG -w /go/src/$FUNCPKG fnproject/go:dev go build -o func
docker build -t username/func-blog .

View File

@@ -1,20 +0,0 @@
package database
import "gopkg.in/mgo.v2"
type Database struct {
Session *mgo.Session
}
func New(uri string) *Database {
session, err := mgo.Dial(uri)
if err != nil {
panic(err)
}
session.SetMode(mgo.Monotonic, true)
return &Database{
Session: session,
}
}

View File

@@ -1,73 +0,0 @@
package database
import (
"errors"
"github.com/fnproject/fn/examples/blog/models"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
var (
ErrNotObjectIdHex = errors.New("Invalid ID")
)
func (db *Database) SavePost(post *models.Post) (*models.Post, error) {
s := db.Session.Copy()
defer s.Close()
c := s.DB("").C("post")
if post.ID.Hex() == "" {
post.ID = bson.NewObjectId()
}
id := post.ID
change := mgo.Change{
Update: bson.M{"$set": post},
ReturnNew: true,
Upsert: true,
}
_, err := c.Find(bson.M{"_id": id}).Apply(change, &post)
if err != nil {
return nil, err
}
return post, nil
}
func (db *Database) GetPost(id string) (*models.Post, error) {
s := db.Session.Copy()
defer s.Close()
c := s.DB("").C("post")
var post models.Post
if !bson.IsObjectIdHex(id) {
return nil, ErrNotObjectIdHex
}
err := c.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&post)
if err != nil {
return nil, err
}
return &post, nil
}
func (db *Database) GetPosts(query []bson.M) ([]*models.Post, error) {
s := db.Session.Copy()
defer s.Close()
c := s.DB("").C("post")
var posts []*models.Post
err := c.Pipe(query).All(&posts)
if err != nil {
return nil, err
}
return posts, nil
}

View File

@@ -1,65 +0,0 @@
package database
import (
"github.com/fnproject/fn/examples/blog/models"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
func (db *Database) SaveUser(user *models.User) (*models.User, error) {
s := db.Session.Copy()
defer s.Close()
c := s.DB("").C("user")
id := user.Username
user.Username = ""
if len(user.Password) > 0 {
user.Password = models.UserPasswordEncrypt(user.Password)
}
change := mgo.Change{
Update: bson.M{"$set": user},
ReturnNew: true,
Upsert: true,
}
_, err := c.Find(bson.M{"_id": id}).Apply(change, &user)
if err != nil {
return nil, err
}
return user, nil
}
func (db *Database) GetUser(id string) (*models.User, error) {
s := db.Session.Copy()
defer s.Close()
c := s.DB("").C("user")
var user models.User
err := c.Find(bson.M{"_id": id}).One(&user)
if err != nil {
return nil, err
}
return &user, nil
}
func (db *Database) GetUsers(query []bson.M) ([]*models.User, error) {
s := db.Session.Copy()
defer s.Close()
c := s.DB("").C("user")
var users []*models.User
err := c.Pipe(query).All(&users)
if err != nil {
return nil, err
}
return users, nil
}

View File

@@ -1,3 +0,0 @@
name: username/func-blog
build:
- ./build.sh

View File

@@ -1,90 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"os"
"github.com/fnproject/fn/examples/blog/database"
"github.com/fnproject/fn/examples/blog/models"
"github.com/fnproject/fn/examples/blog/routes"
)
var noAuth = map[string]interface{}{}
func main() {
request := fmt.Sprintf("%s %s", os.Getenv("FN_METHOD"), os.Getenv("FN_PATH"))
dbURI := os.Getenv("DB")
if dbURI == "" {
dbURI = "127.0.0.1/blog"
}
db := database.New(dbURI)
if created := createUser(db); created {
return
}
// PUBLIC REQUESTS
switch request {
case "GET /posts":
route.HandlePostList(db, noAuth)
return
case "GET /posts/:id":
route.HandlePostRead(db, noAuth)
return
}
// GETTING TOKEN
if os.Getenv("FN_PATH") == "/token" {
route.HandleToken(db)
return
}
// AUTHENTICATION
auth, valid := route.Authentication()
if !valid {
route.SendError("Invalid authentication")
return
}
// AUTHENTICATED ONLY REQUESTS
if request == "POST /posts" {
route.HandlePostCreate(db, auth)
return
}
route.SendError("Not found")
}
func createUser(db *database.Database) bool {
env := os.Getenv("NEWUSER")
if env == "" {
return false
}
var user *models.User
err := json.Unmarshal([]byte(env), &user)
if err != nil {
fmt.Println(err)
return true
}
if user.Username == "" || user.NewPassword == "" {
fmt.Println("missing username or password")
return true
}
user.Password = []byte(user.NewPassword)
user.NewPassword = ""
user, err = db.SaveUser(user)
if err != nil {
fmt.Println("couldn't create user")
} else {
fmt.Println("user created")
}
return true
}

View File

@@ -1,18 +0,0 @@
hash: 5ed6b2d92ab59777802bcfbd57690d5cfb128160bca6cfa799abeb28a8baad4d
updated: 2016-11-01T02:15:49.751792317Z
imports:
- name: github.com/dgrijalva/jwt-go
version: d2709f9f1f31ebcda9651b03077758c1f3a0018c
- name: golang.org/x/crypto
version: 9477e0b78b9ac3d0b03822fd95422e2fe07627cd
subpackages:
- bcrypt
- blowfish
- name: gopkg.in/mgo.v2
version: 3f83fa5005286a7fe593b055f0d7771a7dce4655
subpackages:
- bson
- internal/json
- internal/sasl
- internal/scram
testImports: []

View File

@@ -1,10 +0,0 @@
package: github.com/fnproject/functions/examples/blog
import:
- package: github.com/dgrijalva/jwt-go
version: ^3.0.0
- package: golang.org/x/crypto
subpackages:
- bcrypt
- package: gopkg.in/mgo.v2
subpackages:
- bson

View File

@@ -1,10 +0,0 @@
package models
import "gopkg.in/mgo.v2/bson"
type Post struct {
ID bson.ObjectId `json:"id" bson:"_id,omitempty"`
Title string `json:"title" bson:"title"`
Body string `json:"body" bson:"body"`
User string `json:"user" bsom:"user"`
}

View File

@@ -1,17 +0,0 @@
package models
import "golang.org/x/crypto/bcrypt"
type User struct {
Username string `json:"username" bson:"_id,omitempty"`
Password []byte `json:"-" bson:"password"`
NewPassword string `json:"password" bson:"-"`
}
func UserPasswordEncrypt(pass []byte) []byte {
hashedPassword, err := bcrypt.GenerateFromPassword(pass, bcrypt.DefaultCost)
if err != nil {
panic(err)
}
return hashedPassword
}

View File

@@ -1,31 +0,0 @@
package route
import (
"encoding/json"
"fmt"
"os"
"github.com/fnproject/fn/examples/blog/database"
"github.com/fnproject/fn/examples/blog/models"
)
func HandlePostCreate(db *database.Database, auth map[string]interface{}) {
var post *models.Post
if err := json.NewDecoder(os.Stdin).Decode(&post); err != nil {
fmt.Printf("Couldn't decode post JSON: %v\n", err)
return
}
post, err := db.SavePost(post)
if err != nil {
fmt.Println("Couldn't save that post")
return
}
post.User = auth["user"].(string)
SendResponse(Response{
"post": post,
})
}

View File

@@ -1,18 +0,0 @@
package route
import (
"github.com/fnproject/fn/examples/blog/database"
"gopkg.in/mgo.v2/bson"
)
func HandlePostList(db *database.Database, auth map[string]interface{}) {
posts, err := db.GetPosts([]bson.M{})
if err != nil {
SendError("Couldn't retrieve posts")
return
}
SendResponse(Response{
"posts": posts,
})
}

View File

@@ -1,26 +0,0 @@
package route
import (
"os"
"github.com/fnproject/fn/examples/blog/database"
)
func HandlePostRead(db *database.Database, auth map[string]interface{}) {
id := os.Getenv("FN_PARAM_ID")
if id == "" {
SendError("Missing post ID")
return
}
post, err := db.GetPost(id)
if err != nil {
SendError("Couldn't retrieve that post")
return
}
SendResponse(Response{
"post": post,
})
}

View File

@@ -1,89 +0,0 @@
package route
import (
"encoding/json"
"fmt"
"os"
"strings"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/fnproject/fn/examples/blog/database"
"github.com/fnproject/fn/examples/blog/models"
"golang.org/x/crypto/bcrypt"
)
var jwtSignKey = []byte("mysecretblog")
type Response map[string]interface{}
func SendResponse(resp Response) {
data, _ := json.Marshal(resp)
fmt.Println(string(data))
}
func SendError(err interface{}) {
SendResponse(Response{
"error": err,
})
}
func HandleToken(db *database.Database) {
var login *models.User
if err := json.NewDecoder(os.Stdin).Decode(&login); err != nil {
fmt.Printf("Couldn't decode login JSON: %v\n", err)
return
}
user, err := db.GetUser(login.Username)
if err != nil {
SendError("Couldn't create a token")
return
}
if err := bcrypt.CompareHashAndPassword(user.Password, []byte(login.NewPassword)); err != nil {
SendError("Couldn't create a token")
return
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"user": login.Username,
"exp": time.Now().Add(1 * time.Hour),
})
// Sign and get the complete encoded token as a string using the secret
tokenString, err := token.SignedString(jwtSignKey)
if err != nil {
SendError("Couldn't create a token")
return
}
SendResponse(Response{"token": tokenString})
}
func Authentication() (map[string]interface{}, bool) {
authorization := os.Getenv("FN_HEADER_AUTHORIZATION")
p := strings.Split(authorization, " ")
if len(p) <= 1 {
return nil, false
}
token, err := jwt.Parse(p[1], func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return jwtSignKey, nil
})
if err != nil {
return nil, false
}
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims, true
}
return nil, false
}

View File

@@ -1,16 +0,0 @@
#!/bin/bash
set -x
./build.sh
# test it
docker stop test-mongo-func
docker rm test-mongo-func
docker run -p 27017:27017 --name test-mongo-func -d mongo
echo '{ "title": "My New Post", "body": "Hello world!", "user": "test" }' | docker run --rm -i -e FN_METHOD=POST -e FN_PATH=/posts -e DB=mongo:27017 --link test-mongo-func:mongo -e TEST=1 username/func-blog
docker run --rm -i -e FN_METHOD=GET -e FN_PATH=/posts -e DB=mongo:27017 --link test-mongo-func:mongo -e TEST=1 username/func-blog
docker stop test-mongo-func
docker rm test-mongo-func

View File

@@ -1,5 +0,0 @@
EXAMPLE=`pwd`
cd ..
docker build -f Dockerfile.glide -t glide .
cd $EXAMPLE

View File

@@ -1,5 +0,0 @@
:9000 {
proxy / {$LB_HOST01} {$LB_HOST02} {$LB_HOST03} {
policy least_conn
}
}

View File

@@ -1,58 +0,0 @@
# Fn Load Balance example using Caddy
Simple example of Fn load balancer using Caddy Server
## Run Fn
Start the Fn instances
Ref: https://github.com/fnproject/functions/blob/master/README.md#start-the-functions-api
## Configure environment variable
Pass the host and port of Fn instances in environment variables,
this example uses three Fn instances.
```sh
export LB_HOST01="172.17.0.1:8080"
export LB_HOST02="172.17.0.1:8081"
export LB_HOST03="172.17.0.1:8082"
```
Note: Caddy doesn't support multiple hosts in only one variable.
## Run Caddy
```sh
docker run --rm \
-v $PWD/Caddyfile:/etc/Caddyfile \
-e LB_HOST01=$LB_HOST01 -e LB_HOST02=$LB_HOST02 -e LB_HOST03=$LB_HOST03 \
-p 9000:9000 \
abiosoft/caddy
```
## Execute a function
Follow the Quick-Start steps replacing the example hosts by the Caddy host (localhost:9000)
https://github.com/fnproject/functions/blob/master/README.md#quick-start
## Docker Compose example
This is an additional example.
```sh
docker-compose up
```
## Caddy Reference:
* https://github.com/mholt/caddy
* https://caddyserver.com/

View File

@@ -1 +0,0 @@
0.0.1

View File

@@ -1,4 +0,0 @@
#!/bin/bash
set -ex
docker-compose up

View File

@@ -1,23 +0,0 @@
functions01:
restart: always
image: fnproject/functions
functions02:
restart: always
image: fnproject/functions
functions03:
restart: always
image: fnproject/functions
caddy:
image: abiosoft/caddy
volumes:
- ./Caddyfile:/etc/Caddyfile
ports:
- "9000:9000"
environment:
- LB_HOST01=functions01:8080
- LB_HOST02=functions02:8080
- LB_HOST03=functions03:8080
links:
- functions01
- functions02
- functions03

View File

@@ -1,3 +0,0 @@
name: username/func-caddy-lb
build:
- ./build.sh

View File

@@ -1,3 +0,0 @@
#!/bin/bash
set -x

View File

@@ -1,2 +0,0 @@
bundle/
.bundle/

View File

@@ -1,9 +0,0 @@
FROM fnproject/ruby:dev
WORKDIR /function
ADD Gemfile* /function/
RUN bundle install
ADD . /function/
ENTRYPOINT ["ruby", "function.rb"]

View File

@@ -1,3 +0,0 @@
source 'https://rubygems.org'
gem 'json', '> 1.8.2'

View File

@@ -1,78 +0,0 @@
# Environment Checker Function Image
This images compares the payload info with the header.
## Requirements
- Fn API
## Development
### Building image locally
```
# SET BELOW TO YOUR DOCKER HUB USERNAME
USERNAME=YOUR_DOCKER_HUB_USERNAME
# build it
./build.sh
```
### Publishing to DockerHub
```
# tagging
docker run --rm -v "$PWD":/app treeder/bump patch
docker tag $USERNAME/func-checker:latest $USERNAME/func-checker:`cat VERSION`
# pushing to docker hub
docker push $USERNAME/func-checker
```
### Testing image
```
./test.sh
```
## Running it on Fn
### Let's define some environment variables
```
# Set your Function server address
# Eg. 127.0.0.1:8080
FUNCAPI=YOUR_FUNCTIONS_ADDRESS
```
### Running with Fn
With this command we are going to create an application with name `checker`.
```
curl -X POST --data '{
"app": {
"name": "checker",
}
}' http://$FUNCAPI/v1/apps
```
Now, we can create our route
```
curl -X POST --data '{
"route": {
"image": "'$USERNAME'/func-checker",
"path": "/check",
"config": { "TEST": "1" }
}
}' http://$FUNCAPI/v1/apps/checker/routes
```
#### Testing function
Now that we created our Fn route, let's test our new route
```
curl -X POST --data '{ "env_vars": { "test": "1" } }' http://$FUNCAPI/r/checker/check
```

View File

@@ -1,4 +0,0 @@
name: username/func-checker
version: 0.0.1
entrypoint: ruby function.rb
runtime: ruby

View File

@@ -1,41 +0,0 @@
require 'json'
require 'uri'
puts "Running checker..."
payload = STDIN.read
puts "payload #{payload}"
p ENV
if payload != ""
payload = JSON.parse(payload)
# payload contains checks
if payload["env_vars"]
payload["env_vars"].each do |k,v|
if ENV[k] != v
raise "Env var #{k} does not match"
end
end
end
puts "all good"
end
# Also check for expected env vars: https://github.com/fnproject/fn/blob/master/docs/writing.md#inputs
e = ENV["FN_REQUEST_URL"]
puts e
uri = URI.parse(e)
if !uri.scheme.start_with?('http')
raise "invalid REQUEST_URL, does not start with http"
end
e = ENV["FN_METHOD"]
if !(e == "GET" || e == "POST" || e == "DELETE" || e == "PATCH" || e == "PUT")
raise "Invalid METHOD: #{e}"
end
e = ENV["FN_APP_NAME"]
if e == nil || e == ''
raise "No APP_NAME found"
end
e = ENV["FN_PATH"]
if e == nil || e == ''
raise "No ROUTE found"
end

View File

@@ -1,8 +0,0 @@
#!/bin/bash
set -ex
PAYLOAD='{"env_vars": {"FOO": "bar"}}'
# test it
: ${FN:="fn"}
echo $PAYLOAD | $FN run -e FOO=bar

View File

@@ -1,2 +0,0 @@
bundle/
.bundle/

View File

@@ -1,9 +0,0 @@
FROM fnproject/ruby:dev
WORKDIR /function
ADD Gemfile /function/
RUN bundle install
ADD . /function/
ENTRYPOINT ["ruby", "function.rb"]

View File

@@ -1,3 +0,0 @@
source 'https://rubygems.org'
gem 'json', '> 1.8.2'

View File

@@ -1,77 +0,0 @@
# Echo Function Image
This images compares the payload info with the header.
## Requirements
- Fn API
## Development
### Building image locally
```
# SET BELOW TO YOUR DOCKER HUB USERNAME
USERNAME=YOUR_DOCKER_HUB_USERNAME
# build it
./build.sh
```
### Publishing to DockerHub
```
# tagging
docker run --rm -v "$PWD":/app treeder/bump patch
docker tag $USERNAME/func-echo:latest $USERNAME/func-echo:`cat VERSION`
# pushing to docker hub
docker push $USERNAME/func-echo
```
### Testing image
```
./test.sh
```
## Running it on Fn
### Let's define some environment variables
```
# Set your Function server address
# Eg. 127.0.0.1:8080
FUNCAPI=YOUR_FUNCTIONS_ADDRESS
```
### Running with Fn
With this command we are going to create an application with name `echo`.
```
curl -X POST --data '{
"app": {
"name": "echo",
}
}' http://$FUNCAPI/v1/apps
```
Now, we can create our route
```
curl -X POST --data '{
"route": {
"image": "'$USERNAME'/func-echo",
"path": "/echo",
}
}' http://$FUNCAPI/v1/apps/echo/routes
```
#### Testing function
Now that we created our Fn route, let's test our new route
```
curl -X POST --data '{"input": "yoooo"}' http://$FUNCAPI/r/echo/echo
```

View File

@@ -1 +0,0 @@
0.0.1

View File

@@ -1,5 +0,0 @@
#!/bin/bash
set -ex
# build image
docker build -t username/func-echo .

View File

@@ -1,3 +0,0 @@
name: username/func-echo
build:
- ./build.sh

View File

@@ -1,11 +0,0 @@
require 'json'
payload = STDIN.read
if payload != ""
payload = JSON.parse(payload)
# payload contains checks
if payload["input"]
puts payload["input"]
end
end

View File

@@ -1,9 +0,0 @@
#!/bin/bash
set -x
./build.sh
PAYLOAD='{"input": "yoooo"}'
# test it
echo $PAYLOAD | docker run --rm -i -e TEST=1 username/func-echo

View File

@@ -1,8 +0,0 @@
FROM fnproject/go:dev as build-stage
WORKDIR /function
ADD . /src
RUN cd /src && go build -o func
FROM fnproject/go
WORKDIR /function
COPY --from=build-stage /src/func /function/
ENTRYPOINT ["./func"]

View File

@@ -1,28 +0,0 @@
# Hot Function Example
This is an example of a hot function. The [hot function documentation](/docs/hot-functions.md) contains an analysis of how this example works.
Note that you should probably be using the [fdk](https://github.com/fnproject/fdk-go) but this serves
as a good example of how to do a hot functions raw without the fdk.
### How to run the example
Install the CLI tool, start a Fn server and run `docker login` to login to DockerHub. See the [front page](/README.md) for instructions.
Set your Docker Hub username
```sh
export FN_REGISTRY=<DOCKERHUB_USERNAME>
```
Build and deploy the function to the Fn server (default localhost:8080)
```sh
fn deploy --app hot-app
```
Now call your function:
```sh
curl -X POST -d "World" http://localhost:8080/r/hot-app/hotfn-go
```

View File

@@ -1,45 +0,0 @@
package main
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"net/http"
"os"
"strconv"
)
func main() {
for {
res := http.Response{
Proto: "HTTP/1.1",
ProtoMajor: 1,
ProtoMinor: 1,
StatusCode: 200,
Status: "OK",
}
r := bufio.NewReader(os.Stdin)
req, err := http.ReadRequest(r)
var buf bytes.Buffer
if err != nil {
res.StatusCode = 500
res.Status = http.StatusText(res.StatusCode)
fmt.Fprintln(&buf, err)
} else {
l, _ := strconv.Atoi(req.Header.Get("Content-Length"))
p := make([]byte, l)
r.Read(p)
fmt.Fprintf(&buf, "Hello %s\n", p)
for k, vs := range req.Header {
fmt.Fprintf(&buf, "ENV: %s %#v\n", k, vs)
}
}
res.Body = ioutil.NopCloser(&buf)
res.ContentLength = int64(buf.Len())
res.Write(os.Stdout)
}
}

View File

@@ -1,7 +0,0 @@
name: fnproject/hot-http-go
version: 0.0.1
runtime: docker
type: sync
memory: 521
format: http
path: /hot-http-go

View File

@@ -1,21 +0,0 @@
import fdk
@fdk.coerce_http_input_to_content_type
def app(context, data=None, loop=None):
"""
User's request body handler
:param context: request context
:type context: hotfn.http.request.RequestContext
:param data: request body, it's type depends on request Content-Type header
:type data: object
:param loop: asyncio event loop
:type loop asyncio.AbstractEventLoop
:return: echo of data
:rtype: object
"""
return data
if __name__ == "__main__":
fdk.handle(app)

View File

@@ -1,7 +0,0 @@
name: fnproject/hot-http-python
version: 0.0.1
runtime: python3.6.2
type: sync
memory: 521
format: http
path: /hot-http-python

View File

@@ -1,2 +0,0 @@
fdk==0.0.1
uvloop==0.8.1

View File

@@ -1,8 +0,0 @@
FROM fnproject/go:dev as build-stage
WORKDIR /function
ADD . /src
RUN cd /src && go build -o func
FROM fnproject/go
WORKDIR /function
COPY --from=build-stage /src/func /function/
ENTRYPOINT ["./func"]

View File

@@ -1,3 +0,0 @@
# Go using JSON format
This example uses the `json` input format.

View File

@@ -1,69 +0,0 @@
package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"strconv"
)
type Person struct {
Name string `json:"name"`
}
type JSON struct {
Headers http.Header `json:"headers"`
Body string `json:"body,omitempty"`
StatusCode int `json:"status,omitempty"`
QueryParameters string `json:"query_parameters,omitempty"`
}
func main() {
stdin := json.NewDecoder(os.Stdin)
stdout := json.NewEncoder(os.Stdout)
stderr := json.NewEncoder(os.Stderr)
for {
in := &JSON{}
err := stdin.Decode(in)
if err != nil {
log.Fatalf("Unable to decode incoming data: %s", err.Error())
fmt.Fprintf(os.Stderr, err.Error())
}
person := Person{}
stderr.Encode(in.Body)
if len(in.Body) != 0 {
if err := json.NewDecoder(bytes.NewReader([]byte(in.Body))).Decode(&person); err != nil {
log.Fatalf("Unable to decode Person object data: %s", err.Error())
fmt.Fprintf(os.Stderr, err.Error())
}
}
if person.Name == "" {
person.Name = "World"
}
mapResult := map[string]string{"message": fmt.Sprintf("Hello %s", person.Name)}
b, err := json.Marshal(mapResult)
if err != nil {
log.Fatalf("Unable to marshal JSON response body: %s", err.Error())
fmt.Fprintf(os.Stderr, err.Error())
}
h := http.Header{}
h.Set("Content-Type", "application/json")
h.Set("Content-Length", strconv.Itoa(len(b)))
out := &JSON{
StatusCode: http.StatusOK,
Body: string(b),
Headers: h,
}
stderr.Encode(out)
if err := stdout.Encode(out); err != nil {
log.Fatalf("Unable to encode JSON response: %s", err.Error())
fmt.Fprintf(os.Stderr, err.Error())
}
}
}

View File

@@ -1,7 +0,0 @@
name: fnproject/hot-json-go
version: 0.0.1
runtime: docker
type: sync
memory: 256
format: json
path: /hot-json-go

View File

@@ -1,3 +0,0 @@
{
"name": "Johnny"
}

View File

@@ -1,26 +0,0 @@
{
"tests": [
{
"input": {
"body": {
"name": "Johnny"
}
},
"output": {
"body": {
"message": "Hello Johnny"
}
}
},
{
"input": {
"body": ""
},
"output": {
"body": {
"message": "Hello World"
}
}
}
]
}

View File

@@ -1,20 +0,0 @@
import fdk
def handler(context, data=None, loop=None):
"""
This is just an echo function
:param context: request context
:type context: hotfn.http.request.RequestContext
:param data: request body
:type data: object
:param loop: asyncio event loop
:type loop: asyncio.AbstractEventLoop
:return: echo of request body
:rtype: object
"""
return data
if __name__ == "__main__":
fdk.handle(handler)

View File

@@ -1,7 +0,0 @@
name: fnproject/hot-json-python
version: 0.0.1
runtime: python3.6.2
type: sync
memory: 256
format: json
path: /hot-json-python

View File

@@ -1 +0,0 @@
fdk==0.0.1

View File

@@ -1,6 +1,6 @@
# Tutorial 1: Go Function w/ Input (3 minutes)
Example for putting required vars into the func.yaml file.
Example for using required and optional environment variables defined in the func.yaml file.
Try running the following:

View File

@@ -1,4 +0,0 @@
/func
vendor
func.yaml

View File

@@ -1,25 +0,0 @@
# Postgres INSERT/SELECT Function Image
This function executes an INSERT or SELECT against a table in a given postgres server.
```
# Create your func.yaml file
fn init --name func-postgres
# Build the function
fn build
# Test it
./test.sh
# Push it to Docker Hub
fn push
# Create routes to this function on Fn
fn apps create <YOUR_APP> --config SERVER=<POSTGRES>
fn routes create --config TABLE=<TABLE_NAME> --config COMMAND=INSERT <YOUR_APP> /<TABLE_NAME>/insert
fn routes create --config TABLE=<TABLE_NAME> --config COMMAND=SELECT <YOUR_APP> /<TABLE_NAME>/select
```
Now you can call your function on Fn:
```
echo <JSON_RECORD> | fn call /<YOUR_APP>/<TABLE_NAME>/insert
echo <JSON_QUERY> | fn call /<YOUR_APP>/<TABLE_NAME>/select
```

View File

@@ -1,103 +0,0 @@
package main
import (
"bytes"
"database/sql"
"encoding/json"
"io/ioutil"
"log"
"os"
"strconv"
"github.com/pkg/errors"
_ "github.com/lib/pq"
)
var (
// command to execute, 'SELECT' or 'INSERT'
command = os.Getenv("FN_HEADER_COMMAND")
// postgres host:port, e.g. 'postgres:5432'
server = os.Getenv("FN_HEADER_SERVER")
// postgres table name
table = os.Getenv("FN_HEADER_TABLE")
)
func main() {
req, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatal(errors.Wrap(err, "failed to read stdin"))
}
db, err := sql.Open("postgres", "postgres://postgres@"+server+"?sslmode=disable")
if err != nil {
log.Println("Failed to connect to postgres server")
log.Fatal(err)
return
}
switch command {
case "SELECT":
if resp, err := selectCommand(req, db); err != nil {
log.Fatal(errors.Wrap(err, "select command failed"))
} else {
log.Println(resp)
}
case "INSERT":
if err := insertCommand(req, db); err != nil {
log.Fatal(errors.Wrap(err, "insert command failed"))
}
default:
log.Fatalf("invalid command: %q", command)
}
}
func selectCommand(req []byte, db *sql.DB) (string, error) {
// Parse request JSON
var params map[string]interface{}
if err := json.Unmarshal(req, &params); err != nil {
return "", errors.Wrap(err, "failed to parse json")
}
// Build query and gather arguments
var query bytes.Buffer
var args []interface{}
query.WriteString("SELECT json_agg(t) FROM (SELECT * FROM ")
query.WriteString(table)
query.WriteString(" WHERE")
first := true
arg := 1
for k, v := range params {
args = append(args, v)
if !first {
query.WriteString(" AND")
}
query.WriteString(" ")
query.WriteString(k)
query.WriteString("=$")
query.WriteString(strconv.Itoa(arg))
arg += 1
first = false
}
query.WriteString(") AS t")
// Execute query
r := db.QueryRow(query.String(), args...)
var resp string
if err := r.Scan(&resp); err != nil {
return "", errors.Wrap(err, "failed to execute select query")
}
return resp, nil
}
func insertCommand(req []byte, db *sql.DB) error {
q := "INSERT INTO " + table + " SELECT * FROM json_populate_record(null::" + table + ", $1)"
_, err := db.Exec(q, req)
if err != nil {
return errors.Wrap(err, "Failed to execute insert query")
}
return nil
}

View File

@@ -1,10 +0,0 @@
hash: 12ce0fe3e599891c7aeb6d5a99ff107b4f979e88ff5da7a6d5b1cf5cac8b1ad7
updated: 2017-01-20T22:48:30.561728713Z
imports:
- name: github.com/lib/pq
version: 67c3f2a8884c9b1aac5503c8d42ae4f73a93511c
subpackages:
- oid
- name: github.com/pkg/errors
version: 248dadf4e9068a0b3e79f02ed0a610d935de5302
testImports: []

View File

@@ -1,4 +0,0 @@
package: github.com/fnproject/functions/examples/postgres
import:
- package: github.com/lib/pq
- package: github.com/pkg/errors

View File

@@ -1,39 +0,0 @@
#!/bin/bash
set -x
docker stop test-postgres-func
docker rm test-postgres-func
docker run -p 5432:5432 --name test-postgres-func -d postgres
sleep 5s
docker run --rm -i --link test-postgres-func:postgres postgres psql -h postgres -U postgres -c 'CREATE TABLE people (first TEXT, last TEXT, age INTEGER);'
RECORD1='{
"first": "John",
"last": "Smith",
"age": 30
}'
echo $RECORD1 | fn run -e SERVER=postgres:5432 -e COMMAND=INSERT -e TABLE=people --link test-postgres-func:postgres
QUERY1='{
"last": "Smith"
}'
echo $QUERY1 | fn run -e SERVER=postgres:5432 -e COMMAND=SELECT -e TABLE=people --link test-postgres-func:postgres
RECORD2='{
"first": "Bob",
"last": "Smith",
"age": 43
}'
echo $RECORD2 | fn run -e SERVER=postgres:5432 -e COMMAND=INSERT -e TABLE=people --link test-postgres-func:postgres
echo $QUERY1 | fn run -e SERVER=postgres:5432 -e COMMAND=SELECT -e TABLE=people --link test-postgres-func:postgres
QUERY2='{
"first": "John",
"last": "Smith"
}'
echo $QUERY2 | fn run -e SERVER=postgres:5432 -e COMMAND=SELECT -e TABLE=people --link test-postgres-func:postgres
docker stop test-postgres-func
docker rm test-postgres-func

View File

@@ -1,2 +0,0 @@
/func
vendor

View File

@@ -1,5 +0,0 @@
FROM fnproject/go
ADD func .
ENTRYPOINT ["./func"]

View File

@@ -1,111 +0,0 @@
# Redis GET/SET Function Image
This function basically executes a GET/SET in a given redis server.
## Requirements
- Redis Server
- Functions API
## Development
### Building image locally
```
# SET BELOW TO YOUR DOCKER HUB USERNAME
USERNAME=YOUR_DOCKER_HUB_USERNAME
# build it
./build.sh
```
### Publishing to DockerHub
```
# tagging
docker run --rm -v "$PWD":/app treeder/bump patch
docker tag $USERNAME/func-redis:latest $USERNAME/func-redis:`cat VERSION`
# pushing to docker hub
docker push $USERNAME/func-redis
```
### Testing image
```
./test.sh
```
## Running it on Fn
### Let's define some environment variables
```
# Set your Function server address
# Eg. 127.0.0.1:8080
FUNCAPI=YOUR_FUNCTIONS_ADDRESS
# Set your Redis server address
# Eg. redis:6379
REDIS=YOUR_REDIS_ADDRESS
# Set your Redis server auth (if required)
REDIS_AUTH=REDIS_AUTH_KEY
```
### Running with Fn
With this command we are going to create an application with name `redis`.
```
curl -X POST --data '{
"app": {
"name": "redis",
"config": {
"server": "'$REDIS'"
"redis_auth": "'$REDIS_AUTH'"
}
}
}' http://$FUNCAPI/v1/apps
```
Now, we can create our routes
#### Route for set value
```
curl -X POST --data '{
"route": {
"image": "'$USERNAME'/func-redis",
"path": "/redis",
"config": {
"command": "SET"
}
}
}' http://$FUNCAPI/v1/apps/redis/routes
```
#### Route for get value
```
curl -X POST --data '{
"route": {
"image": "'$USERNAME'/func-redis",
"path": "/redis",
"config": {
"command": "GET"
}
}
}' http://$FUNCAPI/v1/apps/redis/routes
```
#### Testing function
Now that we created our Fn route, let's test our new route
```
curl -X POST --data '{"key": "name", "value": "Johnny"}' http://$FUNCAPI/r/redis/set
// "OK"
curl -X POST --data '{"key": "name"}' http://$FUNCAPI/r/redis/get
// "Johnny"
```

View File

@@ -1 +0,0 @@
0.0.1

View File

@@ -1,12 +0,0 @@
#!/bin/bash
set -ex
FUNCPKG=$(pwd | sed "s|$GOPATH/src/||")
# glide image to install dependencies
../build-glide.sh
docker run --rm -v "$PWD":/go/src/$FUNCPKG -w /go/src/$FUNCPKG glide up
# build image
docker run --rm -v "$PWD":/go/src/$FUNCPKG -w /go/src/$FUNCPKG fnproject/go:dev go build -o func
docker build -t username/func-redis .

View File

@@ -1,3 +0,0 @@
name: username/func-redis
build:
- ./build.sh

View File

@@ -1,76 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"github.com/garyburd/redigo/redis"
)
type payload struct {
Key string `json:"key"`
Value string `json:"value"`
}
func main() {
// Getting stdin
plStdin, _ := ioutil.ReadAll(os.Stdin)
// Transforming JSON to a *payload
var pl payload
err := json.Unmarshal(plStdin, &pl)
if err != nil {
log.Println("Invalid payload")
log.Fatal(err)
return
}
// Dialing redis server
c, err := redis.Dial("tcp", os.Getenv("SERVER"))
if err != nil {
log.Println("Failed to dial redis server")
log.Fatal(err)
return
}
// Authenticate to redis server if exists the password
if os.Getenv("REDIS_AUTH") != "" {
if _, err := c.Do("AUTH", os.Getenv("REDIS_AUTH")); err != nil {
log.Println("Failed to authenticate to redis server")
log.Fatal(err)
return
}
}
// Check if payload command is valid
if os.Getenv("COMMAND") != "GET" && os.Getenv("COMMAND") != "SET" {
log.Println("Invalid command")
return
}
// Execute command on redis server
var r interface{}
if os.Getenv("COMMAND") == "GET" {
r, err = c.Do("GET", pl.Key)
} else if os.Getenv("COMMAND") == "SET" {
r, err = c.Do("SET", pl.Key, pl.Value)
}
if err != nil {
log.Println("Failed to execute command on redis server")
log.Fatal(err)
return
}
// Convert reply to string
res, err := redis.String(r, err)
if err != nil {
return
}
// Print reply
fmt.Println(res)
}

View File

@@ -1,9 +0,0 @@
hash: 8c667282524602aac09a157244397d581f19d256b95a725a4782ab3c67ebb08a
updated: 2016-11-01T02:56:55.36346607Z
imports:
- name: github.com/garyburd/redigo
version: 8873b2f1995f59d4bcdd2b0dc9858e2cb9bf0c13
subpackages:
- internal
- redis
testImports: []

View File

@@ -1,6 +0,0 @@
package: github.com/fnproject/functions/examples/redis
import:
- package: github.com/garyburd/redigo
version: ^1.0.0
subpackages:
- redis

View File

@@ -1,21 +0,0 @@
#!/bin/bash
set -x
./build.sh
PAYLOAD='{
"key": "test",
"value": "123"
}'
# test it
docker stop test-redis-func
docker rm test-redis-func
docker run -p 6379:6379 --name test-redis-func -d redis
echo $PAYLOAD | docker run --rm -i -e SERVER=redis:6379 -e COMMAND=SET --link test-redis-func:redis username/func-redis
echo $PAYLOAD | docker run --rm -i -e SERVER=redis:6379 -e COMMAND=GET --link test-redis-func:redis username/func-redis
docker stop test-redis-func
docker rm test-redis-func

View File

@@ -1,5 +0,0 @@
FROM username/lambda-nodejs
ADD example.js ./example.js
CMD ["example.run"]

View File

@@ -1,7 +0,0 @@
IMAGE=username/lambda-node-aws-example
create: Dockerfile
docker build -t $(IMAGE) .
test:
docker run --rm -it -e PAYLOAD_FILE=/mnt/example-payload.json -e AWS_ACCESS_KEY_ID=change-here -e AWS_SECRET_ACCESS_KEY=change-here -v `pwd`:/mnt $(IMAGE)

View File

@@ -1,2 +0,0 @@
Example on how to use AWS S3 in a lambda function.

View File

@@ -1,5 +0,0 @@
{
"bucket": "iron-lambda-demo-images",
"srcKey": "waterfall.jpg",
"dstKey": "waterfall-1024.jpg"
}

View File

@@ -1,70 +0,0 @@
var im = require('imagemagick');
var fs = require('fs');
var AWS = require('aws-sdk');
// cb(err, resized) is called with true if resized.
function resizeIfRequired(err, features, fileSrc, fileDst, cb) {
if (err) {
cb(err, false);
return;
}
var targetWidth = 1024;
if (features.width > targetWidth)
{
im.resize({
srcPath : fileSrc,
dstPath : fileDst,
width : targetWidth,
format: 'jpg'
}, function(err) {
if (err) {
cb(err, false);
} else {
cb(null, true);
}
});
} else {
cb(null, false);
}
}
exports.run = function(event, context) {
var bucketName = event['bucket']
var srcImageKey = event['srcKey']
var dstImageKey = event['dstKey']
var s3 = new AWS.S3();
s3.getObject({
Bucket: bucketName,
Key: srcImageKey
}, function (err, data) {
if (err) throw err;
var fileSrc = '/tmp/image-src.dat';
var fileDst = '/tmp/image-dst.dat'
fs.writeFileSync(fileSrc, data.Body)
im.identify(fileSrc, function(err, features) {
resizeIfRequired(err, features, fileSrc, fileDst, function(err, resized) {
if (err) throw err;
if (resized) {
s3.putObject({
Bucket:bucketName,
Key: dstImageKey,
Body: fs.createReadStream(fileDst),
ContentType: 'image/jpeg',
ACL: 'public-read',
}, function (err, data) {
if (err) throw err;
context.succeed("Image updated");
});
} else {
context.succeed("Image not updated");
}
});
});
});
}

View File

@@ -1,5 +0,0 @@
source 'https://rubygems.org'
gem 'httparty', '~> 0.14.0'
gem 'slack_webhooks'
gem 'json', '> 1.8.2'

View File

@@ -1,32 +0,0 @@
## Quick Example for a SlackBot command in Ruby
This example will show you how to test and deploy a SlackBot command to Fn.
```sh
# create your func.yaml file
fn init
# build the function - install dependencies from json gem
fn build
# test it
cat slack.payload | fn run
# push it to Docker Hub
fn push
# Create a route to this function on Fn
fn routes create slackbot /guppy
# Change the route response header content-type to application/json
fn routes headers set slackbot /guppy Content-Type application/json
# test it remotely
cat slack.payload | fn call slackbot /guppy
```
## Create a Slash Command integration in Slack
In Slack, go to Integrations, find Slash Commands, click Add, type in / as the command then click Add again. On the next page, take the Fn route URL and paste it into the URL field then click Save Integration.
If running in localhost, use [ngrok](https://github.com/inconshreveable/ngrok).
# Try it out!
In slack, type /<COMMAND> [options] and you'll see the magic!

View File

@@ -1,37 +0,0 @@
{
"tableflip": {"image_url": "http://i.imgur.com/oGwPRux.png"},
"shrug": {"image_url": "http://www.theblaze.com/wp-content/uploads/2015/03/Google-comment-gif.gif"},
"forlorn": {"image_url": "https://lh4.googleusercontent.com/-Jp85Ek_5jJc/UdEYqhHzuLI/AAAAAAACF3s/U708yywLDCQ/w700-h412-no/forlorn%2Bcat.gif"},
"beardscratch": {"image_url": "https://lh5.googleusercontent.com/-gfUwQSvd1bs/UjjHeU-b6HI/AAAAAAAC81o/xtMpBn1F87E/w958-h539-no/beardman.gif"},
"atlast": {"image_url": "https://lh4.googleusercontent.com/-jzywmNWCPps/UdEYqnq2ECI/AAAAAAACF3w/eNnS_KXHzN0/w480-h226-no/morpheus-at-last.gif"},
"ohyeah": {"image_url": "https://lh4.googleusercontent.com/-IqiWUKEzd_U/UnmdxBZp-bI/AAAAAAADFf4/l7dyXzMTdDs/w245-h285-no/code-05.gif"},
"facepalm": {"image_url": "https://lh4.googleusercontent.com/-kbD1OZrG7kI/UnmdupWzP1I/AAAAAAADFfg/g3SXEo1JXIs/s300-no/cQEBX.gif"},
"peak": {"image_url": "https://lh4.googleusercontent.com/-V9zKyTXHrD4/Unmdzpnb1UI/AAAAAAADFgc/-61luVxML_M/w500-h320-no/efuITnY.gif"},
"right": {"image_url": "https://lh6.googleusercontent.com/-vPkV8r6Mhy0/UnmdtC490bI/AAAAAAADFfM/Hil5QyuTX78/w500-h221-no/HuVXfMb.gif"},
"sup": {"image_url": "https://lh3.googleusercontent.com/-iqoKtA72rIo/Unmd7o17ZUI/AAAAAAADFhM/7-MLxTAXU7Q/w470-h248-no/yC5BsCS.gif"},
"nod": {"image_url": "https://lh4.googleusercontent.com/-byviKRrwH5c/Unny4gWkMqI/AAAAAAADFkc/OckIZqXDCY4/w500-h225-no/iPOS6.gif"},
"thumbsup": {"image_url": "https://lh4.googleusercontent.com/-1l8KOia5vis/Unny3Jw851I/AAAAAAADFkY/bRLzh5VyPbc/w312-h176-no/ZCGrZ.gif"},
"dance1": {"image_url": "https://lh5.googleusercontent.com/-5sN8WVo6Myc/Unny6ZsWZGI/AAAAAAADFk8/JssUbaDRG_M/w250-h303-no/mbjD3.gif"},
"dance2": {"image_url": "https://lh5.googleusercontent.com/-2aPDr_v7Jgc/Unny3pXSfvI/AAAAAAADFkI/KyloHLe5DaM/w400-h234-no/gary.gif"},
"dance3": {"image_url": "https://lh5.googleusercontent.com/-rqM2JLfd2xg/Unny2Pvpy1I/AAAAAAADFjY/Zx6D93XEws4/w480-h340-no/1tumblr_lgp6q5NhE21qcjtu8o1_500.gif"},
"sidepunch": {"image_url": "https://lh6.googleusercontent.com/-HZYoVvXWc_s/UnmfpjqTbiI/AAAAAAADFic/q3dGlwfxV2w/w500-h247-no/code-27.gif"},
"tyrionbird": {"image_url": "https://lh5.googleusercontent.com/-6frbpEP6M3g/Unmfl9i3fcI/AAAAAAADFh8/SOpKxwyOk3k/w300-h149-no/code-19.gif"},
"obiwan": {"image_url": "http://i.giphy.com/2vERRTu559XQk.gif"},
"wat": {"image_url": "http://i.giphy.com/qxtxlL4sFFle.gif"},
"ivan": {"image_url": "http://i.giphy.com/2OMHmoFMiJjfq.gif"},
"freakout": {"image_url": "http://i.giphy.com/FwpecpDvcu7vO.gif"},
"boom-chuck": {"image_url": "http://i.giphy.com/10PkQyXWagNrqg.gif"},
"boom-drake": {"image_url": "http://i.giphy.com/8vW915bv0DqXC.gif"},
"boom-dany": {"image_url": "http://i.giphy.com/LrN9NbJNp9SWQ.gif"},
"boom-moon": {"image_url": "http://i.giphy.com/ydMNTWYVjSEFi.gif"},
"boom-franco": {"image_url": "http://i.giphy.com/b3u8anVaWFQ9G.gif"},
"boom-starcraft": {"image_url": "http://i.giphy.com/5xtDarxQ05ee2ktRA5i.gif"},
"boom-anime": {"image_url": "http://i.giphy.com/fMNNDKtOVbxSM.gif"},
"boom-denzel":{"image_url":"http://i.imgur.com/1LXMDns.gif"},
"boom-ump":{"image_url":"http://cdn0.sbnation.com/imported_assets/1160455/umpboom.gif"},
"fun": {"image_url": "http://s-ak.buzzfed.com/static/imagebuzz/web04/2011/3/14/10/anigif_fun-fun-fun-29834-1300112565-20.gif"},
"fthis": {"image_url": "http://i.giphy.com/iICCUuGJOhOnK.gif"},
"disappear": {"image_url": "http://i.giphy.com/4pMX5rJ4PYAEM.gif"},
"cry": {"image_url": "http://i.giphy.com/10tIjpzIu8fe0.gif"},
"micdrop":{"image_url":"http://i.imgur.com/9XHl18c.gif"}
}

View File

@@ -1,44 +0,0 @@
require_relative 'bundle/bundler/setup'
require 'slack_webhooks'
payload = STDIN.read
#STDERR.puts "PAYLOAD: #{payload}"
images = JSON.load(File.open('commands.json'))
response = {}
attachment = {
"fallback" => "wat?!",
"text" => "",
"image_url" => "http://i.imgur.com/7kZ562z.jpg"
}
help = "Available options are:\n"
images.each_key { |k| help << "* #{k}\n" }
response = {}
a = []
response[:attachments] = a
if payload.nil? || payload.strip == ""
response[:text] = help
a << attachment
puts response.to_json
exit
end
sh = SlackWebhooks::Hook.new('guppy', payload, "")
r = images[sh.text]
if r
a << {image_url: r['image_url'], text: ""}
response[:response_type] = "in_channel"
response[:text] = "guppy #{sh.text}"
else
response[:text] = help
a << attachment
end
puts response.to_json

View File

@@ -1 +0,0 @@
token=somerandomtoken&team_id=someteamid&team_domain=somename&channel_id=somechannelid&channel_name=directmessage&user_id=someid&user_name=someuser&command=%2Fguppy&text=freakout

View File

@@ -1,16 +0,0 @@
# Example of Fn test framework - running functions locally
This example will show you how to run a test suite on a function.
```sh
# build the test image (testframework:0.0.1)
fn build
# test it
fn test
```
Alternatively, you can force a rebuild before the test suite with:
```sh
# build and test it
fn test -b
```

View File

@@ -1,14 +0,0 @@
package main
import (
"fmt"
"os"
)
func main() {
envvar := os.Getenv("FN_HEADER_ENVVAR")
if envvar != "" {
fmt.Println("FN_HEADER_ENVVAR:", envvar)
}
fmt.Println("hw")
}

View File

@@ -1,15 +0,0 @@
name: testframework
version: 0.0.1
runtime: go
entrypoint: ./func
path: /tests
tests:
- name: simple
out: |
hw
- name: envvar
out: |
FN_HEADER_ENVVAR: trololo
hw
env:
envvar: trololo

View File

@@ -1,14 +0,0 @@
# Example of Fn test framework - running functions remotely
This example will show you how to run a test suite on a function.
```sh
# build the test image (username/functions-testframework:0.0.1)
fn build
# push it
fn push
# create a route for the testframework
fn routes create testframework
# test it
fn test --remote testframework
```

View File

@@ -1,14 +0,0 @@
package main
import (
"fmt"
"os"
)
func main() {
envvar := os.Getenv("HEADER_ENVVAR")
if envvar != "" {
fmt.Println("HEADER_ENVVAR:", envvar)
}
fmt.Println("hw")
}

View File

@@ -1,15 +0,0 @@
name: treeder/functions-testframework
version: 0.0.1
runtime: go
entrypoint: ./func
path: /tests
tests:
- name: simple
out: |
hw
- name: envvar
out: |
FN_HEADER_ENVVAR: trololo
hw
env:
envvar: trololo

View File

@@ -1,2 +0,0 @@
/func
vendor

Some files were not shown because too many files have changed in this diff Show More