From 2f89cd970d4431beb33adf2d45dd6cf9799ece8b Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Fri, 18 Aug 2023 11:04:01 -0300 Subject: [PATCH 01/12] Collect kube-apiserver audit logs path Signed-off-by: Joao Henri --- .../logging/v1beta1/collector_config_types.go | 6 ++++++ apis/logging/v1beta1/zz_generated.deepcopy.go | 20 +++++++++++++++++++ .../logging.opni.io_collectorconfigs.yaml | 5 +++++ pkg/resources/collector/logging.go | 9 +++++++++ 4 files changed, 40 insertions(+) diff --git a/apis/logging/v1beta1/collector_config_types.go b/apis/logging/v1beta1/collector_config_types.go index 95f7a20982..54014d0775 100644 --- a/apis/logging/v1beta1/collector_config_types.go +++ b/apis/logging/v1beta1/collector_config_types.go @@ -49,6 +49,10 @@ type RKE2Spec struct { LogPath string `json:"logPath,omitempty"` } +type KubeAuditLogsSpec struct { + LogPath string `json:"logPath,omitempty"` +} + // CollectorConfigSpec defines the desired state of CollectorConfig type CollectorConfigSpec struct { // +kubebuilder:validation:Enum:=aks;eks;gke;k3s;rke;rke2;generic @@ -64,6 +68,8 @@ type CollectorConfigSpec struct { K3S *K3SSpec `json:"k3s,omitempty"` RKE *RKESpec `json:"rke,omitempty"` RKE2 *RKE2Spec `json:"rke2,omitempty"` + + KubeAuditLogs *KubeAuditLogsSpec `json:"kubeAuditLogs,omitempty"` } type SelectorConfig struct { diff --git a/apis/logging/v1beta1/zz_generated.deepcopy.go b/apis/logging/v1beta1/zz_generated.deepcopy.go index c54ed61fad..df739512e0 100644 --- a/apis/logging/v1beta1/zz_generated.deepcopy.go +++ b/apis/logging/v1beta1/zz_generated.deepcopy.go @@ -134,6 +134,11 @@ func (in *CollectorConfigSpec) DeepCopyInto(out *CollectorConfigSpec) { *out = new(RKE2Spec) **out = **in } + if in.KubeAuditLogs != nil { + in, out := &in.KubeAuditLogs, &out.KubeAuditLogs + *out = new(KubeAuditLogsSpec) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectorConfigSpec. @@ -354,6 +359,21 @@ func (in *K3SSpec) DeepCopy() *K3SSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeAuditLogsSpec) DeepCopyInto(out *KubeAuditLogsSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeAuditLogsSpec. +func (in *KubeAuditLogsSpec) DeepCopy() *KubeAuditLogsSpec { + if in == nil { + return nil + } + out := new(KubeAuditLogsSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LoggingClusterBinding) DeepCopyInto(out *LoggingClusterBinding) { *out = *in diff --git a/config/crd/bases/logging.opni.io_collectorconfigs.yaml b/config/crd/bases/logging.opni.io_collectorconfigs.yaml index 662ab302dd..be95069cd4 100644 --- a/config/crd/bases/logging.opni.io_collectorconfigs.yaml +++ b/config/crd/bases/logging.opni.io_collectorconfigs.yaml @@ -39,6 +39,11 @@ spec: logPath: type: string type: object + kubeAuditLogs: + properties: + logPath: + type: string + type: object provider: enum: - aks diff --git a/pkg/resources/collector/logging.go b/pkg/resources/collector/logging.go index 8e7e771925..e64100f46b 100644 --- a/pkg/resources/collector/logging.go +++ b/pkg/resources/collector/logging.go @@ -90,6 +90,15 @@ func (r *Reconciler) hostLoggingVolumes() ( }, }, }) + + if config.Spec.KubeAuditLogs != nil && config.Spec.KubeAuditLogs.LogPath != "" { + retVolumeMounts = append(retVolumeMounts, corev1.VolumeMount{ + Name: "kubeauditlogs", + MountPath: config.Spec.KubeAuditLogs.LogPath, + ReadOnly: true, + }) + } + switch config.Spec.Provider { case opniloggingv1beta1.LogProviderRKE: retVolumeMounts = append(retVolumeMounts, corev1.VolumeMount{ From 442d25be19ac5a72f65e86517357fa6c7f460d29 Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Fri, 25 Aug 2023 11:10:02 -0300 Subject: [PATCH 02/12] Generate receiver for kube audit logs Signed-off-by: Joao Henri --- pkg/resources/collector/logging.go | 27 ++++++++++++++++-------- pkg/resources/collector/templates.go | 28 ++++++++++++++++++++----- pkg/resources/collector/workloads.go | 31 +++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 15 deletions(-) diff --git a/pkg/resources/collector/logging.go b/pkg/resources/collector/logging.go index e64100f46b..b5ecef6163 100644 --- a/pkg/resources/collector/logging.go +++ b/pkg/resources/collector/logging.go @@ -8,16 +8,9 @@ import ( "k8s.io/apimachinery/pkg/types" ) -func (r *Reconciler) generateDistributionReceiver() (receiver []string, retBytes []byte, retErr error) { - config := &opniloggingv1beta1.CollectorConfig{} - retErr = r.client.Get(r.ctx, types.NamespacedName{ - Name: r.collector.Spec.LoggingConfig.Name, - Namespace: r.collector.Spec.SystemNamespace, - }, config) - if retErr != nil { - return - } +func (r *Reconciler) generateDistributionReceiver(config *opniloggingv1beta1.CollectorConfig) (receiver []string, retBytes []byte, retErr error) { var providerReceiver bytes.Buffer + switch config.Spec.Provider { case opniloggingv1beta1.LogProviderRKE: return []string{logReceiverRKE}, []byte(templateLogAgentRKE), nil @@ -49,6 +42,22 @@ func (r *Reconciler) generateDistributionReceiver() (receiver []string, retBytes } } +func (r *Reconciler) generateKubeAuditLogsReceiver(config *opniloggingv1beta1.CollectorConfig) (string, []byte, error) { + if config.Spec.KubeAuditLogs != nil && config.Spec.KubeAuditLogs.LogPath != "" { + var receiver bytes.Buffer + + auditLogPath := config.Spec.KubeAuditLogs.LogPath + err := templateKubeAuditLogs.Execute(&receiver, auditLogPath) + if err != nil { + return "", nil, err + } + + return logReceiverKubeAudit, receiver.Bytes(), nil + } + + return "", nil, nil +} + func (r *Reconciler) hostLoggingVolumes() ( retVolumeMounts []corev1.VolumeMount, retVolumes []corev1.Volume, diff --git a/pkg/resources/collector/templates.go b/pkg/resources/collector/templates.go index 200c0f4549..630fa99cff 100644 --- a/pkg/resources/collector/templates.go +++ b/pkg/resources/collector/templates.go @@ -5,11 +5,12 @@ import ( ) const ( - logReceiverK8s = "filelog/k8s" - logReceiverRKE = "filelog/rke" - logReceiverK3s = "journald/k3s" - logReceiverRKE2 = "journald/rke2" - fileLogReceiverRKE2 = "filelog/rke2" + logReceiverK8s = "filelog/k8s" + logReceiverKubeAudit = "filelog/kubeauditlogs" + logReceiverRKE = "filelog/rke" + logReceiverK3s = "journald/k3s" + logReceiverRKE2 = "journald/rke2" + fileLogReceiverRKE2 = "filelog/rke2" ) var ( @@ -101,6 +102,23 @@ journald/k3s: units: [ "k3s" ] directory: {{ . }} `)) + + templateKubeAuditLogs = template.Must(template.New("kubeauditlogsreceiver").Parse(` +filelog/kubeauditlogs: + include: [ /var/log/kube-audit/*.log ] + start_at: beginning + include_file_path: true + operators: + - type: move + from: body + to: attributes.message + - type: add + field: attributes.log_type + value: controlplane + - type: add + field: attributes.kubernetes_component + value: apiserver +`)) templateLogAgentRKE2 = template.Must(template.New("rke2receiver").Parse(` journald/rke2: units: diff --git a/pkg/resources/collector/workloads.go b/pkg/resources/collector/workloads.go index 240e3d8580..8b805531d2 100644 --- a/pkg/resources/collector/workloads.go +++ b/pkg/resources/collector/workloads.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "fmt" + opniloggingv1beta1 "github.com/rancher/opni/apis/logging/v1beta1" monitoringv1beta1 "github.com/rancher/opni/apis/monitoring/v1beta1" "github.com/rancher/opni/pkg/otel" "github.com/rancher/opni/pkg/resources" @@ -14,6 +15,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -78,7 +80,23 @@ func (r *Reconciler) receiverConfig() (retData []byte, retReceivers []string, re retData = append(retData, []byte(templateLogAgentK8sReceiver)...) retReceivers = append(retReceivers, logReceiverK8s) - receiver, data, err := r.generateDistributionReceiver() + config, err := r.fetchCollectorConfig() + if err != nil { + retErr = err + return + } + + auditLogsReceiver, data, err := r.generateKubeAuditLogsReceiver(config) + if err != nil { + retErr = err + return + } + retData = append(retData, data...) + if len(auditLogsReceiver) > 0 { + retReceivers = append(retReceivers, auditLogsReceiver) + } + + receiver, data, err := r.generateDistributionReceiver(config) if err != nil { retErr = err return @@ -97,6 +115,7 @@ func (r *Reconciler) receiverConfig() (retData []byte, retReceivers []string, re } retData = append(retData, data...) } + return } @@ -559,3 +578,13 @@ func (r *Reconciler) configReloaderImageSpec() opnimeta.ImageSpec { }(), }.Resolve() } + +func (r *Reconciler) fetchCollectorConfig() (*opniloggingv1beta1.CollectorConfig, error) { + config := &opniloggingv1beta1.CollectorConfig{} + err := r.client.Get(r.ctx, types.NamespacedName{ + Name: r.collector.Spec.LoggingConfig.Name, + Namespace: r.collector.Spec.SystemNamespace, + }, config) + + return config, err +} From 366ffc63ce956401c174ca049a475e0c3f0cf03d Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Fri, 25 Aug 2023 12:08:21 -0300 Subject: [PATCH 03/12] Add default logpath for kube audit logs Signed-off-by: Joao Henri --- pkg/resources/collector/logging.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pkg/resources/collector/logging.go b/pkg/resources/collector/logging.go index b5ecef6163..0efd0a1d73 100644 --- a/pkg/resources/collector/logging.go +++ b/pkg/resources/collector/logging.go @@ -43,10 +43,14 @@ func (r *Reconciler) generateDistributionReceiver(config *opniloggingv1beta1.Col } func (r *Reconciler) generateKubeAuditLogsReceiver(config *opniloggingv1beta1.CollectorConfig) (string, []byte, error) { - if config.Spec.KubeAuditLogs != nil && config.Spec.KubeAuditLogs.LogPath != "" { - var receiver bytes.Buffer + if config.Spec.KubeAuditLogs != nil { - auditLogPath := config.Spec.KubeAuditLogs.LogPath + auditLogPath := "/var/log/kube-audit" + if config.Spec.KubeAuditLogs.LogPath != "" { + auditLogPath = config.Spec.KubeAuditLogs.LogPath + } + + var receiver bytes.Buffer err := templateKubeAuditLogs.Execute(&receiver, auditLogPath) if err != nil { return "", nil, err From 86565e6edf7a4794cc41ff92dd70f774853fc307 Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Fri, 25 Aug 2023 14:24:23 -0300 Subject: [PATCH 04/12] Fix audit logs mount and enable by default Signed-off-by: Joao Henri --- .../logging/v1beta1/collector_config_types.go | 1 + .../logging.opni.io_collectorconfigs.yaml | 2 ++ pkg/resources/collector/logging.go | 24 +++++++++++++------ .../kubernetes_manager/kubernetes_manager.go | 3 +++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/apis/logging/v1beta1/collector_config_types.go b/apis/logging/v1beta1/collector_config_types.go index 54014d0775..b736e0f79c 100644 --- a/apis/logging/v1beta1/collector_config_types.go +++ b/apis/logging/v1beta1/collector_config_types.go @@ -50,6 +50,7 @@ type RKE2Spec struct { } type KubeAuditLogsSpec struct { + Enabled bool `json:"enabled,omitempty"` LogPath string `json:"logPath,omitempty"` } diff --git a/config/crd/bases/logging.opni.io_collectorconfigs.yaml b/config/crd/bases/logging.opni.io_collectorconfigs.yaml index be95069cd4..016252422a 100644 --- a/config/crd/bases/logging.opni.io_collectorconfigs.yaml +++ b/config/crd/bases/logging.opni.io_collectorconfigs.yaml @@ -41,6 +41,8 @@ spec: type: object kubeAuditLogs: properties: + enabled: + type: boolean logPath: type: string type: object diff --git a/pkg/resources/collector/logging.go b/pkg/resources/collector/logging.go index 0efd0a1d73..724023c1c1 100644 --- a/pkg/resources/collector/logging.go +++ b/pkg/resources/collector/logging.go @@ -43,8 +43,7 @@ func (r *Reconciler) generateDistributionReceiver(config *opniloggingv1beta1.Col } func (r *Reconciler) generateKubeAuditLogsReceiver(config *opniloggingv1beta1.CollectorConfig) (string, []byte, error) { - if config.Spec.KubeAuditLogs != nil { - + if config.Spec.KubeAuditLogs != nil && config.Spec.KubeAuditLogs.Enabled { auditLogPath := "/var/log/kube-audit" if config.Spec.KubeAuditLogs.LogPath != "" { auditLogPath = config.Spec.KubeAuditLogs.LogPath @@ -104,14 +103,25 @@ func (r *Reconciler) hostLoggingVolumes() ( }, }) + kubeAuditLogsDir := "/var/log/kube-audit" if config.Spec.KubeAuditLogs != nil && config.Spec.KubeAuditLogs.LogPath != "" { - retVolumeMounts = append(retVolumeMounts, corev1.VolumeMount{ - Name: "kubeauditlogs", - MountPath: config.Spec.KubeAuditLogs.LogPath, - ReadOnly: true, - }) + kubeAuditLogsDir = config.Spec.KubeAuditLogs.LogPath } + retVolumeMounts = append(retVolumeMounts, corev1.VolumeMount{ + Name: "kubeauditlogs", + MountPath: kubeAuditLogsDir, + ReadOnly: true, + }) + retVolumes = append(retVolumes, corev1.Volume{ + Name: "kubeauditlogs", + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{ + Path: kubeAuditLogsDir, + }, + }, + }) + switch config.Spec.Provider { case opniloggingv1beta1.LogProviderRKE: retVolumeMounts = append(retVolumeMounts, corev1.VolumeMount{ diff --git a/plugins/logging/pkg/agent/drivers/kubernetes_manager/kubernetes_manager.go b/plugins/logging/pkg/agent/drivers/kubernetes_manager/kubernetes_manager.go index 541439c21e..ee2ce87648 100644 --- a/plugins/logging/pkg/agent/drivers/kubernetes_manager/kubernetes_manager.go +++ b/plugins/logging/pkg/agent/drivers/kubernetes_manager/kubernetes_manager.go @@ -152,6 +152,9 @@ func (m *KubernetesManagerDriver) buildLoggingCollectorConfig() *opniloggingv1be }, Spec: opniloggingv1beta1.CollectorConfigSpec{ Provider: opniloggingv1beta1.LogProvider(m.provider), + KubeAuditLogs: &opniloggingv1beta1.KubeAuditLogsSpec{ + Enabled: true, + }, }, } return collectorConfig From f09825cab37e1eba69f5680ab04d3e25d1218b68 Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Fri, 25 Aug 2023 16:03:47 -0300 Subject: [PATCH 05/12] Not include file path for kube audit logs Signed-off-by: Joao Henri --- pkg/resources/collector/templates.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/resources/collector/templates.go b/pkg/resources/collector/templates.go index 630fa99cff..369ac454fc 100644 --- a/pkg/resources/collector/templates.go +++ b/pkg/resources/collector/templates.go @@ -107,7 +107,7 @@ journald/k3s: filelog/kubeauditlogs: include: [ /var/log/kube-audit/*.log ] start_at: beginning - include_file_path: true + include_file_path: false operators: - type: move from: body From 70e7cb120a96b00ce2b42e14320ac88b6b755c78 Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Mon, 28 Aug 2023 10:41:21 -0300 Subject: [PATCH 06/12] Add json parser to kube audit logs collector pipeline Signed-off-by: Joao Henri --- pkg/resources/collector/templates.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pkg/resources/collector/templates.go b/pkg/resources/collector/templates.go index 369ac454fc..f3bc186c90 100644 --- a/pkg/resources/collector/templates.go +++ b/pkg/resources/collector/templates.go @@ -109,9 +109,8 @@ filelog/kubeauditlogs: start_at: beginning include_file_path: false operators: - - type: move - from: body - to: attributes.message + - type: json_parser + if: '$matches "^{.*}$"' - type: add field: attributes.log_type value: controlplane @@ -145,9 +144,6 @@ filelog/rke2: warn: W error: E fatal: F - - type: move - from: body - to: attributes.message - type: add field: attributes.log_type value: controlplane From d4f75504d1c8314c3b9ddee47351aafdd113bc87 Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Mon, 28 Aug 2023 11:13:23 -0300 Subject: [PATCH 07/12] Give ID to json_parser step Signed-off-by: Joao Henri --- pkg/resources/collector/templates.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/resources/collector/templates.go b/pkg/resources/collector/templates.go index f3bc186c90..0a1f97eb8d 100644 --- a/pkg/resources/collector/templates.go +++ b/pkg/resources/collector/templates.go @@ -110,7 +110,7 @@ filelog/kubeauditlogs: include_file_path: false operators: - type: json_parser - if: '$matches "^{.*}$"' + id: parse-body - type: add field: attributes.log_type value: controlplane From 2391902a4420554943592d609a929fb9f7eda38b Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Mon, 28 Aug 2023 17:36:40 -0300 Subject: [PATCH 08/12] Do not include file path or file name Signed-off-by: Joao Henri --- pkg/resources/collector/templates.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/resources/collector/templates.go b/pkg/resources/collector/templates.go index 0a1f97eb8d..a55f02248f 100644 --- a/pkg/resources/collector/templates.go +++ b/pkg/resources/collector/templates.go @@ -108,6 +108,7 @@ filelog/kubeauditlogs: include: [ /var/log/kube-audit/*.log ] start_at: beginning include_file_path: false + include_file_name: false operators: - type: json_parser id: parse-body From 2cd8e9e395eb645a0409546564870adaa9804e55 Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Wed, 30 Aug 2023 17:23:11 -0300 Subject: [PATCH 09/12] Make kube-audit logPath dynamic Signed-off-by: Joao Henri --- pkg/resources/collector/logging.go | 37 +++++++++++++++--- pkg/resources/collector/templates.go | 56 ++++++++++++++++++++++++---- pkg/resources/collector/workloads.go | 6 ++- 3 files changed, 84 insertions(+), 15 deletions(-) diff --git a/pkg/resources/collector/logging.go b/pkg/resources/collector/logging.go index 724023c1c1..51f9356d4e 100644 --- a/pkg/resources/collector/logging.go +++ b/pkg/resources/collector/logging.go @@ -2,6 +2,9 @@ package collector import ( "bytes" + "fmt" + "path/filepath" + "strings" opniloggingv1beta1 "github.com/rancher/opni/apis/logging/v1beta1" corev1 "k8s.io/api/core/v1" @@ -43,19 +46,22 @@ func (r *Reconciler) generateDistributionReceiver(config *opniloggingv1beta1.Col } func (r *Reconciler) generateKubeAuditLogsReceiver(config *opniloggingv1beta1.CollectorConfig) (string, []byte, error) { + var receiver bytes.Buffer + if config.Spec.KubeAuditLogs != nil && config.Spec.KubeAuditLogs.Enabled { - auditLogPath := "/var/log/kube-audit" + filelogDir := "/var/log/kube-audit" + if config.Spec.KubeAuditLogs.LogPath != "" { - auditLogPath = config.Spec.KubeAuditLogs.LogPath + filelogDir = config.Spec.KubeAuditLogs.LogPath } - var receiver bytes.Buffer - err := templateKubeAuditLogs.Execute(&receiver, auditLogPath) + fileGlobPatterns := generateFileGlobPatterns(filelogDir, kubeAuditLogsFileTypes) + err := templateKubeAuditLogs.Execute(&receiver, fileGlobPatterns) if err != nil { return "", nil, err } - return logReceiverKubeAudit, receiver.Bytes(), nil + return logReceiverKubeAuditLogs, receiver.Bytes(), nil } return "", nil, nil @@ -216,3 +222,24 @@ func (r *Reconciler) hostLoggingVolumes() ( } return } + +// generateFileGlobPattern generates a file glob pattern based on the provided path and file type. +// If the path doesn't end with a slash, it appends one before constructing the pattern. +// +// path is the base path for the file glob pattern. fileType is the desired file types to match, +// e.g., [".log", ".json"]. +// +// It returns a single string of the format "[ /foo/*.log, /bar/*.json ]". +func generateFileGlobPatterns(path string, fileTypes []string) string { + if len(path) > 0 && path[len(path)-1] != '/' { + path += "/" + } + + var patterns []string + for _, fileType := range fileTypes { + pattern := filepath.Join(path, fmt.Sprintf("*%s", fileType)) + patterns = append(patterns, pattern) + } + + return fmt.Sprintf("[%s]", strings.Join(patterns, ",")) +} diff --git a/pkg/resources/collector/templates.go b/pkg/resources/collector/templates.go index a55f02248f..41a65b3234 100644 --- a/pkg/resources/collector/templates.go +++ b/pkg/resources/collector/templates.go @@ -5,12 +5,12 @@ import ( ) const ( - logReceiverK8s = "filelog/k8s" - logReceiverKubeAudit = "filelog/kubeauditlogs" - logReceiverRKE = "filelog/rke" - logReceiverK3s = "journald/k3s" - logReceiverRKE2 = "journald/rke2" - fileLogReceiverRKE2 = "filelog/rke2" + logReceiverK8s = "filelog/k8s" + logReceiverKubeAuditLogs = "filelog/kubeauditlogs" + logReceiverRKE = "filelog/rke" + logReceiverK3s = "journald/k3s" + logReceiverRKE2 = "journald/rke2" + fileLogReceiverRKE2 = "filelog/rke2" ) var ( @@ -105,20 +105,50 @@ journald/k3s: templateKubeAuditLogs = template.Must(template.New("kubeauditlogsreceiver").Parse(` filelog/kubeauditlogs: - include: [ /var/log/kube-audit/*.log ] + include: {{ . }} start_at: beginning include_file_path: false include_file_name: false operators: - type: json_parser id: parse-body + timestamp: + parse_from: attributes.stageTimestamp + layout: '%Y-%m-%dT%H:%M:%S.%LZ' - type: add field: attributes.log_type value: controlplane - type: add field: attributes.kubernetes_component - value: apiserver + value: kubeauditlogs + - type: move + from: attributes.stage + to: resource["k8s.auditlog.stage"] + - type: move + from: attributes.stageTimestamp + to: resource["k8s.auditlog.stage_timestamp"] + - type: move + from: attributes.level + to: resource["k8s.auditlog.level"] + - type: move + from: attributes.auditID + to: resource["k8s.auditlog.audit_id"] + - type: move + from: attributes.objectRef.resource + to: resource["k8s.auditlog.resource"] + - type: retain + fields: + - attributes.stage + - attributes.stageTimestamp + - attributes.level + - attributes.auditID + - attributes.objectRef.resource + - attributes.cluster_id + - attributes.time + - attributes.log + - attributes.log_type `)) + templateLogAgentRKE2 = template.Must(template.New("rke2receiver").Parse(` journald/rke2: units: @@ -181,6 +211,16 @@ processors: name: k8s.pod.name - from: resource_attribute name: k8s.namespace.name + - from: resource_attribute + name: k8s.auditlog.stage + - from: resource_attribute + name: k8s.auditlog.stage_timestamp + - from: resource_attribute + name: k8s.auditlog.level + - from: resource_attribute + name: k8s.auditlog.audit_id + - from: resource_attribute + name: k8s.auditlog.resource - sources: - from: connection extract: diff --git a/pkg/resources/collector/workloads.go b/pkg/resources/collector/workloads.go index 8b805531d2..827df5cf55 100644 --- a/pkg/resources/collector/workloads.go +++ b/pkg/resources/collector/workloads.go @@ -40,6 +40,8 @@ const ( var ( directoryOrCreate = corev1.HostPathDirectoryOrCreate + + kubeAuditLogsFileTypes = []string{".log", ".json"} ) func (r *Reconciler) agentConfigMapName() string { @@ -80,7 +82,7 @@ func (r *Reconciler) receiverConfig() (retData []byte, retReceivers []string, re retData = append(retData, []byte(templateLogAgentK8sReceiver)...) retReceivers = append(retReceivers, logReceiverK8s) - config, err := r.fetchCollectorConfig() + config, err := r.fetchLoggingCollectorConfig() if err != nil { retErr = err return @@ -579,7 +581,7 @@ func (r *Reconciler) configReloaderImageSpec() opnimeta.ImageSpec { }.Resolve() } -func (r *Reconciler) fetchCollectorConfig() (*opniloggingv1beta1.CollectorConfig, error) { +func (r *Reconciler) fetchLoggingCollectorConfig() (*opniloggingv1beta1.CollectorConfig, error) { config := &opniloggingv1beta1.CollectorConfig{} err := r.client.Get(r.ctx, types.NamespacedName{ Name: r.collector.Spec.LoggingConfig.Name, From 2d46f2bfba1a0fa208c663ddc92fb35af90ef4f2 Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Wed, 30 Aug 2023 17:39:21 -0300 Subject: [PATCH 10/12] Fix k8sattributes sources Signed-off-by: Joao Henri --- pkg/resources/collector/templates.go | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/pkg/resources/collector/templates.go b/pkg/resources/collector/templates.go index 41a65b3234..ca131eeff5 100644 --- a/pkg/resources/collector/templates.go +++ b/pkg/resources/collector/templates.go @@ -175,6 +175,9 @@ filelog/rke2: warn: W error: E fatal: F + - type: move + from: body + to: attributes.message - type: add field: attributes.log_type value: controlplane @@ -211,16 +214,6 @@ processors: name: k8s.pod.name - from: resource_attribute name: k8s.namespace.name - - from: resource_attribute - name: k8s.auditlog.stage - - from: resource_attribute - name: k8s.auditlog.stage_timestamp - - from: resource_attribute - name: k8s.auditlog.level - - from: resource_attribute - name: k8s.auditlog.audit_id - - from: resource_attribute - name: k8s.auditlog.resource - sources: - from: connection extract: From 46652560398780d56999b945226864a9de87a1bb Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Tue, 12 Sep 2023 09:04:42 -0300 Subject: [PATCH 11/12] Tag audit logs with log_type: audilog Signed-off-by: Joao Henri --- pkg/resources/collector/templates.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/resources/collector/templates.go b/pkg/resources/collector/templates.go index ca131eeff5..4c83451ef5 100644 --- a/pkg/resources/collector/templates.go +++ b/pkg/resources/collector/templates.go @@ -117,7 +117,7 @@ filelog/kubeauditlogs: layout: '%Y-%m-%dT%H:%M:%S.%LZ' - type: add field: attributes.log_type - value: controlplane + value: auditlog - type: add field: attributes.kubernetes_component value: kubeauditlogs From b96a3aefad0af08cb829b5bb235b898baa66788e Mon Sep 17 00:00:00 2001 From: Joao Henri Date: Fri, 15 Sep 2023 12:49:28 -0300 Subject: [PATCH 12/12] Make kubeAuditLogsSpec follow rancher-logging pattern Signed-off-by: Joao Henri --- .../logging/v1beta1/collector_config_types.go | 5 ++- .../logging.opni.io_collectorconfigs.yaml | 4 +- pkg/resources/collector/logging.go | 38 +++++-------------- pkg/resources/collector/templates.go | 2 +- pkg/resources/collector/workloads.go | 6 +-- 5 files changed, 17 insertions(+), 38 deletions(-) diff --git a/apis/logging/v1beta1/collector_config_types.go b/apis/logging/v1beta1/collector_config_types.go index b736e0f79c..8c79661708 100644 --- a/apis/logging/v1beta1/collector_config_types.go +++ b/apis/logging/v1beta1/collector_config_types.go @@ -50,8 +50,9 @@ type RKE2Spec struct { } type KubeAuditLogsSpec struct { - Enabled bool `json:"enabled,omitempty"` - LogPath string `json:"logPath,omitempty"` + Enabled bool `json:"enabled,omitempty"` + AuditFilename string `json:"auditFilename,omitempty"` + PathPrefix string `json:"pathPrefix,omitempty"` } // CollectorConfigSpec defines the desired state of CollectorConfig diff --git a/config/crd/bases/logging.opni.io_collectorconfigs.yaml b/config/crd/bases/logging.opni.io_collectorconfigs.yaml index 016252422a..0773be6590 100644 --- a/config/crd/bases/logging.opni.io_collectorconfigs.yaml +++ b/config/crd/bases/logging.opni.io_collectorconfigs.yaml @@ -41,9 +41,11 @@ spec: type: object kubeAuditLogs: properties: + auditFilename: + type: string enabled: type: boolean - logPath: + pathPrefix: type: string type: object provider: diff --git a/pkg/resources/collector/logging.go b/pkg/resources/collector/logging.go index 51f9356d4e..2ddcf11d4e 100644 --- a/pkg/resources/collector/logging.go +++ b/pkg/resources/collector/logging.go @@ -2,9 +2,7 @@ package collector import ( "bytes" - "fmt" "path/filepath" - "strings" opniloggingv1beta1 "github.com/rancher/opni/apis/logging/v1beta1" corev1 "k8s.io/api/core/v1" @@ -50,13 +48,16 @@ func (r *Reconciler) generateKubeAuditLogsReceiver(config *opniloggingv1beta1.Co if config.Spec.KubeAuditLogs != nil && config.Spec.KubeAuditLogs.Enabled { filelogDir := "/var/log/kube-audit" + if config.Spec.KubeAuditLogs.PathPrefix != "" { + filelogDir = config.Spec.KubeAuditLogs.PathPrefix + } - if config.Spec.KubeAuditLogs.LogPath != "" { - filelogDir = config.Spec.KubeAuditLogs.LogPath + auditLogFilename := "audit.log" + if config.Spec.KubeAuditLogs.AuditFilename != "" { + auditLogFilename = config.Spec.KubeAuditLogs.AuditFilename } - fileGlobPatterns := generateFileGlobPatterns(filelogDir, kubeAuditLogsFileTypes) - err := templateKubeAuditLogs.Execute(&receiver, fileGlobPatterns) + err := templateKubeAuditLogs.Execute(&receiver, filepath.Join(filelogDir, auditLogFilename)) if err != nil { return "", nil, err } @@ -110,8 +111,8 @@ func (r *Reconciler) hostLoggingVolumes() ( }) kubeAuditLogsDir := "/var/log/kube-audit" - if config.Spec.KubeAuditLogs != nil && config.Spec.KubeAuditLogs.LogPath != "" { - kubeAuditLogsDir = config.Spec.KubeAuditLogs.LogPath + if config.Spec.KubeAuditLogs != nil && config.Spec.KubeAuditLogs.PathPrefix != "" { + kubeAuditLogsDir = config.Spec.KubeAuditLogs.PathPrefix } retVolumeMounts = append(retVolumeMounts, corev1.VolumeMount{ @@ -222,24 +223,3 @@ func (r *Reconciler) hostLoggingVolumes() ( } return } - -// generateFileGlobPattern generates a file glob pattern based on the provided path and file type. -// If the path doesn't end with a slash, it appends one before constructing the pattern. -// -// path is the base path for the file glob pattern. fileType is the desired file types to match, -// e.g., [".log", ".json"]. -// -// It returns a single string of the format "[ /foo/*.log, /bar/*.json ]". -func generateFileGlobPatterns(path string, fileTypes []string) string { - if len(path) > 0 && path[len(path)-1] != '/' { - path += "/" - } - - var patterns []string - for _, fileType := range fileTypes { - pattern := filepath.Join(path, fmt.Sprintf("*%s", fileType)) - patterns = append(patterns, pattern) - } - - return fmt.Sprintf("[%s]", strings.Join(patterns, ",")) -} diff --git a/pkg/resources/collector/templates.go b/pkg/resources/collector/templates.go index 4c83451ef5..f24cfd4ee6 100644 --- a/pkg/resources/collector/templates.go +++ b/pkg/resources/collector/templates.go @@ -105,7 +105,7 @@ journald/k3s: templateKubeAuditLogs = template.Must(template.New("kubeauditlogsreceiver").Parse(` filelog/kubeauditlogs: - include: {{ . }} + include: [ {{ . }} ] start_at: beginning include_file_path: false include_file_name: false diff --git a/pkg/resources/collector/workloads.go b/pkg/resources/collector/workloads.go index 827df5cf55..5d9ea7c48a 100644 --- a/pkg/resources/collector/workloads.go +++ b/pkg/resources/collector/workloads.go @@ -38,11 +38,7 @@ const ( machineID = "/etc/machine-id" ) -var ( - directoryOrCreate = corev1.HostPathDirectoryOrCreate - - kubeAuditLogsFileTypes = []string{".log", ".json"} -) +var directoryOrCreate = corev1.HostPathDirectoryOrCreate func (r *Reconciler) agentConfigMapName() string { return fmt.Sprintf("%s-agent-config", r.collector.Name)