Skip to content

Commit

Permalink
Merge pull request #37 from bobrik/multiport
Browse files Browse the repository at this point in the history
Support separate apps per port
  • Loading branch information
bobrik committed May 10, 2016
2 parents 67c9d1a + f7462fd commit eb70f93
Show file tree
Hide file tree
Showing 17 changed files with 357 additions and 199 deletions.
13 changes: 1 addition & 12 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,8 @@ go:
- 1.6
- tip

# installing godep manually: https://github.com/travis-ci/travis-ci/issues/5702
install:
- go get -t github.com/tools/godep
- godep restore
- go get -t -v ./...

env:
global:
- GO15VENDOREXPERIMENT=1

before_script:
- go install ./...
- go get github.com/alecthomas/gometalinter
- gometalinter --install --update
# disabled checks fail on tip
- gometalinter --deadline 60s --cyclo-over 12 -D structcheck -D aligncheck ./...
- GO_VENDOR=1 GO15VENDOREXPERIMENT=1 gometalinter --cyclo-over 12 --deadline 60s ./...
8 changes: 5 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
FROM alpine:3.2
FROM alpine:3.3

COPY . /go/src/github.com/bobrik/zoidberg

RUN apk --update add go && \
export GOPATH=/go:/go/src/github.com/bobrik/zoidberg/Godeps/_workspace && \
RUN apk --update add go ca-certificates && \
export GOPATH=/go GO15VENDOREXPERIMENT=1 && \
go get github.com/bobrik/zoidberg/... && \
apk del go

ENTRYPOINT ["/go/bin/zoidberg"]
8 changes: 4 additions & 4 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM alpine:3.2
FROM alpine:3.3

RUN apk --update add go
RUN apk --update add go ca-certificates

COPY . /go/src/github.com/bobrik/zoidberg

RUN export GOPATH=/go:/go/src/github.com/bobrik/zoidberg/Godeps/_workspace && \
RUN export GOPATH=/go GO15VENDOREXPERIMENT=1 && \
go get github.com/bobrik/zoidberg/...

ENTRYPOINT ["/go/bin/zoidberg"]
ENTRYPOINT ["/go/bin/zoidberg"]
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,21 @@ that they rely on labels to discover applications running on the cluster.

Make sure to use the following labels for your apps:

* `zoidberg_app_name` defines application name.
* `zoidberg_app_version` defines application version, defaults to `"1"`.
* `zoidberg_balanced_by` defines load balancer name for application.
* `zoidberg_meta_*` defines metadata labels for app, available in `meta`.
* `zoidberg_port_X_app_name` defines application name.
* `zoidberg_port_X_app_version` defines application version, defaults to `"1"`.
* `zoidberg_port_X_balanced_by` defines load balancer name for application.
* `zoidberg_port_X_meta_*` defines metadata labels for app, available in `meta`.

Here `X` is the port index. Each port creates a separate app so you can
expose them through different load balancers.

Arguments for `marathon` finder:

* `-application-finder-marathon-url` marathon url in `http://host:port[,host:port]` format.
* `-application-finder-marathon-balancer` balancer name to look for in `zoidberg_balanced_by` label.

Arguments for `mesos` finder:

* `-application-finder-mesos-masters` mesos masters in `http://host:port[,http://host:port]` format.
* `-application-finder-mesos-name` balancer name to look for in `zoidberg_balanced_by` label.

### Load balancer finders

Expand Down Expand Up @@ -103,12 +104,10 @@ Make sure to use the following labels for your apps that are load balancers:
Arguments for `marathon` finder:

* `-balancer-finder-marathon-url` marathon url in `http://host:port[,host:port]` format.
* `-balancer-finder-marathon-name` balancer name to look for in `zoidberg_balancer_for` label.

Arguments for `mesos` finder:

* `-balancer-finder-mesos-masters` mesos masters in `http://host:port[,http://host:port]` format.
* `-balancer-finder-mesos-name` balancer name to look for in `zoidberg_balancer_for` label.

## Running

Expand All @@ -118,6 +117,7 @@ In addition to finder arguments, you also have to specify the following:
* `-host` host to listen on for API.
* `-port` port to listen on for API.
* `-zk` Zookeeper connection string for state persistence.
* `-balancer` balancer name to tie apps and load balancers.

Note that instead of cli arguments you can also use environment variables,
just drop the first `-`, replace and `-` with `_` and capitalize argument name.
Expand Down
10 changes: 5 additions & 5 deletions application/finder.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ type Finder interface {

// FinderMaker represents finder maker tuple:
// * a function to register flags
// * a function to make finder from parsed flags
// * a function to make finder from parsed flags and balancer name
type FinderMaker struct {
Flags func()
Maker func() (Finder, error)
Maker func(balancer string) (Finder, error)
}

// finderMakers contains a mapping of Finder names to their makers
Expand All @@ -25,10 +25,10 @@ func RegisterFinderMaker(name string, maker FinderMaker) {
finderMakers[name] = maker
}

// FinderByName returns existing finder by name
func FinderByName(finder string) (Finder, error) {
// FinderByName returns existing finder by name a balancer name
func FinderByName(finder string, balancer string) (Finder, error) {
if maker, ok := finderMakers[finder]; ok {
return maker.Maker()
return maker.Maker(balancer)
}

return nil, fmt.Errorf("unknown application finder: %q", finder)
Expand Down
57 changes: 51 additions & 6 deletions application/labels.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,60 @@
package application

import "strings"
import (
"log"
"strconv"
"strings"
)

// metaFromLabels creates app labels from zoidberg prefixed labels
func metaFromLabels(labels map[string]string) map[string]string {
r := map[string]string{}
// extractApps returns map{ port => labels } for all found apps
func extractApps(labels map[string]string) map[int]map[string]string {
r := map[int]map[string]string{}

for k, v := range labels {
if strings.HasPrefix(k, "zoidberg_meta_") {
r[strings.TrimPrefix(k, "zoidberg_meta_")] = v
if !strings.HasPrefix(k, "zoidberg_port_") {
continue
}

p := strings.SplitN(strings.TrimPrefix(k, "zoidberg_port_"), "_", 2)
if len(p) != 2 {
log.Printf("invalid port: %s", k)
continue
}

if port, err := strconv.Atoi(p[0]); err != nil {
log.Printf("invalid port: %s", k)
continue
} else {
if _, ok := r[port]; !ok {
r[port] = map[string]string{}
}
r[port][p[1]] = v
}
}

if _, ok := r[0]; !ok {
a := extractLegacyApp(labels)
if a != nil {
r[0] = a
}
}

return r
}

func extractLegacyApp(labels map[string]string) map[string]string {
if labels["zoidberg_app_name"] == "" || labels["zoidberg_balanced_by"] == "" {
// no legacy app present
return nil
}

r := map[string]string{
"app_name": labels["zoidberg_app_name"],
"balanced_by": labels["zoidberg_balanced_by"],
}

if labels["zoidberg_app_version"] != "" {
r["app_version"] = labels["zoidberg_app_version"]
}

return r
Expand Down
121 changes: 121 additions & 0 deletions application/labels_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package application

import (
"reflect"
"testing"
)

func TestLabels(t *testing.T) {
table := []struct {
labels map[string]string
apps map[int]map[string]string
}{
{
labels: map[string]string{},
apps: map[int]map[string]string{},
},
{
labels: map[string]string{
"zoidberg_port_0_app_name": "foo",
"zoidberg_port_0_balanced_by": "bar",
},
apps: map[int]map[string]string{
0: {
"app_name": "foo",
"balanced_by": "bar",
},
},
},
{
labels: map[string]string{
"zoidberg_port_0_app_name": "foo",
"zoidberg_port_0_app_version": "8",
"zoidberg_port_0_balanced_by": "bar",
},
apps: map[int]map[string]string{
0: {
"app_name": "foo",
"app_version": "8",
"balanced_by": "bar",
},
},
},
{
labels: map[string]string{
"zoidberg_port_1_app_name": "foo",
"zoidberg_port_1_balanced_by": "bar",
},
apps: map[int]map[string]string{
1: {
"app_name": "foo",
"balanced_by": "bar",
},
},
},
{
labels: map[string]string{
"zoidberg_port_0_app_name": "foo1",
"zoidberg_port_0_balanced_by": "bar1",
"zoidberg_port_1_app_name": "foo2",
"zoidberg_port_1_balanced_by": "bar2",
},
apps: map[int]map[string]string{
0: {
"app_name": "foo1",
"balanced_by": "bar1",
},
1: {
"app_name": "foo2",
"balanced_by": "bar2",
},
},
},
{
labels: map[string]string{
"zoidberg_app_name": "foo",
"zoidberg_balanced_by": "bar",
},
apps: map[int]map[string]string{
0: {
"app_name": "foo",
"balanced_by": "bar",
},
},
},
{
labels: map[string]string{
"zoidberg_app_name": "foo",
"zoidberg_app_version": "8",
"zoidberg_balanced_by": "bar",
},
apps: map[int]map[string]string{
0: {
"app_name": "foo",
"app_version": "8",
"balanced_by": "bar",
},
},
},
{
labels: map[string]string{
"zoidberg_port_0_app_name": "foo1",
"zoidberg_port_0_balanced_by": "bar1",
"zoidberg_app_name": "foo2",
"zoidberg_balanced_by": "bar2",
},
apps: map[int]map[string]string{
0: {
"app_name": "foo1",
"balanced_by": "bar1",
},
},
},
}

for _, row := range table {
r := extractApps(row.labels)
if !reflect.DeepEqual(r, row.apps) {
t.Errorf("expected: %v, got: %v", row.apps, r)
}
}
}
Loading

0 comments on commit eb70f93

Please # to comment.