mirror of https://github.com/linkerd/linkerd2.git
368 lines
14 KiB
Go
368 lines
14 KiB
Go
package inject
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/go-test/deep"
|
|
l5dcharts "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
|
|
"github.com/linkerd/linkerd2/pkg/k8s"
|
|
"github.com/linkerd/linkerd2/pkg/util"
|
|
"github.com/linkerd/linkerd2/pkg/version"
|
|
appsv1 "k8s.io/api/apps/v1"
|
|
corev1 "k8s.io/api/core/v1"
|
|
k8sResource "k8s.io/apimachinery/pkg/api/resource"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"sigs.k8s.io/yaml"
|
|
)
|
|
|
|
func TestGetOverriddenValues(t *testing.T) {
|
|
// this test uses an annotated deployment and a expected Values object to verify
|
|
// the GetOverriddenValues function.
|
|
|
|
var (
|
|
proxyVersionOverride = "proxy-version-override"
|
|
pullPolicy = "Always"
|
|
)
|
|
|
|
testConfig, err := l5dcharts.NewValues()
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error: %v", err)
|
|
}
|
|
|
|
var testCases = []struct {
|
|
id string
|
|
nsAnnotations map[string]string
|
|
spec appsv1.DeploymentSpec
|
|
expected func() *l5dcharts.Values
|
|
}{
|
|
{id: "use overrides",
|
|
nsAnnotations: make(map[string]string),
|
|
spec: appsv1.DeploymentSpec{
|
|
Template: corev1.PodTemplateSpec{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Annotations: map[string]string{
|
|
k8s.ProxyImageAnnotation: "cr.l5d.io/linkerd/proxy",
|
|
k8s.ProxyImagePullPolicyAnnotation: pullPolicy,
|
|
k8s.ProxyInitImageAnnotation: "cr.l5d.io/linkerd/proxy-init",
|
|
k8s.ProxyControlPortAnnotation: "4000",
|
|
k8s.ProxyInboundPortAnnotation: "5000",
|
|
k8s.ProxyAdminPortAnnotation: "5001",
|
|
k8s.ProxyOutboundPortAnnotation: "5002",
|
|
k8s.ProxyPodInboundPortsAnnotation: "1234,5678",
|
|
k8s.ProxyIgnoreInboundPortsAnnotation: "4222,6222",
|
|
k8s.ProxyIgnoreOutboundPortsAnnotation: "8079,8080",
|
|
k8s.ProxyCPURequestAnnotation: "0.15",
|
|
k8s.ProxyMemoryRequestAnnotation: "120",
|
|
k8s.ProxyEphemeralStorageRequestAnnotation: "10",
|
|
k8s.ProxyCPULimitAnnotation: "1.5",
|
|
k8s.ProxyMemoryLimitAnnotation: "256",
|
|
k8s.ProxyEphemeralStorageLimitAnnotation: "50",
|
|
k8s.ProxyUIDAnnotation: "8500",
|
|
k8s.ProxyGIDAnnotation: "8500",
|
|
k8s.ProxyLogLevelAnnotation: "debug,linkerd=debug",
|
|
k8s.ProxyLogFormatAnnotation: "json",
|
|
k8s.ProxyEnableExternalProfilesAnnotation: "false",
|
|
k8s.ProxyVersionOverrideAnnotation: proxyVersionOverride,
|
|
k8s.ProxyWaitBeforeExitSecondsAnnotation: "123",
|
|
k8s.ProxyRequireIdentityOnInboundPortsAnnotation: "8888,9999",
|
|
k8s.ProxyOutboundConnectTimeout: "6000ms",
|
|
k8s.ProxyInboundConnectTimeout: "600ms",
|
|
k8s.ProxyOpaquePortsAnnotation: "4320-4325,3306",
|
|
k8s.ProxyAwait: "enabled",
|
|
k8s.ProxySkipSubnetsAnnotation: "172.17.0.0/16",
|
|
k8s.ProxyAccessLogAnnotation: "apache",
|
|
k8s.ProxyShutdownGracePeriodAnnotation: "30s",
|
|
k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "50000ms",
|
|
k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "900s",
|
|
k8s.ProxyDisableOutboundProtocolDetectTimeout: "true",
|
|
k8s.ProxyDisableInboundProtocolDetectTimeout: "true",
|
|
k8s.ProxyEnableNativeSidecarAnnotation: "true",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{},
|
|
},
|
|
},
|
|
expected: func() *l5dcharts.Values {
|
|
values, _ := l5dcharts.NewValues()
|
|
|
|
values.Proxy.Runtime.Workers.Maximum = 2
|
|
values.Proxy.Image.Name = "cr.l5d.io/linkerd/proxy"
|
|
values.Proxy.Image.PullPolicy = pullPolicy
|
|
values.Proxy.Image.Version = proxyVersionOverride
|
|
values.Proxy.PodInboundPorts = "1234,5678"
|
|
values.Proxy.Ports.Control = 4000
|
|
values.Proxy.Ports.Inbound = 5000
|
|
values.Proxy.Ports.Admin = 5001
|
|
values.Proxy.Ports.Outbound = 5002
|
|
values.Proxy.WaitBeforeExitSeconds = 123
|
|
values.Proxy.LogLevel = "debug,linkerd=debug"
|
|
values.Proxy.LogFormat = "json"
|
|
values.Proxy.Resources = &l5dcharts.Resources{
|
|
CPU: l5dcharts.Constraints{
|
|
Limit: "1.5",
|
|
Request: "0.15",
|
|
},
|
|
Memory: l5dcharts.Constraints{
|
|
Limit: "256",
|
|
Request: "120",
|
|
},
|
|
EphemeralStorage: l5dcharts.Constraints{
|
|
Limit: "50",
|
|
Request: "10",
|
|
},
|
|
}
|
|
values.Proxy.UID = 8500
|
|
values.Proxy.GID = 8500
|
|
values.ProxyInit.Image.Name = "cr.l5d.io/linkerd/proxy-init"
|
|
values.ProxyInit.Image.PullPolicy = pullPolicy
|
|
values.ProxyInit.Image.Version = version.ProxyInitVersion
|
|
values.ProxyInit.IgnoreInboundPorts = "4222,6222"
|
|
values.ProxyInit.IgnoreOutboundPorts = "8079,8080"
|
|
values.ProxyInit.SkipSubnets = "172.17.0.0/16"
|
|
values.Proxy.RequireIdentityOnInboundPorts = "8888,9999"
|
|
values.Proxy.OutboundConnectTimeout = "6000ms"
|
|
values.Proxy.InboundConnectTimeout = "600ms"
|
|
values.Proxy.OpaquePorts = "4320-4325,3306"
|
|
values.Proxy.Await = true
|
|
values.Proxy.AccessLog = "apache"
|
|
values.Proxy.ShutdownGracePeriod = "30000ms"
|
|
values.Proxy.OutboundDiscoveryCacheUnusedTimeout = "50s"
|
|
values.Proxy.InboundDiscoveryCacheUnusedTimeout = "900s"
|
|
values.Proxy.DisableOutboundProtocolDetectTimeout = true
|
|
values.Proxy.DisableInboundProtocolDetectTimeout = true
|
|
values.Proxy.NativeSidecar = true
|
|
return values
|
|
},
|
|
},
|
|
{id: "use defaults",
|
|
nsAnnotations: make(map[string]string),
|
|
spec: appsv1.DeploymentSpec{
|
|
Template: corev1.PodTemplateSpec{
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Spec: corev1.PodSpec{},
|
|
},
|
|
},
|
|
expected: func() *l5dcharts.Values {
|
|
values, _ := l5dcharts.NewValues()
|
|
return values
|
|
},
|
|
},
|
|
{id: "use namespace overrides",
|
|
nsAnnotations: map[string]string{
|
|
k8s.ProxyImageAnnotation: "cr.l5d.io/linkerd/proxy",
|
|
k8s.ProxyImagePullPolicyAnnotation: pullPolicy,
|
|
k8s.ProxyInitImageAnnotation: "cr.l5d.io/linkerd/proxy-init",
|
|
k8s.ProxyControlPortAnnotation: "4000",
|
|
k8s.ProxyInboundPortAnnotation: "5000",
|
|
k8s.ProxyAdminPortAnnotation: "5001",
|
|
k8s.ProxyOutboundPortAnnotation: "5002",
|
|
k8s.ProxyPodInboundPortsAnnotation: "1234,5678",
|
|
k8s.ProxyIgnoreInboundPortsAnnotation: "4222,6222",
|
|
k8s.ProxyIgnoreOutboundPortsAnnotation: "8079,8080",
|
|
k8s.ProxyCPURequestAnnotation: "0.15",
|
|
k8s.ProxyMemoryRequestAnnotation: "120",
|
|
k8s.ProxyCPULimitAnnotation: "1.5",
|
|
k8s.ProxyMemoryLimitAnnotation: "256",
|
|
k8s.ProxyUIDAnnotation: "8500",
|
|
k8s.ProxyGIDAnnotation: "8500",
|
|
k8s.ProxyLogLevelAnnotation: "debug,linkerd=debug",
|
|
k8s.ProxyLogFormatAnnotation: "json",
|
|
k8s.ProxyEnableExternalProfilesAnnotation: "false",
|
|
k8s.ProxyVersionOverrideAnnotation: proxyVersionOverride,
|
|
k8s.ProxyWaitBeforeExitSecondsAnnotation: "123",
|
|
k8s.ProxyOutboundConnectTimeout: "6000ms",
|
|
k8s.ProxyInboundConnectTimeout: "600ms",
|
|
k8s.ProxyOpaquePortsAnnotation: "4320-4325,3306",
|
|
k8s.ProxyAwait: "enabled",
|
|
k8s.ProxyAccessLogAnnotation: "apache",
|
|
k8s.ProxyInjectAnnotation: "ingress",
|
|
k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "50s",
|
|
k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "6000ms",
|
|
k8s.ProxyDisableOutboundProtocolDetectTimeout: "true",
|
|
k8s.ProxyDisableInboundProtocolDetectTimeout: "false",
|
|
k8s.ProxyEnableNativeSidecarAnnotation: "true",
|
|
},
|
|
spec: appsv1.DeploymentSpec{
|
|
Template: corev1.PodTemplateSpec{
|
|
Spec: corev1.PodSpec{},
|
|
},
|
|
},
|
|
expected: func() *l5dcharts.Values {
|
|
values, _ := l5dcharts.NewValues()
|
|
|
|
values.Proxy.Runtime.Workers.Maximum = 2
|
|
values.Proxy.Image.Name = "cr.l5d.io/linkerd/proxy"
|
|
values.Proxy.Image.PullPolicy = pullPolicy
|
|
values.Proxy.Image.Version = proxyVersionOverride
|
|
values.Proxy.PodInboundPorts = "1234,5678"
|
|
values.Proxy.Ports.Control = 4000
|
|
values.Proxy.Ports.Inbound = 5000
|
|
values.Proxy.Ports.Admin = 5001
|
|
values.Proxy.Ports.Outbound = 5002
|
|
values.Proxy.WaitBeforeExitSeconds = 123
|
|
values.Proxy.LogLevel = "debug,linkerd=debug"
|
|
values.Proxy.LogFormat = "json"
|
|
values.Proxy.Resources = &l5dcharts.Resources{
|
|
CPU: l5dcharts.Constraints{
|
|
Limit: "1.5",
|
|
Request: "0.15",
|
|
},
|
|
Memory: l5dcharts.Constraints{
|
|
Limit: "256",
|
|
Request: "120",
|
|
},
|
|
}
|
|
values.Proxy.UID = 8500
|
|
values.Proxy.GID = 8500
|
|
values.ProxyInit.Image.Name = "cr.l5d.io/linkerd/proxy-init"
|
|
values.ProxyInit.Image.PullPolicy = pullPolicy
|
|
values.ProxyInit.Image.Version = version.ProxyInitVersion
|
|
values.ProxyInit.IgnoreInboundPorts = "4222,6222"
|
|
values.ProxyInit.IgnoreOutboundPorts = "8079,8080"
|
|
values.Proxy.OutboundConnectTimeout = "6000ms"
|
|
values.Proxy.InboundConnectTimeout = "600ms"
|
|
values.Proxy.OpaquePorts = "4320-4325,3306"
|
|
values.Proxy.Await = true
|
|
values.Proxy.AccessLog = "apache"
|
|
values.Proxy.IsIngress = true
|
|
values.Proxy.OutboundDiscoveryCacheUnusedTimeout = "50s"
|
|
values.Proxy.InboundDiscoveryCacheUnusedTimeout = "6s"
|
|
values.Proxy.DisableOutboundProtocolDetectTimeout = true
|
|
values.Proxy.DisableInboundProtocolDetectTimeout = false
|
|
values.Proxy.NativeSidecar = true
|
|
return values
|
|
},
|
|
},
|
|
{id: "use invalid duration for proxy timeouts",
|
|
nsAnnotations: map[string]string{
|
|
k8s.ProxyOutboundConnectTimeout: "6000",
|
|
k8s.ProxyInboundConnectTimeout: "600",
|
|
k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "50",
|
|
k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "5000",
|
|
k8s.ProxyDisableOutboundProtocolDetectTimeout: "9000",
|
|
k8s.ProxyDisableInboundProtocolDetectTimeout: "9",
|
|
},
|
|
spec: appsv1.DeploymentSpec{
|
|
Template: corev1.PodTemplateSpec{
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Spec: corev1.PodSpec{},
|
|
},
|
|
},
|
|
expected: func() *l5dcharts.Values {
|
|
values, _ := l5dcharts.NewValues()
|
|
return values
|
|
},
|
|
},
|
|
{id: "use valid duration for proxy timeouts",
|
|
nsAnnotations: map[string]string{
|
|
// Validate we're converting time values into ms for the proxy to parse correctly.
|
|
k8s.ProxyOutboundConnectTimeout: "6s5ms",
|
|
k8s.ProxyInboundConnectTimeout: "2s5ms",
|
|
k8s.ProxyOutboundDiscoveryCacheUnusedTimeout: "6s5000ms",
|
|
k8s.ProxyInboundDiscoveryCacheUnusedTimeout: "6s5000ms",
|
|
k8s.ProxyDisableOutboundProtocolDetectTimeout: "false",
|
|
k8s.ProxyDisableInboundProtocolDetectTimeout: "true",
|
|
},
|
|
spec: appsv1.DeploymentSpec{
|
|
Template: corev1.PodTemplateSpec{
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Spec: corev1.PodSpec{},
|
|
},
|
|
},
|
|
expected: func() *l5dcharts.Values {
|
|
values, _ := l5dcharts.NewValues()
|
|
values.Proxy.OutboundConnectTimeout = "6005ms"
|
|
values.Proxy.InboundConnectTimeout = "2005ms"
|
|
values.Proxy.OutboundDiscoveryCacheUnusedTimeout = "11s"
|
|
values.Proxy.InboundDiscoveryCacheUnusedTimeout = "11s"
|
|
values.Proxy.DisableOutboundProtocolDetectTimeout = false
|
|
values.Proxy.DisableInboundProtocolDetectTimeout = true
|
|
return values
|
|
},
|
|
},
|
|
{id: "use named port for opaque ports",
|
|
nsAnnotations: make(map[string]string),
|
|
spec: appsv1.DeploymentSpec{
|
|
Template: corev1.PodTemplateSpec{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Annotations: map[string]string{
|
|
k8s.ProxyOpaquePortsAnnotation: "mysql",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "mysql",
|
|
ContainerPort: 3306,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: func() *l5dcharts.Values {
|
|
values, _ := l5dcharts.NewValues()
|
|
values.Proxy.OpaquePorts = "3306"
|
|
return values
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
testCase := tc
|
|
t.Run(testCase.id, func(t *testing.T) {
|
|
data, err := yaml.Marshal(&appsv1.Deployment{Spec: testCase.spec})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
resourceConfig := NewResourceConfig(testConfig, OriginUnknown, "linkerd").
|
|
WithKind("Deployment").WithNsAnnotations(testCase.nsAnnotations)
|
|
if err := resourceConfig.parse(data); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
AppendNamespaceAnnotations(resourceConfig.GetOverrideAnnotations(), resourceConfig.GetNsAnnotations(), resourceConfig.GetWorkloadAnnotations())
|
|
actual, err := GetOverriddenValues(
|
|
resourceConfig.values,
|
|
resourceConfig.getAnnotationOverrides(),
|
|
util.GetNamedPorts(resourceConfig.pod.spec.Containers),
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
expected := testCase.expected()
|
|
if diff := deep.Equal(actual, expected); diff != nil {
|
|
t.Errorf("%+v", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWholeCPUCores(t *testing.T) {
|
|
for _, c := range []struct {
|
|
v string
|
|
n int
|
|
}{
|
|
{v: "1", n: 1},
|
|
{v: "1m", n: 1},
|
|
{v: "1000m", n: 1},
|
|
{v: "1001m", n: 2},
|
|
} {
|
|
q, err := k8sResource.ParseQuantity(c.v)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
n, err := ToWholeCPUCores(q)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if n != int64(c.n) {
|
|
t.Fatalf("Unexpected value: %v != %v", n, c.n)
|
|
}
|
|
}
|
|
}
|