Merge pull request #9926 from hashicorp/f-up-consul-api
consul: upgrade consul/api to 1.8.1
This commit is contained in:
commit
aa3f6f97a7
6
go.mod
6
go.mod
|
@ -52,8 +52,8 @@ require (
|
|||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.1-0.20200228141219-3ce3d519df39
|
||||
github.com/hashicorp/consul v1.7.8
|
||||
github.com/hashicorp/consul-template v0.25.1
|
||||
github.com/hashicorp/consul/api v1.6.0
|
||||
github.com/hashicorp/consul/sdk v0.6.0
|
||||
github.com/hashicorp/consul/api v1.8.1
|
||||
github.com/hashicorp/consul/sdk v0.7.0
|
||||
github.com/hashicorp/cronexpr v1.1.1
|
||||
github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1
|
||||
|
@ -81,7 +81,7 @@ require (
|
|||
github.com/hashicorp/nomad/api v0.0.0-20200529203653-c4416b26d3eb
|
||||
github.com/hashicorp/raft v1.1.3-0.20200211192230-365023de17e6
|
||||
github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea
|
||||
github.com/hashicorp/serf v0.9.3
|
||||
github.com/hashicorp/serf v0.9.5
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20190730042357-746c0b111519
|
||||
github.com/hashicorp/vault/sdk v0.1.14-0.20190730042320-0dc007d98cc8
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d
|
||||
|
|
10
go.sum
10
go.sum
|
@ -329,11 +329,11 @@ github.com/hashicorp/consul v1.7.8/go.mod h1:urbfGaVZDmnXC6geg0LYPh/SRUk1E8nfmDH
|
|||
github.com/hashicorp/consul-template v0.25.1 h1:+D2s8eyRqWyX7GPNxeUi8tsyh8pRn3J6k8giEchPfKQ=
|
||||
github.com/hashicorp/consul-template v0.25.1/go.mod h1:/vUsrJvDuuQHcxEw0zik+YXTS7ZKWZjQeaQhshBmfH0=
|
||||
github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU=
|
||||
github.com/hashicorp/consul/api v1.6.0 h1:SZB2hQW8AcTOpfDmiVblQbijxzsRuiyy0JpHfabvHio=
|
||||
github.com/hashicorp/consul/api v1.6.0/go.mod h1:1NSuaUUkFaJzMasbfq/11wKYWSR67Xn6r2DXKhuDNFg=
|
||||
github.com/hashicorp/consul/api v1.8.1 h1:BOEQaMWoGMhmQ29fC26bi0qb7/rId9JzZP2V0Xmx7m8=
|
||||
github.com/hashicorp/consul/api v1.8.1/go.mod h1:sDjTOq0yUyv5G4h+BqSea7Fn6BU+XbolEz1952UB+mk=
|
||||
github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
|
||||
github.com/hashicorp/consul/sdk v0.6.0 h1:FfhMEkwvQl57CildXJyGHnwGGM4HMODGyfjGwNM1Vdw=
|
||||
github.com/hashicorp/consul/sdk v0.6.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
|
||||
github.com/hashicorp/consul/sdk v0.7.0 h1:H6R9d008jDcHPQPAqPNuydAshJ4v5/8URdFnUvK/+sc=
|
||||
github.com/hashicorp/consul/sdk v0.7.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
|
||||
github.com/hashicorp/cronexpr v1.1.0/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4=
|
||||
github.com/hashicorp/cronexpr v1.1.1 h1:NJZDd87hGXjoZBdvyCF9mX4DCq5Wy7+A/w+A7q0wn6c=
|
||||
github.com/hashicorp/cronexpr v1.1.1/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4=
|
||||
|
@ -435,6 +435,8 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
|
|||
github.com/hashicorp/serf v0.8.3/go.mod h1:UpNcs7fFbpKIyZaUuSW6EPiH+eZC7OuyFD+wc1oal+k=
|
||||
github.com/hashicorp/serf v0.9.3 h1:AVF6JDQQens6nMHT9OGERBvK0f8rPrAGILnsKLr6lzM=
|
||||
github.com/hashicorp/serf v0.9.3/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
||||
github.com/hashicorp/serf v0.9.5 h1:EBWvyu9tcRszt3Bxp3KNssBMP1KuHWyO51lz9+786iM=
|
||||
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
||||
github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q=
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20190730042357-746c0b111519 h1:2qdbEUXjHohC+OYHtVU5lujvPAHPKYR4IMs9rsiUTk8=
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20190730042357-746c0b111519/go.mod h1:i9PKqwFko/s/aihU1uuHGh/FaQS+Xcgvd9dvnfAvQb0=
|
||||
|
|
106
vendor/github.com/hashicorp/consul/api/agent.go
generated
vendored
106
vendor/github.com/hashicorp/consul/api/agent.go
generated
vendored
|
@ -93,6 +93,8 @@ type AgentService struct {
|
|||
// to include the Namespace in the hash. When we do, then we are in for lots of fun with tests.
|
||||
// For now though, ignoring it works well enough.
|
||||
Namespace string `json:",omitempty" bexpr:"-" hash:"ignore"`
|
||||
// Datacenter is only ever returned and is ignored if presented.
|
||||
Datacenter string `json:",omitempty" bexpr:"-" hash:"ignore"`
|
||||
}
|
||||
|
||||
// AgentServiceChecksInfo returns information about a Service and its checks
|
||||
|
@ -121,12 +123,84 @@ type AgentServiceConnectProxyConfig struct {
|
|||
Expose ExposeConfig `json:",omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
// MemberTagKeyACLMode is the key used to indicate what ACL mode the agent is
|
||||
// operating in. The values of this key will be one of the MemberACLMode constants
|
||||
// with the key not being present indicating ACLModeUnknown.
|
||||
MemberTagKeyACLMode = "acls"
|
||||
|
||||
// MemberTagRole is the key used to indicate that the member is a server or not.
|
||||
MemberTagKeyRole = "role"
|
||||
|
||||
// MemberTagValueRoleServer is the value of the MemberTagKeyRole used to indicate
|
||||
// that the member represents a Consul server.
|
||||
MemberTagValueRoleServer = "consul"
|
||||
|
||||
// MemberTagKeySegment is the key name of the tag used to indicate which network
|
||||
// segment this member is in.
|
||||
// Network Segments are a Consul Enterprise feature.
|
||||
MemberTagKeySegment = "segment"
|
||||
|
||||
// MemberTagKeyBootstrap is the key name of the tag used to indicate whether this
|
||||
// agent was started with the "bootstrap" configuration enabled
|
||||
MemberTagKeyBootstrap = "bootstrap"
|
||||
// MemberTagValueBootstrap is the value of the MemberTagKeyBootstrap key when the
|
||||
// agent was started with the "bootstrap" configuration enabled.
|
||||
MemberTagValueBootstrap = "1"
|
||||
|
||||
// MemberTagKeyBootstrapExpect is the key name of the tag used to indicate whether
|
||||
// this agent was started with the "bootstrap_expect" configuration set to a non-zero
|
||||
// value. The value of this key will be the string for of that configuration value.
|
||||
MemberTagKeyBootstrapExpect = "expect"
|
||||
|
||||
// MemberTagKeyUseTLS is the key name of the tag used to indicate whther this agent
|
||||
// was configured to use TLS.
|
||||
MemberTagKeyUseTLS = "use_tls"
|
||||
// MemberTagValueUseTLS is the value of the MemberTagKeyUseTLS when the agent was
|
||||
// configured to use TLS. Any other value indicates that it was not setup in
|
||||
// that manner.
|
||||
MemberTagValueUseTLS = "1"
|
||||
|
||||
// MemberTagKeyReadReplica is the key used to indicate that the member is a read
|
||||
// replica server (will remain a Raft non-voter).
|
||||
// Read Replicas are a Consul Enterprise feature.
|
||||
MemberTagKeyReadReplica = "read_replica"
|
||||
// MemberTagValueReadReplica is the value of the MemberTagKeyReadReplica key when
|
||||
// the member is in fact a read-replica. Any other value indicates that it is not.
|
||||
// Read Replicas are a Consul Enterprise feature.
|
||||
MemberTagValueReadReplica = "1"
|
||||
)
|
||||
|
||||
type MemberACLMode string
|
||||
|
||||
const (
|
||||
// ACLModeDisables indicates that ACLs are disabled for this agent
|
||||
ACLModeDisabled MemberACLMode = "0"
|
||||
// ACLModeEnabled indicates that ACLs are enabled and operating in new ACL
|
||||
// mode (v1.4.0+ ACLs)
|
||||
ACLModeEnabled MemberACLMode = "1"
|
||||
// ACLModeLegacy indicates that ACLs are enabled and operating in legacy mode.
|
||||
ACLModeLegacy MemberACLMode = "2"
|
||||
// ACLModeUnkown is used to indicate that the AgentMember.Tags didn't advertise
|
||||
// an ACL mode at all. This is the case for Consul versions before v1.4.0 and
|
||||
// should be treated similarly to ACLModeLegacy.
|
||||
ACLModeUnknown MemberACLMode = "3"
|
||||
)
|
||||
|
||||
// AgentMember represents a cluster member known to the agent
|
||||
type AgentMember struct {
|
||||
Name string
|
||||
Addr string
|
||||
Port uint16
|
||||
Tags map[string]string
|
||||
Name string
|
||||
Addr string
|
||||
Port uint16
|
||||
Tags map[string]string
|
||||
// Status of the Member which corresponds to github.com/hashicorp/serf/serf.MemberStatus
|
||||
// Value is one of:
|
||||
//
|
||||
// AgentMemberNone = 0
|
||||
// AgentMemberAlive = 1
|
||||
// AgentMemberLeaving = 2
|
||||
// AgentMemberLeft = 3
|
||||
// AgentMemberFailed = 4
|
||||
Status int
|
||||
ProtocolMin uint8
|
||||
ProtocolMax uint8
|
||||
|
@ -136,6 +210,30 @@ type AgentMember struct {
|
|||
DelegateCur uint8
|
||||
}
|
||||
|
||||
// ACLMode returns the ACL mode this agent is operating in.
|
||||
func (m *AgentMember) ACLMode() MemberACLMode {
|
||||
mode := m.Tags[MemberTagKeyACLMode]
|
||||
|
||||
// the key may not have existed but then an
|
||||
// empty string will be returned and we will
|
||||
// handle that in the default case of the switch
|
||||
switch MemberACLMode(mode) {
|
||||
case ACLModeDisabled:
|
||||
return ACLModeDisabled
|
||||
case ACLModeEnabled:
|
||||
return ACLModeEnabled
|
||||
case ACLModeLegacy:
|
||||
return ACLModeLegacy
|
||||
default:
|
||||
return ACLModeUnknown
|
||||
}
|
||||
}
|
||||
|
||||
// IsConsulServer returns true when this member is a Consul server.
|
||||
func (m *AgentMember) IsConsulServer() bool {
|
||||
return m.Tags[MemberTagKeyRole] == MemberTagValueRoleServer
|
||||
}
|
||||
|
||||
// AllSegments is used to select for all segments in MembersOpts.
|
||||
const AllSegments = "_all"
|
||||
|
||||
|
|
19
vendor/github.com/hashicorp/consul/api/api.go
generated
vendored
19
vendor/github.com/hashicorp/consul/api/api.go
generated
vendored
|
@ -254,6 +254,11 @@ type QueryMeta struct {
|
|||
// CacheAge is set if request was ?cached and indicates how stale the cached
|
||||
// response is.
|
||||
CacheAge time.Duration
|
||||
|
||||
// DefaultACLPolicy is used to control the ACL interaction when there is no
|
||||
// defined policy. This can be "allow" which means ACLs are used to
|
||||
// deny-list, or "deny" which means ACLs are allow-lists.
|
||||
DefaultACLPolicy string
|
||||
}
|
||||
|
||||
// WriteMeta is used to return meta data about a write
|
||||
|
@ -305,7 +310,7 @@ type Config struct {
|
|||
TokenFile string
|
||||
|
||||
// Namespace is the name of the namespace to send along for the request
|
||||
// when no other Namespace ispresent in the QueryOptions
|
||||
// when no other Namespace is present in the QueryOptions
|
||||
Namespace string
|
||||
|
||||
TLSConfig TLSConfig
|
||||
|
@ -607,9 +612,11 @@ func NewClient(config *Config) (*Client, error) {
|
|||
trans.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {
|
||||
return net.Dial("unix", parts[1])
|
||||
}
|
||||
config.HttpClient = &http.Client{
|
||||
Transport: trans,
|
||||
httpClient, err := NewHttpClient(trans, config.TLSConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.HttpClient = httpClient
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown protocol scheme: %s", parts[0])
|
||||
}
|
||||
|
@ -960,6 +967,12 @@ func parseQueryMeta(resp *http.Response, q *QueryMeta) error {
|
|||
q.AddressTranslationEnabled = false
|
||||
}
|
||||
|
||||
// Parse X-Consul-Default-ACL-Policy
|
||||
switch v := header.Get("X-Consul-Default-ACL-Policy"); v {
|
||||
case "allow", "deny":
|
||||
q.DefaultACLPolicy = v
|
||||
}
|
||||
|
||||
// Parse Cache info
|
||||
if cacheStr := header.Get("X-Cache"); cacheStr != "" {
|
||||
q.CacheHit = strings.EqualFold(cacheStr, "HIT")
|
||||
|
|
29
vendor/github.com/hashicorp/consul/api/config_entry.go
generated
vendored
29
vendor/github.com/hashicorp/consul/api/config_entry.go
generated
vendored
|
@ -7,6 +7,7 @@ import (
|
|||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
@ -19,6 +20,7 @@ const (
|
|||
ServiceResolver string = "service-resolver"
|
||||
IngressGateway string = "ingress-gateway"
|
||||
TerminatingGateway string = "terminating-gateway"
|
||||
ServiceIntentions string = "service-intentions"
|
||||
|
||||
ProxyConfigGlobal string = "global"
|
||||
)
|
||||
|
@ -26,6 +28,8 @@ const (
|
|||
type ConfigEntry interface {
|
||||
GetKind() string
|
||||
GetName() string
|
||||
GetNamespace() string
|
||||
GetMeta() map[string]string
|
||||
GetCreateIndex() uint64
|
||||
GetModifyIndex() uint64
|
||||
}
|
||||
|
@ -95,6 +99,7 @@ type ServiceConfigEntry struct {
|
|||
MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway"`
|
||||
Expose ExposeConfig `json:",omitempty"`
|
||||
ExternalSNI string `json:",omitempty" alias:"external_sni"`
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
@ -107,6 +112,14 @@ func (s *ServiceConfigEntry) GetName() string {
|
|||
return s.Name
|
||||
}
|
||||
|
||||
func (s *ServiceConfigEntry) GetNamespace() string {
|
||||
return s.Namespace
|
||||
}
|
||||
|
||||
func (s *ServiceConfigEntry) GetMeta() map[string]string {
|
||||
return s.Meta
|
||||
}
|
||||
|
||||
func (s *ServiceConfigEntry) GetCreateIndex() uint64 {
|
||||
return s.CreateIndex
|
||||
}
|
||||
|
@ -122,6 +135,7 @@ type ProxyConfigEntry struct {
|
|||
Config map[string]interface{} `json:",omitempty"`
|
||||
MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway"`
|
||||
Expose ExposeConfig `json:",omitempty"`
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
@ -134,6 +148,14 @@ func (p *ProxyConfigEntry) GetName() string {
|
|||
return p.Name
|
||||
}
|
||||
|
||||
func (p *ProxyConfigEntry) GetNamespace() string {
|
||||
return p.Namespace
|
||||
}
|
||||
|
||||
func (p *ProxyConfigEntry) GetMeta() map[string]string {
|
||||
return p.Meta
|
||||
}
|
||||
|
||||
func (p *ProxyConfigEntry) GetCreateIndex() uint64 {
|
||||
return p.CreateIndex
|
||||
}
|
||||
|
@ -158,6 +180,8 @@ func makeConfigEntry(kind, name string) (ConfigEntry, error) {
|
|||
return &IngressGatewayConfigEntry{Kind: kind, Name: name}, nil
|
||||
case TerminatingGateway:
|
||||
return &TerminatingGatewayConfigEntry{Kind: kind, Name: name}, nil
|
||||
case ServiceIntentions:
|
||||
return &ServiceIntentionsConfigEntry{Kind: kind, Name: name}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid config entry kind: %s", kind)
|
||||
}
|
||||
|
@ -200,7 +224,10 @@ func DecodeConfigEntry(raw map[string]interface{}) (ConfigEntry, error) {
|
|||
}
|
||||
|
||||
decodeConf := &mapstructure.DecoderConfig{
|
||||
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
|
||||
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
||||
mapstructure.StringToTimeDurationHookFunc(),
|
||||
mapstructure.StringToTimeHookFunc(time.RFC3339),
|
||||
),
|
||||
Result: &entry,
|
||||
WeaklyTypedInput: true,
|
||||
}
|
||||
|
|
110
vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go
generated
vendored
110
vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go
generated
vendored
|
@ -12,14 +12,17 @@ type ServiceRouterConfigEntry struct {
|
|||
|
||||
Routes []ServiceRoute `json:",omitempty"`
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
func (e *ServiceRouterConfigEntry) GetKind() string { return e.Kind }
|
||||
func (e *ServiceRouterConfigEntry) GetName() string { return e.Name }
|
||||
func (e *ServiceRouterConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex }
|
||||
func (e *ServiceRouterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex }
|
||||
func (e *ServiceRouterConfigEntry) GetKind() string { return e.Kind }
|
||||
func (e *ServiceRouterConfigEntry) GetName() string { return e.Name }
|
||||
func (e *ServiceRouterConfigEntry) GetNamespace() string { return e.Namespace }
|
||||
func (e *ServiceRouterConfigEntry) GetMeta() map[string]string { return e.Meta }
|
||||
func (e *ServiceRouterConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex }
|
||||
func (e *ServiceRouterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex }
|
||||
|
||||
type ServiceRoute struct {
|
||||
Match *ServiceRouteMatch `json:",omitempty"`
|
||||
|
@ -111,14 +114,17 @@ type ServiceSplitterConfigEntry struct {
|
|||
|
||||
Splits []ServiceSplit `json:",omitempty"`
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
func (e *ServiceSplitterConfigEntry) GetKind() string { return e.Kind }
|
||||
func (e *ServiceSplitterConfigEntry) GetName() string { return e.Name }
|
||||
func (e *ServiceSplitterConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex }
|
||||
func (e *ServiceSplitterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex }
|
||||
func (e *ServiceSplitterConfigEntry) GetKind() string { return e.Kind }
|
||||
func (e *ServiceSplitterConfigEntry) GetName() string { return e.Name }
|
||||
func (e *ServiceSplitterConfigEntry) GetNamespace() string { return e.Namespace }
|
||||
func (e *ServiceSplitterConfigEntry) GetMeta() map[string]string { return e.Meta }
|
||||
func (e *ServiceSplitterConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex }
|
||||
func (e *ServiceSplitterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex }
|
||||
|
||||
type ServiceSplit struct {
|
||||
Weight float32
|
||||
|
@ -138,6 +144,11 @@ type ServiceResolverConfigEntry struct {
|
|||
Failover map[string]ServiceResolverFailover `json:",omitempty"`
|
||||
ConnectTimeout time.Duration `json:",omitempty" alias:"connect_timeout"`
|
||||
|
||||
// LoadBalancer determines the load balancing policy and configuration for services
|
||||
// issuing requests to this upstream service.
|
||||
LoadBalancer *LoadBalancer `json:",omitempty" alias:"load_balancer"`
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
@ -178,10 +189,12 @@ func (e *ServiceResolverConfigEntry) UnmarshalJSON(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (e *ServiceResolverConfigEntry) GetKind() string { return e.Kind }
|
||||
func (e *ServiceResolverConfigEntry) GetName() string { return e.Name }
|
||||
func (e *ServiceResolverConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex }
|
||||
func (e *ServiceResolverConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex }
|
||||
func (e *ServiceResolverConfigEntry) GetKind() string { return e.Kind }
|
||||
func (e *ServiceResolverConfigEntry) GetName() string { return e.Name }
|
||||
func (e *ServiceResolverConfigEntry) GetNamespace() string { return e.Namespace }
|
||||
func (e *ServiceResolverConfigEntry) GetMeta() map[string]string { return e.Meta }
|
||||
func (e *ServiceResolverConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex }
|
||||
func (e *ServiceResolverConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex }
|
||||
|
||||
type ServiceResolverSubset struct {
|
||||
Filter string `json:",omitempty"`
|
||||
|
@ -201,3 +214,76 @@ type ServiceResolverFailover struct {
|
|||
Namespace string `json:",omitempty"`
|
||||
Datacenters []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// LoadBalancer determines the load balancing policy and configuration for services
|
||||
// issuing requests to this upstream service.
|
||||
type LoadBalancer struct {
|
||||
// Policy is the load balancing policy used to select a host
|
||||
Policy string `json:",omitempty"`
|
||||
|
||||
// RingHashConfig contains configuration for the "ring_hash" policy type
|
||||
RingHashConfig *RingHashConfig `json:",omitempty" alias:"ring_hash_config"`
|
||||
|
||||
// LeastRequestConfig contains configuration for the "least_request" policy type
|
||||
LeastRequestConfig *LeastRequestConfig `json:",omitempty" alias:"least_request_config"`
|
||||
|
||||
// HashPolicies is a list of hash policies to use for hashing load balancing algorithms.
|
||||
// Hash policies are evaluated individually and combined such that identical lists
|
||||
// result in the same hash.
|
||||
// If no hash policies are present, or none are successfully evaluated,
|
||||
// then a random backend host will be selected.
|
||||
HashPolicies []HashPolicy `json:",omitempty" alias:"hash_policies"`
|
||||
}
|
||||
|
||||
// RingHashConfig contains configuration for the "ring_hash" policy type
|
||||
type RingHashConfig struct {
|
||||
// MinimumRingSize determines the minimum number of entries in the hash ring
|
||||
MinimumRingSize uint64 `json:",omitempty" alias:"minimum_ring_size"`
|
||||
|
||||
// MaximumRingSize determines the maximum number of entries in the hash ring
|
||||
MaximumRingSize uint64 `json:",omitempty" alias:"maximum_ring_size"`
|
||||
}
|
||||
|
||||
// LeastRequestConfig contains configuration for the "least_request" policy type
|
||||
type LeastRequestConfig struct {
|
||||
// ChoiceCount determines the number of random healthy hosts from which to select the one with the least requests.
|
||||
ChoiceCount uint32 `json:",omitempty" alias:"choice_count"`
|
||||
}
|
||||
|
||||
// HashPolicy defines which attributes will be hashed by hash-based LB algorithms
|
||||
type HashPolicy struct {
|
||||
// Field is the attribute type to hash on.
|
||||
// Must be one of "header","cookie", or "query_parameter".
|
||||
// Cannot be specified along with SourceIP.
|
||||
Field string `json:",omitempty"`
|
||||
|
||||
// FieldValue is the value to hash.
|
||||
// ie. header name, cookie name, URL query parameter name
|
||||
// Cannot be specified along with SourceIP.
|
||||
FieldValue string `json:",omitempty" alias:"field_value"`
|
||||
|
||||
// CookieConfig contains configuration for the "cookie" hash policy type.
|
||||
CookieConfig *CookieConfig `json:",omitempty" alias:"cookie_config"`
|
||||
|
||||
// SourceIP determines whether the hash should be of the source IP rather than of a field and field value.
|
||||
// Cannot be specified along with Field or FieldValue.
|
||||
SourceIP bool `json:",omitempty" alias:"source_ip"`
|
||||
|
||||
// Terminal will short circuit the computation of the hash when multiple hash policies are present.
|
||||
// If a hash is computed when a Terminal policy is evaluated,
|
||||
// then that hash will be used and subsequent hash policies will be ignored.
|
||||
Terminal bool `json:",omitempty"`
|
||||
}
|
||||
|
||||
// CookieConfig contains configuration for the "cookie" hash policy type.
|
||||
// This is specified to have Envoy generate a cookie for a client on its first request.
|
||||
type CookieConfig struct {
|
||||
// Generates a session cookie with no expiration.
|
||||
Session bool `json:",omitempty"`
|
||||
|
||||
// TTL for generated cookies. Cannot be specified for session cookies.
|
||||
TTL time.Duration `json:",omitempty"`
|
||||
|
||||
// The path to set for the cookie
|
||||
Path string `json:",omitempty"`
|
||||
}
|
||||
|
|
22
vendor/github.com/hashicorp/consul/api/config_entry_gateways.go
generated
vendored
22
vendor/github.com/hashicorp/consul/api/config_entry_gateways.go
generated
vendored
|
@ -21,6 +21,8 @@ type IngressGatewayConfigEntry struct {
|
|||
// what services to associated to those ports.
|
||||
Listeners []IngressListener
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
|
||||
// CreateIndex is the Raft index this entry was created at. This is a
|
||||
// read-only field.
|
||||
CreateIndex uint64
|
||||
|
@ -44,7 +46,7 @@ type IngressListener struct {
|
|||
// Protocol declares what type of traffic this listener is expected to
|
||||
// receive. Depending on the protocol, a listener might support multiplexing
|
||||
// services over a single port, or additional discovery chain features. The
|
||||
// current supported values are: (tcp | http).
|
||||
// current supported values are: (tcp | http | http2 | grpc).
|
||||
Protocol string
|
||||
|
||||
// Services declares the set of services to which the listener forwards
|
||||
|
@ -94,6 +96,14 @@ func (i *IngressGatewayConfigEntry) GetName() string {
|
|||
return i.Name
|
||||
}
|
||||
|
||||
func (i *IngressGatewayConfigEntry) GetNamespace() string {
|
||||
return i.Namespace
|
||||
}
|
||||
|
||||
func (i *IngressGatewayConfigEntry) GetMeta() map[string]string {
|
||||
return i.Meta
|
||||
}
|
||||
|
||||
func (i *IngressGatewayConfigEntry) GetCreateIndex() uint64 {
|
||||
return i.CreateIndex
|
||||
}
|
||||
|
@ -115,6 +125,8 @@ type TerminatingGatewayConfigEntry struct {
|
|||
// Services is a list of service names represented by the terminating gateway.
|
||||
Services []LinkedService `json:",omitempty"`
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
|
||||
// CreateIndex is the Raft index this entry was created at. This is a
|
||||
// read-only field.
|
||||
CreateIndex uint64
|
||||
|
@ -161,6 +173,14 @@ func (g *TerminatingGatewayConfigEntry) GetName() string {
|
|||
return g.Name
|
||||
}
|
||||
|
||||
func (g *TerminatingGatewayConfigEntry) GetNamespace() string {
|
||||
return g.Namespace
|
||||
}
|
||||
|
||||
func (g *TerminatingGatewayConfigEntry) GetMeta() map[string]string {
|
||||
return g.Meta
|
||||
}
|
||||
|
||||
func (g *TerminatingGatewayConfigEntry) GetCreateIndex() uint64 {
|
||||
return g.CreateIndex
|
||||
}
|
||||
|
|
80
vendor/github.com/hashicorp/consul/api/config_entry_intentions.go
generated
vendored
Normal file
80
vendor/github.com/hashicorp/consul/api/config_entry_intentions.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
package api
|
||||
|
||||
import "time"
|
||||
|
||||
type ServiceIntentionsConfigEntry struct {
|
||||
Kind string
|
||||
Name string
|
||||
Namespace string `json:",omitempty"`
|
||||
|
||||
Sources []*SourceIntention
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
type SourceIntention struct {
|
||||
Name string
|
||||
Namespace string `json:",omitempty"`
|
||||
Action IntentionAction `json:",omitempty"`
|
||||
Permissions []*IntentionPermission `json:",omitempty"`
|
||||
Precedence int
|
||||
Type IntentionSourceType
|
||||
Description string `json:",omitempty"`
|
||||
|
||||
LegacyID string `json:",omitempty" alias:"legacy_id"`
|
||||
LegacyMeta map[string]string `json:",omitempty" alias:"legacy_meta"`
|
||||
LegacyCreateTime *time.Time `json:",omitempty" alias:"legacy_create_time"`
|
||||
LegacyUpdateTime *time.Time `json:",omitempty" alias:"legacy_update_time"`
|
||||
}
|
||||
|
||||
func (e *ServiceIntentionsConfigEntry) GetKind() string {
|
||||
return e.Kind
|
||||
}
|
||||
|
||||
func (e *ServiceIntentionsConfigEntry) GetName() string {
|
||||
return e.Name
|
||||
}
|
||||
|
||||
func (e *ServiceIntentionsConfigEntry) GetNamespace() string {
|
||||
return e.Namespace
|
||||
}
|
||||
|
||||
func (e *ServiceIntentionsConfigEntry) GetMeta() map[string]string {
|
||||
return e.Meta
|
||||
}
|
||||
|
||||
func (e *ServiceIntentionsConfigEntry) GetCreateIndex() uint64 {
|
||||
return e.CreateIndex
|
||||
}
|
||||
|
||||
func (e *ServiceIntentionsConfigEntry) GetModifyIndex() uint64 {
|
||||
return e.ModifyIndex
|
||||
}
|
||||
|
||||
type IntentionPermission struct {
|
||||
Action IntentionAction
|
||||
HTTP *IntentionHTTPPermission `json:",omitempty"`
|
||||
}
|
||||
|
||||
type IntentionHTTPPermission struct {
|
||||
PathExact string `json:",omitempty" alias:"path_exact"`
|
||||
PathPrefix string `json:",omitempty" alias:"path_prefix"`
|
||||
PathRegex string `json:",omitempty" alias:"path_regex"`
|
||||
|
||||
Header []IntentionHTTPHeaderPermission `json:",omitempty"`
|
||||
|
||||
Methods []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type IntentionHTTPHeaderPermission struct {
|
||||
Name string
|
||||
Present bool `json:",omitempty"`
|
||||
Exact string `json:",omitempty"`
|
||||
Prefix string `json:",omitempty"`
|
||||
Suffix string `json:",omitempty"`
|
||||
Regex string `json:",omitempty"`
|
||||
Invert bool `json:",omitempty"`
|
||||
}
|
125
vendor/github.com/hashicorp/consul/api/connect_intention.go
generated
vendored
125
vendor/github.com/hashicorp/consul/api/connect_intention.go
generated
vendored
|
@ -12,12 +12,12 @@ import (
|
|||
// Connect.
|
||||
type Intention struct {
|
||||
// ID is the UUID-based ID for the intention, always generated by Consul.
|
||||
ID string
|
||||
ID string `json:",omitempty"`
|
||||
|
||||
// Description is a human-friendly description of this intention.
|
||||
// It is opaque to Consul and is only stored and transferred in API
|
||||
// requests.
|
||||
Description string
|
||||
Description string `json:",omitempty"`
|
||||
|
||||
// SourceNS, SourceName are the namespace and name, respectively, of
|
||||
// the source service. Either of these may be the wildcard "*", but only
|
||||
|
@ -34,16 +34,25 @@ type Intention struct {
|
|||
SourceType IntentionSourceType
|
||||
|
||||
// Action is whether this is an allowlist or denylist intention.
|
||||
Action IntentionAction
|
||||
Action IntentionAction `json:",omitempty"`
|
||||
|
||||
// DefaultAddr, DefaultPort of the local listening proxy (if any) to
|
||||
// make this connection.
|
||||
DefaultAddr string
|
||||
DefaultPort int
|
||||
// Permissions is the list of additional L7 attributes that extend the
|
||||
// intention definition.
|
||||
//
|
||||
// NOTE: This field is not editable unless editing the underlying
|
||||
// service-intentions config entry directly.
|
||||
Permissions []*IntentionPermission `json:",omitempty"`
|
||||
|
||||
// DefaultAddr is not used.
|
||||
// Deprecated: DefaultAddr is not used and may be removed in a future version.
|
||||
DefaultAddr string `json:",omitempty"`
|
||||
// DefaultPort is not used.
|
||||
// Deprecated: DefaultPort is not used and may be removed in a future version.
|
||||
DefaultPort int `json:",omitempty"`
|
||||
|
||||
// Meta is arbitrary metadata associated with the intention. This is
|
||||
// opaque to Consul but is served in API responses.
|
||||
Meta map[string]string
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
|
||||
// Precedence is the order that the intention will be applied, with
|
||||
// larger numbers being applied first. This is a read-only field, on
|
||||
|
@ -59,7 +68,7 @@ type Intention struct {
|
|||
// This is needed mainly for replication purposes. When replicating from
|
||||
// one DC to another keeping the content Hash will allow us to detect
|
||||
// content changes more efficiently than checking every single field
|
||||
Hash []byte
|
||||
Hash []byte `json:",omitempty"`
|
||||
|
||||
CreateIndex uint64
|
||||
ModifyIndex uint64
|
||||
|
@ -67,10 +76,20 @@ type Intention struct {
|
|||
|
||||
// String returns human-friendly output describing ths intention.
|
||||
func (i *Intention) String() string {
|
||||
var detail string
|
||||
switch n := len(i.Permissions); n {
|
||||
case 0:
|
||||
detail = string(i.Action)
|
||||
case 1:
|
||||
detail = "1 permission"
|
||||
default:
|
||||
detail = fmt.Sprintf("%d permissions", len(i.Permissions))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s => %s (%s)",
|
||||
i.SourceString(),
|
||||
i.DestinationString(),
|
||||
i.Action)
|
||||
detail)
|
||||
}
|
||||
|
||||
// SourceString returns the namespace/name format for the source, or
|
||||
|
@ -164,7 +183,42 @@ func (h *Connect) Intentions(q *QueryOptions) ([]*Intention, *QueryMeta, error)
|
|||
return out, qm, nil
|
||||
}
|
||||
|
||||
// IntentionGetExact retrieves a single intention by its unique name instead of
|
||||
// its ID.
|
||||
func (h *Connect) IntentionGetExact(source, destination string, q *QueryOptions) (*Intention, *QueryMeta, error) {
|
||||
r := h.c.newRequest("GET", "/v1/connect/intentions/exact")
|
||||
r.setQueryOptions(q)
|
||||
r.params.Set("source", source)
|
||||
r.params.Set("destination", destination)
|
||||
rtt, resp, err := h.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
if resp.StatusCode == 404 {
|
||||
return nil, qm, nil
|
||||
} else if resp.StatusCode != 200 {
|
||||
var buf bytes.Buffer
|
||||
io.Copy(&buf, resp.Body)
|
||||
return nil, nil, fmt.Errorf(
|
||||
"Unexpected response %d: %s", resp.StatusCode, buf.String())
|
||||
}
|
||||
|
||||
var out Intention
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return &out, qm, nil
|
||||
}
|
||||
|
||||
// IntentionGet retrieves a single intention.
|
||||
//
|
||||
// Deprecated: use IntentionGetExact instead
|
||||
func (h *Connect) IntentionGet(id string, q *QueryOptions) (*Intention, *QueryMeta, error) {
|
||||
r := h.c.newRequest("GET", "/v1/connect/intentions/"+id)
|
||||
r.setQueryOptions(q)
|
||||
|
@ -194,7 +248,28 @@ func (h *Connect) IntentionGet(id string, q *QueryOptions) (*Intention, *QueryMe
|
|||
return &out, qm, nil
|
||||
}
|
||||
|
||||
// IntentionDeleteExact deletes a single intention by its unique name instead of its ID.
|
||||
func (h *Connect) IntentionDeleteExact(source, destination string, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := h.c.newRequest("DELETE", "/v1/connect/intentions/exact")
|
||||
r.setWriteOptions(q)
|
||||
r.params.Set("source", source)
|
||||
r.params.Set("destination", destination)
|
||||
|
||||
rtt, resp, err := requireOK(h.c.doRequest(r))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
qm := &WriteMeta{}
|
||||
qm.RequestTime = rtt
|
||||
|
||||
return qm, nil
|
||||
}
|
||||
|
||||
// IntentionDelete deletes a single intention.
|
||||
//
|
||||
// Deprecated: use IntentionDeleteExact instead
|
||||
func (h *Connect) IntentionDelete(id string, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := h.c.newRequest("DELETE", "/v1/connect/intentions/"+id)
|
||||
r.setWriteOptions(q)
|
||||
|
@ -268,9 +343,37 @@ func (h *Connect) IntentionCheck(args *IntentionCheck, q *QueryOptions) (bool, *
|
|||
return out.Allowed, qm, nil
|
||||
}
|
||||
|
||||
// IntentionUpsert will update an existing intention. The Source & Destination parameters
|
||||
// in the structure must be non-empty. The ID must be empty.
|
||||
func (c *Connect) IntentionUpsert(ixn *Intention, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := c.c.newRequest("PUT", "/v1/connect/intentions/exact")
|
||||
r.setWriteOptions(q)
|
||||
r.params.Set("source", maybePrefixNamespace(ixn.SourceNS, ixn.SourceName))
|
||||
r.params.Set("destination", maybePrefixNamespace(ixn.DestinationNS, ixn.DestinationName))
|
||||
r.obj = ixn
|
||||
rtt, resp, err := requireOK(c.c.doRequest(r))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
wm := &WriteMeta{}
|
||||
wm.RequestTime = rtt
|
||||
return wm, nil
|
||||
}
|
||||
|
||||
func maybePrefixNamespace(ns, name string) string {
|
||||
if ns == "" {
|
||||
return name
|
||||
}
|
||||
return ns + "/" + name
|
||||
}
|
||||
|
||||
// IntentionCreate will create a new intention. The ID in the given
|
||||
// structure must be empty and a generate ID will be returned on
|
||||
// success.
|
||||
//
|
||||
// Deprecated: use IntentionUpsert instead
|
||||
func (c *Connect) IntentionCreate(ixn *Intention, q *WriteOptions) (string, *WriteMeta, error) {
|
||||
r := c.c.newRequest("POST", "/v1/connect/intentions")
|
||||
r.setWriteOptions(q)
|
||||
|
@ -293,6 +396,8 @@ func (c *Connect) IntentionCreate(ixn *Intention, q *WriteOptions) (string, *Wri
|
|||
|
||||
// IntentionUpdate will update an existing intention. The ID in the given
|
||||
// structure must be non-empty.
|
||||
//
|
||||
// Deprecated: use IntentionUpsert instead
|
||||
func (c *Connect) IntentionUpdate(ixn *Intention, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := c.c.newRequest("PUT", "/v1/connect/intentions/"+ixn.ID)
|
||||
r.setWriteOptions(q)
|
||||
|
|
3
vendor/github.com/hashicorp/consul/api/discovery_chain.go
generated
vendored
3
vendor/github.com/hashicorp/consul/api/discovery_chain.go
generated
vendored
|
@ -147,6 +147,9 @@ type DiscoveryGraphNode struct {
|
|||
|
||||
// fields for Type==resolver
|
||||
Resolver *DiscoveryResolver
|
||||
|
||||
// shared by Type==resolver || Type==splitter
|
||||
LoadBalancer *LoadBalancer `json:",omitempty"`
|
||||
}
|
||||
|
||||
// compiled form of ServiceRoute
|
||||
|
|
4
vendor/github.com/hashicorp/consul/api/go.mod
generated
vendored
4
vendor/github.com/hashicorp/consul/api/go.mod
generated
vendored
|
@ -5,12 +5,12 @@ go 1.12
|
|||
replace github.com/hashicorp/consul/sdk => ../sdk
|
||||
|
||||
require (
|
||||
github.com/hashicorp/consul/sdk v0.6.0
|
||||
github.com/hashicorp/consul/sdk v0.7.0
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1
|
||||
github.com/hashicorp/go-hclog v0.12.0
|
||||
github.com/hashicorp/go-rootcerts v1.0.2
|
||||
github.com/hashicorp/go-uuid v1.0.1
|
||||
github.com/hashicorp/serf v0.9.3
|
||||
github.com/hashicorp/serf v0.9.5
|
||||
github.com/mitchellh/mapstructure v1.1.2
|
||||
github.com/stretchr/testify v1.4.0
|
||||
)
|
||||
|
|
6
vendor/github.com/hashicorp/consul/api/go.sum
generated
vendored
6
vendor/github.com/hashicorp/consul/api/go.sum
generated
vendored
|
@ -13,8 +13,6 @@ github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
|||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/hashicorp/consul/sdk v0.6.0 h1:FfhMEkwvQl57CildXJyGHnwGGM4HMODGyfjGwNM1Vdw=
|
||||
github.com/hashicorp/consul/sdk v0.6.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
|
||||
|
@ -43,8 +41,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
|||
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
|
||||
github.com/hashicorp/memberlist v0.2.2 h1:5+RffWKwqJ71YPu9mWsF7ZOscZmwfasdA8kbdC7AO2g=
|
||||
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/serf v0.9.3 h1:AVF6JDQQens6nMHT9OGERBvK0f8rPrAGILnsKLr6lzM=
|
||||
github.com/hashicorp/serf v0.9.3/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
||||
github.com/hashicorp/serf v0.9.5 h1:EBWvyu9tcRszt3Bxp3KNssBMP1KuHWyO51lz9+786iM=
|
||||
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
|
|
6
vendor/github.com/hashicorp/consul/api/lock.go
generated
vendored
6
vendor/github.com/hashicorp/consul/api/lock.go
generated
vendored
|
@ -79,6 +79,7 @@ type LockOptions struct {
|
|||
MonitorRetryTime time.Duration // Optional, defaults to DefaultMonitorRetryTime
|
||||
LockWaitTime time.Duration // Optional, defaults to DefaultLockWaitTime
|
||||
LockTryOnce bool // Optional, defaults to false which means try forever
|
||||
LockDelay time.Duration // Optional, defaults to 15s
|
||||
Namespace string `json:",omitempty"` // Optional, defaults to API client config, namespace of ACL token, or "default" namespace
|
||||
}
|
||||
|
||||
|
@ -351,8 +352,9 @@ func (l *Lock) createSession() (string, error) {
|
|||
se := l.opts.SessionOpts
|
||||
if se == nil {
|
||||
se = &SessionEntry{
|
||||
Name: l.opts.SessionName,
|
||||
TTL: l.opts.SessionTTL,
|
||||
Name: l.opts.SessionName,
|
||||
TTL: l.opts.SessionTTL,
|
||||
LockDelay: l.opts.LockDelay,
|
||||
}
|
||||
}
|
||||
w := WriteOptions{Namespace: l.opts.Namespace}
|
||||
|
|
6
vendor/github.com/hashicorp/consul/api/namespace.go
generated
vendored
6
vendor/github.com/hashicorp/consul/api/namespace.go
generated
vendored
|
@ -26,7 +26,7 @@ type Namespace struct {
|
|||
|
||||
// DeletedAt is the time when the Namespace was marked for deletion
|
||||
// This is nullable so that we can omit if empty when encoding in JSON
|
||||
DeletedAt *time.Time `json:"DeletedAt,omitempty"`
|
||||
DeletedAt *time.Time `json:"DeletedAt,omitempty" alias:"deleted_at"`
|
||||
|
||||
// CreateIndex is the Raft index at which the Namespace was created
|
||||
CreateIndex uint64 `json:"CreateIndex,omitempty"`
|
||||
|
@ -39,10 +39,10 @@ type Namespace struct {
|
|||
type NamespaceACLConfig struct {
|
||||
// PolicyDefaults is the list of policies that should be used for the parent authorizer
|
||||
// of all tokens in the associated namespace.
|
||||
PolicyDefaults []ACLLink `json:"PolicyDefaults"`
|
||||
PolicyDefaults []ACLLink `json:"PolicyDefaults" alias:"policy_defaults"`
|
||||
// RoleDefaults is the list of roles that should be used for the parent authorizer
|
||||
// of all tokens in the associated namespace.
|
||||
RoleDefaults []ACLLink `json:"RoleDefaults"`
|
||||
RoleDefaults []ACLLink `json:"RoleDefaults" alias:"role_defaults"`
|
||||
}
|
||||
|
||||
// Namespaces can be used to manage Namespaces in Consul Enterprise..
|
||||
|
|
133
vendor/github.com/hashicorp/consul/api/operator_autopilot.go
generated
vendored
133
vendor/github.com/hashicorp/consul/api/operator_autopilot.go
generated
vendored
|
@ -111,6 +111,122 @@ type OperatorHealthReply struct {
|
|||
Servers []ServerHealth
|
||||
}
|
||||
|
||||
type AutopilotState struct {
|
||||
Healthy bool
|
||||
FailureTolerance int
|
||||
OptimisticFailureTolerance int
|
||||
|
||||
Servers map[string]AutopilotServer
|
||||
Leader string
|
||||
Voters []string
|
||||
ReadReplicas []string `json:",omitempty"`
|
||||
RedundancyZones map[string]AutopilotZone `json:",omitempty"`
|
||||
Upgrade *AutopilotUpgrade `json:",omitempty"`
|
||||
}
|
||||
|
||||
type AutopilotServer struct {
|
||||
ID string
|
||||
Name string
|
||||
Address string
|
||||
NodeStatus string
|
||||
Version string
|
||||
LastContact *ReadableDuration
|
||||
LastTerm uint64
|
||||
LastIndex uint64
|
||||
Healthy bool
|
||||
StableSince time.Time
|
||||
RedundancyZone string `json:",omitempty"`
|
||||
UpgradeVersion string `json:",omitempty"`
|
||||
ReadReplica bool
|
||||
Status AutopilotServerStatus
|
||||
Meta map[string]string
|
||||
NodeType AutopilotServerType
|
||||
}
|
||||
|
||||
type AutopilotServerStatus string
|
||||
|
||||
const (
|
||||
AutopilotServerNone AutopilotServerStatus = "none"
|
||||
AutopilotServerLeader AutopilotServerStatus = "leader"
|
||||
AutopilotServerVoter AutopilotServerStatus = "voter"
|
||||
AutopilotServerNonVoter AutopilotServerStatus = "non-voter"
|
||||
AutopilotServerStaging AutopilotServerStatus = "staging"
|
||||
)
|
||||
|
||||
type AutopilotServerType string
|
||||
|
||||
const (
|
||||
AutopilotTypeVoter AutopilotServerType = "voter"
|
||||
AutopilotTypeReadReplica AutopilotServerType = "read-replica"
|
||||
AutopilotTypeZoneVoter AutopilotServerType = "zone-voter"
|
||||
AutopilotTypeZoneExtraVoter AutopilotServerType = "zone-extra-voter"
|
||||
AutopilotTypeZoneStandby AutopilotServerType = "zone-standby"
|
||||
)
|
||||
|
||||
type AutopilotZone struct {
|
||||
Servers []string
|
||||
Voters []string
|
||||
FailureTolerance int
|
||||
}
|
||||
|
||||
type AutopilotZoneUpgradeVersions struct {
|
||||
TargetVersionVoters []string `json:",omitempty"`
|
||||
TargetVersionNonVoters []string `json:",omitempty"`
|
||||
OtherVersionVoters []string `json:",omitempty"`
|
||||
OtherVersionNonVoters []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type AutopilotUpgrade struct {
|
||||
Status AutopilotUpgradeStatus
|
||||
TargetVersion string `json:",omitempty"`
|
||||
TargetVersionVoters []string `json:",omitempty"`
|
||||
TargetVersionNonVoters []string `json:",omitempty"`
|
||||
TargetVersionReadReplicas []string `json:",omitempty"`
|
||||
OtherVersionVoters []string `json:",omitempty"`
|
||||
OtherVersionNonVoters []string `json:",omitempty"`
|
||||
OtherVersionReadReplicas []string `json:",omitempty"`
|
||||
RedundancyZones map[string]AutopilotZoneUpgradeVersions `json:",omitempty"`
|
||||
}
|
||||
|
||||
type AutopilotUpgradeStatus string
|
||||
|
||||
const (
|
||||
// AutopilotUpgradeIdle is the status when no upgrade is in progress.
|
||||
AutopilotUpgradeIdle AutopilotUpgradeStatus = "idle"
|
||||
|
||||
// AutopilotUpgradeAwaitNewVoters is the status when more servers of
|
||||
// the target version must be added in order to start the promotion
|
||||
// phase of the upgrade
|
||||
AutopilotUpgradeAwaitNewVoters AutopilotUpgradeStatus = "await-new-voters"
|
||||
|
||||
// AutopilotUpgradePromoting is the status when autopilot is promoting
|
||||
// servers of the target version.
|
||||
AutopilotUpgradePromoting AutopilotUpgradeStatus = "promoting"
|
||||
|
||||
// AutopilotUpgradeDemoting is the status when autopilot is demoting
|
||||
// servers not on the target version
|
||||
AutopilotUpgradeDemoting AutopilotUpgradeStatus = "demoting"
|
||||
|
||||
// AutopilotUpgradeLeaderTransfer is the status when autopilot is transferring
|
||||
// leadership from a server running an older version to a server
|
||||
// using the target version.
|
||||
AutopilotUpgradeLeaderTransfer AutopilotUpgradeStatus = "leader-transfer"
|
||||
|
||||
// AutopilotUpgradeAwaitNewServers is the status when autpilot has finished
|
||||
// transferring leadership and has demoted all the other versioned
|
||||
// servers but wants to indicate that more target version servers
|
||||
// are needed to replace all the existing other version servers.
|
||||
AutopilotUpgradeAwaitNewServers AutopilotUpgradeStatus = "await-new-servers"
|
||||
|
||||
// AutopilotUpgradeAwaitServerRemoval is the status when autopilot is waiting
|
||||
// for the servers on non-target versions to be removed
|
||||
AutopilotUpgradeAwaitServerRemoval AutopilotUpgradeStatus = "await-server-removal"
|
||||
|
||||
// AutopilotUpgradeDisabled is the status when automated ugprades are
|
||||
// disabled in the autopilot configuration
|
||||
AutopilotUpgradeDisabled AutopilotUpgradeStatus = "disabled"
|
||||
)
|
||||
|
||||
// ReadableDuration is a duration type that is serialized to JSON in human readable format.
|
||||
type ReadableDuration time.Duration
|
||||
|
||||
|
@ -230,3 +346,20 @@ func (op *Operator) AutopilotServerHealth(q *QueryOptions) (*OperatorHealthReply
|
|||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (op *Operator) AutopilotState(q *QueryOptions) (*AutopilotState, error) {
|
||||
r := op.c.newRequest("GET", "/v1/operator/autopilot/state")
|
||||
r.setQueryOptions(q)
|
||||
_, resp, err := requireOK(op.c.doRequest(r))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var out AutopilotState
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &out, nil
|
||||
}
|
||||
|
|
3
vendor/github.com/hashicorp/consul/api/operator_keyring.go
generated
vendored
3
vendor/github.com/hashicorp/consul/api/operator_keyring.go
generated
vendored
|
@ -22,6 +22,9 @@ type KeyringResponse struct {
|
|||
// A map of the encryption keys to the number of nodes they're installed on
|
||||
Keys map[string]int
|
||||
|
||||
// A map of the encryption primary keys to the number of nodes they're installed on
|
||||
PrimaryKeys map[string]int
|
||||
|
||||
// The total number of nodes in this ring
|
||||
NumNodes int
|
||||
}
|
||||
|
|
22
vendor/github.com/hashicorp/consul/api/status.go
generated
vendored
22
vendor/github.com/hashicorp/consul/api/status.go
generated
vendored
|
@ -11,8 +11,13 @@ func (c *Client) Status() *Status {
|
|||
}
|
||||
|
||||
// Leader is used to query for a known leader
|
||||
func (s *Status) Leader() (string, error) {
|
||||
func (s *Status) LeaderWithQueryOptions(q *QueryOptions) (string, error) {
|
||||
r := s.c.newRequest("GET", "/v1/status/leader")
|
||||
|
||||
if q != nil {
|
||||
r.setQueryOptions(q)
|
||||
}
|
||||
|
||||
_, resp, err := requireOK(s.c.doRequest(r))
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -26,9 +31,18 @@ func (s *Status) Leader() (string, error) {
|
|||
return leader, nil
|
||||
}
|
||||
|
||||
func (s *Status) Leader() (string, error) {
|
||||
return s.LeaderWithQueryOptions(nil)
|
||||
}
|
||||
|
||||
// Peers is used to query for a known raft peers
|
||||
func (s *Status) Peers() ([]string, error) {
|
||||
func (s *Status) PeersWithQueryOptions(q *QueryOptions) ([]string, error) {
|
||||
r := s.c.newRequest("GET", "/v1/status/peers")
|
||||
|
||||
if q != nil {
|
||||
r.setQueryOptions(q)
|
||||
}
|
||||
|
||||
_, resp, err := requireOK(s.c.doRequest(r))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -41,3 +55,7 @@ func (s *Status) Peers() ([]string, error) {
|
|||
}
|
||||
return peers, nil
|
||||
}
|
||||
|
||||
func (s *Status) Peers() ([]string, error) {
|
||||
return s.PeersWithQueryOptions(nil)
|
||||
}
|
||||
|
|
50
vendor/github.com/hashicorp/consul/sdk/testutil/io.go
generated
vendored
50
vendor/github.com/hashicorp/consul/sdk/testutil/io.go
generated
vendored
|
@ -29,40 +29,54 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
// TempDir creates a temporary directory within tmpdir
|
||||
// with the name 'testname-name'. If the directory cannot
|
||||
// be created t.Fatal is called.
|
||||
var noCleanup = strings.ToLower(os.Getenv("TEST_NOCLEANUP")) == "true"
|
||||
|
||||
// TempDir creates a temporary directory within tmpdir with the name 'testname-name'.
|
||||
// If the directory cannot be created t.Fatal is called.
|
||||
// The directory will be removed when the test ends. Set TEST_NOCLEANUP env var
|
||||
// to prevent the directory from being removed.
|
||||
func TempDir(t *testing.T, name string) string {
|
||||
if t != nil && t.Name() != "" {
|
||||
name = t.Name() + "-" + name
|
||||
if t == nil {
|
||||
panic("argument t must be non-nil")
|
||||
}
|
||||
name = t.Name() + "-" + name
|
||||
name = strings.Replace(name, "/", "_", -1)
|
||||
d, err := ioutil.TempDir(tmpdir, name)
|
||||
if err != nil {
|
||||
if t == nil {
|
||||
panic(err)
|
||||
}
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
if noCleanup {
|
||||
t.Logf("skipping cleanup because TEST_NOCLEANUP was enabled")
|
||||
return
|
||||
}
|
||||
os.RemoveAll(d)
|
||||
})
|
||||
return d
|
||||
}
|
||||
|
||||
// TempFile creates a temporary file within tmpdir
|
||||
// with the name 'testname-name'. If the file cannot
|
||||
// be created t.Fatal is called. If a temporary directory
|
||||
// has been created before consider storing the file
|
||||
// inside this directory to avoid double cleanup.
|
||||
// TempFile creates a temporary file within tmpdir with the name 'testname-name'.
|
||||
// If the file cannot be created t.Fatal is called. If a temporary directory
|
||||
// has been created before consider storing the file inside this directory to
|
||||
// avoid double cleanup.
|
||||
// The file will be removed when the test ends. Set TEST_NOCLEANUP env var
|
||||
// to prevent the file from being removed.
|
||||
func TempFile(t *testing.T, name string) *os.File {
|
||||
if t != nil && t.Name() != "" {
|
||||
name = t.Name() + "-" + name
|
||||
if t == nil {
|
||||
panic("argument t must be non-nil")
|
||||
}
|
||||
name = t.Name() + "-" + name
|
||||
name = strings.Replace(name, "/", "_", -1)
|
||||
f, err := ioutil.TempFile(tmpdir, name)
|
||||
if err != nil {
|
||||
if t == nil {
|
||||
panic(err)
|
||||
}
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
if noCleanup {
|
||||
t.Logf("skipping cleanup because TEST_NOCLEANUP was enabled")
|
||||
return
|
||||
}
|
||||
os.Remove(f.Name())
|
||||
})
|
||||
return f
|
||||
}
|
||||
|
|
3
vendor/github.com/hashicorp/consul/sdk/testutil/retry/retry.go
generated
vendored
3
vendor/github.com/hashicorp/consul/sdk/testutil/retry/retry.go
generated
vendored
|
@ -23,6 +23,8 @@ import (
|
|||
|
||||
// Failer is an interface compatible with testing.T.
|
||||
type Failer interface {
|
||||
Helper()
|
||||
|
||||
// Log is called for the final test output
|
||||
Log(args ...interface{})
|
||||
|
||||
|
@ -116,6 +118,7 @@ func dedup(a []string) string {
|
|||
func run(r Retryer, t Failer, f func(r *R)) {
|
||||
rr := &R{}
|
||||
fail := func() {
|
||||
t.Helper()
|
||||
out := dedup(rr.output)
|
||||
if out != "" {
|
||||
t.Log(out)
|
||||
|
|
71
vendor/github.com/hashicorp/consul/sdk/testutil/server.go
generated
vendored
71
vendor/github.com/hashicorp/consul/sdk/testutil/server.go
generated
vendored
|
@ -25,6 +25,7 @@ import (
|
|||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -133,7 +134,7 @@ type ServerConfigCallback func(c *TestServerConfig)
|
|||
|
||||
// defaultServerConfig returns a new TestServerConfig struct
|
||||
// with all of the listen ports incremented by one.
|
||||
func defaultServerConfig(t CleanupT) *TestServerConfig {
|
||||
func defaultServerConfig(t TestingTB) *TestServerConfig {
|
||||
nodeID, err := uuid.GenerateUUID()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -215,11 +216,11 @@ type TestServer struct {
|
|||
tmpdir string
|
||||
}
|
||||
|
||||
// NewTestServerConfig creates a new TestServer, and makes a call to an optional
|
||||
// NewTestServerConfigT creates a new TestServer, and makes a call to an optional
|
||||
// callback function to modify the configuration. If there is an error
|
||||
// configuring or starting the server, the server will NOT be running when the
|
||||
// function returns (thus you do not need to stop it).
|
||||
func NewTestServerConfigT(t testing.TB, cb ServerConfigCallback) (*TestServer, error) {
|
||||
func NewTestServerConfigT(t TestingTB, cb ServerConfigCallback) (*TestServer, error) {
|
||||
path, err := exec.LookPath("consul")
|
||||
if err != nil || path == "" {
|
||||
return nil, fmt.Errorf("consul not found on $PATH - download and install " +
|
||||
|
@ -328,9 +329,22 @@ func (s *TestServer) Stop() error {
|
|||
}
|
||||
}
|
||||
|
||||
waitDone := make(chan error)
|
||||
go func() {
|
||||
waitDone <- s.cmd.Wait()
|
||||
close(waitDone)
|
||||
}()
|
||||
|
||||
// wait for the process to exit to be sure that the data dir can be
|
||||
// deleted on all platforms.
|
||||
return s.cmd.Wait()
|
||||
select {
|
||||
case err := <-waitDone:
|
||||
return err
|
||||
case <-time.After(10 * time.Second):
|
||||
s.cmd.Process.Signal(syscall.SIGABRT)
|
||||
s.cmd.Wait()
|
||||
return fmt.Errorf("timeout waiting for server to stop gracefully")
|
||||
}
|
||||
}
|
||||
|
||||
// waitForAPI waits for the /status/leader HTTP endpoint to start
|
||||
|
@ -351,11 +365,12 @@ func (s *TestServer) waitForAPI() error {
|
|||
time.Sleep(timer.Wait)
|
||||
|
||||
url := s.url("/v1/status/leader")
|
||||
_, err := s.masterGet(url)
|
||||
resp, err := s.masterGet(url)
|
||||
if err != nil {
|
||||
failed = true
|
||||
continue
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
failed = false
|
||||
}
|
||||
|
@ -378,7 +393,7 @@ func (s *TestServer) WaitForLeader(t *testing.T) {
|
|||
}
|
||||
defer resp.Body.Close()
|
||||
if err := s.requireOK(resp); err != nil {
|
||||
r.Fatal("failed OK response", err)
|
||||
r.Fatalf("failed OK response: %v", err)
|
||||
}
|
||||
|
||||
// Ensure we have a leader and a node registration.
|
||||
|
@ -387,7 +402,7 @@ func (s *TestServer) WaitForLeader(t *testing.T) {
|
|||
}
|
||||
index, err := strconv.ParseInt(resp.Header.Get("X-Consul-Index"), 10, 64)
|
||||
if err != nil {
|
||||
r.Fatal("bad consul index", err)
|
||||
r.Fatalf("bad consul index: %v", err)
|
||||
}
|
||||
if index < 2 {
|
||||
r.Fatal("consul index should be at least 2")
|
||||
|
@ -418,7 +433,7 @@ func (s *TestServer) WaitForActiveCARoot(t *testing.T) {
|
|||
// since this is used in both `api` and consul test or duplication. The 200
|
||||
// is all we really need to wait for.
|
||||
if err := s.requireOK(resp); err != nil {
|
||||
r.Fatal("failed OK response", err)
|
||||
r.Fatalf("failed OK response: %v", err)
|
||||
}
|
||||
|
||||
var roots rootsResponse
|
||||
|
@ -434,6 +449,27 @@ func (s *TestServer) WaitForActiveCARoot(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
// WaitForServiceIntentions waits until the server can accept config entry
|
||||
// kinds of service-intentions meaning any migration bootstrapping from pre-1.9
|
||||
// intentions has completed.
|
||||
func (s *TestServer) WaitForServiceIntentions(t *testing.T) {
|
||||
const fakeConfigName = "Sa4ohw5raith4si0Ohwuqu3lowiethoh"
|
||||
retry.Run(t, func(r *retry.R) {
|
||||
// Try to delete a non-existent service-intentions config entry. The
|
||||
// preflightCheck call in agent/consul/config_endpoint.go will fail if
|
||||
// we aren't ready yet, vs just doing no work instead.
|
||||
url := s.url("/v1/config/service-intentions/" + fakeConfigName)
|
||||
resp, err := s.masterDelete(url)
|
||||
if err != nil {
|
||||
r.Fatalf("failed http get '%s': %v", url, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if err := s.requireOK(resp); err != nil {
|
||||
r.Fatalf("failed OK response: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// WaitForSerfCheck ensures we have a node with serfHealth check registered
|
||||
// Behavior mirrors testrpc.WaitForTestAgent but avoids the dependency cycle in api pkg
|
||||
func (s *TestServer) WaitForSerfCheck(t *testing.T) {
|
||||
|
@ -442,11 +478,11 @@ func (s *TestServer) WaitForSerfCheck(t *testing.T) {
|
|||
url := s.url("/v1/catalog/nodes?index=0")
|
||||
resp, err := s.masterGet(url)
|
||||
if err != nil {
|
||||
r.Fatal("failed http get", err)
|
||||
r.Fatalf("failed http get: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if err := s.requireOK(resp); err != nil {
|
||||
r.Fatal("failed OK response", err)
|
||||
r.Fatalf("failed OK response: %v", err)
|
||||
}
|
||||
|
||||
// Watch for the anti-entropy sync to finish.
|
||||
|
@ -463,11 +499,11 @@ func (s *TestServer) WaitForSerfCheck(t *testing.T) {
|
|||
url = s.url(fmt.Sprintf("/v1/health/node/%s", payload[0]["Node"]))
|
||||
resp, err = s.masterGet(url)
|
||||
if err != nil {
|
||||
r.Fatal("failed http get", err)
|
||||
r.Fatalf("failed http get: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if err := s.requireOK(resp); err != nil {
|
||||
r.Fatal("failed OK response", err)
|
||||
r.Fatalf("failed OK response: %v", err)
|
||||
}
|
||||
dec = json.NewDecoder(resp.Body)
|
||||
if err = dec.Decode(&payload); err != nil {
|
||||
|
@ -497,3 +533,14 @@ func (s *TestServer) masterGet(url string) (*http.Response, error) {
|
|||
}
|
||||
return s.HTTPClient.Do(req)
|
||||
}
|
||||
|
||||
func (s *TestServer) masterDelete(url string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("DELETE", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if s.Config.ACL.Tokens.Master != "" {
|
||||
req.Header.Set("x-consul-token", s.Config.ACL.Tokens.Master)
|
||||
}
|
||||
return s.HTTPClient.Do(req)
|
||||
}
|
||||
|
|
17
vendor/github.com/hashicorp/consul/sdk/testutil/testlog.go
generated
vendored
17
vendor/github.com/hashicorp/consul/sdk/testutil/testlog.go
generated
vendored
|
@ -10,11 +10,11 @@ import (
|
|||
"github.com/hashicorp/go-hclog"
|
||||
)
|
||||
|
||||
func Logger(t testing.TB) hclog.InterceptLogger {
|
||||
func Logger(t TestingTB) hclog.InterceptLogger {
|
||||
return LoggerWithOutput(t, NewLogBuffer(t))
|
||||
}
|
||||
|
||||
func LoggerWithOutput(t testing.TB, output io.Writer) hclog.InterceptLogger {
|
||||
func LoggerWithOutput(t TestingTB, output io.Writer) hclog.InterceptLogger {
|
||||
return hclog.NewInterceptLogger(&hclog.LoggerOptions{
|
||||
Name: t.Name(),
|
||||
Level: hclog.Trace,
|
||||
|
@ -25,18 +25,18 @@ func LoggerWithOutput(t testing.TB, output io.Writer) hclog.InterceptLogger {
|
|||
var sendTestLogsToStdout = os.Getenv("NOLOGBUFFER") == "1"
|
||||
|
||||
// NewLogBuffer returns an io.Writer which buffers all writes. When the test
|
||||
// ends, t.Failed is checked. If the test has failed all log output is printed
|
||||
// to stdout.
|
||||
// ends, t.Failed is checked. If the test has failed or has been run in verbose
|
||||
// mode all log output is printed to stdout.
|
||||
//
|
||||
// Set the env var NOLOGBUFFER=1 to disable buffering, resulting in all log
|
||||
// output being written immediately to stdout.
|
||||
func NewLogBuffer(t CleanupT) io.Writer {
|
||||
func NewLogBuffer(t TestingTB) io.Writer {
|
||||
if sendTestLogsToStdout {
|
||||
return os.Stdout
|
||||
}
|
||||
buf := &logBuffer{buf: new(bytes.Buffer)}
|
||||
t.Cleanup(func() {
|
||||
if t.Failed() {
|
||||
if t.Failed() || testing.Verbose() {
|
||||
buf.Lock()
|
||||
defer buf.Unlock()
|
||||
buf.buf.WriteTo(os.Stdout)
|
||||
|
@ -45,11 +45,6 @@ func NewLogBuffer(t CleanupT) io.Writer {
|
|||
return buf
|
||||
}
|
||||
|
||||
type CleanupT interface {
|
||||
Cleanup(f func())
|
||||
Failed() bool
|
||||
}
|
||||
|
||||
type logBuffer struct {
|
||||
buf *bytes.Buffer
|
||||
sync.Mutex
|
||||
|
|
11
vendor/github.com/hashicorp/consul/sdk/testutil/types.go
generated
vendored
Normal file
11
vendor/github.com/hashicorp/consul/sdk/testutil/types.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
package testutil
|
||||
|
||||
// TestingTB is an interface that describes the implementation of the testing object.
|
||||
// Using an interface that describes testing.TB instead of the actual implementation
|
||||
// makes testutil usable in a wider variety of contexts (e.g. use with ginkgo : https://godoc.org/github.com/onsi/ginkgo#GinkgoT)
|
||||
type TestingTB interface {
|
||||
Cleanup(func())
|
||||
Failed() bool
|
||||
Logf(format string, args ...interface{})
|
||||
Name() string
|
||||
}
|
4
vendor/github.com/hashicorp/serf/coordinate/phantom.go
generated
vendored
4
vendor/github.com/hashicorp/serf/coordinate/phantom.go
generated
vendored
|
@ -11,7 +11,7 @@ import (
|
|||
// given config.
|
||||
func GenerateClients(nodes int, config *Config) ([]*Client, error) {
|
||||
clients := make([]*Client, nodes)
|
||||
for i, _ := range clients {
|
||||
for i := range clients {
|
||||
client, err := NewClient(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -146,7 +146,7 @@ func Simulate(clients []*Client, truth [][]time.Duration, cycles int) {
|
|||
|
||||
nodes := len(clients)
|
||||
for cycle := 0; cycle < cycles; cycle++ {
|
||||
for i, _ := range clients {
|
||||
for i := range clients {
|
||||
if j := rand.Intn(nodes); j != i {
|
||||
c := clients[j].GetCoordinate()
|
||||
rtt := truth[i][j]
|
||||
|
|
10
vendor/github.com/hashicorp/serf/serf/config.go
generated
vendored
10
vendor/github.com/hashicorp/serf/serf/config.go
generated
vendored
|
@ -253,6 +253,15 @@ type Config struct {
|
|||
//
|
||||
// WARNING: this should ONLY be used in tests
|
||||
messageDropper func(typ messageType) bool
|
||||
|
||||
// ReconnectTimeoutOverride is an optional interface which when present allows
|
||||
// the application to cause reaping of a node to happen when it otherwise wouldn't
|
||||
ReconnectTimeoutOverride ReconnectTimeoutOverrider
|
||||
|
||||
// ValidateNodeNames controls whether nodenames only
|
||||
// contain alphanumeric, dashes and '.'characters
|
||||
// and sets maximum length to 128 characters
|
||||
ValidateNodeNames bool
|
||||
}
|
||||
|
||||
// Init allocates the subdata structures
|
||||
|
@ -298,6 +307,7 @@ func DefaultConfig() *Config {
|
|||
QuerySizeLimit: 1024,
|
||||
EnableNameConflictResolution: true,
|
||||
DisableCoordinates: false,
|
||||
ValidateNodeNames: false,
|
||||
UserEventSizeLimit: 512,
|
||||
}
|
||||
}
|
||||
|
|
8
vendor/github.com/hashicorp/serf/serf/internal_query.go
generated
vendored
8
vendor/github.com/hashicorp/serf/serf/internal_query.go
generated
vendored
|
@ -64,6 +64,9 @@ type nodeKeyResponse struct {
|
|||
|
||||
// Keys is used in listing queries to relay a list of installed keys
|
||||
Keys []string
|
||||
|
||||
// PrimaryKey is used in listing queries to relay the primary key
|
||||
PrimaryKey string
|
||||
}
|
||||
|
||||
// newSerfQueries is used to create a new serfQueries. We return an event
|
||||
|
@ -346,7 +349,7 @@ SEND:
|
|||
func (s *serfQueries) handleListKeys(q *Query) {
|
||||
response := nodeKeyResponse{Result: false}
|
||||
keyring := s.serf.config.MemberlistConfig.Keyring
|
||||
|
||||
var primaryKeyBytes []byte
|
||||
if !s.serf.EncryptionEnabled() {
|
||||
response.Message = "Keyring is empty (encryption not enabled)"
|
||||
s.logger.Printf("[ERR] serf: Keyring is empty (encryption not enabled)")
|
||||
|
@ -360,6 +363,9 @@ func (s *serfQueries) handleListKeys(q *Query) {
|
|||
key := base64.StdEncoding.EncodeToString(keyBytes)
|
||||
response.Keys = append(response.Keys, key)
|
||||
}
|
||||
primaryKeyBytes = keyring.GetPrimaryKey()
|
||||
response.PrimaryKey = base64.StdEncoding.EncodeToString(primaryKeyBytes)
|
||||
|
||||
response.Result = true
|
||||
|
||||
SEND:
|
||||
|
|
17
vendor/github.com/hashicorp/serf/serf/keymanager.go
generated
vendored
17
vendor/github.com/hashicorp/serf/serf/keymanager.go
generated
vendored
|
@ -31,6 +31,10 @@ type KeyResponse struct {
|
|||
// Keys is a mapping of the base64-encoded value of the key bytes to the
|
||||
// number of nodes that have the key installed.
|
||||
Keys map[string]int
|
||||
|
||||
// PrimaryKeys is a mapping of the base64-encoded value of the primary
|
||||
// key bytes to the number of nodes that have the key installed.
|
||||
PrimaryKeys map[string]int
|
||||
}
|
||||
|
||||
// KeyRequestOptions is used to contain optional parameters for a keyring operation
|
||||
|
@ -76,13 +80,11 @@ func (k *KeyManager) streamKeyResp(resp *KeyResponse, ch <-chan NodeResponse) {
|
|||
// Currently only used for key list queries, this adds keys to a counter
|
||||
// and increments them for each node response which contains them.
|
||||
for _, key := range nodeResponse.Keys {
|
||||
if _, ok := resp.Keys[key]; !ok {
|
||||
resp.Keys[key] = 1
|
||||
} else {
|
||||
resp.Keys[key]++
|
||||
}
|
||||
resp.Keys[key]++
|
||||
}
|
||||
|
||||
resp.PrimaryKeys[nodeResponse.PrimaryKey]++
|
||||
|
||||
NEXT:
|
||||
// Return early if all nodes have responded. This allows us to avoid
|
||||
// waiting for the full timeout when there is nothing left to do.
|
||||
|
@ -97,8 +99,9 @@ func (k *KeyManager) streamKeyResp(resp *KeyResponse, ch <-chan NodeResponse) {
|
|||
// KeyResponse for uniform response handling.
|
||||
func (k *KeyManager) handleKeyRequest(key, query string, opts *KeyRequestOptions) (*KeyResponse, error) {
|
||||
resp := &KeyResponse{
|
||||
Messages: make(map[string]string),
|
||||
Keys: make(map[string]int),
|
||||
Messages: make(map[string]string),
|
||||
Keys: make(map[string]int),
|
||||
PrimaryKeys: make(map[string]int),
|
||||
}
|
||||
qName := internalQueryName(query)
|
||||
|
||||
|
|
37
vendor/github.com/hashicorp/serf/serf/merge_delegate.go
generated
vendored
37
vendor/github.com/hashicorp/serf/serf/merge_delegate.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
package serf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/hashicorp/memberlist"
|
||||
|
@ -17,22 +18,31 @@ type mergeDelegate struct {
|
|||
func (m *mergeDelegate) NotifyMerge(nodes []*memberlist.Node) error {
|
||||
members := make([]*Member, len(nodes))
|
||||
for idx, n := range nodes {
|
||||
members[idx] = m.nodeToMember(n)
|
||||
var err error
|
||||
members[idx], err = m.nodeToMember(n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return m.serf.config.Merge.NotifyMerge(members)
|
||||
}
|
||||
|
||||
func (m *mergeDelegate) NotifyAlive(peer *memberlist.Node) error {
|
||||
member := m.nodeToMember(peer)
|
||||
member, err := m.nodeToMember(peer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.serf.config.Merge.NotifyMerge([]*Member{member})
|
||||
}
|
||||
|
||||
func (m *mergeDelegate) nodeToMember(n *memberlist.Node) *Member {
|
||||
func (m *mergeDelegate) nodeToMember(n *memberlist.Node) (*Member, error) {
|
||||
status := StatusNone
|
||||
if n.State == memberlist.StateLeft {
|
||||
status = StatusLeft
|
||||
}
|
||||
|
||||
if err := m.validateMemberInfo(n); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Member{
|
||||
Name: n.Name,
|
||||
Addr: net.IP(n.Addr),
|
||||
|
@ -45,5 +55,22 @@ func (m *mergeDelegate) nodeToMember(n *memberlist.Node) *Member {
|
|||
DelegateMin: n.DMin,
|
||||
DelegateMax: n.DMax,
|
||||
DelegateCur: n.DCur,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// validateMemberInfo checks that the data we are sending is valid
|
||||
func (m *mergeDelegate) validateMemberInfo(n *memberlist.Node) error {
|
||||
if err := m.serf.validateNodeName(n.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(n.Addr) != 4 && len(n.Addr) != 16 {
|
||||
return fmt.Errorf("IP byte length is invalid: %d bytes is not either 4 or 16", len(n.Addr))
|
||||
}
|
||||
|
||||
if len(n.Meta) > memberlist.MetaMaxSize {
|
||||
return fmt.Errorf("Encoded length of tags exceeds limit of %d bytes",
|
||||
memberlist.MetaMaxSize)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
57
vendor/github.com/hashicorp/serf/serf/serf.go
generated
vendored
57
vendor/github.com/hashicorp/serf/serf/serf.go
generated
vendored
|
@ -11,6 +11,7 @@ import (
|
|||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
@ -36,6 +37,8 @@ const (
|
|||
tagMagicByte uint8 = 255
|
||||
)
|
||||
|
||||
const MaxNodeNameLength int = 128
|
||||
|
||||
var (
|
||||
// FeatureNotSupported is returned if a feature cannot be used
|
||||
// due to an older protocol version being used.
|
||||
|
@ -47,6 +50,12 @@ func init() {
|
|||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
// ReconnectTimeoutOverrider is an interface that can be implemented to allow overriding
|
||||
// the reconnect timeout for individual members.
|
||||
type ReconnectTimeoutOverrider interface {
|
||||
ReconnectTimeout(member *Member, timeout time.Duration) time.Duration
|
||||
}
|
||||
|
||||
// Serf is a single node that is part of a single cluster that gets
|
||||
// events about joins/leaves/failures/etc. It is created with the Create
|
||||
// method.
|
||||
|
@ -269,6 +278,9 @@ func Create(conf *Config) (*Serf, error) {
|
|||
if len(serf.encodeTags(conf.Tags)) > memberlist.MetaMaxSize {
|
||||
return nil, fmt.Errorf("Encoded length of tags exceeds limit of %d bytes", memberlist.MetaMaxSize)
|
||||
}
|
||||
if err := serf.ValidateNodeNames(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check if serf member event coalescing is enabled
|
||||
if conf.CoalescePeriod > 0 && conf.QuiescentPeriod > 0 && conf.EventCh != nil {
|
||||
|
@ -1102,8 +1114,21 @@ func (s *Serf) handleNodeLeaveIntent(leaveMsg *messageLeave) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// Always set the lamport time so that if we retransmit below it won't echo
|
||||
// around forever!
|
||||
// Always update the lamport time even when the status does not change
|
||||
// (despite the variable naming implying otherwise).
|
||||
//
|
||||
// By updating this statusLTime here we ensure that the earlier conditional
|
||||
// on "leaveMsg.LTime <= member.statusLTime" will prevent an infinite
|
||||
// rebroadcast when seeing two successive leave message for the same
|
||||
// member. Without this fix a leave message that arrives after a member is
|
||||
// already marked as leaving/left will cause it to be rebroadcast without
|
||||
// marking it locally as witnessed. If more than one serf instance in the
|
||||
// cluster experiences this series of events then they will rebroadcast
|
||||
// each other's messages about the affected node indefinitely.
|
||||
//
|
||||
// This eventually leads to overflowing serf intent queues
|
||||
// - https://github.com/hashicorp/consul/issues/8179
|
||||
// - https://github.com/hashicorp/consul/issues/7960
|
||||
member.statusLTime = leaveMsg.LTime
|
||||
|
||||
// State transition depends on current state
|
||||
|
@ -1558,8 +1583,13 @@ func (s *Serf) reap(old []*memberState, now time.Time, timeout time.Duration) []
|
|||
for i := 0; i < n; i++ {
|
||||
m := old[i]
|
||||
|
||||
memberTimeout := timeout
|
||||
if s.config.ReconnectTimeoutOverride != nil {
|
||||
memberTimeout = s.config.ReconnectTimeoutOverride.ReconnectTimeout(&m.Member, memberTimeout)
|
||||
}
|
||||
|
||||
// Skip if the timeout is not yet reached
|
||||
if now.Sub(m.leaveTime) <= timeout {
|
||||
if now.Sub(m.leaveTime) <= memberTimeout {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -1871,3 +1901,24 @@ func (s *Serf) NumNodes() (numNodes int) {
|
|||
|
||||
return numNodes
|
||||
}
|
||||
|
||||
// ValidateNodeNames verifies the NodeName contains
|
||||
// only alphanumeric, -, or . and is under 128 chracters
|
||||
func (s *Serf) ValidateNodeNames() error {
|
||||
return s.validateNodeName(s.config.NodeName)
|
||||
}
|
||||
|
||||
func (s *Serf) validateNodeName(name string) error {
|
||||
if s.config.ValidateNodeNames {
|
||||
var InvalidNameRe = regexp.MustCompile(`[^A-Za-z0-9\-\.]+`)
|
||||
if InvalidNameRe.MatchString(name) {
|
||||
return fmt.Errorf("Node name contains invalid characters %v , Valid characters include "+
|
||||
"all alpha-numerics and dashes and '.' ", name)
|
||||
}
|
||||
if len(name) > MaxNodeNameLength {
|
||||
return fmt.Errorf("Node name is %v characters. "+
|
||||
"Valid length is between 1 and 128 characters", len(name))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
|
@ -364,10 +364,10 @@ github.com/hashicorp/consul-template/signals
|
|||
github.com/hashicorp/consul-template/template
|
||||
github.com/hashicorp/consul-template/version
|
||||
github.com/hashicorp/consul-template/watch
|
||||
# github.com/hashicorp/consul/api v1.6.0
|
||||
# github.com/hashicorp/consul/api v1.8.1
|
||||
## explicit
|
||||
github.com/hashicorp/consul/api
|
||||
# github.com/hashicorp/consul/sdk v0.6.0
|
||||
# github.com/hashicorp/consul/sdk v0.7.0
|
||||
## explicit
|
||||
github.com/hashicorp/consul/sdk/freeport
|
||||
github.com/hashicorp/consul/sdk/testutil
|
||||
|
@ -503,7 +503,7 @@ github.com/hashicorp/raft
|
|||
# github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea
|
||||
## explicit
|
||||
github.com/hashicorp/raft-boltdb
|
||||
# github.com/hashicorp/serf v0.9.3
|
||||
# github.com/hashicorp/serf v0.9.5
|
||||
## explicit
|
||||
github.com/hashicorp/serf/coordinate
|
||||
github.com/hashicorp/serf/serf
|
||||
|
|
Loading…
Reference in a new issue