├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── examples ├── README.md ├── go │ ├── Makefile │ ├── env.example │ ├── hipchat │ │ ├── functions.yml │ │ └── hipchat.go │ ├── kafka-http │ │ ├── functions.yml │ │ └── kafka.go │ ├── kafka │ │ ├── functions.yml │ │ └── kafka.go │ ├── mail │ │ ├── functions.yml │ │ └── mail.go │ └── redis │ │ ├── functions.yml │ │ └── redis.go ├── nodejs │ ├── Makefile │ ├── env.example │ ├── hipchat │ │ ├── functions.yml │ │ └── hipchat.js │ ├── kafka-http │ │ ├── functions.yml │ │ └── kafka.js │ ├── mail │ │ ├── functions.yml │ │ ├── mail.js │ │ └── package.json │ └── redis │ │ ├── functions.yml │ │ ├── package.json │ │ └── redis.js ├── perl │ ├── Makefile │ ├── env.example │ ├── hipchat │ │ ├── functions.yml │ │ └── hipchat.pm │ ├── kafka-http │ │ ├── functions.yml │ │ └── kafka.pm │ ├── mail │ │ ├── functions.yml │ │ └── mail.pm │ └── redis │ │ ├── functions.yml │ │ └── redis.pm └── python │ ├── Makefile │ ├── env.example │ ├── hipchat │ ├── functions.yml │ └── hipchat.py │ ├── kafka-http │ ├── functions.yml │ └── kafka.py │ ├── mail │ ├── functions.yml │ └── mail.py │ └── redis │ ├── functions.yml │ ├── redis_db.py │ └── requirements.txt └── go-sdk └── event └── event.go /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to OVH Functions 2 | 3 | This project accepts contributions. In order to contribute, you should 4 | pay attention to a few things: 5 | 6 | 1. your code must be fully documented 7 | 2. your work must be signed 8 | 3. GitHub Pull Requests 9 | 10 | ## Submitting Modifications: 11 | 12 | The contributions should be github Pull Requests. The guidelines are the same 13 | as the patch submission for the Linux kernel except for the DCO which 14 | is defined below. The guidelines are defined in the 15 | 'SubmittingPatches' file, available in the directory 'Documentation' 16 | of the Linux kernel source tree. 17 | 18 | It can be accessed online too: 19 | 20 | https://www.kernel.org/doc/Documentation/SubmittingPatches 21 | 22 | You can submit your patches via GitHub 23 | 24 | ## Licensing for new files: 25 | 26 | Functions is licensed under a (modified) BSD license. Anything contributed to 27 | OVH Functions must be released under this license. 28 | 29 | When introducing a new file into the project, please make sure it has a 30 | copyright header making clear under which license it''s being released. 31 | 32 | ## Developer Certificate of Origin: 33 | 34 | ``` 35 | To improve tracking of contributions to this project we will use a 36 | process modeled on the modified DCO 1.1 and use a "sign-off" procedure 37 | on patches that are being contributed. 38 | 39 | The sign-off is a simple line at the end of the explanation for the 40 | patch, which certifies that you wrote it or otherwise have the right 41 | to pass it on as an open-source patch. The rules are pretty simple: 42 | if you can certify the below: 43 | 44 | By making a contribution to this project, I certify that: 45 | 46 | (a) The contribution was created in whole or in part by me and I have 47 | the right to submit it under the open source license indicated in 48 | the file; or 49 | 50 | (b) The contribution is based upon previous work that, to the best of 51 | my knowledge, is covered under an appropriate open source License 52 | and I have the right under that license to submit that work with 53 | modifications, whether created in whole or in part by me, under 54 | the same open source license (unless I am permitted to submit 55 | under a different license), as indicated in the file; or 56 | 57 | (c) The contribution was provided directly to me by some other person 58 | who certified (a), (b) or (c) and I have not modified it. 59 | 60 | (d) The contribution is made free of any other party''s intellectual 61 | property claims or rights. 62 | 63 | (e) I understand and agree that this project and the contribution are 64 | public and that a record of the contribution (including all 65 | personal information I submit with it, including my sign-off) is 66 | maintained indefinitely and may be redistributed consistent with 67 | this project or the open source license(s) involved. 68 | then you just add a line saying 69 | ``` 70 | Signed-off-by: Random J Developer 71 | ``` 72 | using your real name (sorry, no pseudonyms or anonymous contributions.) 73 | 74 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, OVH SAS. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of OVH SAS nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY OVH SAS AND CONTRIBUTORS ``AS IS'' AND ANY 17 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL OVH SAS AND CONTRIBUTORS BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OVH Functions -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # OVH Functions examples 2 | 3 | Go to [docs.functions.ovh](https://docs.functions.ovh/) if you don't have the ovh-functions cli yet. 4 | 5 | ## Environment variables 6 | 7 | These examples are using environment variables. 8 | See corresponding functions.yml config to know which ones. 9 | 10 | ## Examples 11 | 12 | ### Redis SET/GET 13 | 14 | Set and get Redis key/value. 15 | [code](nodejs/redis) 16 | 17 | ``` 18 | echo '{"k":"date","v":"'$(date)'"}' | ovh-functions exec redis.set 19 | OK 20 | 21 | echo '{"k":"date"}' | ovh-functions exec redis.get 22 | vendredi 21 avril 2017, 01:23:36 (UTC+0200) 23 | ``` 24 | 25 | ### Mail 26 | 27 | Send an email. 28 | [code](nodejs/mail) 29 | 30 | ``` 31 | echo '{"to":"", "subject":"Time", "text":"'$(date)'"}' | \ 32 | ovh-functions exec mail.send 33 | {"accepted":[""],"rejected":[],"response":"250 2.0.0 OK ..."} 34 | ``` 35 | 36 | ### Kafka HTTPS 37 | 38 | Produce a message in Kafka using the OVH Kafka HTTPS proxy. 39 | [code](nodejs/kafka) 40 | 41 | ``` 42 | echo '{"message":"'$(date)'"}' | \ 43 | ovh-functions exec kafka.pub 44 | [{"Value":"\"vendredi 21 avril 2017, 01:13:49 (UTC+0200)\""}] 45 | 46 | ``` 47 | 48 | ### Hipchat 49 | 50 | Send an Hipchat notification. 51 | [code](nodejs/hipchat) 52 | 53 | ``` 54 | echo '{"message":"'$(date)'"}' | \ 55 | ovh-functions exec hipchat.notify 56 | {"statusCode":204,"location":"https://api.hipchat.com/v2/room/123456/history/7a254146-...} 57 | ``` 58 | -------------------------------------------------------------------------------- /examples/go/Makefile: -------------------------------------------------------------------------------- 1 | deploy: 2 | cd hipchat && ovh-functions deploy 3 | cd kafka-http && ovh-functions deploy 4 | cd kafka && ovh-functions deploy 5 | cd mail && ovh-functions deploy 6 | cd redis && ovh-functions deploy 7 | 8 | exec: exec-hipchat exec-kafka-http exec-kafka exec-mail exec-redis 9 | 10 | exec-hipchat: 11 | echo '{"message":"'$$(date)'"}' | \ 12 | ovh-functions exec hipchat.notify 13 | 14 | exec-kafka-http: 15 | echo $(date) | \ 16 | ovh-functions exec kafka-http.pub 17 | 18 | exec-kafka: 19 | echo $(date) | \ 20 | ovh-functions exec kafka.pub 21 | 22 | exec-mail: 23 | echo '{"to":["hello@functions.ovh"], "subject":"Time", "text":"'$$(date)'"}' | \ 24 | ovh-functions exec mail.send 25 | 26 | exec-redis: 27 | echo '{"k":"date","v":"'$$(date)'"}' | ovh-functions exec redis.set 28 | echo '{"k":"date"}' | ovh-functions exec redis.get -------------------------------------------------------------------------------- /examples/go/env.example: -------------------------------------------------------------------------------- 1 | HIPCHAT_ROOM_ID= 2 | HIPCHAT_AUTH_TOKEN= 3 | 4 | KAFKA_HTTP_HOST=https:// 5 | KAFKA_HTTP_USER= 6 | KAFKA_HTTP_PASSWORD= 7 | KAFKA_HTTP_TOPIC= 8 | 9 | KAFKA_HOST=: 10 | KAFKA_USER= 11 | KAFKA_PASSWORD= 12 | KAFKA_TOPIC= 13 | 14 | REDIS_HOST= 15 | REDIS_DB= 16 | REDIS_PASSWORD= 17 | 18 | MAIL_FROM= 19 | MAIL_SMTP_URL=smtps://:@ 20 | 21 | MAIL_SMTP_USERNAME= 22 | MAIL_SMTP_PASSWORD= 23 | MAIL_SMTP_HOST= 24 | MAIL_SMTP_PORT= -------------------------------------------------------------------------------- /examples/go/hipchat/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | hipchat.notify: 3 | runtime: go 4 | handler: hipchat.Notify 5 | environment: 6 | HIPCHAT_ROOM_ID: ${env:HIPCHAT_ROOM_ID} 7 | HIPCHAT_AUTH_TOKEN: ${env:HIPCHAT_AUTH_TOKEN} -------------------------------------------------------------------------------- /examples/go/hipchat/hipchat.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "errors" 7 | "net/http" 8 | "os" 9 | 10 | "github.com/ovhlabs/functions/go-sdk/event" 11 | ) 12 | 13 | type Data struct { 14 | Color string `json:"color"` 15 | Message string `json:"message"` 16 | MessageFormat string `json:"message_format"` 17 | } 18 | 19 | func Notify(event event.Event) (string, error) { 20 | roomID := os.Getenv("HIPCHAT_ROOM_ID") 21 | authToken := os.Getenv("HIPCHAT_AUTH_TOKEN") 22 | url := "https://api.hipchat.com/v2/room/" + roomID + "/notification?auth_token=" + authToken 23 | 24 | // parse the event.Data string 25 | var data Data 26 | err := json.Unmarshal([]byte(event.Data), &data) 27 | if err != nil { 28 | return "", err 29 | } 30 | 31 | // prepare the request body 32 | data.MessageFormat = "html" 33 | if data.Message == "" { 34 | return "", errors.New("message not found") 35 | } 36 | if data.Color == "" { 37 | data.Color = "green" 38 | } 39 | jsonBody, err := json.Marshal(data) 40 | if err != nil { 41 | return "", err 42 | } 43 | 44 | // send the request 45 | resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonBody)) 46 | if err != nil { 47 | return "", err 48 | } 49 | defer resp.Body.Close() 50 | 51 | // check the response status 52 | if resp.StatusCode != 204 { 53 | return "", errors.New("failed to send " + data.Message) 54 | } 55 | 56 | return "OK", err 57 | } 58 | -------------------------------------------------------------------------------- /examples/go/kafka-http/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | kafka-http.pub: 3 | runtime: go 4 | handler: kafka.Pub 5 | environment: 6 | KAFKA_HOST: ${env:KAFKA_HTTP_HOST} 7 | KAFKA_USER: ${env:KAFKA_HTTP_USER} 8 | KAFKA_PASSWORD: ${env:KAFKA_HTTP_PASSWORD} 9 | KAFKA_TOPIC: ${env:KAFKA_HTTP_TOPIC} -------------------------------------------------------------------------------- /examples/go/kafka-http/kafka.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "io/ioutil" 7 | "net/http" 8 | "os" 9 | 10 | "github.com/ovhlabs/functions/go-sdk/event" 11 | ) 12 | 13 | func Pub(event event.Event) (string, error) { 14 | topic := os.Getenv("KAFKA_TOPIC") 15 | host := os.Getenv("KAFKA_HOST") 16 | user := os.Getenv("KAFKA_USER") 17 | password := os.Getenv("KAFKA_PASSWORD") 18 | 19 | if event.Data == "" { 20 | return "", errors.New("data not found") 21 | } 22 | 23 | // prepares the request 24 | client := &http.Client{} 25 | url := host + "/topic/" + topic + "?format=raw" 26 | req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(event.Data))) 27 | if err != nil { 28 | return "", err 29 | } 30 | req.SetBasicAuth(user, password) 31 | 32 | // sends the request 33 | resp, err := client.Do(req) 34 | if err != nil { 35 | return "", err 36 | } 37 | defer resp.Body.Close() 38 | 39 | body, err := ioutil.ReadAll(resp.Body) 40 | 41 | return string(body), err 42 | } 43 | -------------------------------------------------------------------------------- /examples/go/kafka/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | kafka.pub: 3 | runtime: go 4 | handler: kafka.Pub 5 | environment: 6 | KAFKA_HOST: ${env:KAFKA_HOST} 7 | KAFKA_USER: ${env:KAFKA_USER} 8 | KAFKA_PASSWORD: ${env:KAFKA_PASSWORD} 9 | KAFKA_TOPIC: ${env:KAFKA_TOPIC} -------------------------------------------------------------------------------- /examples/go/kafka/kafka.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/Shopify/sarama" 9 | "github.com/ovhlabs/functions/go-sdk/event" 10 | ) 11 | 12 | func Pub(event event.Event) (string, error) { 13 | topic := os.Getenv("KAFKA_TOPIC") 14 | host := os.Getenv("KAFKA_HOST") 15 | user := os.Getenv("KAFKA_USER") 16 | password := os.Getenv("KAFKA_PASSWORD") 17 | 18 | if event.Data == "" { 19 | return "", errors.New("data not found") 20 | } 21 | 22 | var config = sarama.NewConfig() 23 | config.Net.TLS.Enable = true 24 | config.Net.SASL.Enable = true 25 | config.Net.SASL.User = user 26 | config.Net.SASL.Password = password 27 | config.ClientID = user 28 | config.Producer.Return.Successes = true 29 | 30 | var err error 31 | producer, err := sarama.NewSyncProducer([]string{host}, config) 32 | if err != nil { 33 | return "", err 34 | } 35 | defer producer.Close() 36 | 37 | msg := &sarama.ProducerMessage{Topic: topic, Value: sarama.StringEncoder(event.Data)} 38 | 39 | partition, offset, err := producer.SendMessage(msg) 40 | if err != nil { 41 | return "", err 42 | } 43 | 44 | return fmt.Sprintf("Message '%s' sent to partition %d at offset %d\n", event.Data, partition, offset), nil 45 | } 46 | -------------------------------------------------------------------------------- /examples/go/mail/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | mail.send: 3 | runtime: go 4 | handler: mail.Send 5 | environment: 6 | MAIL_SMTP_USERNAME: ${env:MAIL_SMTP_USERNAME} 7 | MAIL_SMTP_PASSWORD: ${env:MAIL_SMTP_PASSWORD} 8 | MAIL_SMTP_HOST: ${env:MAIL_SMTP_HOST} 9 | MAIL_SMTP_PORT: ${env:MAIL_SMTP_PORT} -------------------------------------------------------------------------------- /examples/go/mail/mail.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "net/smtp" 6 | "os" 7 | "strings" 8 | 9 | "github.com/ovhlabs/functions/go-sdk/event" 10 | ) 11 | 12 | type Data struct { 13 | To []string `json:"to"` 14 | Subject string `json:"subject"` 15 | Text string `json:"text"` 16 | } 17 | 18 | func Send(event event.Event) (string, error) { 19 | host := os.Getenv("MAIL_SMTP_HOST") 20 | port := os.Getenv("MAIL_SMTP_PORT") 21 | username := os.Getenv("MAIL_SMTP_USERNAME") 22 | password := os.Getenv("MAIL_SMTP_PASSWORD") 23 | 24 | var data Data 25 | err := json.Unmarshal([]byte(event.Data), &data) 26 | if err != nil { 27 | return "", err 28 | } 29 | 30 | msg := []byte("To: " + strings.Join(data.To[:], " ") + "\r\n" + 31 | "Subject: " + data.Subject + "\r\n" + 32 | "\r\n" + 33 | data.Text + "\r\n", 34 | ) 35 | 36 | auth := smtp.PlainAuth("", username, password, host) 37 | err = smtp.SendMail(host+":"+port, auth, username, data.To, msg) 38 | if err != nil { 39 | return "", err 40 | } 41 | 42 | return "Mail sent", nil 43 | } 44 | -------------------------------------------------------------------------------- /examples/go/redis/functions.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Redis URL syntax: : 3 | # 4 | functions: 5 | redis.set: 6 | runtime: go 7 | handler: redis.Set 8 | environment: 9 | REDIS_HOST: ${env:REDIS_HOST} 10 | REDIS_DB: ${env:REDIS_DB} 11 | REDIS_PASSWORD: ${env:REDIS_PASSWORD} 12 | redis.get: 13 | runtime: go 14 | handler: redis.Get 15 | environment: 16 | REDIS_HOST: ${env:REDIS_HOST} 17 | REDIS_DB: ${env:REDIS_DB} 18 | REDIS_PASSWORD: ${env:REDIS_PASSWORD} -------------------------------------------------------------------------------- /examples/go/redis/redis.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "os" 6 | "strconv" 7 | 8 | "github.com/ovhlabs/functions/go-sdk/event" 9 | redis "gopkg.in/redis.v5" 10 | ) 11 | 12 | type Data struct { 13 | Key string `json:"key"` 14 | Value string `json:"value"` 15 | } 16 | 17 | func Set(event event.Event) (string, error) { 18 | var data Data 19 | err := json.Unmarshal([]byte(event.Data), &data) 20 | if err != nil { 21 | return "", err 22 | } 23 | 24 | result, err := NewRedisClient().Set(data.Key, data.Value, 0).Result() 25 | if err != nil { 26 | return "", err 27 | } 28 | 29 | return result, nil 30 | } 31 | 32 | func Get(event event.Event) (string, error) { 33 | var data Data 34 | err := json.Unmarshal([]byte(event.Data), &data) 35 | if err != nil { 36 | return "", err 37 | } 38 | 39 | value, err := NewRedisClient().Get(data.Key).Result() 40 | if err != nil { 41 | return "", err 42 | } 43 | 44 | return value, nil 45 | } 46 | 47 | func NewRedisClient() *redis.Client { 48 | host := os.Getenv("REDIS_HOST") 49 | password := os.Getenv("REDIS_PASSWORD") 50 | db, _ := strconv.ParseInt(os.Getenv("REDIS_DB"), 10, 0) 51 | 52 | client := redis.NewClient(&redis.Options{ 53 | Addr: host, 54 | Password: password, 55 | DB: int(db), 56 | }) 57 | 58 | return client 59 | } 60 | -------------------------------------------------------------------------------- /examples/nodejs/Makefile: -------------------------------------------------------------------------------- 1 | deploy: 2 | cd hipchat && ovh-functions deploy 3 | cd kafka-http && ovh-functions deploy 4 | cd mail && ovh-functions deploy 5 | cd redis && ovh-functions deploy 6 | 7 | exec: exec-hipchat exec-kafka-http exec-mail exec-redis 8 | 9 | exec-hipchat: 10 | echo '{"message":"'$$(date)'"}' | \ 11 | ovh-functions exec hipchat.notify 12 | 13 | exec-kafka-http: 14 | echo $(date) | \ 15 | ovh-functions exec kafka.pub 16 | 17 | exec-mail: 18 | echo '{"to":"hello@functions.ovh", "subject":"Time", "text":"'$$(date)'"}' | \ 19 | ovh-functions exec mail.send 20 | 21 | exec-redis: 22 | echo '{"k":"date","v":"'$$(date)'"}' | ovh-functions exec redis.set 23 | echo '{"k":"date"}' | ovh-functions exec redis.get 24 | -------------------------------------------------------------------------------- /examples/nodejs/env.example: -------------------------------------------------------------------------------- 1 | HIPCHAT_ROOM_ID= 2 | HIPCHAT_AUTH_TOKEN= 3 | 4 | KAFKA_HOST=https://: 5 | KAFKA_USER= 6 | KAFKA_PASSWORD= 7 | KAFKA_TOPIC= 8 | 9 | REDIS_URL=redis://x:@:/ 10 | 11 | MAIL_FROM= 12 | MAIL_SMTP_URL=smtps://:@ -------------------------------------------------------------------------------- /examples/nodejs/hipchat/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | hipchat.notify: 3 | runtime: nodejs 4 | handler: hipchat.notify 5 | environment: 6 | HIPCHAT_ROOM_ID: ${env:HIPCHAT_ROOM_ID} 7 | HIPCHAT_AUTH_TOKEN: ${env:HIPCHAT_AUTH_TOKEN} -------------------------------------------------------------------------------- /examples/nodejs/hipchat/hipchat.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | 3 | exports.notify = function(event, callback) { 4 | var roomID = process.env.HIPCHAT_ROOM_ID 5 | var authToken = process.env.HIPCHAT_AUTH_TOKEN 6 | 7 | if (!event.data.message) return callback(null, "message not found") 8 | 9 | var req = { 10 | method: 'POST', 11 | uri: 'https://api.hipchat.com/v2/room/'+roomID+'/notification?auth_token='+authToken, 12 | json: { 13 | color: event.data.color || 'green', 14 | message_format: 'html', 15 | message: event.data.message 16 | } 17 | } 18 | 19 | request(req, function (error, resp) { 20 | if (error) return callback(error) 21 | callback(null, JSON.stringify(resp)) 22 | }) 23 | } -------------------------------------------------------------------------------- /examples/nodejs/kafka-http/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | kafka.pub: 3 | runtime: nodejs 4 | handler: kafka.pub 5 | environment: 6 | KAFKA_HOST: ${env:KAFKA_HOST} 7 | KAFKA_USER: ${env:KAFKA_USER} 8 | KAFKA_PASSWORD: ${env:KAFKA_PASSWORD} 9 | KAFKA_TOPIC: ${env:KAFKA_TOPIC} -------------------------------------------------------------------------------- /examples/nodejs/kafka-http/kafka.js: -------------------------------------------------------------------------------- 1 | var request = require('request') 2 | 3 | exports.pub = function(event, callback) { 4 | var topic = process.env.KAFKA_TOPIC 5 | var host = process.env.KAFKA_HOST 6 | var user = process.env.KAFKA_USER 7 | var password = process.env.KAFKA_PASSWORD 8 | 9 | if (!event.data) return callback('data not found') 10 | 11 | var uri = host+'/topic/'+topic+'?format=raw' 12 | var req = { 13 | method: 'POST', 14 | auth: { 15 | user: user, 16 | password: password 17 | }, 18 | json: event.data, 19 | } 20 | 21 | request.post(uri, req, function (error, resp) { 22 | if (error) return callback(error) 23 | callback(null, JSON.stringify(resp.body)) 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /examples/nodejs/mail/functions.yml: -------------------------------------------------------------------------------- 1 | # 2 | # SMTP URL syntax: smtps://:@ 3 | # 4 | functions: 5 | mail.send: 6 | runtime: nodejs 7 | handler: mail.send 8 | environment: 9 | MAIL_FROM: ${env:MAIL_FROM} 10 | MAIL_SMTP_URL: ${env:MAIL_SMTP_URL} -------------------------------------------------------------------------------- /examples/nodejs/mail/mail.js: -------------------------------------------------------------------------------- 1 | var nodemailer = require('nodemailer'); 2 | 3 | exports.send = function(event, callback) { 4 | var url = process.env.MAIL_SMTP_URL 5 | var from = process.env.MAIL_FROM 6 | 7 | if (!event.data.to) return callback('email recipient ("to") not found') 8 | if (!event.data.subject) return callback('subject not found') 9 | if (!event.data.text) return callback('text not found') 10 | 11 | var mail = { 12 | from: from, 13 | to: event.data.to, 14 | subject: event.data.subject, 15 | text: event.data.text 16 | } 17 | 18 | nodemailer 19 | .createTransport(url) 20 | .sendMail(mail, function(error, resp) { 21 | if (error) return callback(error) 22 | callback(null, JSON.stringify(resp)) 23 | }); 24 | 25 | } -------------------------------------------------------------------------------- /examples/nodejs/mail/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "nodemailer": "4.1.0" 4 | } 5 | } -------------------------------------------------------------------------------- /examples/nodejs/redis/functions.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Redis URL syntax: redis://x:@:/ 3 | # 4 | functions: 5 | redis.set: 6 | runtime: nodejs 7 | handler: redis.set 8 | environment: 9 | REDIS_URL: ${env:REDIS_URL} 10 | redis.get: 11 | runtime: nodejs 12 | handler: redis.get 13 | environment: 14 | REDIS_URL: ${env:REDIS_URL} -------------------------------------------------------------------------------- /examples/nodejs/redis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "redis": "2.8.0" 4 | } 5 | } -------------------------------------------------------------------------------- /examples/nodejs/redis/redis.js: -------------------------------------------------------------------------------- 1 | var redis = require('redis') 2 | 3 | exports.set = function(event, callback) { 4 | url = process.env.REDIS_URL 5 | 6 | if (!event.data.k) return callback('k is missing') 7 | if (!event.data.v) return callback('v is missing') 8 | 9 | var client = newRedisClient(url) 10 | 11 | client.set(event.data.k, event.data.v, function (err, reply) { 12 | if (err) return callback(err) 13 | client.quit() 14 | callback(null, reply.toString()) 15 | }) 16 | } 17 | 18 | exports.get = function(event, callback) { 19 | url = process.env.REDIS_URL 20 | 21 | if (!event.data.k) return callback('k is missing') 22 | 23 | var client = newRedisClient(url) 24 | 25 | client.get(event.data.k, function(err, reply) { 26 | if (err) return callback(err) 27 | if (!reply) return callback('key does not exist') 28 | client.quit() 29 | callback(null, reply.toString()) 30 | }) 31 | } 32 | 33 | function newRedisClient(url) { 34 | var client = redis.createClient({ 35 | url: url 36 | }) 37 | client.on('error', function (err) { 38 | console.log('error', err) 39 | callback('Internal error') 40 | }) 41 | return client 42 | } -------------------------------------------------------------------------------- /examples/perl/Makefile: -------------------------------------------------------------------------------- 1 | deploy: 2 | cd hipchat && ovh-functions deploy 3 | cd kafka-http && ovh-functions deploy 4 | cd redis && ovh-functions deploy 5 | 6 | exec: exec-hipchat exec-kafka-http exec-redis 7 | 8 | exec-hipchat: 9 | echo '{"message":"'$$(date)'"}' | \ 10 | ovh-functions exec hipchat.notify 11 | 12 | exec-kafka-http: 13 | echo '{"message":"'$$(date)'"}' | \ 14 | ovh-functions exec kafka.pub 15 | 16 | exec-redis: 17 | echo '{"key":"date","value":"'$$(date)'"}' | ovh-functions exec redis.set 18 | echo '{"key":"date"}' | ovh-functions exec redis.get -------------------------------------------------------------------------------- /examples/perl/env.example: -------------------------------------------------------------------------------- 1 | HIPCHAT_ROOM_ID= 2 | HIPCHAT_AUTH_TOKEN= 3 | 4 | KAFKA_HOST=https://: 5 | KAFKA_USER= 6 | KAFKA_PASSWORD= 7 | KAFKA_TOPIC= 8 | 9 | REDIS_URL=: 10 | REDIS_PASSWORD: -------------------------------------------------------------------------------- /examples/perl/hipchat/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | hipchat.notify: 3 | runtime: perl 4 | handler: hipchat.notify 5 | environment: 6 | HIPCHAT_ROOM_ID: ${env:HIPCHAT_ROOM_ID} 7 | HIPCHAT_AUTH_TOKEN: ${env:HIPCHAT_AUTH_TOKEN} -------------------------------------------------------------------------------- /examples/perl/hipchat/hipchat.pm: -------------------------------------------------------------------------------- 1 | use JSON; 2 | use LWP::UserAgent; 3 | 4 | sub notify { 5 | my ($event) = @_; 6 | my $apiUrl = 'https://api.hipchat.com/v2/room/' 7 | my $roomID = $ENV{'HIPCHAT_ROOM_ID'}; 8 | my $authToken = $ENV{'HIPCHAT_AUTH_TOKEN'}; 9 | my $message = $event->{'data'}{'message'}; 10 | my $color = $event->{'data'}{'color'} || 'green'; 11 | 12 | if ($message eq "") { 13 | die "message not found"; 14 | } 15 | 16 | my $r = LWP::UserAgent->new; 17 | my $req = HTTP::Request->new('POST' => $apiUrl . $roomID . '/notification?auth_token=' . $authToken); 18 | $req->header( 'Content-Type' => 'application/json' ); 19 | 20 | my $content = { 21 | 'color' => $color, 22 | 'message_format' => 'html', 23 | 'message' => $message 24 | }; 25 | 26 | $req->content(encode_json($content)); 27 | 28 | my $resp = $r->request($req); 29 | if ($resp->is_success) { 30 | return $resp->decoded_content; 31 | } else { 32 | die $resp->decoded_content; 33 | } 34 | } 35 | 1; -------------------------------------------------------------------------------- /examples/perl/kafka-http/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | kafka.pub: 3 | runtime: perl 4 | handler: kafka.pub 5 | environment: 6 | KAFKA_HOST: ${env:KAFKA_HOST} 7 | KAFKA_USER: ${env:KAFKA_USER} 8 | KAFKA_PASSWORD: ${env:KAFKA_PASSWORD} 9 | KAFKA_TOPIC: ${env:KAFKA_TOPIC} -------------------------------------------------------------------------------- /examples/perl/kafka-http/kafka.pm: -------------------------------------------------------------------------------- 1 | use LWP::UserAgent; 2 | use Time::HiRes qw(time); 3 | 4 | sub pub { 5 | my ($event) = @_; 6 | my $topic = $ENV{'KAFKA_TOPIC'}; 7 | my $host = $ENV{'KAFKA_HOST'}; 8 | my $user = $ENV{'KAFKA_USER'}; 9 | my $password = $ENV{'KAFKA_PASSWORD'}; 10 | my $message = $event->{'data'}; 11 | 12 | if ($message eq "") { 13 | die "data not found"; 14 | } 15 | 16 | my $req = HTTP::Request->new('POST' => $host . '/topic/' . $topic . '?format=raw'); 17 | $req->authorization_basic($user, $password); 18 | $req->content($message); 19 | 20 | my $r = LWP::UserAgent->new; 21 | my $start = time(); 22 | my $resp = $r->request($req); 23 | 24 | my $transactionTime = (time() - $start) * 1000; 25 | print "Kafka production status: " . $resp->code . " " . $resp->decoded_content . " in " . $transactionTime . " ms\n"; 26 | if ($resp->is_success) { 27 | return $resp->decoded_content; 28 | } else { 29 | die $resp->decoded_content; 30 | } 31 | } 32 | 1; -------------------------------------------------------------------------------- /examples/perl/mail/functions.yml: -------------------------------------------------------------------------------- 1 | # 2 | # SMTP URL syntax: :@ 3 | # 4 | functions: 5 | mail.send: 6 | runtime: perl 7 | handler: mail.send 8 | environment: 9 | MAIL_FROM: ${env:MAIL_FROM} 10 | MAIL_SMTP_URL: ${env:MAIL_SMTP_URL} 11 | -------------------------------------------------------------------------------- /examples/perl/mail/mail.pm: -------------------------------------------------------------------------------- 1 | use Mail::Sendmail; 2 | 3 | sub send { 4 | my ($event) = @_; 5 | my $url = $ENV{'MAIL_SMTP_URL'}; 6 | my $from = $ENV{'MAIL_FROM'}; 7 | 8 | %mail = ( 9 | Smtp => $url, 10 | To => $event->{'data'}{'to'}, 11 | From => $from, 12 | Subject => $event->{'data'}{'subject'}, 13 | Message => $event->{'data'}{'text'} 14 | ); 15 | 16 | sendmail(%mail) or die $Mail::Sendmail::error; 17 | return $Mail::Sendmail::log."\n"; 18 | } 19 | 1; -------------------------------------------------------------------------------- /examples/perl/redis/functions.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Redis URL syntax: : 3 | # 4 | functions: 5 | redis.set: 6 | runtime: perl 7 | handler: redis.set 8 | environment: 9 | REDIS_URL: ${env:REDIS_URL} 10 | REDIS_PASSWORD: ${env:REDIS_PASSWORD} 11 | redis.get: 12 | runtime: perl 13 | handler: redis.get 14 | environment: 15 | REDIS_URL: ${env:REDIS_URL} 16 | REDIS_PASSWORD: ${env:REDIS_PASSWORD} -------------------------------------------------------------------------------- /examples/perl/redis/redis.pm: -------------------------------------------------------------------------------- 1 | use Redis; 2 | 3 | sub get { 4 | my ($event) = @_; 5 | $r = new_redis_client(); 6 | 7 | my $resp = $r->get( $event->{'data'}{'key'} ); 8 | 9 | $r->quit; 10 | 11 | return $resp; 12 | } 13 | 14 | sub set { 15 | my ($event) = @_; 16 | $r = new_redis_client(); 17 | 18 | my $resp = $r->set( $event->{'data'}{'key'} => $event->{'data'}{'value'} ); 19 | 20 | $r->quit; 21 | 22 | return $resp; 23 | } 24 | 25 | sub new_redis_client{ 26 | my $host = $ENV{'REDIS_URL'}; 27 | 28 | my $r = Redis->new (server => $host, encoding => undef) || die "Redis connection failed"; 29 | $r->auth ($ENV{'REDIS_PASSWORD'}); 30 | 31 | return $r; 32 | } 33 | 1; -------------------------------------------------------------------------------- /examples/python/Makefile: -------------------------------------------------------------------------------- 1 | deploy: 2 | cd hipchat && ovh-functions deploy 3 | cd kafka-http && ovh-functions deploy 4 | cd mail && ovh-functions deploy 5 | cd redis && ovh-functions deploy 6 | 7 | exec: exec-hipchat exec-kafka-http exec-mail exec-redis 8 | 9 | exec-hipchat: 10 | echo '{"message":"'$$(date)'"}' | \ 11 | ovh-functions exec hipchat.notify 12 | 13 | exec-kafka-http: 14 | echo $(date) | \ 15 | ovh-functions exec kafka.pub 16 | 17 | exec-mail: 18 | echo '{"to":"hello@functions.ovh", "subject":"Time", "text":"'$$(date)'"}' | \ 19 | ovh-functions exec mail.send 20 | 21 | exec-redis: 22 | echo '{"key":"date","value":"'$$(date)'"}' | ovh-functions exec redis.set 23 | echo '{"key":"date"}' | ovh-functions exec redis.get 24 | -------------------------------------------------------------------------------- /examples/python/env.example: -------------------------------------------------------------------------------- 1 | HIPCHAT_ROOM_ID= 2 | HIPCHAT_AUTH_TOKEN= 3 | 4 | KAFKA_HOST=https://: 5 | KAFKA_USER= 6 | KAFKA_PASSWORD= 7 | KAFKA_TOPIC= 8 | 9 | REDIS_URL= 10 | REDIS_PORT= 11 | REDIS_DB= 12 | REDIS_PASSWORD= 13 | 14 | MAIL_SMTP_URL= 15 | MAIL_SMTP_USER= 16 | MAIL_SMTP_PASSWORD= 17 | -------------------------------------------------------------------------------- /examples/python/hipchat/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | hipchat.notify: 3 | runtime: python-2.7 4 | handler: hipchat.notify 5 | environment: 6 | HIPCHAT_ROOM_ID: ${env:HIPCHAT_ROOM_ID} 7 | HIPCHAT_AUTH_TOKEN: ${env:HIPCHAT_AUTH_TOKEN} -------------------------------------------------------------------------------- /examples/python/hipchat/hipchat.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import os 3 | import requests 4 | 5 | def notify(event): 6 | roomID = os.environ['HIPCHAT_ROOM_ID'] 7 | authToken = os.environ['HIPCHAT_AUTH_TOKEN'] 8 | 9 | try: 10 | message = event['data']['message'] 11 | except: 12 | raise Exception("message not found") 13 | 14 | start = datetime.datetime.now() 15 | r = requests.post('https://api.hipchat.com/v2/room/' + roomID + '/notification?auth_token=' + authToken, 16 | json = { 17 | 'color': event['data'].get('color', 'green'), 18 | 'message_format': 'html', 19 | 'message': message 20 | }) 21 | print("Hipchat notify status:", r.status_code, r.text, "in", datetime.datetime.now() - start) 22 | 23 | if r.status_code != 204: 24 | raise Exception("failed to send", message) 25 | 26 | return "message " + message + " sent" -------------------------------------------------------------------------------- /examples/python/kafka-http/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | kafka.pub: 3 | runtime: python-2.7 4 | handler: kafka.pub 5 | environment: 6 | KAFKA_HOST: ${env:KAFKA_HOST} 7 | KAFKA_USER: ${env:KAFKA_USER} 8 | KAFKA_PASSWORD: ${env:KAFKA_PASSWORD} 9 | KAFKA_TOPIC: ${env:KAFKA_TOPIC} -------------------------------------------------------------------------------- /examples/python/kafka-http/kafka.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import os 3 | import requests 4 | 5 | def pub(event): 6 | topic = os.environ['KAFKA_TOPIC'] 7 | host = os.environ['KAFKA_HOST'] 8 | user = os.environ['KAFKA_USER'] 9 | password = os.environ['KAFKA_PASSWORD'] 10 | 11 | if event['data'] != "": 12 | message = event['data'] 13 | else: 14 | raise Exception("data not found") 15 | 16 | start = datetime.datetime.now() 17 | uri = host + '/topic/' + topic + '?format=raw' 18 | r = requests.post(uri, 19 | auth = (user, password), 20 | json = message 21 | ) 22 | 23 | print("Kafka production status:", r.status_code, r.text, "in", datetime.datetime.now() - start) 24 | 25 | if r.status_code != 200: 26 | raise Exception(r.text) 27 | 28 | return r.text -------------------------------------------------------------------------------- /examples/python/mail/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | mail.send: 3 | runtime: python-2.7 4 | handler: mail.send 5 | environment: 6 | MAIL_SMTP_USER: ${env:MAIL_SMTP_USER} 7 | MAIL_SMTP_PASSWORD: ${env:MAIL_SMTP_PASSWORD} 8 | MAIL_SMTP_URL: ${env:MAIL_SMTP_URL} 9 | -------------------------------------------------------------------------------- /examples/python/mail/mail.py: -------------------------------------------------------------------------------- 1 | import os 2 | import smtplib 3 | 4 | from email.mime.text import MIMEText 5 | 6 | def send(event): 7 | url = os.environ['MAIL_SMTP_URL'] 8 | user = os.environ['MAIL_SMTP_USER'] 9 | password = os.environ['MAIL_SMTP_PASSWORD'] 10 | 11 | try: 12 | msg = MIMEText(event['data']['text']) 13 | except: 14 | raise Exception('no message found') 15 | 16 | msg['Subject'] = event['data']['subject'] 17 | msg['From'] = user 18 | msg['To'] = event['data']['to'] 19 | 20 | s = smtplib.SMTP(url) 21 | s.login(user, password) 22 | s.sendmail(user, event['data']['to'], msg.as_string()) 23 | s.quit() 24 | 25 | return "mail sent to " + event['data']['to'] -------------------------------------------------------------------------------- /examples/python/redis/functions.yml: -------------------------------------------------------------------------------- 1 | functions: 2 | redis.set: 3 | runtime: python-3.6 4 | handler: redis_db.set 5 | environment: 6 | REDIS_URL: ${env:REDIS_URL} 7 | REDIS_PORT: ${env:REDIS_PORT} 8 | REDIS_DB: ${env:REDIS_DB} 9 | REDIS_PASSWORD: ${env:REDIS_PASSWORD} 10 | redis.get: 11 | runtime: python-3.6 12 | handler: redis_db.get 13 | environment: 14 | REDIS_URL: ${env:REDIS_URL} 15 | REDIS_PORT: ${env:REDIS_PORT} 16 | REDIS_DB: ${env:REDIS_DB} 17 | REDIS_PASSWORD: ${env:REDIS_PASSWORD} -------------------------------------------------------------------------------- /examples/python/redis/redis_db.py: -------------------------------------------------------------------------------- 1 | import os 2 | import redis 3 | 4 | def set(event): 5 | r = new_redis_client() 6 | 7 | resp = r.set(event['data']['key'], event['data']['value']) 8 | 9 | return str(resp) 10 | 11 | def get(event): 12 | r = new_redis_client() 13 | 14 | resp = r.get(event['data']['key']) 15 | 16 | return str(resp) 17 | 18 | def new_redis_client(): 19 | host = os.environ['REDIS_URL'] 20 | port = os.environ['REDIS_PORT'] 21 | db = os.environ['REDIS_DB'] 22 | password = os.environ['REDIS_PASSWORD'] 23 | 24 | return redis.StrictRedis(host=host, port=port, db=db, password=password) -------------------------------------------------------------------------------- /examples/python/redis/requirements.txt: -------------------------------------------------------------------------------- 1 | redis==2.10.6 -------------------------------------------------------------------------------- /go-sdk/event/event.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | type Event struct { 4 | Data string 5 | Method string 6 | Params map[string]string 7 | Secrets map[string]string 8 | } 9 | --------------------------------------------------------------------------------