Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 592 : support service meta data #593

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
FROM golang:1.9
FROM golang:1.13

ENV CONSUL_VERSION=1.0.0
ENV CONSUL_VERSION=1.9.5
ENV GLIDE_VERSION=0.12.3

RUN apt-get update \
&& apt-get install -y unzip \
&& go get github.com/golang/lint/golint \
&& go get -u golang.org/x/lint/golint \
&& curl -Lo /tmp/glide.tgz "https://github.com/Masterminds/glide/releases/download/v${GLIDE_VERSION}/glide-v${GLIDE_VERSION}-linux-amd64.tar.gz" \
&& tar -C /usr/bin -xzf /tmp/glide.tgz --strip=1 linux-amd64/glide \
&& curl --fail -Lso consul.zip "https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip" \
&& unzip consul.zip -d /usr/bin

ENV CGO_ENABLED 0
ENV GOPATH /go:/cp
ENV XDG_CACHE_HOME=/tmp/.cache
1 change: 1 addition & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func TestValidConfigJobs(t *testing.T) {
assert.Equal(job0.Port, 8080, "config for job0.Port")
assert.Equal(job0.Exec, "/bin/serviceA", "config for job0.Exec")
assert.Equal(job0.Tags, []string{"tag1", "tag2"}, "config for job0.Tags")
assert.Equal(job0.Meta, map[string]string{"keyA": "A"}, "config for job0.Meta")
assert.Equal(job0.Restarts, nil, "config for job1.Restarts")

job1 := cfg.Jobs[1]
Expand Down
5 changes: 4 additions & 1 deletion config/testdata/test.json5
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
interval: 19,
ttl: 30,
},
tags: ["tag1","tag2"]
tags: ["tag1","tag2"],
meta: {
keyA: "A",
}
},
{
name: "serviceB",
Expand Down
53 changes: 46 additions & 7 deletions discovery/consul_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,14 @@ func TestWithConsul(t *testing.T) {
}
defer testServer.Stop()

testServer.WaitForAPI()
testServer.WaitForAPI(t)

t.Run("TestConsulTTLPass", testConsulTTLPass(testServer))
t.Run("TestConsulRegisterWithInitialStatus", testConsulRegisterWithInitialStatus(testServer))
t.Run("TestConsulReregister", testConsulReregister(testServer))
t.Run("TestConsulCheckForChanges", testConsulCheckForChanges(testServer))
t.Run("TestConsulEnableTagOverride", testConsulEnableTagOverride(testServer))
t.Run("testConsulTagsMeta", testConsulTagsMeta(testServer))
}

func testConsulTTLPass(testServer *TestServer) func(*testing.T) {
Expand Down Expand Up @@ -146,6 +147,39 @@ func testConsulReregister(testServer *TestServer) func(*testing.T) {
}
}

func contains(s []string, str string) bool {
for _, v := range s {
if v == str {
return true
}
}

return false
}

func testConsulTagsMeta(testServer *TestServer) func(*testing.T) {
return func(t *testing.T) {
consul, _ := NewConsul(testServer.HTTPAddr)
name := fmt.Sprintf("TestConsulReregister")
service := generateServiceDefinition(name, consul)
id := service.ID

service.SendHeartbeat() // force registration and 1st heartbeat
services, _ := consul.Agent().Services()
svc := services[id]
if !contains(svc.Tags, "a") || !contains(svc.Tags, "b") {
t.Fatalf("first tag must containt a & b but is %s", svc.Tags)
}
if svc.Meta["keyA"] != "A" {
t.Fatalf("first meta must containt keyA:A but is %s", svc.Meta["keyA"])
}
if svc.Meta["keyB"] != "B" {
t.Fatalf("first meta must containt keyB:B but is %s", svc.Meta["keyB"])
}

}
}

func testConsulCheckForChanges(testServer *TestServer) func(*testing.T) {
return func(t *testing.T) {
backend := fmt.Sprintf("TestConsulCheckForChanges")
Expand Down Expand Up @@ -204,12 +238,17 @@ func testConsulEnableTagOverride(testServer *TestServer) func(*testing.T) {

func generateServiceDefinition(serviceName string, consul *Consul) *ServiceDefinition {
return &ServiceDefinition{
ID: serviceName,
Name: serviceName,
IPAddress: "192.168.1.1",
ID: serviceName,
Name: serviceName,
IPAddress: "192.168.1.1",
InitialStatus: "warning",
TTL: 5,
Port: 9000,
Consul: consul,
TTL: 5,
Port: 9000,
Consul: consul,
Tags: []string{"a", "b"},
Meta: map[string]string{
"keyA": "A",
"keyB": "B",
},
}
}
28 changes: 15 additions & 13 deletions discovery/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type ServiceDefinition struct {
Port int
TTL int
Tags []string
Meta map[string]string
InitialStatus string
IPAddress string
EnableTagOverride bool
Expand Down Expand Up @@ -59,19 +60,19 @@ func (service *ServiceDefinition) RegisterWithInitialStatus() {
status := ""

switch service.InitialStatus {
case "passing":
status = api.HealthPassing
break
case "warning":
status = api.HealthWarning
break
case "critical":
status = api.HealthCritical
break
case "passing":
status = api.HealthPassing
break
case "warning":
status = api.HealthWarning
break
case "critical":
status = api.HealthCritical
break
}

log.Infof("Registering service %v with initial status set to %v",
service.Name, service.InitialStatus)
service.Name, service.InitialStatus)
service.register(status)
}

Expand All @@ -96,13 +97,14 @@ func (service *ServiceDefinition) registerService(status string) error {
ID: service.ID,
Name: service.Name,
Tags: service.Tags,
Meta: service.Meta,
Port: service.Port,
Address: service.IPAddress,
EnableTagOverride: service.EnableTagOverride,
Check: &api.AgentServiceCheck{
TTL: fmt.Sprintf("%ds", service.TTL),
Status: status,
Notes: fmt.Sprintf("TTL for %s set by containerpilot", service.Name),
TTL: fmt.Sprintf("%ds", service.TTL),
Status: status,
Notes: fmt.Sprintf("TTL for %s set by containerpilot", service.Name),
DeregisterCriticalServiceAfter: service.DeregisterCriticalServiceAfter,
},
},
Expand Down
21 changes: 7 additions & 14 deletions discovery/test_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
"os"
"os/exec"
"strconv"
"testing"

"github.com/hashicorp/consul/testutil/retry"
"github.com/hashicorp/consul/sdk/testutil/retry"
cleanhttp "github.com/hashicorp/go-cleanhttp"
)

Expand Down Expand Up @@ -59,21 +60,13 @@ func (s *TestServer) Stop() error {
return s.cmd.Wait()
}

// failer implements the retry.Failer interface
type failer struct {
failed bool
}

func (f *failer) Log(args ...interface{}) { fmt.Println(args) }
func (f *failer) FailNow() { f.failed = true }

// WaitForAPI waits for only the agent HTTP endpoint to start responding. This
// is an indication that the agent has started, but will likely return before a
// leader is elected.
func (s *TestServer) WaitForAPI() error {
f := &failer{}
retry.Run(f, func(r *retry.R) {
resp, err := s.client.Get(s.HTTPAddr + "/v1/agent/self")
func (s *TestServer) WaitForAPI(t *testing.T) error {
//f := &failer{}
retry.Run(t, func(r *retry.R) {
resp, err := s.client.Get("http://" + s.HTTPAddr + "/v1/agent/self")
if err != nil {
r.Fatal(err)
}
Expand All @@ -83,7 +76,7 @@ func (s *TestServer) WaitForAPI() error {
r.Fatalf("bad status code %d", resp.StatusCode)
}
})
if f.failed {
if t.Failed() {
return errors.New("failed waiting for API")
}
return nil
Expand Down
4 changes: 4 additions & 0 deletions docs/30-configuration/32-configuration-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ The following is a completed example of the JSON5 file configuration schema, wit
"app",
"prod"
],
meta: {
keyA: "A",
keyB: "B",
},
interfaces: [
"eth0",
"eth1[1]",
Expand Down
8 changes: 8 additions & 0 deletions docs/30-configuration/34-jobs.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ jobs: [
"app",
"prod"
],
meta: {
keyA: "A",
keyB: "B",
},
interfaces: [
"eth0",
"eth1[1]",
Expand Down Expand Up @@ -233,6 +237,10 @@ The `initial_status` field is optional and specifies which status to immediately

The `tags` field is an optional array of tags to be used when the job is registered as a service in Consul. Other containers can use these tags in `watches` to filter a service by tag.

##### `meta`

The `meta` field is an optional map key/value to be used when the job is registered as a service in Consul. Key names must be valid JSON5/Ecmascript identifierNames or be quoted and follow consul limitation , practical this means only [a-zA-Z0-9_-] can be used in key names and key names with '-' must be quoted

##### `interfaces`

The `interfaces` field is an optional single or array of interface specifications. If given, the IP of the service will be obtained from the first interface specification that matches. (Default value is `["eth0:inet"]`). The value that ContainerPilot uses for the IP address of the interface will be set as an environment variable with the name `CONTAINERPILOT_{JOB}_IP`. See the [environment variables](./32-configuration-file.md#environment-variables) section.
Expand Down
94 changes: 76 additions & 18 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading