mirror of https://github.com/status-im/consul.git
switch all client nodes in dc2 to dataplane [NET-4299] (#18608)
This commit is contained in:
parent
4eb2197e82
commit
373c7dc144
|
@ -86,7 +86,10 @@ func (s *ac5_2PQFailoverSuite) setupDC(ct *commonTopo, clu, peerClu *topology.Cl
|
||||||
Service: NewFortioServiceWithDefaults(
|
Service: NewFortioServiceWithDefaults(
|
||||||
clu.Datacenter,
|
clu.Datacenter,
|
||||||
serverSID,
|
serverSID,
|
||||||
nil,
|
func(s *topology.Service) {
|
||||||
|
s.EnvoyAdminPort = 0
|
||||||
|
s.DisableServiceMesh = true
|
||||||
|
},
|
||||||
),
|
),
|
||||||
Exports: []api.ServiceConsumer{{Peer: peer}},
|
Exports: []api.ServiceConsumer{{Peer: peer}},
|
||||||
}
|
}
|
||||||
|
@ -149,7 +152,10 @@ func (s *ac5_2PQFailoverSuite) setupDC3(ct *commonTopo, clu, peer1, peer2 *topol
|
||||||
Service: NewFortioServiceWithDefaults(
|
Service: NewFortioServiceWithDefaults(
|
||||||
clu.Datacenter,
|
clu.Datacenter,
|
||||||
serverSID,
|
serverSID,
|
||||||
nil,
|
func(s *topology.Service) {
|
||||||
|
s.EnvoyAdminPort = 0
|
||||||
|
s.DisableServiceMesh = true
|
||||||
|
},
|
||||||
),
|
),
|
||||||
Exports: func() []api.ServiceConsumer {
|
Exports: func() []api.ServiceConsumer {
|
||||||
var consumers []api.ServiceConsumer
|
var consumers []api.ServiceConsumer
|
||||||
|
|
|
@ -141,8 +141,12 @@ func (s *suiteRotateGW) setup(t *testing.T, ct *commonTopo) {
|
||||||
|
|
||||||
// add a second mesh gateway "new"
|
// add a second mesh gateway "new"
|
||||||
s.newMGWNodeName = fmt.Sprintf("new-%s-default-mgw", clu.Name)
|
s.newMGWNodeName = fmt.Sprintf("new-%s-default-mgw", clu.Name)
|
||||||
|
nodeKind := topology.NodeKindClient
|
||||||
|
if clu.Datacenter == agentlessDC {
|
||||||
|
nodeKind = topology.NodeKindDataplane
|
||||||
|
}
|
||||||
clu.Nodes = append(clu.Nodes, newTopologyMeshGatewaySet(
|
clu.Nodes = append(clu.Nodes, newTopologyMeshGatewaySet(
|
||||||
topology.NodeKindClient,
|
nodeKind,
|
||||||
"default",
|
"default",
|
||||||
s.newMGWNodeName,
|
s.newMGWNodeName,
|
||||||
1,
|
1,
|
||||||
|
|
|
@ -41,6 +41,7 @@ type asserter struct {
|
||||||
type sprawlLite interface {
|
type sprawlLite interface {
|
||||||
HTTPClientForCluster(clusterName string) (*http.Client, error)
|
HTTPClientForCluster(clusterName string) (*http.Client, error)
|
||||||
APIClientForNode(clusterName string, nid topology.NodeID, token string) (*api.Client, error)
|
APIClientForNode(clusterName string, nid topology.NodeID, token string) (*api.Client, error)
|
||||||
|
APIClientForCluster(clusterName string, token string) (*api.Client, error)
|
||||||
Topology() *topology.Topology
|
Topology() *topology.Topology
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,18 +59,12 @@ func (a *asserter) mustGetHTTPClient(t *testing.T, cluster string) *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *asserter) mustGetAPIClient(t *testing.T, cluster string) *api.Client {
|
func (a *asserter) mustGetAPIClient(t *testing.T, cluster string) *api.Client {
|
||||||
cl, err := a.apiClientFor(cluster)
|
clu := a.sp.Topology().Clusters[cluster]
|
||||||
|
cl, err := a.sp.APIClientForCluster(clu.Name, "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return cl
|
return cl
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *asserter) apiClientFor(cluster string) (*api.Client, error) {
|
|
||||||
clu := a.sp.Topology().Clusters[cluster]
|
|
||||||
// TODO: this always goes to the first client, but we might want to balance this
|
|
||||||
cl, err := a.sp.APIClientForNode(cluster, clu.FirstClient().ID(), "")
|
|
||||||
return cl, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// httpClientFor returns a pre-configured http.Client that proxies requests
|
// httpClientFor returns a pre-configured http.Client that proxies requests
|
||||||
// through the embedded squid instance in each LAN.
|
// through the embedded squid instance in each LAN.
|
||||||
//
|
//
|
||||||
|
|
|
@ -52,6 +52,8 @@ type commonTopo struct {
|
||||||
services map[string]map[topology.ServiceID]struct{}
|
services map[string]map[topology.ServiceID]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const agentlessDC = "dc2"
|
||||||
|
|
||||||
func NewCommonTopo(t *testing.T) *commonTopo {
|
func NewCommonTopo(t *testing.T) *commonTopo {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
@ -84,11 +86,9 @@ func NewCommonTopo(t *testing.T) *commonTopo {
|
||||||
peerings = append(peerings, addPeerings(dc1, dc3)...)
|
peerings = append(peerings, addPeerings(dc1, dc3)...)
|
||||||
peerings = append(peerings, addPeerings(dc2, dc3)...)
|
peerings = append(peerings, addPeerings(dc2, dc3)...)
|
||||||
|
|
||||||
addMeshGateways(dc1, topology.NodeKindClient)
|
addMeshGateways(dc1)
|
||||||
addMeshGateways(dc2, topology.NodeKindClient)
|
addMeshGateways(dc2)
|
||||||
addMeshGateways(dc3, topology.NodeKindClient)
|
addMeshGateways(dc3)
|
||||||
// TODO: consul-topology doesn't support this yet
|
|
||||||
// addMeshGateways(dc2, topology.NodeKindDataplane)
|
|
||||||
|
|
||||||
setupGlobals(dc1)
|
setupGlobals(dc1)
|
||||||
setupGlobals(dc2)
|
setupGlobals(dc2)
|
||||||
|
@ -131,7 +131,7 @@ func (ct *commonTopo) postLaunchChecks(t *testing.T) {
|
||||||
)
|
)
|
||||||
|
|
||||||
// check that exports line up as expected
|
// check that exports line up as expected
|
||||||
for _, clu := range ct.Sprawl.Config().Clusters {
|
for _, clu := range ct.Sprawl.Topology().Clusters {
|
||||||
// expected exports per peer
|
// expected exports per peer
|
||||||
type key struct {
|
type key struct {
|
||||||
peer string
|
peer string
|
||||||
|
@ -191,9 +191,6 @@ func LocalPeerName(clu *topology.Cluster, partition string) string {
|
||||||
type serviceExt struct {
|
type serviceExt struct {
|
||||||
*topology.Service
|
*topology.Service
|
||||||
|
|
||||||
// default NodeKindClient
|
|
||||||
NodeKind topology.NodeKind
|
|
||||||
|
|
||||||
Exports []api.ServiceConsumer
|
Exports []api.ServiceConsumer
|
||||||
Config *api.ServiceConfigEntry
|
Config *api.ServiceConfigEntry
|
||||||
Intentions *api.ServiceIntentionsConfigEntry
|
Intentions *api.ServiceIntentionsConfigEntry
|
||||||
|
@ -227,8 +224,15 @@ func (ct *commonTopo) AddServiceNode(clu *topology.Cluster, svc serviceExt) *top
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodeKind := topology.NodeKindClient
|
||||||
|
// TODO: bug in deployer somewhere; it should guard against a KindDataplane node with
|
||||||
|
// DisableServiceMesh services on it; dataplane is only for service-mesh
|
||||||
|
if !svc.DisableServiceMesh && clu.Datacenter == agentlessDC {
|
||||||
|
nodeKind = topology.NodeKindDataplane
|
||||||
|
}
|
||||||
|
|
||||||
node := &topology.Node{
|
node := &topology.Node{
|
||||||
Kind: topology.NodeKindClient,
|
Kind: nodeKind,
|
||||||
Name: serviceHostnameString(clu.Datacenter, svc.ID),
|
Name: serviceHostnameString(clu.Datacenter, svc.ID),
|
||||||
Partition: svc.ID.Partition,
|
Partition: svc.ID.Partition,
|
||||||
Addresses: []*topology.Address{
|
Addresses: []*topology.Address{
|
||||||
|
@ -239,9 +243,6 @@ func (ct *commonTopo) AddServiceNode(clu *topology.Cluster, svc serviceExt) *top
|
||||||
},
|
},
|
||||||
Cluster: clusterName,
|
Cluster: clusterName,
|
||||||
}
|
}
|
||||||
if svc.NodeKind != "" {
|
|
||||||
node.Kind = svc.NodeKind
|
|
||||||
}
|
|
||||||
clu.Nodes = append(clu.Nodes, node)
|
clu.Nodes = append(clu.Nodes, node)
|
||||||
|
|
||||||
// Export if necessary
|
// Export if necessary
|
||||||
|
@ -265,7 +266,7 @@ func (ct *commonTopo) AddServiceNode(clu *topology.Cluster, svc serviceExt) *top
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ct *commonTopo) APIClientForCluster(t *testing.T, clu *topology.Cluster) *api.Client {
|
func (ct *commonTopo) APIClientForCluster(t *testing.T, clu *topology.Cluster) *api.Client {
|
||||||
cl, err := ct.Sprawl.APIClientForNode(clu.Name, clu.FirstClient().ID(), "")
|
cl, err := ct.Sprawl.APIClientForCluster(clu.Name, "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return cl
|
return cl
|
||||||
}
|
}
|
||||||
|
@ -372,10 +373,14 @@ func setupGlobals(clu *topology.Cluster) {
|
||||||
|
|
||||||
// addMeshGateways adds a mesh gateway for every partition in the cluster.
|
// addMeshGateways adds a mesh gateway for every partition in the cluster.
|
||||||
// Assumes that the LAN network name is equal to datacenter name.
|
// Assumes that the LAN network name is equal to datacenter name.
|
||||||
func addMeshGateways(c *topology.Cluster, kind topology.NodeKind) {
|
func addMeshGateways(c *topology.Cluster) {
|
||||||
|
nodeKind := topology.NodeKindClient
|
||||||
|
if c.Datacenter == agentlessDC {
|
||||||
|
nodeKind = topology.NodeKindDataplane
|
||||||
|
}
|
||||||
for _, p := range c.Partitions {
|
for _, p := range c.Partitions {
|
||||||
c.Nodes = topology.MergeSlices(c.Nodes, newTopologyMeshGatewaySet(
|
c.Nodes = topology.MergeSlices(c.Nodes, newTopologyMeshGatewaySet(
|
||||||
kind,
|
nodeKind,
|
||||||
p.Name,
|
p.Name,
|
||||||
fmt.Sprintf("%s-%s-mgw", c.Name, p.Name),
|
fmt.Sprintf("%s-%s-mgw", c.Name, p.Name),
|
||||||
1,
|
1,
|
||||||
|
|
|
@ -318,6 +318,18 @@ func serviceToCatalogRegistration(
|
||||||
Address: node.LocalAddress(),
|
Address: node.LocalAddress(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if svc.IsMeshGateway {
|
||||||
|
reg.Service.Kind = api.ServiceKindMeshGateway
|
||||||
|
reg.Service.Proxy = &api.AgentServiceConnectProxyConfig{
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"envoy_gateway_no_default_bind": true,
|
||||||
|
"envoy_gateway_bind_tagged_addresses": true,
|
||||||
|
},
|
||||||
|
MeshGateway: api.MeshGatewayConfig{
|
||||||
|
Mode: api.MeshGatewayModeLocal,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
if node.HasPublicAddress() {
|
if node.HasPublicAddress() {
|
||||||
reg.TaggedAddresses = map[string]string{
|
reg.TaggedAddresses = map[string]string{
|
||||||
"lan": node.LocalAddress(),
|
"lan": node.LocalAddress(),
|
||||||
|
@ -325,6 +337,26 @@ func serviceToCatalogRegistration(
|
||||||
"wan": node.PublicAddress(),
|
"wan": node.PublicAddress(),
|
||||||
"wan_ipv4": node.PublicAddress(),
|
"wan_ipv4": node.PublicAddress(),
|
||||||
}
|
}
|
||||||
|
// TODO: not sure what the difference is between these, but with just the
|
||||||
|
// top-level set, it appeared to not get set in either :/
|
||||||
|
reg.Service.TaggedAddresses = map[string]api.ServiceAddress{
|
||||||
|
"lan": {
|
||||||
|
Address: node.LocalAddress(),
|
||||||
|
Port: svc.Port,
|
||||||
|
},
|
||||||
|
"lan_ipv4": {
|
||||||
|
Address: node.LocalAddress(),
|
||||||
|
Port: svc.Port,
|
||||||
|
},
|
||||||
|
"wan": {
|
||||||
|
Address: node.PublicAddress(),
|
||||||
|
Port: svc.Port,
|
||||||
|
},
|
||||||
|
"wan_ipv4": {
|
||||||
|
Address: node.PublicAddress(),
|
||||||
|
Port: svc.Port,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if cluster.Enterprise {
|
if cluster.Enterprise {
|
||||||
reg.Partition = svc.ID.Partition
|
reg.Partition = svc.ID.Partition
|
||||||
|
|
|
@ -23,9 +23,10 @@ COPY --from=0 /bin/consul /bin/consul
|
||||||
|
|
||||||
// FROM hashicorp/consul-dataplane:latest
|
// FROM hashicorp/consul-dataplane:latest
|
||||||
// COPY --from=busybox:uclibc /bin/sh /bin/sh
|
// COPY --from=busybox:uclibc /bin/sh /bin/sh
|
||||||
|
// TODO: busybox:latest doesn't work, see https://hashicorp.slack.com/archives/C03EUN3QF1C/p1691784078972959
|
||||||
const dockerfileDataplane = `
|
const dockerfileDataplane = `
|
||||||
ARG DATAPLANE_IMAGE
|
ARG DATAPLANE_IMAGE
|
||||||
FROM busybox:latest
|
FROM busybox:1.34
|
||||||
FROM ${DATAPLANE_IMAGE}
|
FROM ${DATAPLANE_IMAGE}
|
||||||
COPY --from=0 /bin/busybox /bin/busybox
|
COPY --from=0 /bin/busybox /bin/busybox
|
||||||
USER 0:0
|
USER 0:0
|
||||||
|
|
|
@ -13,14 +13,14 @@ import (
|
||||||
"github.com/hashicorp/consul/testing/deployer/topology"
|
"github.com/hashicorp/consul/testing/deployer/topology"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g *Generator) generateAgentHCL(node *topology.Node) (string, error) {
|
func (g *Generator) generateAgentHCL(node *topology.Node) string {
|
||||||
if !node.IsAgent() {
|
if !node.IsAgent() {
|
||||||
return "", fmt.Errorf("not an agent")
|
panic("generateAgentHCL only applies to agents")
|
||||||
}
|
}
|
||||||
|
|
||||||
cluster, ok := g.topology.Clusters[node.Cluster]
|
cluster, ok := g.topology.Clusters[node.Cluster]
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", fmt.Errorf("no such cluster: %s", node.Cluster)
|
panic(fmt.Sprintf("no such cluster: %s", node.Cluster))
|
||||||
}
|
}
|
||||||
|
|
||||||
var b HCLBuilder
|
var b HCLBuilder
|
||||||
|
@ -167,7 +167,7 @@ func (g *Generator) generateAgentHCL(node *topology.Node) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.String(), nil
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type HCLBuilder struct {
|
type HCLBuilder struct {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/hashicorp/consul/testing/deployer/topology"
|
"github.com/hashicorp/consul/testing/deployer/topology"
|
||||||
"github.com/hashicorp/consul/testing/deployer/util"
|
"github.com/hashicorp/consul/testing/deployer/util"
|
||||||
|
@ -179,5 +178,3 @@ server IN A %s ; Consul server
|
||||||
|
|
||||||
return buf.Bytes()
|
return buf.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
var tfCorednsT = template.Must(template.ParseFS(content, "templates/container-coredns.tf.tmpl"))
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ import (
|
||||||
var invalidResourceName = regexp.MustCompile(`[^a-z0-9-]+`)
|
var invalidResourceName = regexp.MustCompile(`[^a-z0-9-]+`)
|
||||||
|
|
||||||
func DockerImageResourceName(image string) string {
|
func DockerImageResourceName(image string) string {
|
||||||
|
if image == "" {
|
||||||
|
panic(`image must not be ""`)
|
||||||
|
}
|
||||||
return invalidResourceName.ReplaceAllLiteralString(image, "-")
|
return invalidResourceName.ReplaceAllLiteralString(image, "-")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,6 @@ package tfgen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/hashicorp/consul/testing/deployer/topology"
|
"github.com/hashicorp/consul/testing/deployer/topology"
|
||||||
)
|
)
|
||||||
|
@ -22,32 +19,6 @@ type terraformPod struct {
|
||||||
DockerNetworkName string
|
DockerNetworkName string
|
||||||
}
|
}
|
||||||
|
|
||||||
type terraformConsulAgent struct {
|
|
||||||
terraformPod
|
|
||||||
ImageResource string
|
|
||||||
HCL string
|
|
||||||
EnterpriseLicense string
|
|
||||||
Env []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type terraformMeshGatewayService struct {
|
|
||||||
terraformPod
|
|
||||||
EnvoyImageResource string
|
|
||||||
Service *topology.Service
|
|
||||||
Command []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type terraformService struct {
|
|
||||||
terraformPod
|
|
||||||
AppImageResource string
|
|
||||||
EnvoyImageResource string // agentful
|
|
||||||
DataplaneImageResource string // agentless
|
|
||||||
Service *topology.Service
|
|
||||||
Env []string
|
|
||||||
Command []string
|
|
||||||
EnvoyCommand []string // agentful
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) generateNodeContainers(
|
func (g *Generator) generateNodeContainers(
|
||||||
step Step,
|
step Step,
|
||||||
cluster *topology.Cluster,
|
cluster *topology.Cluster,
|
||||||
|
@ -82,156 +53,99 @@ func (g *Generator) generateNodeContainers(
|
||||||
}
|
}
|
||||||
pod.DockerNetworkName = net.DockerName
|
pod.DockerNetworkName = net.DockerName
|
||||||
|
|
||||||
var (
|
containers := []Resource{}
|
||||||
containers []Resource
|
|
||||||
)
|
|
||||||
|
|
||||||
if node.IsAgent() {
|
if node.IsAgent() {
|
||||||
agentHCL, err := g.generateAgentHCL(node)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
agent := terraformConsulAgent{
|
|
||||||
terraformPod: pod,
|
|
||||||
ImageResource: DockerImageResourceName(node.Images.Consul),
|
|
||||||
HCL: agentHCL,
|
|
||||||
EnterpriseLicense: g.license,
|
|
||||||
Env: node.AgentEnv,
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case node.IsServer() && step.StartServers(),
|
case node.IsServer() && step.StartServers(),
|
||||||
!node.IsServer() && step.StartAgents():
|
!node.IsServer() && step.StartAgents():
|
||||||
containers = append(containers, Eval(tfConsulT, &agent))
|
containers = append(containers, Eval(tfConsulT, struct {
|
||||||
|
terraformPod
|
||||||
|
ImageResource string
|
||||||
|
HCL string
|
||||||
|
EnterpriseLicense string
|
||||||
|
}{
|
||||||
|
terraformPod: pod,
|
||||||
|
ImageResource: DockerImageResourceName(node.Images.Consul),
|
||||||
|
HCL: g.generateAgentHCL(node),
|
||||||
|
EnterpriseLicense: g.license,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svcContainers := []Resource{}
|
||||||
for _, svc := range node.SortedServices() {
|
for _, svc := range node.SortedServices() {
|
||||||
if svc.IsMeshGateway {
|
token := g.sec.ReadServiceToken(node.Cluster, svc.ID)
|
||||||
if node.Kind == topology.NodeKindDataplane {
|
switch {
|
||||||
panic("NOT READY YET")
|
case svc.IsMeshGateway && !node.IsDataplane():
|
||||||
}
|
svcContainers = append(svcContainers, Eval(tfMeshGatewayT, struct {
|
||||||
gw := terraformMeshGatewayService{
|
terraformPod
|
||||||
|
ImageResource string
|
||||||
|
Enterprise bool
|
||||||
|
Service *topology.Service
|
||||||
|
Token string
|
||||||
|
}{
|
||||||
terraformPod: pod,
|
terraformPod: pod,
|
||||||
EnvoyImageResource: DockerImageResourceName(node.Images.EnvoyConsulImage()),
|
ImageResource: DockerImageResourceName(node.Images.EnvoyConsulImage()),
|
||||||
|
Enterprise: cluster.Enterprise,
|
||||||
Service: svc,
|
Service: svc,
|
||||||
Command: []string{
|
Token: token,
|
||||||
"consul", "connect", "envoy",
|
}))
|
||||||
"-register",
|
case svc.IsMeshGateway && node.IsDataplane():
|
||||||
"-mesh-gateway",
|
svcContainers = append(svcContainers, Eval(tfMeshGatewayDataplaneT, &struct {
|
||||||
},
|
terraformPod
|
||||||
}
|
ImageResource string
|
||||||
if token := g.sec.ReadServiceToken(node.Cluster, svc.ID); token != "" {
|
Enterprise bool
|
||||||
gw.Command = append(gw.Command, "-token", token)
|
Service *topology.Service
|
||||||
}
|
Token string
|
||||||
if cluster.Enterprise {
|
}{
|
||||||
gw.Command = append(gw.Command,
|
|
||||||
"-partition",
|
|
||||||
svc.ID.Partition,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
gw.Command = append(gw.Command,
|
|
||||||
"-address",
|
|
||||||
`{{ GetInterfaceIP \"eth0\" }}:`+strconv.Itoa(svc.Port),
|
|
||||||
"-wan-address",
|
|
||||||
`{{ GetInterfaceIP \"eth1\" }}:`+strconv.Itoa(svc.Port),
|
|
||||||
)
|
|
||||||
gw.Command = append(gw.Command,
|
|
||||||
"-grpc-addr", "http://127.0.0.1:8502",
|
|
||||||
"-admin-bind",
|
|
||||||
// for demo purposes
|
|
||||||
"0.0.0.0:"+strconv.Itoa(svc.EnvoyAdminPort),
|
|
||||||
"--",
|
|
||||||
"-l",
|
|
||||||
"trace",
|
|
||||||
)
|
|
||||||
if step.StartServices() {
|
|
||||||
containers = append(containers, Eval(tfMeshGatewayT, &gw))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tfsvc := terraformService{
|
|
||||||
terraformPod: pod,
|
terraformPod: pod,
|
||||||
AppImageResource: DockerImageResourceName(svc.Image),
|
ImageResource: DockerImageResourceName(node.Images.LocalDataplaneImage()),
|
||||||
|
Enterprise: cluster.Enterprise,
|
||||||
Service: svc,
|
Service: svc,
|
||||||
Command: svc.Command,
|
Token: token,
|
||||||
|
}))
|
||||||
|
|
||||||
|
case !svc.IsMeshGateway:
|
||||||
|
svcContainers = append(svcContainers, Eval(tfAppT, struct {
|
||||||
|
terraformPod
|
||||||
|
ImageResource string
|
||||||
|
Service *topology.Service
|
||||||
|
}{
|
||||||
|
terraformPod: pod,
|
||||||
|
ImageResource: DockerImageResourceName(svc.Image),
|
||||||
|
Service: svc,
|
||||||
|
}))
|
||||||
|
|
||||||
|
if svc.DisableServiceMesh {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
tfsvc.Env = append(tfsvc.Env, svc.Env...)
|
|
||||||
|
tmpl := tfAppSidecarT
|
||||||
|
var img string
|
||||||
|
if node.IsDataplane() {
|
||||||
|
tmpl = tfAppDataplaneT
|
||||||
|
img = DockerImageResourceName(node.Images.LocalDataplaneImage())
|
||||||
|
} else {
|
||||||
|
img = DockerImageResourceName(node.Images.EnvoyConsulImage())
|
||||||
|
}
|
||||||
|
svcContainers = append(svcContainers, Eval(tmpl, struct {
|
||||||
|
terraformPod
|
||||||
|
ImageResource string
|
||||||
|
Service *topology.Service
|
||||||
|
Token string
|
||||||
|
Enterprise bool
|
||||||
|
}{
|
||||||
|
terraformPod: pod,
|
||||||
|
ImageResource: img,
|
||||||
|
Service: svc,
|
||||||
|
Token: token,
|
||||||
|
Enterprise: cluster.Enterprise,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
if step.StartServices() {
|
if step.StartServices() {
|
||||||
containers = append(containers, Eval(tfAppT, &tfsvc))
|
containers = append(containers, svcContainers...)
|
||||||
}
|
|
||||||
|
|
||||||
setenv := func(k, v string) {
|
|
||||||
tfsvc.Env = append(tfsvc.Env, k+"="+v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !svc.DisableServiceMesh {
|
|
||||||
if node.IsDataplane() {
|
|
||||||
tfsvc.DataplaneImageResource = DockerImageResourceName(node.Images.LocalDataplaneImage())
|
|
||||||
tfsvc.EnvoyImageResource = ""
|
|
||||||
tfsvc.EnvoyCommand = nil
|
|
||||||
// --- REQUIRED ---
|
|
||||||
setenv("DP_CONSUL_ADDRESSES", "server."+node.Cluster+"-consulcluster.lan")
|
|
||||||
setenv("DP_SERVICE_NODE_NAME", node.PodName())
|
|
||||||
setenv("DP_PROXY_SERVICE_ID", svc.ID.Name+"-sidecar-proxy")
|
|
||||||
} else {
|
|
||||||
tfsvc.DataplaneImageResource = ""
|
|
||||||
tfsvc.EnvoyImageResource = DockerImageResourceName(node.Images.EnvoyConsulImage())
|
|
||||||
tfsvc.EnvoyCommand = []string{
|
|
||||||
"consul", "connect", "envoy",
|
|
||||||
"-sidecar-for", svc.ID.Name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cluster.Enterprise {
|
|
||||||
if node.IsDataplane() {
|
|
||||||
setenv("DP_SERVICE_NAMESPACE", svc.ID.Namespace)
|
|
||||||
setenv("DP_SERVICE_PARTITION", svc.ID.Partition)
|
|
||||||
} else {
|
|
||||||
tfsvc.EnvoyCommand = append(tfsvc.EnvoyCommand,
|
|
||||||
"-partition",
|
|
||||||
svc.ID.Partition,
|
|
||||||
"-namespace",
|
|
||||||
svc.ID.Namespace,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if token := g.sec.ReadServiceToken(node.Cluster, svc.ID); token != "" {
|
|
||||||
if node.IsDataplane() {
|
|
||||||
setenv("DP_CREDENTIAL_TYPE", "static")
|
|
||||||
setenv("DP_CREDENTIAL_STATIC_TOKEN", token)
|
|
||||||
} else {
|
|
||||||
tfsvc.EnvoyCommand = append(tfsvc.EnvoyCommand, "-token", token)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if node.IsDataplane() {
|
|
||||||
setenv("DP_ENVOY_ADMIN_BIND_ADDRESS", "0.0.0.0") // for demo purposes
|
|
||||||
setenv("DP_ENVOY_ADMIN_BIND_PORT", "19000")
|
|
||||||
setenv("DP_LOG_LEVEL", "trace")
|
|
||||||
|
|
||||||
setenv("DP_CA_CERTS", "/consul/config/certs/consul-agent-ca.pem")
|
|
||||||
setenv("DP_CONSUL_GRPC_PORT", "8503")
|
|
||||||
setenv("DP_TLS_SERVER_NAME", "server."+node.Datacenter+".consul")
|
|
||||||
} else {
|
|
||||||
tfsvc.EnvoyCommand = append(tfsvc.EnvoyCommand,
|
|
||||||
"-grpc-addr", "http://127.0.0.1:8502",
|
|
||||||
"-admin-bind",
|
|
||||||
// for demo purposes
|
|
||||||
"0.0.0.0:"+strconv.Itoa(svc.EnvoyAdminPort),
|
|
||||||
"--",
|
|
||||||
"-l",
|
|
||||||
"trace",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if step.StartServices() {
|
|
||||||
sort.Strings(tfsvc.Env)
|
|
||||||
|
|
||||||
if node.IsDataplane() {
|
|
||||||
containers = append(containers, Eval(tfAppDataplaneT, &tfsvc))
|
|
||||||
} else {
|
|
||||||
containers = append(containers, Eval(tfAppSidecarT, &tfsvc))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,10 +157,3 @@ func (g *Generator) generateNodeContainers(
|
||||||
|
|
||||||
return containers, nil
|
return containers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var tfPauseT = template.Must(template.ParseFS(content, "templates/container-pause.tf.tmpl"))
|
|
||||||
var tfConsulT = template.Must(template.ParseFS(content, "templates/container-consul.tf.tmpl"))
|
|
||||||
var tfMeshGatewayT = template.Must(template.ParseFS(content, "templates/container-mgw.tf.tmpl"))
|
|
||||||
var tfAppT = template.Must(template.ParseFS(content, "templates/container-app.tf.tmpl"))
|
|
||||||
var tfAppSidecarT = template.Must(template.ParseFS(content, "templates/container-app-sidecar.tf.tmpl"))
|
|
||||||
var tfAppDataplaneT = template.Must(template.ParseFS(content, "templates/container-app-dataplane.tf.tmpl"))
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/hashicorp/consul/testing/deployer/topology"
|
"github.com/hashicorp/consul/testing/deployer/topology"
|
||||||
"github.com/hashicorp/consul/testing/deployer/util"
|
"github.com/hashicorp/consul/testing/deployer/util"
|
||||||
|
@ -86,5 +85,3 @@ func (g *Generator) getForwardProxyContainer(
|
||||||
|
|
||||||
return Eval(tfForwardProxyT, &proxy)
|
return Eval(tfForwardProxyT, &proxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
var tfForwardProxyT = template.Must(template.ParseFS(content, "templates/container-proxy.tf.tmpl"))
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" {
|
resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" {
|
||||||
name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar"
|
name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar"
|
||||||
network_mode = "container:${docker_container.{{.PodName}}.id}"
|
network_mode = "container:${docker_container.{{.PodName}}.id}"
|
||||||
image = docker_image.{{.DataplaneImageResource}}.latest
|
image = docker_image.{{.ImageResource}}.latest
|
||||||
restart = "on-failure"
|
restart = "on-failure"
|
||||||
|
|
||||||
{{- range $k, $v := .Labels }}
|
{{- range $k, $v := .Labels }}
|
||||||
|
@ -18,9 +18,24 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidec
|
||||||
}
|
}
|
||||||
|
|
||||||
env = [
|
env = [
|
||||||
{{- range .Env }}
|
"DP_CONSUL_ADDRESSES=server.{{.Node.Cluster}}-consulcluster.lan",
|
||||||
"{{.}}",
|
"DP_SERVICE_NODE_NAME={{.Node.PodName}}",
|
||||||
{{- end}}
|
"DP_PROXY_SERVICE_ID={{.Service.ID.Name}}-sidecar-proxy",
|
||||||
|
{{ if .Enterprise }}
|
||||||
|
"DP_SERVICE_NAMESPACE={{.Service.ID.Namespace}}",
|
||||||
|
"DP_SERVICE_PARTITION={{.Service.ID.Partition}}",
|
||||||
|
{{ end }}
|
||||||
|
{{ if .Token }}
|
||||||
|
"DP_CREDENTIAL_TYPE=static",
|
||||||
|
"DP_CREDENTIAL_STATIC_TOKEN={{.Token}}",
|
||||||
|
{{ end }}
|
||||||
|
// for demo purposes
|
||||||
|
"DP_ENVOY_ADMIN_BIND_ADDRESS=0.0.0.0",
|
||||||
|
"DP_ENVOY_ADMIN_BIND_PORT=19000",
|
||||||
|
"DP_LOG_LEVEL=trace",
|
||||||
|
"DP_CA_CERTS=/consul/config/certs/consul-agent-ca.pem",
|
||||||
|
"DP_CONSUL_GRPC_PORT=8503",
|
||||||
|
"DP_TLS_SERVER_NAME=server.{{.Node.Datacenter}}.consul",
|
||||||
]
|
]
|
||||||
|
|
||||||
command = [
|
command = [
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" {
|
resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" {
|
||||||
name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar"
|
name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar"
|
||||||
network_mode = "container:${docker_container.{{.PodName}}.id}"
|
network_mode = "container:${docker_container.{{.PodName}}.id}"
|
||||||
image = docker_image.{{.EnvoyImageResource}}.latest
|
image = docker_image.{{.ImageResource}}.latest
|
||||||
restart = "on-failure"
|
restart = "on-failure"
|
||||||
|
|
||||||
{{- range $k, $v := .Labels }}
|
{{- range $k, $v := .Labels }}
|
||||||
|
@ -17,15 +17,21 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidec
|
||||||
read_only = true
|
read_only = true
|
||||||
}
|
}
|
||||||
|
|
||||||
env = [
|
|
||||||
{{- range .Env }}
|
|
||||||
"{{.}}",
|
|
||||||
{{- end}}
|
|
||||||
]
|
|
||||||
|
|
||||||
command = [
|
command = [
|
||||||
{{- range .EnvoyCommand }}
|
"consul", "connect", "envoy",
|
||||||
"{{.}}",
|
"-sidecar-for={{.Service.ID.Name}}",
|
||||||
{{- end }}
|
"-grpc-addr=http://127.0.0.1:8502",
|
||||||
|
// for demo purposes (TODO: huh?)
|
||||||
|
"-admin-bind=0.0.0.0:{{.Service.EnvoyAdminPort}}",
|
||||||
|
{{if .Enterprise}}
|
||||||
|
"-partition={{.Service.ID.Partition}}",
|
||||||
|
"-namespace={{.Service.ID.Namespace}}",
|
||||||
|
{{end}}
|
||||||
|
{{if .Token }}
|
||||||
|
"-token={{.Token}}",
|
||||||
|
{{end}}
|
||||||
|
"--",
|
||||||
|
"-l",
|
||||||
|
"trace",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" {
|
resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" {
|
||||||
name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}"
|
name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}"
|
||||||
network_mode = "container:${docker_container.{{.PodName}}.id}"
|
network_mode = "container:${docker_container.{{.PodName}}.id}"
|
||||||
image = docker_image.{{.AppImageResource}}.latest
|
image = docker_image.{{.ImageResource}}.latest
|
||||||
restart = "on-failure"
|
restart = "on-failure"
|
||||||
|
|
||||||
{{- range $k, $v := .Labels }}
|
{{- range $k, $v := .Labels }}
|
||||||
|
@ -12,13 +12,13 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" {
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
env = [
|
env = [
|
||||||
{{- range .Env }}
|
{{- range .Service.Env }}
|
||||||
"{{.}}",
|
"{{.}}",
|
||||||
{{- end}}
|
{{- end}}
|
||||||
]
|
]
|
||||||
|
|
||||||
command = [
|
command = [
|
||||||
{{- range .Command }}
|
{{- range .Service.Command }}
|
||||||
"{{.}}",
|
"{{.}}",
|
||||||
{{- end }}
|
{{- end }}
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,9 +8,6 @@ resource "docker_container" "{{.Node.DockerName}}" {
|
||||||
"CONSUL_UID=0",
|
"CONSUL_UID=0",
|
||||||
"CONSUL_GID=0",
|
"CONSUL_GID=0",
|
||||||
"CONSUL_LICENSE={{.EnterpriseLicense}}",
|
"CONSUL_LICENSE={{.EnterpriseLicense}}",
|
||||||
{{- range .Env }}
|
|
||||||
"{{.}}",
|
|
||||||
{{- end}}
|
|
||||||
]
|
]
|
||||||
|
|
||||||
{{- range $k, $v := .Labels }}
|
{{- range $k, $v := .Labels }}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" {
|
||||||
|
name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}"
|
||||||
|
network_mode = "container:${docker_container.{{.PodName}}.id}"
|
||||||
|
image = docker_image.{{.ImageResource}}.latest
|
||||||
|
restart = "on-failure"
|
||||||
|
|
||||||
|
{{- range $k, $v := .Labels }}
|
||||||
|
labels {
|
||||||
|
label = "{{ $k }}"
|
||||||
|
value = "{{ $v }}"
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
volumes {
|
||||||
|
volume_name = "{{.TLSVolumeName}}"
|
||||||
|
container_path = "/consul/config/certs"
|
||||||
|
read_only = true
|
||||||
|
}
|
||||||
|
|
||||||
|
env = [
|
||||||
|
"DP_CONSUL_ADDRESSES=server.{{.Node.Cluster}}-consulcluster.lan",
|
||||||
|
"DP_SERVICE_NODE_NAME={{.Node.PodName}}",
|
||||||
|
"DP_PROXY_SERVICE_ID={{.Service.ID.Name}}",
|
||||||
|
{{ if .Enterprise }}
|
||||||
|
"DP_SERVICE_NAMESPACE={{.Service.ID.Namespace}}",
|
||||||
|
"DP_SERVICE_PARTITION={{.Service.ID.Partition}}",
|
||||||
|
{{ end }}
|
||||||
|
{{ if .Token }}
|
||||||
|
"DP_CREDENTIAL_TYPE=static",
|
||||||
|
"DP_CREDENTIAL_STATIC_TOKEN={{.Token}}",
|
||||||
|
{{ end }}
|
||||||
|
// for demo purposes
|
||||||
|
"DP_ENVOY_ADMIN_BIND_ADDRESS=0.0.0.0",
|
||||||
|
"DP_ENVOY_ADMIN_BIND_PORT=19000",
|
||||||
|
"DP_LOG_LEVEL=trace",
|
||||||
|
"DP_CA_CERTS=/consul/config/certs/consul-agent-ca.pem",
|
||||||
|
"DP_CONSUL_GRPC_PORT=8503",
|
||||||
|
"DP_TLS_SERVER_NAME=server.{{.Node.Datacenter}}.consul",
|
||||||
|
]
|
||||||
|
|
||||||
|
command = [
|
||||||
|
"/usr/local/bin/consul-dataplane",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" {
|
resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" {
|
||||||
name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}"
|
name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}"
|
||||||
network_mode = "container:${docker_container.{{.PodName}}.id}"
|
network_mode = "container:${docker_container.{{.PodName}}.id}"
|
||||||
image = docker_image.{{.EnvoyImageResource}}.latest
|
image = docker_image.{{.ImageResource}}.latest
|
||||||
restart = "on-failure"
|
restart = "on-failure"
|
||||||
|
|
||||||
{{- range $k, $v := .Labels }}
|
{{- range $k, $v := .Labels }}
|
||||||
|
@ -18,8 +18,22 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" {
|
||||||
}
|
}
|
||||||
|
|
||||||
command = [
|
command = [
|
||||||
{{- range .Command }}
|
"consul", "connect", "envoy",
|
||||||
"{{.}}",
|
"-register",
|
||||||
{{- end }}
|
"-mesh-gateway",
|
||||||
|
"-address={{`{{ GetInterfaceIP \"eth0\" }}`}}:{{.Service.Port}}",
|
||||||
|
"-wan-address={{`{{ GetInterfaceIP \"eth1\" }}`}}:{{.Service.Port}}",
|
||||||
|
"-grpc-addr=http://127.0.0.1:8502",
|
||||||
|
// for demo purposes (TODO: huh?)
|
||||||
|
"-admin-bind=0.0.0.0:{{.Service.EnvoyAdminPort}}",
|
||||||
|
{{ if .Enterprise }}
|
||||||
|
"-partition={{.Service.ID.Partition}}",
|
||||||
|
{{end}}
|
||||||
|
{{ if .Token }}
|
||||||
|
"-token={{.Token}}",
|
||||||
|
{{end}}
|
||||||
|
"--",
|
||||||
|
"-l",
|
||||||
|
"trace",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ package tfgen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
|
"text/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed templates/container-app-dataplane.tf.tmpl
|
//go:embed templates/container-app-dataplane.tf.tmpl
|
||||||
|
@ -12,7 +13,20 @@ import (
|
||||||
//go:embed templates/container-app.tf.tmpl
|
//go:embed templates/container-app.tf.tmpl
|
||||||
//go:embed templates/container-consul.tf.tmpl
|
//go:embed templates/container-consul.tf.tmpl
|
||||||
//go:embed templates/container-mgw.tf.tmpl
|
//go:embed templates/container-mgw.tf.tmpl
|
||||||
|
//go:embed templates/container-mgw-dataplane.tf.tmpl
|
||||||
//go:embed templates/container-pause.tf.tmpl
|
//go:embed templates/container-pause.tf.tmpl
|
||||||
//go:embed templates/container-proxy.tf.tmpl
|
//go:embed templates/container-proxy.tf.tmpl
|
||||||
//go:embed templates/container-coredns.tf.tmpl
|
//go:embed templates/container-coredns.tf.tmpl
|
||||||
var content embed.FS
|
var content embed.FS
|
||||||
|
|
||||||
|
var (
|
||||||
|
tfAppDataplaneT = template.Must(template.ParseFS(content, "templates/container-app-dataplane.tf.tmpl"))
|
||||||
|
tfAppSidecarT = template.Must(template.ParseFS(content, "templates/container-app-sidecar.tf.tmpl"))
|
||||||
|
tfAppT = template.Must(template.ParseFS(content, "templates/container-app.tf.tmpl"))
|
||||||
|
tfConsulT = template.Must(template.ParseFS(content, "templates/container-consul.tf.tmpl"))
|
||||||
|
tfMeshGatewayT = template.Must(template.ParseFS(content, "templates/container-mgw.tf.tmpl"))
|
||||||
|
tfMeshGatewayDataplaneT = template.Must(template.ParseFS(content, "templates/container-mgw-dataplane.tf.tmpl"))
|
||||||
|
tfPauseT = template.Must(template.ParseFS(content, "templates/container-pause.tf.tmpl"))
|
||||||
|
tfForwardProxyT = template.Must(template.ParseFS(content, "templates/container-proxy.tf.tmpl"))
|
||||||
|
tfCorednsT = template.Must(template.ParseFS(content, "templates/container-coredns.tf.tmpl"))
|
||||||
|
)
|
||||||
|
|
|
@ -113,6 +113,21 @@ func (s *Sprawl) APIClientForNode(clusterName string, nid topology.NodeID, token
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// APIClientForCluster is a convenience wrapper for APIClientForNode that returns
|
||||||
|
// an API client for an agent node in the cluster, preferring clients, then servers
|
||||||
|
func (s *Sprawl) APIClientForCluster(clusterName, token string) (*api.Client, error) {
|
||||||
|
clu := s.topology.Clusters[clusterName]
|
||||||
|
// TODO: this always goes to the first client, but we might want to balance this
|
||||||
|
firstAgent := clu.FirstClient()
|
||||||
|
if firstAgent == nil {
|
||||||
|
firstAgent = clu.FirstServer()
|
||||||
|
}
|
||||||
|
if firstAgent == nil {
|
||||||
|
return nil, fmt.Errorf("failed to find agent in cluster %s", clusterName)
|
||||||
|
}
|
||||||
|
return s.APIClientForNode(clusterName, firstAgent.ID(), token)
|
||||||
|
}
|
||||||
|
|
||||||
func copyConfig(cfg *topology.Config) (*topology.Config, error) {
|
func copyConfig(cfg *topology.Config) (*topology.Config, error) {
|
||||||
dup, err := copystructure.Copy(cfg)
|
dup, err := copystructure.Copy(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -88,7 +88,9 @@ fi
|
||||||
"-i",
|
"-i",
|
||||||
"--net=none",
|
"--net=none",
|
||||||
"-v", cluster.TLSVolumeName + ":/data",
|
"-v", cluster.TLSVolumeName + ":/data",
|
||||||
"busybox:latest",
|
// TODO: latest busted?
|
||||||
|
// https://hashicorp.slack.com/archives/C03EUN3QF1C/p1691784078972959
|
||||||
|
"busybox:1.34",
|
||||||
"sh", "-c",
|
"sh", "-c",
|
||||||
// Need this so the permissions stick; docker seems to treat unused volumes differently.
|
// Need this so the permissions stick; docker seems to treat unused volumes differently.
|
||||||
`touch /data/VOLUME_PLACEHOLDER && chown -R ` + consulUserArg + ` /data`,
|
`touch /data/VOLUME_PLACEHOLDER && chown -R ` + consulUserArg + ` /data`,
|
||||||
|
|
|
@ -66,6 +66,7 @@ func (i Images) EnvoyConsulImage() string {
|
||||||
return "local/" + name1 + "-and-" + name2 + ":" + tag1 + "-with-" + tag2
|
return "local/" + name1 + "-and-" + name2 + ":" + tag1 + "-with-" + tag2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: what is this for and why do we need to do this and why is it named this?
|
||||||
func (i Images) ChooseNode(kind NodeKind) Images {
|
func (i Images) ChooseNode(kind NodeKind) Images {
|
||||||
switch kind {
|
switch kind {
|
||||||
case NodeKindServer:
|
case NodeKindServer:
|
||||||
|
|
|
@ -290,6 +290,7 @@ func (c *Cluster) ServerByAddr(addr string) *Node {
|
||||||
|
|
||||||
func (c *Cluster) FirstServer() *Node {
|
func (c *Cluster) FirstServer() *Node {
|
||||||
for _, node := range c.Nodes {
|
for _, node := range c.Nodes {
|
||||||
|
// TODO: not sure why we check that it has 8500 exposed?
|
||||||
if node.IsServer() && !node.Disabled && node.ExposedPort(8500) > 0 {
|
if node.IsServer() && !node.Disabled && node.ExposedPort(8500) > 0 {
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
@ -432,9 +433,6 @@ type Node struct {
|
||||||
// the enclosing Cluster.
|
// the enclosing Cluster.
|
||||||
Images Images
|
Images Images
|
||||||
|
|
||||||
// AgentEnv contains optional environment variables to attach to Consul agents.
|
|
||||||
AgentEnv []string
|
|
||||||
|
|
||||||
Disabled bool `json:",omitempty"`
|
Disabled bool `json:",omitempty"`
|
||||||
|
|
||||||
Addresses []*Address
|
Addresses []*Address
|
||||||
|
|
Loading…
Reference in New Issue