From 1bfb739230a6c38588ebed4440e9566b9c076e6d Mon Sep 17 00:00:00 2001 From: Afra Abnar <122131693+ti-afra@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:18:24 -0800 Subject: [PATCH 1/3] expose logLevel in apiserver manifest for its containers --- api/v1/apiserver_types.go | 5 +++ api/v1/zz_generated.deepcopy.go | 5 +++ .../operator.tigera.io_apiservers.yaml | 10 +++++ pkg/render/apiserver.go | 38 ++++++++++++++++++- pkg/render/apiserver_test.go | 37 ++++++++++-------- 5 files changed, 78 insertions(+), 17 deletions(-) diff --git a/api/v1/apiserver_types.go b/api/v1/apiserver_types.go index e3ff08611a..9a82d76305 100644 --- a/api/v1/apiserver_types.go +++ b/api/v1/apiserver_types.go @@ -86,6 +86,11 @@ type APIServerDeploymentContainer struct { // If used in conjunction with the deprecated ComponentResources, then this value takes precedence. // +optional Resources *v1.ResourceRequirements `json:"resources,omitempty"` + + // +kubebuilder:validation:Enum=Fatal;Error;Warn;Info;Debug;Trace + // +kubebuilder:default=Info + // +optional + LogLevel *string `json:"logLevel,omitempty"` } // APIServerDeploymentInitContainer is an API server Deployment init container. diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 349d18bb57..69307ba009 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -88,6 +88,11 @@ func (in *APIServerDeploymentContainer) DeepCopyInto(out *APIServerDeploymentCon *out = new(corev1.ResourceRequirements) (*in).DeepCopyInto(*out) } + if in.LogLevel != nil { + in, out := &in.LogLevel, &out.LogLevel + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServerDeploymentContainer. diff --git a/pkg/crds/operator/operator.tigera.io_apiservers.yaml b/pkg/crds/operator/operator.tigera.io_apiservers.yaml index 6043c4ce65..e3730a8d49 100644 --- a/pkg/crds/operator/operator.tigera.io_apiservers.yaml +++ b/pkg/crds/operator/operator.tigera.io_apiservers.yaml @@ -1068,6 +1068,16 @@ spec: description: APIServerDeploymentContainer is an API server Deployment container. properties: + logLevel: + default: Info + enum: + - Fatal + - Error + - Warn + - Info + - Debug + - Trace + type: string name: description: |- Name is an enum which identifies the API server Deployment container by name. diff --git a/pkg/render/apiserver.go b/pkg/render/apiserver.go index fd83a1df75..b1e78a7f34 100644 --- a/pkg/render/apiserver.go +++ b/pkg/render/apiserver.go @@ -1193,6 +1193,24 @@ func (c *apiServerComponent) apiServerContainer() corev1.Container { env = append(env, c.cfg.K8SServiceEndpoint.EnvVars(c.hostNetwork(), c.cfg.Installation.KubernetesProvider)...) + // set Log_LEVEL for apiserver container + if c.cfg.APIServer.APIServerDeployment != nil && c.cfg.APIServer.APIServerDeployment.Spec != nil && + c.cfg.APIServer.APIServerDeployment.Spec.Template != nil && + c.cfg.APIServer.APIServerDeployment.Spec.Template.Spec != nil && + c.cfg.APIServer.APIServerDeployment.Spec.Template.Spec.Containers != nil { + containers := c.cfg.APIServer.APIServerDeployment.Spec.Template.Spec.Containers + for _, con := range containers { + if strings.Contains(con.Name, "apiserver") { + if logLevel := con.LogLevel; logLevel != nil { + env = append(env, corev1.EnvVar{Name: "LOG_LEVEL", Value: strings.ToLower(*logLevel)}) + } + } + } + } else { + // set default LOG_LEVEL to info when not set by the user + env = append(env, corev1.EnvVar{Name: "LOG_LEVEL", Value: "info"}) + } + if c.cfg.Installation.CalicoNetwork != nil && c.cfg.Installation.CalicoNetwork.MultiInterfaceMode != nil { env = append(env, corev1.EnvVar{Name: "MULTI_INTERFACE_MODE", Value: c.cfg.Installation.CalicoNetwork.MultiInterfaceMode.Value()}) } @@ -1263,8 +1281,6 @@ func (c *apiServerComponent) startUpArgs() []string { // queryServerContainer creates the query server container. func (c *apiServerComponent) queryServerContainer() corev1.Container { env := []corev1.EnvVar{ - // Set queryserver logging to "info" - {Name: "LOGLEVEL", Value: "info"}, {Name: "DATASTORE_TYPE", Value: "kubernetes"}, {Name: "LISTEN_ADDR", Value: fmt.Sprintf(":%d", QueryServerPort)}, {Name: "TLS_CERT", Value: fmt.Sprintf("/%s/tls.crt", ProjectCalicoAPIServerTLSSecretName(c.cfg.Installation.Variant))}, @@ -1284,6 +1300,24 @@ func (c *apiServerComponent) queryServerContainer() corev1.Container { env = append(env, c.cfg.KeyValidatorConfig.RequiredEnv("")...) } + // set Log_LEVEL for queryserver container + if c.cfg.APIServer.APIServerDeployment != nil && c.cfg.APIServer.APIServerDeployment.Spec != nil && + c.cfg.APIServer.APIServerDeployment.Spec.Template != nil && + c.cfg.APIServer.APIServerDeployment.Spec.Template.Spec != nil && + c.cfg.APIServer.APIServerDeployment.Spec.Template.Spec.Containers != nil { + containers := c.cfg.APIServer.APIServerDeployment.Spec.Template.Spec.Containers + for _, con := range containers { + if strings.Contains(con.Name, "queryserver") { + if logLevel := con.LogLevel; logLevel != nil { + env = append(env, corev1.EnvVar{Name: "LOGLEVEL", Value: strings.ToLower(*logLevel)}) + } + } + } + } else { + // set default LOGLEVEL to info when not set by the user + env = append(env, corev1.EnvVar{Name: "LOGLEVEL", Value: "info"}) + } + volumeMounts := []corev1.VolumeMount{ c.cfg.TLSKeyPair.VolumeMount(c.SupportedOSType()), } diff --git a/pkg/render/apiserver_test.go b/pkg/render/apiserver_test.go index 64575873ca..095bba537b 100644 --- a/pkg/render/apiserver_test.go +++ b/pkg/render/apiserver_test.go @@ -222,10 +222,13 @@ var _ = Describe("API server rendering tests (Calico Enterprise)", func() { "--audit-log-path=/var/log/calico/audit/tsee-audit.log", } Expect(d.Spec.Template.Spec.Containers[0].Args).To(ConsistOf(expectedArgs)) - Expect(len(d.Spec.Template.Spec.Containers[0].Env)).To(Equal(1)) + Expect(len(d.Spec.Template.Spec.Containers[0].Env)).To(Equal(2)) Expect(d.Spec.Template.Spec.Containers[0].Env[0].Name).To(Equal("DATASTORE_TYPE")) Expect(d.Spec.Template.Spec.Containers[0].Env[0].Value).To(Equal("kubernetes")) Expect(d.Spec.Template.Spec.Containers[0].Env[0].ValueFrom).To(BeNil()) + Expect(d.Spec.Template.Spec.Containers[0].Env[1].Name).To(Equal("LOG_LEVEL")) + Expect(d.Spec.Template.Spec.Containers[0].Env[1].Value).To(Equal("info")) + Expect(d.Spec.Template.Spec.Containers[0].Env[1].ValueFrom).To(BeNil()) Expect(len(d.Spec.Template.Spec.Containers[0].VolumeMounts)).To(Equal(3)) Expect(d.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name).To(Equal("tigera-apiserver-certs")) @@ -259,23 +262,24 @@ var _ = Describe("API server rendering tests (Calico Enterprise)", func() { Expect(d.Spec.Template.Spec.Containers[1].Args).To(BeEmpty()) Expect(d.Spec.Template.Spec.Containers[1].Env).To(HaveLen(6)) - Expect(d.Spec.Template.Spec.Containers[1].Env[0].Name).To(Equal("LOGLEVEL")) - Expect(d.Spec.Template.Spec.Containers[1].Env[0].Value).To(Equal("info")) + + Expect(d.Spec.Template.Spec.Containers[1].Env[0].Name).To(Equal("DATASTORE_TYPE")) + Expect(d.Spec.Template.Spec.Containers[1].Env[0].Value).To(Equal("kubernetes")) Expect(d.Spec.Template.Spec.Containers[1].Env[0].ValueFrom).To(BeNil()) - Expect(d.Spec.Template.Spec.Containers[1].Env[1].Name).To(Equal("DATASTORE_TYPE")) - Expect(d.Spec.Template.Spec.Containers[1].Env[1].Value).To(Equal("kubernetes")) + Expect(d.Spec.Template.Spec.Containers[1].Env[1].Name).To(Equal("LISTEN_ADDR")) + Expect(d.Spec.Template.Spec.Containers[1].Env[1].Value).To(Equal(":8080")) Expect(d.Spec.Template.Spec.Containers[1].Env[1].ValueFrom).To(BeNil()) - Expect(d.Spec.Template.Spec.Containers[1].Env[2].Name).To(Equal("LISTEN_ADDR")) - Expect(d.Spec.Template.Spec.Containers[1].Env[2].Value).To(Equal(":8080")) + Expect(d.Spec.Template.Spec.Containers[1].Env[2].Name).To(Equal("TLS_CERT")) + Expect(d.Spec.Template.Spec.Containers[1].Env[2].Value).To(Equal("/tigera-apiserver-certs/tls.crt")) Expect(d.Spec.Template.Spec.Containers[1].Env[2].ValueFrom).To(BeNil()) - Expect(d.Spec.Template.Spec.Containers[1].Env[3].Name).To(Equal("TLS_CERT")) - Expect(d.Spec.Template.Spec.Containers[1].Env[3].Value).To(Equal("/tigera-apiserver-certs/tls.crt")) + Expect(d.Spec.Template.Spec.Containers[1].Env[3].Name).To(Equal("TLS_KEY")) + Expect(d.Spec.Template.Spec.Containers[1].Env[3].Value).To(Equal("/tigera-apiserver-certs/tls.key")) Expect(d.Spec.Template.Spec.Containers[1].Env[3].ValueFrom).To(BeNil()) - Expect(d.Spec.Template.Spec.Containers[1].Env[4].Name).To(Equal("TLS_KEY")) - Expect(d.Spec.Template.Spec.Containers[1].Env[4].Value).To(Equal("/tigera-apiserver-certs/tls.key")) - Expect(d.Spec.Template.Spec.Containers[1].Env[4].ValueFrom).To(BeNil()) - Expect(d.Spec.Template.Spec.Containers[1].Env[5].Name).To(Equal("TRUSTED_BUNDLE_PATH")) - Expect(d.Spec.Template.Spec.Containers[1].Env[5].Value).To(Equal("/etc/pki/tls/certs/tigera-ca-bundle.crt")) + Expect(d.Spec.Template.Spec.Containers[1].Env[4].Name).To(Equal("TRUSTED_BUNDLE_PATH")) + Expect(d.Spec.Template.Spec.Containers[1].Env[4].Value).To(Equal("/etc/pki/tls/certs/tigera-ca-bundle.crt")) + Expect(d.Spec.Template.Spec.Containers[1].Env[5].Name).To(Equal("LOGLEVEL")) + Expect(d.Spec.Template.Spec.Containers[1].Env[5].Value).To(Equal("info")) + Expect(d.Spec.Template.Spec.Containers[1].Env[5].ValueFrom).To(BeNil()) // Expect the SECURITY_GROUP env variables to not be set Expect(d.Spec.Template.Spec.Containers[1].Env).NotTo(ContainElement(gstruct.MatchFields(gstruct.IgnoreExtras, gstruct.Fields{"Name": Equal("TIGERA_DEFAULT_SECURITY_GROUPS")}))) @@ -1678,10 +1682,13 @@ var _ = Describe("API server rendering tests (Calico)", func() { "--tls-cert-file=/calico-apiserver-certs/tls.crt", } Expect(d.Spec.Template.Spec.Containers[0].Args).To(ConsistOf(expectedArgs)) - Expect(len(d.Spec.Template.Spec.Containers[0].Env)).To(Equal(1)) + Expect(len(d.Spec.Template.Spec.Containers[0].Env)).To(Equal(2)) Expect(d.Spec.Template.Spec.Containers[0].Env[0].Name).To(Equal("DATASTORE_TYPE")) Expect(d.Spec.Template.Spec.Containers[0].Env[0].Value).To(Equal("kubernetes")) Expect(d.Spec.Template.Spec.Containers[0].Env[0].ValueFrom).To(BeNil()) + Expect(d.Spec.Template.Spec.Containers[0].Env[1].Name).To(Equal("LOG_LEVEL")) + Expect(d.Spec.Template.Spec.Containers[0].Env[1].Value).To(Equal("info")) + Expect(d.Spec.Template.Spec.Containers[0].Env[1].ValueFrom).To(BeNil()) Expect(len(d.Spec.Template.Spec.Containers[0].VolumeMounts)).To(Equal(1)) From 853adca607ad97190efcf31d49e4d979db52008a Mon Sep 17 00:00:00 2001 From: Afra Abnar <122131693+ti-afra@users.noreply.github.com> Date: Tue, 17 Dec 2024 11:43:07 -0800 Subject: [PATCH 2/3] fix unstable gomega match for large nested dex policies gomega Expect was not able to compare correctly the dex policies and would fail when running in "Run" mode but pass when running in "Debug" mode. It was also passing when we print the values before the Expect().To() call. To fix this, we convert the larger and nested struct to String and compare the string values. --- pkg/render/dex_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/render/dex_test.go b/pkg/render/dex_test.go index 172b487623..c33b99b54b 100644 --- a/pkg/render/dex_test.go +++ b/pkg/render/dex_test.go @@ -15,6 +15,7 @@ package render_test import ( + "encoding/json" "fmt" . "github.com/onsi/ginkgo" @@ -526,7 +527,9 @@ var _ = Describe("dex rendering tests", func() { policy := testutils.GetAllowTigeraPolicyFromResources(policyName, resources) expectedPolicy := getExpectedPolicy(scenario) - Expect(policy).To(Equal(expectedPolicy)) + policyJ, _ := json.Marshal(policy) + expectedPolicyJ, _ := json.Marshal(expectedPolicy) + Expect(string(policyJ)).To(Equal(string(expectedPolicyJ))) }, // Dex only renders in the presence of an Authentication CR, therefore does not have a config option for managed clusters. Entry("for management/standalone, kube-dns", testutils.AllowTigeraScenario{ManagedCluster: false, OpenShift: false}), From ff05e28e885faacfac12a77e3295c700c670f639 Mon Sep 17 00:00:00 2001 From: Afra Abnar <122131693+ti-afra@users.noreply.github.com> Date: Tue, 17 Dec 2024 13:20:13 -0800 Subject: [PATCH 3/3] update crd: securityeventwebhooks --- .../crd.projectcalico.org_securityeventwebhooks.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/crds/enterprise/crd.projectcalico.org_securityeventwebhooks.yaml b/pkg/crds/enterprise/crd.projectcalico.org_securityeventwebhooks.yaml index 7bb44f826c..7714972c41 100644 --- a/pkg/crds/enterprise/crd.projectcalico.org_securityeventwebhooks.yaml +++ b/pkg/crds/enterprise/crd.projectcalico.org_securityeventwebhooks.yaml @@ -97,7 +97,7 @@ spec: type: array consumer: description: 'indicates the SecurityEventWebhook intended consumer, - one of: Slack, Jira' + one of: Slack, Jira, Generic, AlertManager' type: string query: description: defines the SecurityEventWebhook query to be executed @@ -105,7 +105,7 @@ spec: type: string state: description: 'defines the webhook desired state, one of: Enabled, - Disabled or Debug' + Disabled, Test or Debug' type: string required: - config