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/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 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)) 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}),