Skip to content

Commit

Permalink
documentation and a working container image
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewhoff committed Apr 12, 2020
1 parent 900849a commit ff8c625
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 39 deletions.
2 changes: 0 additions & 2 deletions .env.example

This file was deleted.

12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM golang:1.13 as builder
COPY . /coap-hooks-router
WORKDIR /coap-hooks-router
ENV CGO_ENABLED 0
RUN go build -o server .

FROM scratch as release
ARG ADMIN_BEARER
WORKDIR /
VOLUME /dbdata
COPY --from=builder /coap-hooks-router/server /server
ENTRYPOINT ["/server"]
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
run:
go run main.go
dev:
go run main.go

docker-build:
docker build -t coap-hooks-router .

docker-run:
docker run -v container-db:/dbdata -e ADMIN_BEARER=${ADMIN_BEARER} -p 8081:8081 -p 5683:5683 coap-hooks-router
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
# To Run
- `cp .env.example .env`
- generate your ADMIN_BEARER
- `make run`
# CoAP Webhooks Router

# To create a new hook
## To Run
- generate your ADMIN_BEARER (`openssl rand -base64 27` can do it) and export ADMIN_BEARER="generatedbearertokenvalue" in your shell
- `make dev` for local run
- `make docker-run` for local docker run (functionally the same as the previous)
- `make docker-build` to build the docker image
- the Admin Hooks API runs on 8081, and the CoAP server runs on 5683

## Using the Hooks API

### Create a new hook
- `curl -v -d '{"owner":"{OWNER_NAME}","name":"{HOOK_NAME}","destination":"{HTTPS_ADDRESS}"}' -H "Content-Type:application/json" -H "Authorization: Bearer {BEARER}" http://localhost:8081/api/hooks/`

# To list all hooks for an owner
### List all hooks for an owner
- `curl -v -H "Accept:application/json" -H "Authorization: Bearer {BEARER}" http://localhost:8081/api/hooks/{OWNER_NAME}`

### List all hooks existing in the system
- `curl -v -H "Accept:application/json" -H "Authorization: Bearer {BEARER}" http://localhost:8081/api/hooks`

### Delete an existing hook by name
- `curl -v -X DELETE -H "Content-Type:application/json" -H "Authorization: Bearer {BEARER}" http://localhost:8081/api/hooks/{OWNER_NAME}/{HOOK_NAME}`

### Delete all hooks for an owner
- `curl -v -X DELETE -H "Content-Type:application/json" -H "Authorization: Bearer {BEARER}" http://localhost:8081/api/hooks/{OWNER_NAME}`
20 changes: 9 additions & 11 deletions coap/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/coapcloud/coap-hooks-router/hooks"
"github.com/coapcloud/go-coap"
"github.com/coapcloud/go-coap/codes"
)

func ListenAndServe(hooksRepo hooks.Repository, port int) {
Expand All @@ -21,18 +22,15 @@ func ListenAndServe(hooksRepo hooks.Repository, port int) {
// start listening for hook API events to register and deregister routes
go func() {
for e := range hooksRepo.Events() {
changedHooks := e.Hooks

switch e.EventType {
case hooks.EventTypeCreate:
r.HotAddRoute(*e.Hook)
r.HotAddRoute(*changedHooks[0])
case hooks.EventTypeDelete:
r.HotRemoveRoute(*e.Hook)
r.HotRemoveRoute(*changedHooks[0])
case hooks.EventTypeDeleteForOwner:
ownerHooks, err := hooksRepo.ListHooksForOwner(e.Hook.Owner)
if err != nil {
log.Fatal("couldn't list all hooks")
}

for _, v := range ownerHooks {
for _, v := range changedHooks {
err := r.HotRemoveRoute(*v)
if err != nil {
log.Printf("couldn't remove hook: %v with error: %v", *v, err)
Expand Down Expand Up @@ -60,7 +58,7 @@ func (r routeTable) ServeCOAP(w coap.ResponseWriter, req *coap.Request) {
dest, ok := r.match(req.Msg.Code(), req.Msg.Path())
if !ok {
log.Println("could not match route")
w.SetCode(coap.NotFound)
w.SetCode(codes.NotFound)
respBdy = []byte("not found")
}

Expand All @@ -70,7 +68,7 @@ func (r routeTable) ServeCOAP(w coap.ResponseWriter, req *coap.Request) {
respBdy, err = dest.Fire(buf)
if err != nil {
log.Printf("Error while trying to invoke webhook %v\n", err)
w.SetCode(coap.InternalServerError)
w.SetCode(codes.InternalServerError)
respBdy = []byte("could not run callback for request")
}

Expand All @@ -84,7 +82,7 @@ func (r routeTable) ServeCOAP(w coap.ResponseWriter, req *coap.Request) {
}
}

func (r *routeTable) match(verb coap.COAPCode, pathComponents []string) (hooks.Hook, bool) {
func (r *routeTable) match(verb codes.Code, pathComponents []string) (hooks.Hook, bool) {
r.RLock()
defer r.RUnlock()

Expand Down
8 changes: 4 additions & 4 deletions coap/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"sync"

"github.com/coapcloud/coap-hooks-router/hooks"
"github.com/coapcloud/go-coap"
"github.com/coapcloud/go-coap/codes"
"github.com/derekparker/trie"
)

Expand Down Expand Up @@ -57,7 +57,7 @@ func (r *routeTable) HotRemoveRoute(h hooks.Hook) error {
return r.deregisterRouteForHook(h)
}

func routeKey(verb coap.COAPCode, owner, hookName string) string {
func routeKey(verb codes.Code, owner, hookName string) string {
key := fmt.Sprintf("%d-%s/%s", verb, owner, hookName)

fmt.Printf("route key generated: %s\n", key)
Expand All @@ -68,7 +68,7 @@ func (r *routeTable) registerRouteForHook(h hooks.Hook) error {
r.Lock()
defer r.Unlock()

verb := coap.POST // this part can later be extended to allow the registration of different verbs
verb := codes.POST // this part can later be extended to allow the registration of different verbs

key := routeKey(verb, h.Owner, h.Name)

Expand All @@ -85,7 +85,7 @@ func (r *routeTable) deregisterRouteForHook(h hooks.Hook) error {
r.Lock()
defer r.Unlock()

verb := coap.POST // this part can later be extended to allow the registration of different verbs
verb := codes.POST // this part can later be extended to allow the registration of different verbs

key := routeKey(verb, h.Owner, h.Name)

Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ module github.com/coapcloud/coap-hooks-router
go 1.13

require (
github.com/coapcloud/go-coap v0.0.0-20190923040847-c7ef78cd84df
github.com/coapcloud/go-coap v0.1.1
github.com/derekparker/trie v0.0.0-20200317170641-1fdf38b7b0e9
github.com/go-ocf/go-coap v0.0.0-20200406073902-cf923db524db // indirect
github.com/joho/godotenv v1.3.0
github.com/labstack/echo/v4 v4.1.16
github.com/pion/dtls v1.5.4 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/coapcloud/go-coap v0.0.0-20190923040847-c7ef78cd84df h1:HBYTFGnoYOhg1a365JTZfqIPI49mpSGfR/ib/58lQdQ=
github.com/coapcloud/go-coap v0.0.0-20190923040847-c7ef78cd84df/go.mod h1:mp7wB/7I0+hzZx6QgoUZyjMErTWVv8Kjrwk+ZnNXri8=
github.com/coapcloud/go-coap v0.1.1 h1:xmAFX3d0BcPv/Qjm3jHmeoaUOdocQW2z+/WbBP1ZXNg=
github.com/coapcloud/go-coap v0.1.1/go.mod h1:LDN/oanDUGZ8gRORYbxoSzXvzgnPjFdrh03Q54P0Koo=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand All @@ -16,6 +18,8 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-ocf/go-coap v0.0.0-20200406073902-cf923db524db h1:zYs9RIr1Ghp2POmmwWl1nmgCSrInPRqRhM1fPFqG0UY=
github.com/go-ocf/go-coap v0.0.0-20200406073902-cf923db524db/go.mod h1:QoCnsMBbmLW/XqYJj5reW4Mm7QxIz8QTycLGqWczpZA=
github.com/go-ocf/go-coap v0.0.0-20200410132222-418332224ecf h1:8YTWo9pmtJSf8R0DePBYXb9Fk1fMJOFslQsLvlgg3hA=
github.com/go-ocf/go-coap v0.0.0-20200410132222-418332224ecf/go.mod h1:QoCnsMBbmLW/XqYJj5reW4Mm7QxIz8QTycLGqWczpZA=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
Expand Down
5 changes: 2 additions & 3 deletions hooks/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,13 @@ func ListenAndServe(hooksRepo Repository, port int) {
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Use(middleware.AddTrailingSlash())

hooksGroup := e.Group("/api/hooks")
hooksGroup.Use(middleware.KeyAuth(func(key string, c echo.Context) (bool, error) {
return subtle.ConstantTimeCompare([]byte(key), config.AdminBearer) == 1, nil
}))

hooksGroup.POST("/", func(c echo.Context) error {
hooksGroup.POST("", func(c echo.Context) error {
var reqHook Hook
err := c.Bind(&reqHook)
if err != nil {
Expand All @@ -60,7 +59,7 @@ func ListenAndServe(hooksRepo Repository, port int) {
return c.JSON(http.StatusOK, reqHook)
})

hooksGroup.GET("/", func(c echo.Context) error {
hooksGroup.GET("", func(c echo.Context) error {
hooks, err := s.store.ListAllHooks()
if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
Expand Down
22 changes: 15 additions & 7 deletions hooks/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const (

type HookAPIEvent struct {
EventType EventType
Hook *Hook
Hooks []*Hook
}

type repo struct {
Expand Down Expand Up @@ -92,8 +92,8 @@ func (r *repo) CreateHook(h Hook) (err error) {
}

r.events <- HookAPIEvent{
EventTypeCreate,
&h,
EventType: EventTypeCreate,
Hooks: []*Hook{&h},
}
} else {
e := tx.Rollback()
Expand Down Expand Up @@ -163,6 +163,8 @@ func (r *repo) DeleteHooksForOwner(owner string) (err error) {
return err
}

var hooks []*Hook

defer func() {
if err == nil {
e := tx.Commit()
Expand All @@ -172,6 +174,7 @@ func (r *repo) DeleteHooksForOwner(owner string) (err error) {

r.events <- HookAPIEvent{
EventType: EventTypeDeleteForOwner,
Hooks: hooks,
}
} else {
e := tx.Rollback()
Expand All @@ -181,6 +184,11 @@ func (r *repo) DeleteHooksForOwner(owner string) (err error) {
}
}()

hooks, err = r.ListHooksForOwner(owner)
if err != nil {
return err
}

err = tx.DeleteBucket([]byte(owner))
if err != nil {
return err
Expand All @@ -197,7 +205,7 @@ func (r *repo) DeleteHookByOwnerAndName(owner, name string) (err error) {
return err
}

var h *Hook
var h Hook

defer func() {
if err == nil {
Expand All @@ -207,8 +215,8 @@ func (r *repo) DeleteHookByOwnerAndName(owner, name string) (err error) {
}

r.events <- HookAPIEvent{
EventTypeDelete,
h,
EventType: EventTypeDelete,
Hooks: []*Hook{&h},
}
} else {
e := tx.Rollback()
Expand All @@ -230,7 +238,7 @@ func (r *repo) DeleteHookByOwnerAndName(owner, name string) (err error) {
return fmt.Errorf("could not find hook: %s to delete for owner: %s", name, owner)
}

h = &Hook{
h = Hook{
Owner: owner,
Name: name,
Destination: string(v),
Expand Down
3 changes: 1 addition & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"log"

"github.com/coapcloud/coap-hooks-router/coap"
"github.com/coapcloud/coap-hooks-router/config"
hooksAPI "github.com/coapcloud/coap-hooks-router/hooks"
)

Expand All @@ -14,7 +13,7 @@ const (
)

func main() {
hooksRepo, err := hooksAPI.NewHooksRepository(config.DBFilename)
hooksRepo, err := hooksAPI.NewHooksRepository("dbdata/hooks.db")
if err != nil {
log.Fatalf("Error trying to create HooksRepository: %v\n", err)
}
Expand Down

0 comments on commit ff8c625

Please sign in to comment.