Goji: Marathon Task Proxy Config Generator

goji is a server that registers with a Marathon instance, consumes events, and emits templated configs containing information about running tasks for a set of apps that you care about.

Run

One-shot mode

Just hit up marathon for the task list, generate a config, and write it out.

./goji -conf myconfig.json

Server

Generates a config like one-shot mode, but goji will then listen on http-port for events from Marathon.

./goji -conf myconfig.json -server

Docker

An automated build of master is available at registry.hub.docker.com/u/byxorna/goji. The container is more useful when run in single shot mode, as opposed to -server mode. You can use dockers -v argument to mount directories into the container to provide a config or output directory.

Configuration

goji takes a config file, formatted in json, as the -conf option. It tells goji information about your marathon instance, what services (app IDs) to query for tasks, and where and with what template to write configs out.

http-port: What port to start an HTTP event listener on to register and receive event messages from marathon (optional, default: 8000)

delay: Coalesce events within this window before triggering a task get and config emit (optional, default: 0)

command: Run a script after writing out the config (optional, default: empty)

services: List of Services. A service is an object with a app-id key of the marathon app ID you want tasks from, and a name that will be passed into your template for each service. See below.

Service Configuration

{
// marathon app id for your application
"app-id": "/sre/byxorna/webapp",
// a name that is associated with the service. Useful for doing nginx vhosting for http apps, or service name for DNS SRV records. Just a string
"name": "web.service.iata.tumblr.net",
// TCP or HTTP, defaults to HTTP
"protocol":"HTTP",
// if the protocol of the service is HTTP, you can specify a health check URI here
"health-check":"/_health",
// what service port to use. Defaults to 80, but you can override for TCP services
"port":80
// options is an optional map[string]string of arbitrary options you can switch on in your templates
// these are useful to specify behavior logic per service
options: { "acl-match": "-m beg", "healthcheck-rate":"100" }
}

Commands

The comand field in the config json specifies a command to run upon successful creation of a new config. This can be anything you want, but here are some useful examples:

Templates

You can use goji to emit whatever configs you care about. Common usecases would be HAproxy or Nginx configurations. The name attribute could be useful for doing nginx/apache vhosting to identify a request by Host: header.

A much more useful template is available in example/haproxy.tmpl, example/nginx.tmpl, and example/named.tmpl

You may use arbitrary keys and values in $service.Options to do clever things per service. For example, this snippet will allow you to modify how the haproxy acl rule works with options stored per service.acl {{ $service.EscapeAppIdColon }}-aclrule hdr(host) {{with index $service.Options "acl-opts"}}{{index $service.Options "acl-opts"}} {{end}}{{ $service.Name }}

DNS SRV Records

You can generate a named zone with SRV records from marathon backends trivially, given the template: