open-nomad/api/consul_test.go

575 lines
13 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package api
import (
"testing"
"time"
"github.com/hashicorp/nomad/api/internal/testutil"
"github.com/shoenig/test/must"
)
func TestConsul_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("missing ns", func(t *testing.T) {
c := new(Consul)
c.Canonicalize()
must.Eq(t, "", c.Namespace)
})
t.Run("complete", func(t *testing.T) {
c := &Consul{Namespace: "foo"}
c.Canonicalize()
must.Eq(t, "foo", c.Namespace)
})
}
func TestConsul_Copy(t *testing.T) {
testutil.Parallel(t)
t.Run("complete", func(t *testing.T) {
result := (&Consul{
Namespace: "foo",
}).Copy()
must.Eq(t, &Consul{
Namespace: "foo",
}, result)
})
}
func TestConsul_MergeNamespace(t *testing.T) {
testutil.Parallel(t)
t.Run("already set", func(t *testing.T) {
a := &Consul{Namespace: "foo"}
ns := pointerOf("bar")
a.MergeNamespace(ns)
must.Eq(t, "foo", a.Namespace)
must.Eq(t, "bar", *ns)
})
t.Run("inherit", func(t *testing.T) {
a := &Consul{Namespace: ""}
ns := pointerOf("bar")
a.MergeNamespace(ns)
must.Eq(t, "bar", a.Namespace)
must.Eq(t, "bar", *ns)
})
t.Run("parent is nil", func(t *testing.T) {
a := &Consul{Namespace: "foo"}
ns := (*string)(nil)
a.MergeNamespace(ns)
must.Eq(t, "foo", a.Namespace)
must.Nil(t, ns)
})
}
func TestConsulConnect_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("nil connect", func(t *testing.T) {
cc := (*ConsulConnect)(nil)
cc.Canonicalize()
must.Nil(t, cc)
})
t.Run("empty connect", func(t *testing.T) {
cc := new(ConsulConnect)
cc.Canonicalize()
must.False(t, cc.Native)
must.Nil(t, cc.SidecarService)
must.Nil(t, cc.SidecarTask)
})
}
func TestConsulSidecarService_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("nil sidecar_service", func(t *testing.T) {
css := (*ConsulSidecarService)(nil)
css.Canonicalize()
must.Nil(t, css)
})
t.Run("empty sidecar_service", func(t *testing.T) {
css := new(ConsulSidecarService)
css.Canonicalize()
must.SliceEmpty(t, css.Tags)
must.Nil(t, css.Proxy)
})
t.Run("non-empty sidecar_service", func(t *testing.T) {
css := &ConsulSidecarService{
Tags: make([]string, 0),
Port: "port",
Proxy: &ConsulProxy{
LocalServiceAddress: "lsa",
LocalServicePort: 80,
},
Meta: map[string]string{
"test-key": "test-value",
},
}
css.Canonicalize()
must.Eq(t, &ConsulSidecarService{
Tags: nil,
Port: "port",
Proxy: &ConsulProxy{
LocalServiceAddress: "lsa",
LocalServicePort: 80},
Meta: map[string]string{
"test-key": "test-value",
},
}, css)
})
}
func TestConsulProxy_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("nil proxy", func(t *testing.T) {
cp := (*ConsulProxy)(nil)
cp.Canonicalize()
must.Nil(t, cp)
})
t.Run("empty proxy", func(t *testing.T) {
cp := new(ConsulProxy)
cp.Canonicalize()
must.Eq(t, "", cp.LocalServiceAddress)
must.Zero(t, cp.LocalServicePort)
must.Nil(t, cp.Expose)
must.Nil(t, cp.Upstreams)
must.MapEmpty(t, cp.Config)
})
t.Run("non empty proxy", func(t *testing.T) {
cp := &ConsulProxy{
LocalServiceAddress: "127.0.0.1",
LocalServicePort: 80,
Expose: new(ConsulExposeConfig),
Upstreams: make([]*ConsulUpstream, 0),
Config: make(map[string]interface{}),
}
cp.Canonicalize()
must.Eq(t, "127.0.0.1", cp.LocalServiceAddress)
must.Eq(t, 80, cp.LocalServicePort)
must.Eq(t, &ConsulExposeConfig{}, cp.Expose)
must.Nil(t, cp.Upstreams)
must.Nil(t, cp.Config)
})
}
func TestConsulUpstream_Copy(t *testing.T) {
testutil.Parallel(t)
t.Run("nil upstream", func(t *testing.T) {
cu := (*ConsulUpstream)(nil)
result := cu.Copy()
must.Nil(t, result)
})
t.Run("complete upstream", func(t *testing.T) {
cu := &ConsulUpstream{
DestinationName: "dest1",
DestinationNamespace: "ns2",
DestinationPeer: "10.0.0.1:6379",
DestinationType: "tcp",
Datacenter: "dc2",
LocalBindPort: 2000,
LocalBindAddress: "10.0.0.1",
LocalBindSocketPath: "/var/run/testsocket.sock",
LocalBindSocketMode: "0666",
MeshGateway: &ConsulMeshGateway{Mode: "remote"},
Config: map[string]any{"connect_timeout_ms": 5000},
}
result := cu.Copy()
must.Eq(t, cu, result)
})
}
func TestConsulUpstream_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("nil upstream", func(t *testing.T) {
cu := (*ConsulUpstream)(nil)
cu.Canonicalize()
must.Nil(t, cu)
})
t.Run("complete", func(t *testing.T) {
cu := &ConsulUpstream{
DestinationName: "dest1",
DestinationNamespace: "ns2",
DestinationPeer: "10.0.0.1:6379",
DestinationType: "tcp",
Datacenter: "dc2",
LocalBindPort: 2000,
LocalBindAddress: "10.0.0.1",
LocalBindSocketPath: "/var/run/testsocket.sock",
LocalBindSocketMode: "0666",
MeshGateway: &ConsulMeshGateway{Mode: ""},
Config: make(map[string]any),
}
cu.Canonicalize()
must.Eq(t, &ConsulUpstream{
DestinationName: "dest1",
DestinationNamespace: "ns2",
DestinationPeer: "10.0.0.1:6379",
DestinationType: "tcp",
Datacenter: "dc2",
LocalBindPort: 2000,
LocalBindAddress: "10.0.0.1",
LocalBindSocketPath: "/var/run/testsocket.sock",
LocalBindSocketMode: "0666",
MeshGateway: &ConsulMeshGateway{Mode: ""},
Config: nil,
}, cu)
})
}
func TestSidecarTask_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("nil sidecar_task", func(t *testing.T) {
st := (*SidecarTask)(nil)
st.Canonicalize()
must.Nil(t, st)
})
t.Run("empty sidecar_task", func(t *testing.T) {
st := new(SidecarTask)
st.Canonicalize()
must.Nil(t, st.Config)
must.Nil(t, st.Env)
must.Eq(t, DefaultResources(), st.Resources)
must.Eq(t, DefaultLogConfig(), st.LogConfig)
must.Nil(t, st.Meta)
must.Eq(t, 5*time.Second, *st.KillTimeout)
must.Eq(t, 0*time.Second, *st.ShutdownDelay)
})
t.Run("non empty sidecar_task resources", func(t *testing.T) {
exp := DefaultResources()
exp.MemoryMB = pointerOf(333)
st := &SidecarTask{
Resources: &Resources{MemoryMB: pointerOf(333)},
}
st.Canonicalize()
must.Eq(t, exp, st.Resources)
})
}
func TestConsulGateway_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
cg := (*ConsulGateway)(nil)
cg.Canonicalize()
must.Nil(t, cg)
})
t.Run("set defaults", func(t *testing.T) {
cg := &ConsulGateway{
Proxy: &ConsulGatewayProxy{
ConnectTimeout: nil,
EnvoyGatewayBindTaggedAddresses: true,
EnvoyGatewayBindAddresses: make(map[string]*ConsulGatewayBindAddress, 0),
EnvoyGatewayNoDefaultBind: true,
Config: make(map[string]interface{}, 0),
},
Ingress: &ConsulIngressConfigEntry{
TLS: &ConsulGatewayTLSConfig{
Enabled: false,
},
Listeners: make([]*ConsulIngressListener, 0),
},
}
cg.Canonicalize()
must.Eq(t, pointerOf(5*time.Second), cg.Proxy.ConnectTimeout)
must.True(t, cg.Proxy.EnvoyGatewayBindTaggedAddresses)
must.Nil(t, cg.Proxy.EnvoyGatewayBindAddresses)
must.True(t, cg.Proxy.EnvoyGatewayNoDefaultBind)
must.Eq(t, "", cg.Proxy.EnvoyDNSDiscoveryType)
must.Nil(t, cg.Proxy.Config)
must.Nil(t, cg.Ingress.Listeners)
})
}
func TestConsulGateway_Copy(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
result := (*ConsulGateway)(nil).Copy()
must.Nil(t, result)
})
gateway := &ConsulGateway{
Proxy: &ConsulGatewayProxy{
ConnectTimeout: pointerOf(3 * time.Second),
EnvoyGatewayBindTaggedAddresses: true,
EnvoyGatewayBindAddresses: map[string]*ConsulGatewayBindAddress{
"listener1": {Address: "10.0.0.1", Port: 2000},
"listener2": {Address: "10.0.0.1", Port: 2001},
},
EnvoyGatewayNoDefaultBind: true,
EnvoyDNSDiscoveryType: "STRICT_DNS",
Config: map[string]interface{}{
"foo": "bar",
"baz": 3,
},
},
Ingress: &ConsulIngressConfigEntry{
TLS: &ConsulGatewayTLSConfig{
Enabled: true,
},
Listeners: []*ConsulIngressListener{{
Port: 3333,
Protocol: "tcp",
Services: []*ConsulIngressService{{
Name: "service1",
Hosts: []string{
"127.0.0.1", "127.0.0.1:3333",
}},
}},
},
},
Terminating: &ConsulTerminatingConfigEntry{
Services: []*ConsulLinkedService{{
Name: "linked-service1",
}},
},
}
t.Run("complete", func(t *testing.T) {
result := gateway.Copy()
must.Eq(t, gateway, result)
})
}
func TestConsulIngressConfigEntry_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
c := (*ConsulIngressConfigEntry)(nil)
c.Canonicalize()
must.Nil(t, c)
})
t.Run("empty fields", func(t *testing.T) {
c := &ConsulIngressConfigEntry{
TLS: nil,
Listeners: []*ConsulIngressListener{},
}
c.Canonicalize()
must.Nil(t, c.TLS)
must.Nil(t, c.Listeners)
})
t.Run("complete", func(t *testing.T) {
c := &ConsulIngressConfigEntry{
TLS: &ConsulGatewayTLSConfig{Enabled: true},
Listeners: []*ConsulIngressListener{{
Port: 9090,
Protocol: "http",
Services: []*ConsulIngressService{{
Name: "service1",
Hosts: []string{"1.1.1.1"},
}},
}},
}
c.Canonicalize()
must.Eq(t, &ConsulIngressConfigEntry{
TLS: &ConsulGatewayTLSConfig{Enabled: true},
Listeners: []*ConsulIngressListener{{
Port: 9090,
Protocol: "http",
Services: []*ConsulIngressService{{
Name: "service1",
Hosts: []string{"1.1.1.1"},
}},
}},
}, c)
})
}
func TestConsulIngressConfigEntry_Copy(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
result := (*ConsulIngressConfigEntry)(nil).Copy()
must.Nil(t, result)
})
entry := &ConsulIngressConfigEntry{
TLS: &ConsulGatewayTLSConfig{
Enabled: true,
},
Listeners: []*ConsulIngressListener{{
Port: 1111,
Protocol: "http",
Services: []*ConsulIngressService{{
Name: "service1",
Hosts: []string{"1.1.1.1", "1.1.1.1:9000"},
}, {
Name: "service2",
Hosts: []string{"2.2.2.2"},
}},
}},
}
t.Run("complete", func(t *testing.T) {
result := entry.Copy()
must.Eq(t, entry, result)
})
}
func TestConsulTerminatingConfigEntry_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
c := (*ConsulTerminatingConfigEntry)(nil)
c.Canonicalize()
must.Nil(t, c)
})
t.Run("empty services", func(t *testing.T) {
c := &ConsulTerminatingConfigEntry{
Services: []*ConsulLinkedService{},
}
c.Canonicalize()
must.Nil(t, c.Services)
})
}
func TestConsulTerminatingConfigEntry_Copy(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
result := (*ConsulIngressConfigEntry)(nil).Copy()
must.Nil(t, result)
})
entry := &ConsulTerminatingConfigEntry{
Services: []*ConsulLinkedService{{
Name: "servic1",
}, {
Name: "service2",
CAFile: "ca_file.pem",
CertFile: "cert_file.pem",
KeyFile: "key_file.pem",
SNI: "sni.terminating.consul",
}},
}
t.Run("complete", func(t *testing.T) {
result := entry.Copy()
must.Eq(t, entry, result)
})
}
func TestConsulMeshConfigEntry_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
ce := (*ConsulMeshConfigEntry)(nil)
ce.Canonicalize()
must.Nil(t, ce)
})
t.Run("instantiated", func(t *testing.T) {
ce := new(ConsulMeshConfigEntry)
ce.Canonicalize()
must.NotNil(t, ce)
})
}
func TestConsulMeshConfigEntry_Copy(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
ce := (*ConsulMeshConfigEntry)(nil)
ce2 := ce.Copy()
must.Nil(t, ce2)
})
t.Run("instantiated", func(t *testing.T) {
ce := new(ConsulMeshConfigEntry)
ce2 := ce.Copy()
must.NotNil(t, ce2)
})
}
func TestConsulMeshGateway_Canonicalize(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
c := (*ConsulMeshGateway)(nil)
c.Canonicalize()
must.Nil(t, c)
})
t.Run("unset mode", func(t *testing.T) {
c := &ConsulMeshGateway{Mode: ""}
c.Canonicalize()
must.Eq(t, "", c.Mode)
})
t.Run("set mode", func(t *testing.T) {
c := &ConsulMeshGateway{Mode: "remote"}
c.Canonicalize()
must.Eq(t, "remote", c.Mode)
})
}
func TestConsulMeshGateway_Copy(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
c := (*ConsulMeshGateway)(nil)
result := c.Copy()
must.Nil(t, result)
})
t.Run("instantiated", func(t *testing.T) {
c := &ConsulMeshGateway{
Mode: "local",
}
result := c.Copy()
must.Eq(t, c, result)
})
}
func TestConsulGatewayTLSConfig_Copy(t *testing.T) {
testutil.Parallel(t)
t.Run("nil", func(t *testing.T) {
c := (*ConsulGatewayTLSConfig)(nil)
result := c.Copy()
must.Nil(t, result)
})
t.Run("enabled", func(t *testing.T) {
c := &ConsulGatewayTLSConfig{
Enabled: true,
}
result := c.Copy()
must.Eq(t, c, result)
})
t.Run("customized", func(t *testing.T) {
c := &ConsulGatewayTLSConfig{
Enabled: true,
TLSMinVersion: "TLSv1_2",
TLSMaxVersion: "TLSv1_3",
CipherSuites: []string{"foo", "bar"},
}
result := c.Copy()
must.Eq(t, c, result)
})
}