mirror of https://github.com/linkerd/linkerd2.git
Check for Namespace level config override annotations (#3194)
* Check for Namespace level config override annotations * Add unit tests for namespace level config overrides * add integration test for namespace level config override * use different namespace for override tests * check resource requests for integration tests Signed-off-by: Tarun Pothulapati <tarunpothulapati@outlook.com>
This commit is contained in:
parent
879650cef9
commit
242566ac7c
|
@ -537,7 +537,10 @@ func (conf *ResourceConfig) injectPodAnnotations(values *patch) {
|
|||
}
|
||||
|
||||
func (conf *ResourceConfig) getOverride(annotation string) string {
|
||||
return conf.pod.meta.Annotations[annotation]
|
||||
if override := conf.pod.meta.Annotations[annotation]; override != "" {
|
||||
return override
|
||||
}
|
||||
return conf.nsAnnotations[annotation]
|
||||
}
|
||||
|
||||
func (conf *ResourceConfig) proxyImage() string {
|
||||
|
|
|
@ -75,9 +75,10 @@ func TestConfigAccessors(t *testing.T) {
|
|||
configs := &config.All{Global: globalConfig, Proxy: proxyConfig}
|
||||
|
||||
var testCases = []struct {
|
||||
id string
|
||||
spec appsv1.DeploymentSpec
|
||||
expected expectedProxyConfigs
|
||||
id string
|
||||
nsAnnotations map[string]string
|
||||
spec appsv1.DeploymentSpec
|
||||
expected expectedProxyConfigs
|
||||
}{
|
||||
{id: "use overrides",
|
||||
spec: appsv1.DeploymentSpec{
|
||||
|
@ -168,6 +169,58 @@ func TestConfigAccessors(t *testing.T) {
|
|||
outboundSkipPorts: "9079",
|
||||
},
|
||||
},
|
||||
{id: "use namespace overrides",
|
||||
nsAnnotations: map[string]string{
|
||||
k8s.ProxyDisableIdentityAnnotation: "true",
|
||||
k8s.ProxyImageAnnotation: "gcr.io/linkerd-io/proxy",
|
||||
k8s.ProxyImagePullPolicyAnnotation: "Always",
|
||||
k8s.ProxyInitImageAnnotation: "gcr.io/linkerd-io/proxy-init",
|
||||
k8s.ProxyControlPortAnnotation: "4000",
|
||||
k8s.ProxyInboundPortAnnotation: "5000",
|
||||
k8s.ProxyAdminPortAnnotation: "5001",
|
||||
k8s.ProxyOutboundPortAnnotation: "5002",
|
||||
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.ProxyLogLevelAnnotation: "debug,linkerd2_proxy=debug",
|
||||
k8s.ProxyEnableExternalProfilesAnnotation: "false",
|
||||
k8s.ProxyVersionOverrideAnnotation: proxyVersionOverride},
|
||||
spec: appsv1.DeploymentSpec{
|
||||
Template: corev1.PodTemplateSpec{
|
||||
Spec: corev1.PodSpec{},
|
||||
},
|
||||
},
|
||||
expected: expectedProxyConfigs{
|
||||
image: "gcr.io/linkerd-io/proxy",
|
||||
imagePullPolicy: "Always",
|
||||
proxyVersion: proxyVersionOverride,
|
||||
controlPort: int32(4000),
|
||||
inboundPort: int32(5000),
|
||||
adminPort: int32(5001),
|
||||
outboundPort: int32(5002),
|
||||
logLevel: "debug,linkerd2_proxy=debug",
|
||||
resourceRequirements: &charts.Resources{
|
||||
CPU: charts.Constraints{
|
||||
Limit: "1500m",
|
||||
Request: "150m",
|
||||
},
|
||||
Memory: charts.Constraints{
|
||||
Limit: "256",
|
||||
Request: "120",
|
||||
},
|
||||
},
|
||||
proxyUID: int64(8500),
|
||||
initImage: "gcr.io/linkerd-io/proxy-init",
|
||||
initImagePullPolicy: "Always",
|
||||
initVersion: version.ProxyInitVersion,
|
||||
inboundSkipPorts: "4222,6222",
|
||||
outboundSkipPorts: "8079,8080",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
@ -178,7 +231,7 @@ func TestConfigAccessors(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resourceConfig := NewResourceConfig(configs, OriginUnknown).WithKind("Deployment")
|
||||
resourceConfig := NewResourceConfig(configs, OriginUnknown).WithKind("Deployment").WithNsAnnotations(testCase.nsAnnotations)
|
||||
if err := resourceConfig.parse(data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"github.com/linkerd/linkerd2/pkg/k8s"
|
||||
"github.com/linkerd/linkerd2/pkg/version"
|
||||
|
@ -89,6 +92,72 @@ func TestInjectParams(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNamespaceOverrideAnnotations(t *testing.T) {
|
||||
// Check for Namespace level override of proxy Configurations
|
||||
injectYAML, err := testutil.ReadFile("testdata/inject_test.yaml")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read inject test file: %s", err)
|
||||
}
|
||||
|
||||
injectNS := "inject-namespace-override-test"
|
||||
deployName := "inject-test-terminus"
|
||||
nsProxyMemReq := "50Mi"
|
||||
nsProxyCPUReq := "200m"
|
||||
|
||||
// Namespace level proxy configuration override
|
||||
nsAnnotations := map[string]string{
|
||||
k8s.ProxyInjectAnnotation: k8s.ProxyInjectEnabled,
|
||||
k8s.ProxyCPURequestAnnotation: nsProxyCPUReq,
|
||||
k8s.ProxyMemoryRequestAnnotation: nsProxyMemReq,
|
||||
}
|
||||
|
||||
ns := TestHelper.GetTestNamespace(injectNS)
|
||||
err = TestHelper.CreateNamespaceIfNotExists(ns, nsAnnotations)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create %s namespace: %s", ns, err)
|
||||
}
|
||||
|
||||
// patch injectYAML with unique name and pod annotations
|
||||
// Pod Level proxy configuration override
|
||||
podProxyCPUReq := "600m"
|
||||
podAnnotations := map[string]string{
|
||||
k8s.ProxyCPURequestAnnotation: podProxyCPUReq,
|
||||
}
|
||||
|
||||
patchedYAML, err := patchDeploy(injectYAML, deployName, podAnnotations)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to patch inject test YAML in namespace %s for deploy/%s: %s", ns, deployName, err)
|
||||
}
|
||||
|
||||
o, err := TestHelper.Kubectl(patchedYAML, "--namespace", ns, "create", "-f", "-")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create deploy/%s in namespace %s for %s: %s", deployName, ns, err, o)
|
||||
}
|
||||
|
||||
o, err = TestHelper.Kubectl("", "--namespace", ns, "wait", "--for=condition=available", "--timeout=30s", "deploy/"+deployName)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to wait for condition=available for deploy/%s in namespace %s: %s: %s", deployName, ns, err, o)
|
||||
}
|
||||
|
||||
pods, err := TestHelper.GetPodsForDeployment(ns, deployName)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get pods for namespace %s: %s", ns, err)
|
||||
}
|
||||
|
||||
containers := pods[0].Spec.Containers
|
||||
proxyContainer := getProxyContainer(containers)
|
||||
|
||||
// Match the pod configuration with the namespace level overrides
|
||||
if proxyContainer.Resources.Requests["memory"] != resource.MustParse(nsProxyMemReq) {
|
||||
t.Fatalf("proxy memory resource request falied to match with namespace level override")
|
||||
}
|
||||
|
||||
// Match with proxy level override
|
||||
if proxyContainer.Resources.Requests["cpu"] != resource.MustParse(podProxyCPUReq) {
|
||||
t.Fatalf("proxy cpu resource request falied to match with pod level override")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnotationPermutations(t *testing.T) {
|
||||
injectYAML, err := testutil.ReadFile("testdata/inject_test.yaml")
|
||||
if err != nil {
|
||||
|
@ -287,3 +356,15 @@ func validateInject(actual, fixtureFile string) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get Proxy Container from Containers
|
||||
func getProxyContainer(containers []v1.Container) *v1.Container {
|
||||
for _, c := range containers {
|
||||
container := c
|
||||
if container.Name == k8s.ProxyContainerName {
|
||||
return &container
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue