mirror of https://github.com/hashicorp/consul
256 lines
7.0 KiB
Go
256 lines
7.0 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package upgrade
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/hashicorp/consul/api"
|
|
"github.com/hashicorp/consul/test/integration/consul-container/libs/utils"
|
|
"github.com/hashicorp/consul/testing/deployer/sprawl"
|
|
"github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest"
|
|
"github.com/hashicorp/consul/testing/deployer/topology"
|
|
|
|
"github.com/hashicorp/consul/test-integ/topoutil"
|
|
)
|
|
|
|
// The commonTopo comprises 3 agent servers and 3 nodes to run workload
|
|
// - workload node 1: static-server
|
|
// - workload node 2: static-client
|
|
// - workload node 3 (disabled initially): static-server
|
|
//
|
|
// The post upgrade validation enables workload node 3 to test upgraded
|
|
// cluster
|
|
type commonTopo struct {
|
|
Cfg *topology.Config
|
|
|
|
Sprawl *sprawl.Sprawl
|
|
Assert *topoutil.Asserter
|
|
|
|
StaticServerSID topology.ID
|
|
StaticClientSID topology.ID
|
|
|
|
StaticServerWorkload *topology.Workload
|
|
StaticClientWorkload *topology.Workload
|
|
|
|
// node index of static-server one
|
|
StaticServerInstOne int
|
|
// node index of static-server two
|
|
StaticServerInstTwo int
|
|
}
|
|
|
|
func NewCommonTopo(t *testing.T) *commonTopo {
|
|
t.Helper()
|
|
return newCommonTopo(t)
|
|
}
|
|
|
|
func newCommonTopo(t *testing.T) *commonTopo {
|
|
t.Helper()
|
|
|
|
ct := &commonTopo{}
|
|
staticServerSID := topology.NewID("static-server", "default", "default")
|
|
staticClientSID := topology.NewID("static-client", "default", "default")
|
|
|
|
cfg := &topology.Config{
|
|
Images: topology.Images{
|
|
// ConsulEnterprise: "hashicorp/consul-enterprise:local",
|
|
},
|
|
Networks: []*topology.Network{
|
|
{Name: "dc1"},
|
|
},
|
|
Clusters: []*topology.Cluster{
|
|
{
|
|
Name: "dc1",
|
|
Nodes: []*topology.Node{
|
|
{
|
|
Kind: topology.NodeKindServer,
|
|
Images: utils.LatestImages(),
|
|
Name: "dc1-server1",
|
|
Addresses: []*topology.Address{
|
|
{Network: "dc1"},
|
|
},
|
|
Meta: map[string]string{
|
|
"build": "0.0.1",
|
|
},
|
|
},
|
|
{
|
|
Kind: topology.NodeKindServer,
|
|
Images: utils.LatestImages(),
|
|
Name: "dc1-server2",
|
|
Addresses: []*topology.Address{
|
|
{Network: "dc1"},
|
|
},
|
|
Meta: map[string]string{
|
|
"build": "0.0.1",
|
|
},
|
|
},
|
|
{
|
|
Kind: topology.NodeKindServer,
|
|
Images: utils.LatestImages(),
|
|
Name: "dc1-server3",
|
|
Addresses: []*topology.Address{
|
|
{Network: "dc1"},
|
|
},
|
|
Meta: map[string]string{
|
|
"build": "0.0.1",
|
|
},
|
|
},
|
|
{
|
|
Kind: topology.NodeKindDataplane,
|
|
Name: "dc1-client1",
|
|
Workloads: []*topology.Workload{
|
|
{
|
|
ID: staticServerSID,
|
|
Image: "docker.mirror.hashicorp.services/fortio/fortio",
|
|
Port: 8080,
|
|
EnvoyAdminPort: 19000,
|
|
CheckTCP: "127.0.0.1:8080",
|
|
Command: []string{
|
|
"server",
|
|
"-http-port", "8080",
|
|
"-redirect-port", "-disabled",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Kind: topology.NodeKindDataplane,
|
|
Name: "dc1-client2",
|
|
Workloads: []*topology.Workload{
|
|
{
|
|
ID: staticClientSID,
|
|
Image: "docker.mirror.hashicorp.services/fortio/fortio",
|
|
Port: 8080,
|
|
EnvoyAdminPort: 19000,
|
|
CheckTCP: "127.0.0.1:8080",
|
|
Command: []string{
|
|
"server",
|
|
"-http-port", "8080",
|
|
"-redirect-port", "-disabled",
|
|
},
|
|
Upstreams: []*topology.Destination{
|
|
{
|
|
ID: staticServerSID,
|
|
LocalPort: 5000,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
// Client3 for second static-server
|
|
{
|
|
Kind: topology.NodeKindDataplane,
|
|
Name: "dc1-client3",
|
|
Disabled: true,
|
|
Workloads: []*topology.Workload{
|
|
{
|
|
ID: staticServerSID,
|
|
Image: "docker.mirror.hashicorp.services/fortio/fortio",
|
|
Port: 8080,
|
|
EnvoyAdminPort: 19000,
|
|
CheckTCP: "127.0.0.1:8080",
|
|
Command: []string{
|
|
"server",
|
|
"-http-port", "8080",
|
|
"-redirect-port", "-disabled",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Enterprise: utils.IsEnterprise(),
|
|
InitialConfigEntries: []api.ConfigEntry{
|
|
&api.ProxyConfigEntry{
|
|
Kind: api.ProxyDefaults,
|
|
Name: "global",
|
|
Partition: topoutil.ConfigEntryPartition("default"),
|
|
Config: map[string]any{
|
|
"protocol": "http",
|
|
},
|
|
},
|
|
&api.ServiceConfigEntry{
|
|
Kind: api.ServiceDefaults,
|
|
Name: "static-server",
|
|
Partition: topoutil.ConfigEntryPartition("default"),
|
|
},
|
|
&api.ServiceIntentionsConfigEntry{
|
|
Kind: api.ServiceIntentions,
|
|
Name: "static-server",
|
|
Partition: topoutil.ConfigEntryPartition("default"),
|
|
Sources: []*api.SourceIntention{
|
|
{
|
|
Name: "static-client",
|
|
Action: api.IntentionActionAllow},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
ct.Cfg = cfg
|
|
ct.StaticClientSID = staticClientSID
|
|
ct.StaticServerSID = staticServerSID
|
|
|
|
ct.StaticServerInstOne = 3
|
|
ct.StaticServerInstTwo = 5
|
|
return ct
|
|
}
|
|
|
|
// PostUpgradeValidation - replace the existing static-server with a new
|
|
// instance; verify the connection between static-client and the new instance
|
|
func (ct *commonTopo) PostUpgradeValidation(t *testing.T) {
|
|
t.Helper()
|
|
t.Log("Take down old static-server")
|
|
cfg := ct.Sprawl.Config()
|
|
cluster := cfg.Cluster("dc1")
|
|
cluster.Nodes[ct.StaticServerInstOne].Disabled = true // client 1 -- static-server
|
|
require.NoError(t, ct.Sprawl.RelaunchWithPhase(cfg, sprawl.LaunchPhaseRegular))
|
|
// verify static-server is down
|
|
ct.Assert.HTTPStatus(t, ct.StaticServerWorkload, ct.StaticServerWorkload.Port, 504)
|
|
|
|
// Add a new static-server
|
|
t.Log("Add a new static server")
|
|
cfg = ct.Sprawl.Config()
|
|
cluster = cfg.Cluster("dc1")
|
|
cluster.Nodes[ct.StaticServerInstTwo].Disabled = false // client 3 -- new static-server
|
|
require.NoError(t, ct.Sprawl.RelaunchWithPhase(cfg, sprawl.LaunchPhaseRegular))
|
|
// Ensure the static-client connected to the new static-server
|
|
ct.Assert.FortioFetch2HeaderEcho(t, ct.StaticClientWorkload, &topology.Destination{
|
|
ID: ct.StaticServerSID,
|
|
LocalPort: 5000,
|
|
})
|
|
}
|
|
|
|
// calls sprawltest.Launch followed by validating the connection between
|
|
// static-client and static-server
|
|
func (ct *commonTopo) Launch(t *testing.T) {
|
|
t.Helper()
|
|
if ct.Sprawl != nil {
|
|
t.Fatalf("Launch must only be called once")
|
|
}
|
|
ct.Sprawl = sprawltest.Launch(t, ct.Cfg)
|
|
ct.Assert = topoutil.NewAsserter(ct.Sprawl)
|
|
|
|
staticServerWorkload := ct.Sprawl.Topology().Clusters["dc1"].WorkloadByID(
|
|
topology.NewNodeID("dc1-client1", "default"),
|
|
ct.StaticServerSID,
|
|
)
|
|
ct.Assert.HTTPStatus(t, staticServerWorkload, staticServerWorkload.Port, 200)
|
|
|
|
staticClientWorkload := ct.Sprawl.Topology().Clusters["dc1"].WorkloadByID(
|
|
topology.NewNodeID("dc1-client2", "default"),
|
|
ct.StaticClientSID,
|
|
)
|
|
ct.Assert.FortioFetch2HeaderEcho(t, staticClientWorkload, &topology.Destination{
|
|
ID: ct.StaticServerSID,
|
|
LocalPort: 5000,
|
|
})
|
|
|
|
ct.StaticServerWorkload = staticServerWorkload
|
|
ct.StaticClientWorkload = staticClientWorkload
|
|
}
|