From d71f071becf227b60f8d77cf254daff53650a250 Mon Sep 17 00:00:00 2001 From: Derek Menteer <105233703+hashi-derek@users.noreply.github.com> Date: Fri, 18 Nov 2022 10:32:01 -0600 Subject: [PATCH] Fix SDK to support older versions of Consul. (#15423) This change was necessary, because the configuration was always generated with a gRPC TLS port, which did not exist in Consul 1.13, and would result in the server failing to launch with an error. This code checks the version of Consul and conditionally adds the gRPC TLS port, only if the version number is greater than 1.14. --- .changelog/15423.txt | 3 +++ api/go.mod | 1 + api/go.sum | 2 ++ sdk/go.mod | 1 + sdk/go.sum | 2 ++ sdk/testutil/server.go | 50 +++++++++++++++++++++++++++++++++++++----- 6 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 .changelog/15423.txt diff --git a/.changelog/15423.txt b/.changelog/15423.txt new file mode 100644 index 000000000..3721d5c8c --- /dev/null +++ b/.changelog/15423.txt @@ -0,0 +1,3 @@ +```release-note:bug +sdk: Fix SDK testutil backwards compatibility by only configuring grpc_tls port for new Consul versions. +``` diff --git a/api/go.mod b/api/go.mod index f65d2826f..4fd417ee2 100644 --- a/api/go.mod +++ b/api/go.mod @@ -26,6 +26,7 @@ require ( github.com/hashicorp/go-msgpack v0.5.3 // indirect github.com/hashicorp/go-multierror v1.1.0 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/go-version v1.2.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect github.com/kr/pretty v0.2.1 // indirect diff --git a/api/go.sum b/api/go.sum index 19adcc8f6..043db4cd1 100644 --- a/api/go.sum +++ b/api/go.sum @@ -38,6 +38,8 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= diff --git a/sdk/go.mod b/sdk/go.mod index 65050ac37..b7c2eb014 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -6,6 +6,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.1 github.com/hashicorp/go-hclog v0.12.0 github.com/hashicorp/go-uuid v1.0.1 + github.com/hashicorp/go-version v1.2.1 github.com/pkg/errors v0.8.1 github.com/stretchr/testify v1.4.0 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad diff --git a/sdk/go.sum b/sdk/go.sum index 94ec34ba4..65c687138 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -10,6 +10,8 @@ github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tk github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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= diff --git a/sdk/testutil/server.go b/sdk/testutil/server.go index 4ab2144b3..de42a8e41 100644 --- a/sdk/testutil/server.go +++ b/sdk/testutil/server.go @@ -12,6 +12,7 @@ package testutil // otherwise cause an import cycle. import ( + "bytes" "context" "encoding/json" "fmt" @@ -30,6 +31,7 @@ import ( "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-uuid" + "github.com/hashicorp/go-version" "github.com/pkg/errors" "github.com/hashicorp/consul/sdk/freeport" @@ -150,17 +152,17 @@ type ServerConfigCallback func(c *TestServerConfig) // defaultServerConfig returns a new TestServerConfig struct // with all of the listen ports incremented by one. -func defaultServerConfig(t TestingTB) *TestServerConfig { +func defaultServerConfig(t TestingTB, consulVersion *version.Version) *TestServerConfig { nodeID, err := uuid.GenerateUUID() if err != nil { panic(err) } - ports := freeport.GetN(t, 8) + ports := freeport.GetN(t, 7) logBuffer := NewLogBuffer(t) - return &TestServerConfig{ + conf := &TestServerConfig{ NodeName: "node-" + nodeID, NodeID: nodeID, DisableCheckpoint: true, @@ -180,7 +182,6 @@ func defaultServerConfig(t TestingTB) *TestServerConfig { SerfWan: ports[4], Server: ports[5], GRPC: ports[6], - GRPCTLS: ports[7], }, ReadyTimeout: 10 * time.Second, StopTimeout: 10 * time.Second, @@ -196,6 +197,17 @@ func defaultServerConfig(t TestingTB) *TestServerConfig { Stderr: logBuffer, Peering: &TestPeeringConfig{Enabled: true}, } + + // Add version-specific tweaks + if consulVersion != nil { + // The GRPC TLS port did not exist prior to Consul 1.14 + // Including it will cause issues in older installations. + if consulVersion.GreaterThanOrEqual(version.Must(version.NewVersion("1.14"))) { + conf.Ports.GRPCTLS = freeport.GetOne(t) + } + } + + return conf } // TestService is used to serialize a service definition. @@ -259,7 +271,12 @@ func NewTestServerConfigT(t TestingTB, cb ServerConfigCallback) (*TestServer, er return nil, errors.Wrap(err, "failed to create tempdir") } - cfg := defaultServerConfig(t) + consulVersion, err := findConsulVersion() + if err != nil { + return nil, err + } + + cfg := defaultServerConfig(t, consulVersion) cfg.DataDir = filepath.Join(tmpdir, "data") if cb != nil { cb(cfg) @@ -564,3 +581,26 @@ func (s *TestServer) privilegedDelete(url string) (*http.Response, error) { } return s.HTTPClient.Do(req) } + +func findConsulVersion() (*version.Version, error) { + cmd := exec.Command("consul", "version", "-format=json") + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + if err := cmd.Start(); err != nil { + return nil, errors.Wrap(err, "failed to get consul version") + } + cmd.Wait() + type consulVersion struct { + Version string + } + v := consulVersion{} + if err := json.Unmarshal(stdout.Bytes(), &v); err != nil { + return nil, errors.Wrap(err, "error parsing consul version json") + } + parsed, err := version.NewVersion(v.Version) + if err != nil { + return nil, errors.Wrap(err, "error parsing consul version") + } + return parsed, nil +}