diff --git a/deployments/helm/KubeArmorOperator/crds/operator.kubearmor.com_kubearmorconfigs.yaml b/deployments/helm/KubeArmorOperator/crds/operator.kubearmor.com_kubearmorconfigs.yaml index f2d2b6251..e5a5fe122 100644 --- a/deployments/helm/KubeArmorOperator/crds/operator.kubearmor.com_kubearmorconfigs.yaml +++ b/deployments/helm/KubeArmorOperator/crds/operator.kubearmor.com_kubearmorconfigs.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.5 name: kubearmorconfigs.operator.kubearmor.com spec: group: operator.kubearmor.com @@ -43,6 +43,27 @@ spec: spec: description: KubeArmorConfigSpec defines the desired state of KubeArmorConfig properties: + adapters: + properties: + elasticsearch: + properties: + alertsIndex: + type: string + auth: + properties: + passwordKey: + type: string + secretName: + type: string + usernameKey: + type: string + type: object + enabled: + type: boolean + url: + type: string + type: object + type: object alertThrottling: type: boolean defaultCapabilitiesPosture: diff --git a/deployments/operator/operator.yaml b/deployments/operator/operator.yaml index 93bd2bc61..21c6a9faa 100644 --- a/deployments/operator/operator.yaml +++ b/deployments/operator/operator.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.5 name: kubearmorconfigs.operator.kubearmor.com spec: group: operator.kubearmor.com @@ -42,6 +42,27 @@ spec: spec: description: KubeArmorConfigSpec defines the desired state of KubeArmorConfig properties: + adapters: + properties: + elasticsearch: + properties: + alertsIndex: + type: string + auth: + properties: + passwordKey: + type: string + secretName: + type: string + usernameKey: + type: string + type: object + enabled: + type: boolean + url: + type: string + type: object + type: object alertThrottling: type: boolean defaultCapabilitiesPosture: diff --git a/pkg/KubeArmorOperator/api/operator.kubearmor.com/v1/kubearmorconfig_types.go b/pkg/KubeArmorOperator/api/operator.kubearmor.com/v1/kubearmorconfig_types.go index abe45ac35..b2185f469 100644 --- a/pkg/KubeArmorOperator/api/operator.kubearmor.com/v1/kubearmorconfig_types.go +++ b/pkg/KubeArmorOperator/api/operator.kubearmor.com/v1/kubearmorconfig_types.go @@ -39,6 +39,23 @@ type RecommendedPolicies struct { ExcludePolicy []string `json:"excludePolicy,omitempty"` } +type ElasticSearchAuth struct { + SecretName string `json:"secretName,omitempty"` + UserNameKey string `json:"usernameKey,omitempty"` + PasswordKey string `json:"passwordKey,omitempty"` +} + +type ElasticSearchAdapter struct { + Enabled bool `json:"enabled,omitempty"` + Url string `json:"url,omitempty"` + AlertsIndexName string `json:"alertsIndex,omitempty"` + Auth ElasticSearchAuth `json:"auth,omitempty"` +} + +type Adapters struct { + ElasticSearch ElasticSearchAdapter `json:"elasticsearch,omitempty"` +} + // KubeArmorConfigSpec defines the desired state of KubeArmorConfig type KubeArmorConfigSpec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster @@ -80,6 +97,8 @@ type KubeArmorConfigSpec struct { MaxAlertPerSec int `json:"maxAlertPerSec,omitempty"` // +kubebuilder:validation:Optional ThrottleSec int `json:"throttleSec,omitempty"` + // +kubebuilder:validation:Optional + Adapters Adapters `json:"adapters,omitempty"` } // KubeArmorConfigStatus defines the observed state of KubeArmorConfig diff --git a/pkg/KubeArmorOperator/api/operator.kubearmor.com/v1/zz_generated.deepcopy.go b/pkg/KubeArmorOperator/api/operator.kubearmor.com/v1/zz_generated.deepcopy.go index 01d594de5..c73836350 100644 --- a/pkg/KubeArmorOperator/api/operator.kubearmor.com/v1/zz_generated.deepcopy.go +++ b/pkg/KubeArmorOperator/api/operator.kubearmor.com/v1/zz_generated.deepcopy.go @@ -12,6 +12,53 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Adapters) DeepCopyInto(out *Adapters) { + *out = *in + out.ElasticSearch = in.ElasticSearch +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Adapters. +func (in *Adapters) DeepCopy() *Adapters { + if in == nil { + return nil + } + out := new(Adapters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ElasticSearchAdapter) DeepCopyInto(out *ElasticSearchAdapter) { + *out = *in + out.Auth = in.Auth +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ElasticSearchAdapter. +func (in *ElasticSearchAdapter) DeepCopy() *ElasticSearchAdapter { + if in == nil { + return nil + } + out := new(ElasticSearchAdapter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ElasticSearchAuth) DeepCopyInto(out *ElasticSearchAuth) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ElasticSearchAuth. +func (in *ElasticSearchAuth) DeepCopy() *ElasticSearchAuth { + if in == nil { + return nil + } + out := new(ElasticSearchAuth) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImageSpec) DeepCopyInto(out *ImageSpec) { *out = *in @@ -96,6 +143,7 @@ func (in *KubeArmorConfigSpec) DeepCopyInto(out *KubeArmorConfigSpec) { out.KubeArmorControllerImage = in.KubeArmorControllerImage out.KubeRbacProxyImage = in.KubeRbacProxyImage in.Tls.DeepCopyInto(&out.Tls) + out.Adapters = in.Adapters } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeArmorConfigSpec. diff --git a/pkg/KubeArmorOperator/common/defaults.go b/pkg/KubeArmorOperator/common/defaults.go index 970780653..6d4d7c8fa 100644 --- a/pkg/KubeArmorOperator/common/defaults.go +++ b/pkg/KubeArmorOperator/common/defaults.go @@ -139,7 +139,21 @@ var ( }, }, } + + Adapter opv1.Adapters = opv1.Adapters{ + ElasticSearch: opv1.ElasticSearchAdapter{ + Enabled: false, + Url: "", + AlertsIndexName: "kubearmor-alerts", + Auth: opv1.ElasticSearchAuth{ + SecretName: "", + UserNameKey: "username", + PasswordKey: "password", + }, + }, + } ) +var Pointer2True bool = true var ConfigMapData = map[string]string{ ConfigGRPC: "32767", diff --git a/pkg/KubeArmorOperator/config/crd/bases/operator.kubearmor.com_kubearmorconfigs.yaml b/pkg/KubeArmorOperator/config/crd/bases/operator.kubearmor.com_kubearmorconfigs.yaml index f2d2b6251..e5a5fe122 100644 --- a/pkg/KubeArmorOperator/config/crd/bases/operator.kubearmor.com_kubearmorconfigs.yaml +++ b/pkg/KubeArmorOperator/config/crd/bases/operator.kubearmor.com_kubearmorconfigs.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.5 name: kubearmorconfigs.operator.kubearmor.com spec: group: operator.kubearmor.com @@ -43,6 +43,27 @@ spec: spec: description: KubeArmorConfigSpec defines the desired state of KubeArmorConfig properties: + adapters: + properties: + elasticsearch: + properties: + alertsIndex: + type: string + auth: + properties: + passwordKey: + type: string + secretName: + type: string + usernameKey: + type: string + type: object + enabled: + type: boolean + url: + type: string + type: object + type: object alertThrottling: type: boolean defaultCapabilitiesPosture: diff --git a/pkg/KubeArmorOperator/internal/controller/cluster.go b/pkg/KubeArmorOperator/internal/controller/cluster.go index 9725d2f9f..4d2ef3b7e 100644 --- a/pkg/KubeArmorOperator/internal/controller/cluster.go +++ b/pkg/KubeArmorOperator/internal/controller/cluster.go @@ -472,6 +472,42 @@ func (clusterWatcher *ClusterWatcher) UpdateKubearmorRelayEnv(cfg *opv1.KubeArmo Name: "ENABLE_STDOUT_MSGS", Value: common.KubearmorRelayEnvMap[common.EnableStdOutMsgs], }, + { + Name: "ENABLE_DASHBOARDS", + Value: strconv.FormatBool(common.Adapter.ElasticSearch.Enabled), + }, + { + Name: "ES_URL", + Value: common.Adapter.ElasticSearch.Url, + }, + { + Name: "ES_ALERTS_INDEX", + Value: common.Adapter.ElasticSearch.AlertsIndexName, + }, + { + Name: "ES_USERNAME", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.Adapter.ElasticSearch.Auth.SecretName, + }, + Key: common.Adapter.ElasticSearch.Auth.UserNameKey, + Optional: &common.Pointer2True, + }, + }, + }, + { + Name: "ES_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.Adapter.ElasticSearch.Auth.SecretName, + }, + Key: common.Adapter.ElasticSearch.Auth.PasswordKey, + Optional: &common.Pointer2True, + }, + }, + }, } _, err = clusterWatcher.Client.AppsV1().Deployments(common.Namespace).Update(context.Background(), relay, v1.UpdateOptions{}) if err != nil { @@ -955,6 +991,34 @@ func UpdatedKubearmorRelayEnv(config *opv1.KubeArmorConfigSpec) bool { updated = true } } + + stringEnableElasticAdapter := strconv.FormatBool(config.Adapters.ElasticSearch.Enabled) + if stringEnableElasticAdapter != "" { + if common.Adapter.ElasticSearch.Enabled != config.Adapters.ElasticSearch.Enabled { + updated = true + common.Adapter.ElasticSearch.Enabled = config.Adapters.ElasticSearch.Enabled + } + if common.Adapter.ElasticSearch.AlertsIndexName != config.Adapters.ElasticSearch.AlertsIndexName { + updated = true + common.Adapter.ElasticSearch.AlertsIndexName = config.Adapters.ElasticSearch.AlertsIndexName + } + if common.Adapter.ElasticSearch.Url != config.Adapters.ElasticSearch.Url { + updated = true + common.Adapter.ElasticSearch.Url = config.Adapters.ElasticSearch.Url + } + if common.Adapter.ElasticSearch.Auth.SecretName != config.Adapters.ElasticSearch.Auth.SecretName { + updated = true + common.Adapter.ElasticSearch.Auth.SecretName = config.Adapters.ElasticSearch.Auth.SecretName + } + if common.Adapter.ElasticSearch.Auth.UserNameKey != config.Adapters.ElasticSearch.Auth.UserNameKey { + updated = true + common.Adapter.ElasticSearch.Auth.UserNameKey = config.Adapters.ElasticSearch.Auth.UserNameKey + } + if common.Adapter.ElasticSearch.Auth.PasswordKey != config.Adapters.ElasticSearch.Auth.PasswordKey { + updated = true + common.Adapter.ElasticSearch.Auth.PasswordKey = config.Adapters.ElasticSearch.Auth.PasswordKey + } + } return updated } diff --git a/pkg/KubeArmorOperator/internal/controller/resources.go b/pkg/KubeArmorOperator/internal/controller/resources.go index b4b8f2208..b51705205 100644 --- a/pkg/KubeArmorOperator/internal/controller/resources.go +++ b/pkg/KubeArmorOperator/internal/controller/resources.go @@ -7,6 +7,7 @@ import ( "bytes" "context" "fmt" + "strconv" "strings" "time" @@ -533,7 +534,6 @@ func (clusterWatcher *ClusterWatcher) WatchRequiredResources() { // kubearmor-controller and relay-server deployments controller := deployments.GetKubeArmorControllerDeployment(common.Namespace) relayServer := deployments.GetRelayDeployment(common.Namespace) - // update relay env vars relayServer.Spec.Template.Spec.Containers[0].Env = []corev1.EnvVar{ { @@ -548,6 +548,42 @@ func (clusterWatcher *ClusterWatcher) WatchRequiredResources() { Name: "ENABLE_STDOUT_MSGS", Value: common.KubearmorRelayEnvMap[common.EnableStdOutMsgs], }, + { + Name: "ENABLE_DASHBOARDS", + Value: strconv.FormatBool(common.Adapter.ElasticSearch.Enabled), + }, + { + Name: "ES_URL", + Value: common.Adapter.ElasticSearch.Url, + }, + { + Name: "ES_ALERTS_INDEX", + Value: common.Adapter.ElasticSearch.AlertsIndexName, + }, + { + Name: "ES_USERNAME", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.Adapter.ElasticSearch.Auth.SecretName, + }, + Key: common.Adapter.ElasticSearch.Auth.UserNameKey, + Optional: &common.Pointer2True, + }, + }, + }, + { + Name: "ES_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.Adapter.ElasticSearch.Auth.SecretName, + }, + Key: common.Adapter.ElasticSearch.Auth.PasswordKey, + Optional: &common.Pointer2True, + }, + }, + }, } if common.EnableTls {