agent: expose the list of supported envoy versions on /v1/agent/self (#8545)

This commit is contained in:
R.B. Boyer 2020-08-26 10:04:11 -05:00 committed by GitHub
parent 539b1076e2
commit 6fad634512
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 77 additions and 29 deletions

3
.changelog/8545.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:feature
agent: expose the list of supported envoy versions on /v1/agent/self
```

View File

@ -17,6 +17,7 @@ import (
"github.com/hashicorp/consul/agent/debug" "github.com/hashicorp/consul/agent/debug"
"github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs"
token_store "github.com/hashicorp/consul/agent/token" token_store "github.com/hashicorp/consul/agent/token"
"github.com/hashicorp/consul/agent/xds/proxysupport"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/ipaddr" "github.com/hashicorp/consul/ipaddr"
"github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib"
@ -38,6 +39,11 @@ type Self struct {
Member serf.Member Member serf.Member
Stats map[string]map[string]string Stats map[string]map[string]string
Meta map[string]string Meta map[string]string
XDS *xdsSelf `json:"xDS,omitempty"`
}
type xdsSelf struct {
SupportedProxies map[string][]string
} }
func (s *HTTPServer) AgentSelf(resp http.ResponseWriter, req *http.Request) (interface{}, error) { func (s *HTTPServer) AgentSelf(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
@ -60,6 +66,15 @@ func (s *HTTPServer) AgentSelf(resp http.ResponseWriter, req *http.Request) (int
} }
} }
var xds *xdsSelf
if s.agent.grpcServer != nil {
xds = &xdsSelf{
SupportedProxies: map[string][]string{
"envoy": proxysupport.EnvoyVersions,
},
}
}
config := struct { config := struct {
Datacenter string Datacenter string
NodeName string NodeName string
@ -82,6 +97,7 @@ func (s *HTTPServer) AgentSelf(resp http.ResponseWriter, req *http.Request) (int
Member: s.agent.LocalMember(), Member: s.agent.LocalMember(),
Stats: s.agent.Stats(), Stats: s.agent.Stats(),
Meta: s.agent.State.Metadata(), Meta: s.agent.State.Metadata(),
XDS: xds,
}, nil }, nil
} }

View File

@ -13,7 +13,6 @@ import (
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"os" "os"
"reflect"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
@ -27,6 +26,7 @@ import (
"github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/token" "github.com/hashicorp/consul/agent/token"
tokenStore "github.com/hashicorp/consul/agent/token" tokenStore "github.com/hashicorp/consul/agent/token"
"github.com/hashicorp/consul/agent/xds/proxysupport"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil"
@ -1209,39 +1209,65 @@ func TestAgent_Checks_ACLFilter(t *testing.T) {
func TestAgent_Self(t *testing.T) { func TestAgent_Self(t *testing.T) {
t.Parallel() t.Parallel()
a := NewTestAgent(t, `
cases := map[string]struct {
hcl string
expectXDS bool
}{
"normal": {
hcl: `
node_meta { node_meta {
somekey = "somevalue" somekey = "somevalue"
} }
`) `,
expectXDS: true,
},
"no grpc": {
hcl: `
node_meta {
somekey = "somevalue"
}
ports = {
grpc = -1
}
`,
expectXDS: false,
},
}
for name, tc := range cases {
tc := tc
t.Run(name, func(t *testing.T) {
a := NewTestAgent(t, tc.hcl)
defer a.Shutdown() defer a.Shutdown()
testrpc.WaitForTestAgent(t, a.RPC, "dc1") testrpc.WaitForTestAgent(t, a.RPC, "dc1")
req, _ := http.NewRequest("GET", "/v1/agent/self", nil) req, _ := http.NewRequest("GET", "/v1/agent/self", nil)
obj, err := a.srv.AgentSelf(nil, req) obj, err := a.srv.AgentSelf(nil, req)
if err != nil { require.NoError(t, err)
t.Fatalf("err: %v", err)
}
val := obj.(Self) val := obj.(Self)
if int(val.Member.Port) != a.Config.SerfPortLAN { require.Equal(t, a.Config.SerfPortLAN, int(val.Member.Port))
t.Fatalf("incorrect port: %v", obj) require.Equal(t, a.Config.SerfPortLAN, val.DebugConfig["SerfPortLAN"].(int))
}
if val.DebugConfig["SerfPortLAN"].(int) != a.Config.SerfPortLAN {
t.Fatalf("incorrect port: %v", obj)
}
cs, err := a.GetLANCoordinate() cs, err := a.GetLANCoordinate()
if err != nil { require.NoError(t, err)
t.Fatalf("err: %v", err) require.Equal(t, cs[a.config.SegmentName], val.Coord)
}
if c := cs[a.config.SegmentName]; !reflect.DeepEqual(c, val.Coord) {
t.Fatalf("coordinates are not equal: %v != %v", c, val.Coord)
}
delete(val.Meta, structs.MetaSegmentKey) // Added later, not in config. delete(val.Meta, structs.MetaSegmentKey) // Added later, not in config.
if !reflect.DeepEqual(a.config.NodeMeta, val.Meta) { require.Equal(t, a.config.NodeMeta, val.Meta)
t.Fatalf("meta fields are not equal: %v != %v", a.config.NodeMeta, val.Meta)
if tc.expectXDS {
require.NotNil(t, val.XDS, "xds component missing when gRPC is enabled")
require.Equal(t,
map[string][]string{"envoy": proxysupport.EnvoyVersions},
val.XDS.SupportedProxies,
)
} else {
require.Nil(t, val.XDS, "xds component should be missing when gRPC is disabled")
}
})
} }
} }

View File

@ -2,6 +2,9 @@ package proxysupport
// EnvoyVersions lists the latest officially supported versions of envoy. // EnvoyVersions lists the latest officially supported versions of envoy.
// //
// This list must be sorted by semver descending. Only one point release for
// each major release should be present.
//
// see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions // see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions
var EnvoyVersions = []string{ var EnvoyVersions = []string{
"1.15.0", "1.15.0",