Only register HTTPS agent check when Consul>=0.7.2
Support for TLSSkipVerify in other checks coming soon!
This commit is contained in:
parent
c8d3e869c6
commit
947e31e9c2
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
@ -54,6 +55,10 @@ type Agent struct {
|
|||
// consulCatalog is the subset of Consul's Catalog API Nomad uses.
|
||||
consulCatalog consul.CatalogAPI
|
||||
|
||||
// consulSupportsTLSSkipVerify flags whether or not Nomad can register
|
||||
// checks with TLSSkipVerify
|
||||
consulSupportsTLSSkipVerify bool
|
||||
|
||||
client *client.Client
|
||||
|
||||
server *nomad.Server
|
||||
|
@ -374,6 +379,16 @@ func (a *Agent) setupServer() error {
|
|||
},
|
||||
},
|
||||
}
|
||||
if conf.TLSConfig.EnableHTTP {
|
||||
if a.consulSupportsTLSSkipVerify {
|
||||
httpServ.Checks[0].Protocol = "https"
|
||||
httpServ.Checks[0].TLSSkipVerify = true
|
||||
} else {
|
||||
// No TLSSkipVerify support, don't register https check
|
||||
a.logger.Printf("[WARN] agent: not registering Nomad HTTPS Health Check because it requires Consul>=0.7.2")
|
||||
httpServ.Checks = []*structs.ServiceCheck{}
|
||||
}
|
||||
}
|
||||
rpcServ := &structs.Service{
|
||||
Name: a.config.Consul.ServerServiceName,
|
||||
PortLabel: a.config.AdvertiseAddrs.RPC,
|
||||
|
@ -404,13 +419,10 @@ func (a *Agent) setupServer() error {
|
|||
}
|
||||
|
||||
// Add the http port check if TLS isn't enabled
|
||||
// TODO Add TLS check when Consul 0.7.1 comes out.
|
||||
consulServices := []*structs.Service{
|
||||
rpcServ,
|
||||
serfServ,
|
||||
}
|
||||
if !conf.TLSConfig.EnableHTTP {
|
||||
consulServices = append(consulServices, httpServ)
|
||||
httpServ,
|
||||
}
|
||||
if err := a.consulService.RegisterAgent(consulRoleServer, consulServices); err != nil {
|
||||
return err
|
||||
|
@ -477,8 +489,6 @@ func (a *Agent) setupClient() error {
|
|||
}
|
||||
|
||||
// Create the Nomad Client services for Consul
|
||||
// TODO think how we can re-introduce HTTP/S checks when Consul 0.7.1 comes
|
||||
// out
|
||||
if *a.config.Consul.AutoAdvertise {
|
||||
httpServ := &structs.Service{
|
||||
Name: a.config.Consul.ClientServiceName,
|
||||
|
@ -496,11 +506,19 @@ func (a *Agent) setupClient() error {
|
|||
},
|
||||
},
|
||||
}
|
||||
if !conf.TLSConfig.EnableHTTP {
|
||||
if err := a.consulService.RegisterAgent(consulRoleClient, []*structs.Service{httpServ}); err != nil {
|
||||
return err
|
||||
if conf.TLSConfig.EnableHTTP {
|
||||
if a.consulSupportsTLSSkipVerify {
|
||||
httpServ.Checks[0].Protocol = "https"
|
||||
httpServ.Checks[0].TLSSkipVerify = true
|
||||
} else {
|
||||
// No TLSSkipVerify support, don't register https check
|
||||
a.logger.Printf("[WARN] agent: not registering Nomad HTTPS Health Check because it requires Consul>=0.7.2")
|
||||
httpServ.Checks = []*structs.ServiceCheck{}
|
||||
}
|
||||
}
|
||||
if err := a.consulService.RegisterAgent(consulRoleClient, []*structs.Service{httpServ}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -672,6 +690,11 @@ func (a *Agent) setupConsul(consulConfig *config.ConsulConfig) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Determine version for TLSSkipVerify
|
||||
if self, err := client.Agent().Self(); err != nil {
|
||||
a.consulSupportsTLSSkipVerify = consulSupportsTLSSkipVerify(self)
|
||||
}
|
||||
|
||||
// Create Consul Catalog client for service discovery.
|
||||
a.consulCatalog = client.Catalog()
|
||||
|
||||
|
@ -680,3 +703,59 @@ func (a *Agent) setupConsul(consulConfig *config.ConsulConfig) error {
|
|||
go a.consulService.Run()
|
||||
return nil
|
||||
}
|
||||
|
||||
// consulSupportsTLSSkipVerify returns true if Consul supports TLSSkipVerify.
|
||||
func consulSupportsTLSSkipVerify(self map[string]map[string]interface{}) bool {
|
||||
member, ok := self["Member"]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
tagsI, ok := member["Tags"]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
tags, ok := tagsI.(map[string]interface{})
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
buildI, ok := tags["build"]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
build, ok := buildI.(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
parts := strings.SplitN(build, ":", 2)
|
||||
if len(parts) == 0 {
|
||||
return false
|
||||
}
|
||||
parts = strings.Split(parts[0], ".")
|
||||
if len(parts) != 3 {
|
||||
return false
|
||||
}
|
||||
major, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
minor, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
patch, err := strconv.Atoi(parts[2])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if major > 0 || minor > 7 {
|
||||
// After 0.7.2!
|
||||
return true
|
||||
}
|
||||
if minor < 7 {
|
||||
return false
|
||||
}
|
||||
if patch < 2 {
|
||||
return false
|
||||
}
|
||||
// 0.7.2 or higher!
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package agent
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
|
@ -358,3 +359,107 @@ func TestAgent_ClientConfig(t *testing.T) {
|
|||
t.Fatalf("Expected http addr: %v, got: %v", expectedHttpAddr, c.Node.HTTPAddr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAgent_ConsulSupportsTLSSkipVerify(t *testing.T) {
|
||||
assertSupport := func(expected bool, blob string) {
|
||||
self := map[string]map[string]interface{}{}
|
||||
if err := json.Unmarshal([]byte("{"+blob+"}"), &self); err != nil {
|
||||
t.Fatalf("invalid json: %v", err)
|
||||
}
|
||||
actual := consulSupportsTLSSkipVerify(self)
|
||||
if actual != expected {
|
||||
t.Errorf("expected %t but got %t for:\n%s\n", expected, actual, blob)
|
||||
}
|
||||
}
|
||||
|
||||
// 0.6.4
|
||||
assertSupport(false, `"Member": {
|
||||
"Addr": "127.0.0.1",
|
||||
"DelegateCur": 4,
|
||||
"DelegateMax": 4,
|
||||
"DelegateMin": 2,
|
||||
"Name": "rusty",
|
||||
"Port": 8301,
|
||||
"ProtocolCur": 2,
|
||||
"ProtocolMax": 3,
|
||||
"ProtocolMin": 1,
|
||||
"Status": 1,
|
||||
"Tags": {
|
||||
"build": "0.6.4:26a0ef8c",
|
||||
"dc": "dc1",
|
||||
"port": "8300",
|
||||
"role": "consul",
|
||||
"vsn": "2",
|
||||
"vsn_max": "3",
|
||||
"vsn_min": "1"
|
||||
}}`)
|
||||
|
||||
// 0.7.0
|
||||
assertSupport(false, `"Member": {
|
||||
"Addr": "127.0.0.1",
|
||||
"DelegateCur": 4,
|
||||
"DelegateMax": 4,
|
||||
"DelegateMin": 2,
|
||||
"Name": "rusty",
|
||||
"Port": 8301,
|
||||
"ProtocolCur": 2,
|
||||
"ProtocolMax": 4,
|
||||
"ProtocolMin": 1,
|
||||
"Status": 1,
|
||||
"Tags": {
|
||||
"build": "0.7.0:'a189091",
|
||||
"dc": "dc1",
|
||||
"port": "8300",
|
||||
"role": "consul",
|
||||
"vsn": "2",
|
||||
"vsn_max": "3",
|
||||
"vsn_min": "2"
|
||||
}}`)
|
||||
|
||||
// 0.7.2
|
||||
assertSupport(true, `"Member": {
|
||||
"Addr": "127.0.0.1",
|
||||
"DelegateCur": 4,
|
||||
"DelegateMax": 4,
|
||||
"DelegateMin": 2,
|
||||
"Name": "rusty",
|
||||
"Port": 8301,
|
||||
"ProtocolCur": 2,
|
||||
"ProtocolMax": 5,
|
||||
"ProtocolMin": 1,
|
||||
"Status": 1,
|
||||
"Tags": {
|
||||
"build": "0.7.2:'a9afa0c",
|
||||
"dc": "dc1",
|
||||
"port": "8300",
|
||||
"role": "consul",
|
||||
"vsn": "2",
|
||||
"vsn_max": "3",
|
||||
"vsn_min": "2"
|
||||
}}`)
|
||||
|
||||
// 0.8.1
|
||||
assertSupport(true, `"Member": {
|
||||
"Addr": "127.0.0.1",
|
||||
"DelegateCur": 4,
|
||||
"DelegateMax": 5,
|
||||
"DelegateMin": 2,
|
||||
"Name": "rusty",
|
||||
"Port": 8301,
|
||||
"ProtocolCur": 2,
|
||||
"ProtocolMax": 5,
|
||||
"ProtocolMin": 1,
|
||||
"Status": 1,
|
||||
"Tags": {
|
||||
"build": "0.8.1:'e9ca44d",
|
||||
"dc": "dc1",
|
||||
"id": "3ddc1b59-460e-a100-1d5c-ce3972122664",
|
||||
"port": "8300",
|
||||
"raft_vsn": "2",
|
||||
"role": "consul",
|
||||
"vsn": "2",
|
||||
"vsn_max": "3",
|
||||
"vsn_min": "2",
|
||||
"wan_join_port": "8302"
|
||||
}}`)
|
||||
}
|
||||
|
|
|
@ -666,6 +666,9 @@ func createCheckReg(serviceID, checkID string, check *structs.ServiceCheck, host
|
|||
if check.Protocol == "" {
|
||||
check.Protocol = "http"
|
||||
}
|
||||
if check.TLSSkipVerify {
|
||||
chkReg.TLSSkipVerify = true
|
||||
}
|
||||
base := url.URL{
|
||||
Scheme: check.Protocol,
|
||||
Host: net.JoinHostPort(host, strconv.Itoa(port)),
|
||||
|
|
|
@ -2116,6 +2116,7 @@ type ServiceCheck struct {
|
|||
Interval time.Duration // Interval of the check
|
||||
Timeout time.Duration // Timeout of the response from the check before consul fails the check
|
||||
InitialStatus string // Initial status of the check
|
||||
TLSSkipVerify bool // Skip TLS verification when Protocol=https
|
||||
}
|
||||
|
||||
func (sc *ServiceCheck) Copy() *ServiceCheck {
|
||||
|
@ -2199,6 +2200,10 @@ func (sc *ServiceCheck) RequiresPort() bool {
|
|||
}
|
||||
}
|
||||
|
||||
// Hash all ServiceCheck fields and the check's corresponding service ID to
|
||||
// create an identifier. The identifier is not guaranteed to be unique as if
|
||||
// the PortLabel is blank, the Service's PortLabel will be used after Hash is
|
||||
// called.
|
||||
func (sc *ServiceCheck) Hash(serviceID string) string {
|
||||
h := sha1.New()
|
||||
io.WriteString(h, serviceID)
|
||||
|
@ -2211,6 +2216,10 @@ func (sc *ServiceCheck) Hash(serviceID string) string {
|
|||
io.WriteString(h, sc.PortLabel)
|
||||
io.WriteString(h, sc.Interval.String())
|
||||
io.WriteString(h, sc.Timeout.String())
|
||||
// Only include TLSSkipVerify if set to maintain ID stability with Nomad <0.6
|
||||
if sc.TLSSkipVerify {
|
||||
io.WriteString(h, "true")
|
||||
}
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue