kubelatte-ce
Форк от sbertech/kubelatte-ce
615 строк · 28.6 Кб
1package mutation2
3import (4"context"5"fmt"6"github.com/InVisionApp/conjungo"7"github.com/Masterminds/sprig/v3"8"github.com/wI2L/jsondiff"9"gitverse.ru/synapse/kubelatte/pkg/api/common"10"gitverse.ru/synapse/kubelatte/pkg/api/v1alpha1"11"gitverse.ru/synapse/kubelatte/pkg/observability/logger/lib"12"gitverse.ru/synapse/kubelatte/pkg/storage"13"gitverse.ru/synapse/kubelatte/pkg/util"14"gitverse.ru/synapse/kubelatte/pkg/util/env"15baseMatch "gitverse.ru/synapse/kubelatte/pkg/util/match"16"gitverse.ru/synapse/kubelatte/pkg/util/templates"17"go.uber.org/zap"18"html/template"19metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"20"k8s.io/apimachinery/pkg/util/yaml"21"log"22"os"23"reflect"24"strings"25"testing"26)
27
28func TestMutateController_CheckMatchSelector(t *testing.T) {29type args struct {30config *v1alpha1.MutationConfig31obj ObjInfo
32}33tests := []struct {34name string35args args
36want bool37}{38{39name: "wrong operator",40args: args{41config: &v1alpha1.MutationConfig{42LabelSelector: metav1.LabelSelector{43MatchExpressions: []metav1.LabelSelectorRequirement{{Key: "", Values: []string{}, Operator: "s0m3 wr0n9 0p3rat0r"}}},44},45obj: ObjInfo{46labels: map[string]string{"str": "str"},47},48},49want: false,50},51{52name: "matching",53args: args{54obj: ObjInfo{55Kind: "pod",56name: "name",57labels: map[string]string{"str": "str"},58},59config: &v1alpha1.MutationConfig{60ObjectSelector: v1alpha1.ObjectSelector{Kind: "pod", Name: "name"},61LabelSelector: metav1.LabelSelector{62MatchExpressions: []metav1.LabelSelectorRequirement{{Key: "", Values: []string{}, Operator: "s0m3 wr0n9 0p3rat0r"}}},63},64},65want: true,66},67}68for _, tt := range tests {69t.Run(tt.name, func(t *testing.T) {70lib.ZapLogger = zap.NewNop()71
72r := &MutRenderer{}73if got := r.checkMatchSelector(context.Background(), tt.args.config, tt.args.obj); got != tt.want {74t.Errorf("checkMatchSelector() = %v, want %v", got, tt.want)75}76})77}78}
79
80func TestMutateController_GetRenders(t *testing.T) {81tests := []struct {82name string83obj map[string]interface{}84trigger v1alpha1.Trigger85template v1alpha1.Template86want []util.RenderItem87}{88{89name: "merge",90obj: map[string]interface{}{91"metadata": map[string]interface{}{92"annotations": map[string]interface{}{93"ns/annotK": "enabled",94},95"labels": map[string]interface{}{96"labK": "labV",97},98},99},100trigger: v1alpha1.Trigger{101TypeMeta: metav1.TypeMeta{},102ObjectMeta: metav1.ObjectMeta{},103Spec: v1alpha1.TriggerSpec{104MutationConfigs: []v1alpha1.MutationConfig{{105UpdateStrategy: "",106AnnotationNamespace: "ns",107AnnotationTrigger: "annotK",108TemplateRefs: []string{"templNs/templName"},109LabelSelector: metav1.LabelSelector{110MatchLabels: nil,111MatchExpressions: []metav1.LabelSelectorRequirement{112{113Key: "labK",114Operator: "Exists",115Values: nil,116},117},118},119}}},120Status: v1alpha1.TriggerStatus{},121},122template: v1alpha1.Template{123TypeMeta: metav1.TypeMeta{},124ObjectMeta: metav1.ObjectMeta{125Namespace: "templNs",126Name: "templName",127},128Spec: v1alpha1.TemplateSpec{},129Status: v1alpha1.TemplateStatus{},130},131want: []util.RenderItem{{132Template: v1alpha1.Template{133TypeMeta: metav1.TypeMeta{},134ObjectMeta: metav1.ObjectMeta{135Namespace: "templNs",136Name: "templName",137},138Spec: v1alpha1.TemplateSpec{},139Status: v1alpha1.TemplateStatus{},140},141Render: "",142Action: "",143},144},145},146{147name: "replace",148obj: map[string]interface{}{149"metadata": map[string]interface{}{150"annotations": map[string]interface{}{151"ns/annotK": "enabled",152},153"labels": map[string]interface{}{154"labK": "labV",155},156},157},158trigger: v1alpha1.Trigger{159TypeMeta: metav1.TypeMeta{},160ObjectMeta: metav1.ObjectMeta{},161Spec: v1alpha1.TriggerSpec{162MutationConfigs: []v1alpha1.MutationConfig{{163Name: "",164UpdateStrategy: "replace",165AnnotationNamespace: "ns",166AnnotationTrigger: "annotK",167TemplateRefs: []string{"templNs/templName"},168LabelSelector: metav1.LabelSelector{169MatchLabels: nil,170MatchExpressions: []metav1.LabelSelectorRequirement{171{172Key: "labK",173Operator: "Exists",174Values: nil,175},176},177},178}}},179Status: v1alpha1.TriggerStatus{},180},181template: v1alpha1.Template{182TypeMeta: metav1.TypeMeta{},183ObjectMeta: metav1.ObjectMeta{184Namespace: "templNs",185Name: "templName",186},187Spec: v1alpha1.TemplateSpec{},188Status: v1alpha1.TemplateStatus{},189},190want: []util.RenderItem{{191Template: v1alpha1.Template{192TypeMeta: metav1.TypeMeta{},193ObjectMeta: metav1.ObjectMeta{194Namespace: "templNs",195Name: "templName",196},197Spec: v1alpha1.TemplateSpec{},198Status: v1alpha1.TemplateStatus{},199},200Render: "",201Action: "replace",202},203},204},205}206for _, tt := range tests {207t.Run(tt.name, func(t *testing.T) {208lib.ZapLogger = zap.NewNop()209matcher := baseMatch.NewMatcher()210renderer := NewMutRenderer(matcher, nil)211r := Mutator{renderer}212storage.Storage = &storage.StorageController{}213storage.Storage.Start(false, false)214storage.Storage.UpdateTrigger(&tt.trigger)215storage.Storage.UpdateTemplate(&tt.template)216
217if got := r.renderer.GetRenders(context.Background(), &common.ARFields{Object: tt.obj}); !reflect.DeepEqual(got, tt.want) {218t.Errorf("getRenders() = %v, want %v", got, tt.want)219}220})221}222}
223
224func TestMutateController_Mutate(t *testing.T) {225type args struct {226obj map[string]interface{}227raw []byte228}229tests := []struct {230name string231trigger v1alpha1.Trigger232template v1alpha1.Template233args args
234want []jsondiff.Operation235}{236{237name: "ok",238want: []jsondiff.Operation{239{240Value: nil,241OldValue: "annotV",242Type: "remove",243From: "",244Path: "/metadata/annotations/annotK",245},246{247Value: "annotVal",248OldValue: nil,249Type: "add",250From: "",251Path: "/metadata/annotations/annotKey",252},253{254Value: nil,255OldValue: map[string]interface{}{"labK": "labV"},256Type: "remove",257From: "",258Path: "/metadata/labels",259},260},261args: args{262obj: map[string]interface{}{263"metadata": map[string]interface{}{264"annotations": map[string]interface{}{265"annotK": "annotV",266},267"labels": map[string]interface{}{268"labK": "labV",269},270},271},272raw: []byte("{\n \"metadata\": {\n \"annotations\": {\n \"annotKey\": \"annotVal\"\n }\n }\n}"),273},274trigger: v1alpha1.Trigger{275TypeMeta: metav1.TypeMeta{},276ObjectMeta: metav1.ObjectMeta{},277Spec: v1alpha1.TriggerSpec{278MutationConfigs: []v1alpha1.MutationConfig{{279Name: "",280UpdateStrategy: "",281TemplateRefs: []string{"templNs/templName"},282LabelSelector: metav1.LabelSelector{283MatchLabels: nil,284MatchExpressions: []metav1.LabelSelectorRequirement{285{286Key: "labK",287Operator: "Exists",288Values: nil,289},290},291},292}}},293Status: v1alpha1.TriggerStatus{},294},295template: v1alpha1.Template{296TypeMeta: metav1.TypeMeta{},297ObjectMeta: metav1.ObjectMeta{298Namespace: "templNs",299Name: "templName",300},301Spec: v1alpha1.TemplateSpec{},302Status: v1alpha1.TemplateStatus{},303},304},305{306name: "ok2",307args: args{308obj: map[string]interface{}{309"kind": "Pod",310"metadata": map[string]interface{}{311"annotations": map[string]interface{}{312"ann_ns/ann_trig": "enabled",313},314},315},316raw: []byte("{\"spec\": {\"containers\": [{\"name\": \"cont1\",\"image\": \"noimage\"}]}}")},317trigger: v1alpha1.Trigger{318Spec: v1alpha1.TriggerSpec{319MutationConfigs: []v1alpha1.MutationConfig{320{321AnnotationNamespace: "ann_ns",322AnnotationTrigger: "ann_trig",323Name: "mutation cfg",324UpdateStrategy: string(MergeStrategy),325Containers: []string{"some-ns/some-templ/container_mutated"}},326},327},328},329
330template: v1alpha1.Template{331ObjectMeta: metav1.ObjectMeta{Namespace: "some-ns", Name: "some-templ"},332Spec: v1alpha1.TemplateSpec{Data: `spec:333containers:
334- name: container_mutated
335image: imagemut`,336},337},338want: []jsondiff.Operation{339{Type: "remove", Path: "/kind", OldValue: "Pod"},340{Type: "remove", Path: "/metadata/annotations", OldValue: map[string]interface{}{"ann_ns/ann_trig": "enabled"}},341{Value: map[string]interface{}{env.ServiceAnnotationPrefix + "mutation.resource": "true"}, Type: "add", Path: "/metadata/labels"},342{Value: map[string]interface{}{343"containers": []interface{}{344map[string]interface{}{"image": "noimage", "name": "cont1"},345map[string]interface{}{"image": "imagemut", "name": "container_mutated"},346},347}, Type: "add", Path: "/spec"},348},349},350{351name: "location",352args: args{obj: map[string]interface{}{353"Kind": "Deployment",354"metadata": map[string]interface{}{355"annotations": map[string]interface{}{356"ann_ns/ann_trig": "enabled",357},358},359},360raw: []byte("{\n \"apiVersion\": \"apps/v1\",\n \"Kind\": \"Deployment\",\n \"metadata\": {\n \"name\": \"scope-volume-deployment\",\n \"namespace\": \"kblt-dev\",\n \"labels\": {\n \"kblt.dev\": \"test\",\n \"kblt.testname\": \"scope_volume_aft\",\n \"app\": \"to-test-latte\"\n },\n \"annotations\": {\n \"kblt.annotations/merge\": \"enabled\"\n }\n },\n \"spec\": {\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"replicas\": 1,\n \"selector\": {\n \"matchLabels\": {\n \"app\": \"to-test-latte\"\n }\n },\n \"template\": {\n \"metadata\": {\n \"labels\": {\n \"kblt.dev\": \"test\",\n \"kblt.testname\": \"scope_volume_aft\",\n \"app\": \"to-test-latte\",\n \"find-pod\": \"scope-volume-aft\",\n \"sidecar.istio.io/inject\": \"false\"\n },\n \"annotations\": {\n \"kblt.annotations/merge\": \"enabled\"\n }\n },\n \"spec\": {\n \"securityContext\": {\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n },\n \"runAsNonRoot\": true\n },\n \"containers\": [\n {\n \"name\": \"to-test-latte-2\",\n \"image\": \"dzo.sw.sbc.space/sbt/ci90000221_fedmesh/federation-demo@sha256:548cc416011c86bb1e2c6d06289aab0771a0f749c044656deaac5fc86d891fea\",\n \"securityContext\": {\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"allowPrivilegeEscalation\": false\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"100m\",\n \"memory\": \"100Mi\"\n },\n \"requests\": {\n \"cpu\": \"100m\",\n \"memory\": \"100Mi\"\n }\n }\n },\n {\n \"name\": \"to-test-latte-1\",\n \"image\": \"dzo.sw.sbc.space/sbt/ci90000221_fedmesh/federation-demo@sha256:548cc416011c86bb1e2c6d06289aab0771a0f749c044656deaac5fc86d891fea\",\n \"securityContext\": {\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"allowPrivilegeEscalation\": false\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"100m\",\n \"memory\": \"100Mi\"\n },\n \"requests\": {\n \"cpu\": \"100m\",\n \"memory\": \"100Mi\"\n }\n }\n }\n ],\n \"volumes\": [\n {\n \"name\": \"test-volume-1\",\n \"emptyDir\": {\n \"sizeLimit\": \"49Mi\"\n }\n }\n ]\n }\n }\n }\n}")},361trigger: v1alpha1.Trigger{362Spec: v1alpha1.TriggerSpec{363MutationConfigs: []v1alpha1.MutationConfig{364{365AnnotationNamespace: "ann_ns",366AnnotationTrigger: "ann_trig",367Name: "mutation cfg",368UpdateStrategy: string(ReplaceStrategy),369TemplateRefs: []string{"some-ns/some-templ"}},370},371},372},373
374template: v1alpha1.Template{375ObjectMeta: metav1.ObjectMeta{Namespace: "some-ns", Name: "some-templ"},376Spec: v1alpha1.TemplateSpec{Data: `377
378name: container_mutated
379image: imagemut
380`,381Location: "spec.template.spec.containers[@.name==`to-test-latte-2`]",382},383},384want: []jsondiff.Operation{385{386Value: "apps/v1",387Path: "/apiVersion",388Type: "add",389},390{391Type: "remove",392Path: "/metadata/annotations/ann_ns~1ann_trig",393OldValue: "enabled",394},395{396Value: "enabled",397Type: "add",398Path: "/metadata/annotations/kblt.annotations~1merge",399},400{401Value: map[string]interface{}{"app": "to-test-latte", "kblt.dev": "test", env.ServiceAnnotationPrefix + "mutation.resource": "true", "kblt.testname": "scope_volume_aft"},402Type: "add",403Path: "/metadata/labels",404},405{406Value: "scope-volume-deployment",407Type: "add",408Path: "/metadata/name",409},410{411Value: "kblt-dev",412OldValue: nil,413Type: "add",414From: "",415Path: "/metadata/namespace",416},417{418Value: map[string]interface{}{"replicas": float64(1),419"selector": map[string]interface{}{"matchLabels": map[string]interface{}{"app": "to-test-latte"}},420"strategy": map[string]interface{}{"type": "Recreate"},421"template": map[string]interface{}{"metadata": map[string]interface{}{"annotations": map[string]interface{}{"kblt.annotations/merge": "enabled"},422"labels": map[string]interface{}{"app": "to-test-latte", "find-pod": "scope-volume-aft", "kblt.dev": "test", "kblt.testname": "scope_volume_aft", "sidecar.istio.io/inject": "false"}},423"spec": map[string]interface{}{"containers": []interface{}{map[string]interface{}{"image": "imagemut", "name": "container_mutated"}, map[string]interface{}{"image": "dzo.sw.sbc.space/sbt/ci90000221_fedmesh/federation-demo@sha256:548cc416011c86bb1e2c6d06289aab0771a0f749c044656deaac5fc86d891fea", "name": "to-test-latte-1", "resources": map[string]interface{}{"limits": map[string]interface{}{"cpu": "100m", "memory": "100Mi"}, "requests": map[string]interface{}{"cpu": "100m", "memory": "100Mi"}}, "securityContext": map[string]interface{}{"allowPrivilegeEscalation": false, "capabilities": map[string]interface{}{"drop": []interface{}{"ALL"}}}}},424"securityContext": map[string]interface{}{"runAsNonRoot": true, "seccompProfile": map[string]interface{}{"type": "RuntimeDefault"}}, "volumes": []interface{}{map[string]interface{}{"emptyDir": map[string]interface{}{"sizeLimit": "49Mi"}, "name": "test-volume-1"}}},425}},426Type: "add",427Path: "/spec",428},429},430},431}432for _, tt := range tests {433t.Run(tt.name, func(t *testing.T) {434lib.ZapLogger = zap.NewNop()435matcher := baseMatch.NewMatcher()436renderer := NewMutRenderer(matcher, nil)437r := NewMutator(renderer)438storage.Storage = &storage.StorageController{}439storage.Storage.Start(false, false)440storage.Storage.UpdateTrigger(&tt.trigger)441storage.Storage.UpdateTemplate(&tt.template)442
443if got, _ := r.ApplyMutation(context.Background(), &common.ARFields{Object: tt.args.obj}, tt.args.raw); !reflect.DeepEqual(got, tt.want) {444t.Errorf("ApplyMutation() = %v, want %v\n", got, tt.want)445for i := 0; i < len(got); i++ {446fmt.Printf("%v: result: %+v\n", i, got[i])447fmt.Printf("%v: want : %+v\n", i, tt.want[i])448}449}450})451}452}
453
454func TestMergeFunc(t *testing.T) {455ym1 := "containers: \n - name: test\n image: aaaaaa\n testdt:\n - asda\n - adad\n - cvbcvb\n - name: test1\n image: bbbbbb\n - name: test2\n image: cccccc "456ym2 := "containers: \n - name: test\n image: ssssss\n testdt:\n - xxx\n - yyy\n - zzz\n - name: test2\n image: zzzzzz "457var obj1 map[string]interface{}458var obj2 map[string]interface{}459yaml.Unmarshal([]byte(ym1), &obj1)460yaml.Unmarshal([]byte(ym2), &obj2)461opts := conjungo.NewOptions()462opts.SetKindMergeFunc(463reflect.Slice,464
465func(t, s reflect.Value, o *conjungo.Options) (reflect.Value, error) {466aT, _ := t.Interface().([]interface{})467aS, _ := s.Interface().([]interface{})468
469aT = util.MergeSlice(aT, aS)470
471return reflect.ValueOf(aT), nil472},473)474opts.Overwrite = false475err := conjungo.Merge(&obj1, obj2, opts)476if err != nil {477fmt.Printf("%s", err)478}479fmt.Printf("Data %v\n", obj1)480}
481
482func TestRangeTemplate(t *testing.T) {483data := "spec:\n template:\n spec:\n containers:\n {{% range .spec.template.spec.containers %}}\n - name: {{% .name %}}\n securityContext:\n privileged: false\n runAsUser: 10000\n runAsGroup: 5000\n readOnlyRootFilesystem: true\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL \n {{% end %}}"484templateEngine := template.New("common").485Delims("{{%", "%}}").486Funcs(template.FuncMap{487"fromYaml": templates.FromYAML,488}).489Funcs(sprig.TxtFuncMap())490temp, err := templateEngine.New("test").Parse(data)491if err != nil {492log.Fatalf("Failed parse %s", err)493}494
495var inputObj interface{}496input := "apiVersion: apps/v1\nKind: Deployment\nmetadata:\n name: test-igeg\n namespace: synapse-metrics-system\n annotations:\n kblt.synapse/deploymentigeg: enabled\n kblt.synapse/deployment-all: enabled\n labels:\n secman-injector: enabled\n user-label: 'true'\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: egw-syn-metrics-synapse-metrics-system\n istio: egw-syn-metrics-synapse-metrics-system\n template:\n metadata:\n labels:\n app: egw-syn-metrics-synapse-metrics-system\n istio: egw-syn-metrics-synapse-metrics-system\n annotations:\n openshift.io/scc: restricted\n sidecar.istio.io/inject: 'false'\n spec:\n volumes:\n - configMap:\n defaultMode: 256\n name: istio-basic\n optional: true\n name: config-volume\n - name: istiod-ca-cert\n configMap:\n name: istio-ca-root-cert\n defaultMode: 256\n - name: podinfo\n downwardAPI:\n items:\n - path: labels\n fieldRef:\n apiVersion: v1\n fieldPath: metadata.labels\n - path: annotations\n fieldRef:\n apiVersion: v1\n fieldPath: metadata.annotations\n defaultMode: 256\n - name: istio-envoy\n emptyDir: {}\n - name: istio-data\n emptyDir: {}\n - name: istio-token\n projected:\n sources:\n - serviceAccountToken:\n audience: istio-ca\n expirationSeconds: 43200\n path: istio-token\n defaultMode: 256\n containers:\n - name: istio-proxy\n image: image\n args:\n - proxy\n - router\n - '--domain'\n - $(POD_NAMESPACE).svc.cluster.local\n - '--proxyLogLevel=warning'\n - '--proxyComponentLogLevel=misc:error'\n - '--log_output_level=default:info'\n - '--serviceCluster'\n - $(POD_NAMESPACE)\n - '--trust-domain=cluster.local'\n ports:\n - name: status-port\n containerPort: 15021\n protocol: TCP\n - name: https-kubeapi\n containerPort: 4443\n protocol: TCP\n env:\n - name: JWT_POLICY\n value: first-party-jwt\n - name: TRUST_DOMAIN\n value: cluster.local\n - name: ISTIO_META_UNPRIVILEGED_POD\n value: 'true'\n - name: PILOT_CERT_PROVIDER\n value: istiod\n - name: CA_ADDR\n value: blabla.ci00000-cp.svc:15012\n - name: NODE_NAME\n valueFrom:\n fieldRef:\n apiVersion: v1\n fieldPath: spec.nodeName\n - name: POD_NAME\n valueFrom:\n fieldRef:\n apiVersion: v1\n fieldPath: metadata.name\n - name: POD_NAMESPACE\n valueFrom:\n fieldRef:\n apiVersion: v1\n fieldPath: metadata.namespace\n - name: INSTANCE_IP\n valueFrom:\n fieldRef:\n apiVersion: v1\n fieldPath: status.podIP\n - name: HOST_IP\n valueFrom:\n fieldRef:\n apiVersion: v1\n fieldPath: status.hostIP\n - name: SERVICE_ACCOUNT\n valueFrom:\n fieldRef:\n apiVersion: v1\n fieldPath: spec.serviceAccountName\n - name: CANONICAL_SERVICE\n valueFrom:\n fieldRef:\n apiVersion: v1\n fieldPath: metadata.labels['service.istio.io/canonical-name']\n - name: CANONICAL_REVISION\n valueFrom:\n fieldRef:\n apiVersion: v1\n fieldPath: metadata.labels['service.istio.io/canonical-revision']\n - name: ISTIO_META_WORKLOAD_NAME\n value: egressgateway-synapse-metrics\n - name: ISTIO_META_OWNER\n value: >-\n kubernetes://apis/apps/v1/namespaces/synapse-metrics-system/deployments/egw-syn-metrics-synapse-metrics-system\n - name: ISTIO_META_MESH_ID\n value: cluster.local\n - name: ISTIO_META_ROUTER_MODE\n value: sni-dnat\n - name: ISTIO_META_CLUSTER_ID\n value: Kubernetes\n resources:\n limits:\n cpu: 300m\n ephemeral-storage: 500Mi\n memory: 500Mi\n requests:\n cpu: 300m\n ephemeral-storage: 500Mi\n memory: 500Mi\n volumeMounts:\n - mountPath: /etc/istio/config\n name: config-volume\n - name: istio-envoy\n mountPath: /etc/istio/proxy\n - name: istiod-ca-cert\n mountPath: /var/run/secrets/istio\n - name: podinfo\n mountPath: /etc/istio/pod\n - name: istio-token\n readOnly: true\n mountPath: /var/run/secrets/tokens\n - name: istio-data\n mountPath: /var/lib/istio/data\n readinessProbe:\n httpGet:\n path: /healthz/ready\n port: 15021\n scheme: HTTP\n initialDelaySeconds: 1\n timeoutSeconds: 1\n periodSeconds: 2\n successThreshold: 1\n failureThreshold: 30\n terminationMessagePath: /dev/termination-log\n terminationMessagePolicy: File\n imagePullPolicy: Always\n securityContext:\n readOnlyRootFilesystem: true\n restartPolicy: Always\n terminationGracePeriodSeconds: 30\n dnsPolicy: ClusterFirst\n affinity:\n nodeAffinity:\n requiredDuringSchedulingIgnoredDuringExecution:\n nodeSelectorTerms:\n - matchExpressions:\n - key: kubernetes.io/arch\n operator: In\n values:\n - amd64\n - ppc64le\n - s390x\n preferredDuringSchedulingIgnoredDuringExecution:\n - weight: 2\n preference:\n matchExpressions:\n - key: kubernetes.io/arch\n operator: In\n values:\n - amd64\n - weight: 2\n preference:\n matchExpressions:\n - key: kubernetes.io/arch\n operator: In\n values:\n - ppc64le\n - weight: 2\n preference:\n matchExpressions:\n - key: kubernetes.io/arch\n operator: In\n values:\n - s390x\n schedulerName: default-scheduler\n strategy:\n type: RollingUpdate\n rollingUpdate:\n maxUnavailable: 25%\n maxSurge: 100%\n revisionHistoryLimit: 10\n progressDeadlineSeconds: 600"497err = yaml.Unmarshal([]byte(input), &inputObj)498if err != nil {499log.Fatalf("Failed Unmarshal %s", err)500}501
502var tempBuffer strings.Builder503err = temp.Execute(&tempBuffer, inputObj)504if err != nil {505log.Fatalf("Failed Execute %s", err)506}507
508log.Printf("%s", tempBuffer.String())509}
510
511func TestGetSelector(t *testing.T) {512os.Setenv("CONFIGS_PATH", "./configs")513os.Setenv("LOGS_PATH", "./logs")514os.Setenv("TMPDIR", "./logs")515os.Setenv("KBLT_PORT_MAIN", "9998")516os.Setenv("KBLT_PORT_LOG", "9999")517os.Setenv("KBLT_ENABLED_TRIGGER_PREFIX", "true")518
519//noexception520getSelectorKey("simple-key", []string{"value"})521//exception522os.Setenv("KBLT_PREFIX_EXCEPTION", "true")523env.InitEnvWebhookServer()524getSelectorKey("simple-key", []string{"value"})525//istio526os.Setenv("KBLT_PREFIX_EXCEPTION", "true")527env.InitEnvWebhookServer()528getSelectorKey("app", []string{"istiod"})529}
530
531func TestGetNewEmtyObject(t *testing.T) {532lib.ZapLogger = zap.NewNop()533
534ctrl := Mutator{}535obj := ctrl.getNewObject(context.Background(), util.RenderItem{}, nil)536
537if obj != nil {538t.Errorf("should be nil object")539}540}
541
542func TestGetNewBrokenObject(t *testing.T) {543lib.ZapLogger = zap.NewNop()544
545ctrl := Mutator{}546obj := ctrl.getNewObject(context.Background(), util.RenderItem{}, []byte("1"))547
548if obj != nil {549t.Errorf("should be nil object")550}551}
552
553func TestController_getNewObject(t *testing.T) {554lib.ZapLogger = zap.NewNop()555
556type args struct {557templateRender util.RenderItem558raw []byte559}560tests := []struct {561name string562args args
563wantMap bool564}{565{566name: "templateRender.Template.Spec.Location != ''",567args: args{568templateRender: util.RenderItem{569Template: v1alpha1.Template{570Spec: v1alpha1.TemplateSpec{571Location: "location",572},573},574},575raw: []byte("{\"key\": \"value\"}"),576},577wantMap: true,578},579{580name: "error when Unmarshal",581args: args{582templateRender: util.RenderItem{583Render: "1",584},585raw: []byte("{\"key\": \"value\"}"),586},587wantMap: false,588},589{590name: "error when Unmarshal with location",591args: args{592templateRender: util.RenderItem{593Render: "1",594Template: v1alpha1.Template{595Spec: v1alpha1.TemplateSpec{596Location: "location",597},598},599},600raw: []byte("{\"key\": \"value\"}"),601},602wantMap: true,603},604}605for _, tt := range tests {606t.Run(tt.name, func(t *testing.T) {607r := &Mutator{}608got := r.getNewObject(context.Background(), tt.args.templateRender, tt.args.raw)609
610if (got != nil) != tt.wantMap {611t.Errorf("return map required")612}613})614}615}
616