diff --git a/images/virtualization-artifact/pkg/audit/events/forbid/forbid.go b/images/virtualization-artifact/pkg/audit/events/forbid/forbid.go index 2695f1e830..e3b2ea4179 100644 --- a/images/virtualization-artifact/pkg/audit/events/forbid/forbid.go +++ b/images/virtualization-artifact/pkg/audit/events/forbid/forbid.go @@ -60,6 +60,11 @@ func (m *Forbid) IsMatched() bool { return false } + if strings.HasPrefix(m.event.User.Username, "system:") && + !strings.HasPrefix(m.event.User.Username, "system:serviceaccount:d8-service-accounts") { + return false + } + if m.event.Annotations[annotations.AnnAuditDecision] == "forbid" { return true } @@ -82,7 +87,7 @@ func (m *Forbid) Fill() error { } m.eventLog.Name = fmt.Sprintf( - "User (%s) attempted to perform a forbidden operation (%s) on resource (%s).", + "User '%s' attempted to perform a forbidden operation '%s' on resource '%s'.", m.event.User.Username, m.event.Verb, resource) diff --git a/images/virtualization-artifact/pkg/audit/events/forbid/forbid_test.go b/images/virtualization-artifact/pkg/audit/events/forbid/forbid_test.go index b86226a3a5..94d0906873 100644 --- a/images/virtualization-artifact/pkg/audit/events/forbid/forbid_test.go +++ b/images/virtualization-artifact/pkg/audit/events/forbid/forbid_test.go @@ -168,7 +168,7 @@ var _ = Describe("Forbid Events", func() { Expect(eventLog.eventLog.Type).To(Equal("Forbidden operation")) Expect(eventLog.eventLog.Level).To(Equal("warn")) - Expect(eventLog.eventLog.Name).To(Equal("User (test-user) attempted to perform a forbidden operation (create) on resource (pods/test/test-vmi).")) + Expect(eventLog.eventLog.Name).To(Equal("User 'test-user' attempted to perform a forbidden operation 'create' on resource 'pods/test/test-vmi'.")) Expect(eventLog.eventLog.Datetime).To(Equal(currentTime.Format(time.RFC3339))) Expect(eventLog.eventLog.UID).To(Equal("0000-0000-0000")) diff --git a/images/virtualization-artifact/pkg/audit/events/integrity/integrity_check_vm.go b/images/virtualization-artifact/pkg/audit/events/integrity/integrity_check_vm.go index af26c0303c..a837e44873 100644 --- a/images/virtualization-artifact/pkg/audit/events/integrity/integrity_check_vm.go +++ b/images/virtualization-artifact/pkg/audit/events/integrity/integrity_check_vm.go @@ -18,6 +18,7 @@ package integrity import ( "fmt" + "strings" "k8s.io/apiserver/pkg/apis/audit" @@ -54,6 +55,11 @@ func (m *IntegrityCheckVM) IsMatched() bool { return false } + if strings.HasPrefix(m.event.User.Username, "system:") && + !strings.HasPrefix(m.event.User.Username, "system:serviceaccount:d8-service-accounts") { + return false + } + if (m.event.Verb == "patch" || m.event.Verb == "update") && m.event.ObjectRef.Resource == "internalvirtualizationvirtualmachineinstances" { return true } @@ -64,25 +70,25 @@ func (m *IntegrityCheckVM) IsMatched() bool { func (m *IntegrityCheckVM) Fill() error { m.eventLog = NewIntegrityCheckEventLog(m.event) - m.eventLog.Name = "VM config integrity check failed" + vmi, err := util.GetInternalVMIFromInformer(m.ttlCache, m.informerList.GetInternalVMIInformer(), m.event.ObjectRef.Namespace+"/"+m.event.ObjectRef.Name) + if err != nil { + return fmt.Errorf("failed to get VMI from informer: %w", err) + } + + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' config integrity check failed", vmi.Name) m.eventLog.ObjectType = "Virtual machine configuration" m.eventLog.ControlMethod = "Integrity Check" m.eventLog.ReactionType = "info" m.eventLog.IntegrityCheckAlgo = "sha256" - vmi, err := util.GetInternalVMIFromInformer(m.ttlCache, m.informerList.GetInternalVMIInformer(), m.event.ObjectRef.Namespace+"/"+m.event.ObjectRef.Name) - if err != nil { - return fmt.Errorf("failed to get VMI from informer: %w", err) - } + m.eventLog.VirtualMachineName = vmi.Name + m.eventLog.ReferenceChecksum = vmi.Annotations[annotations.AnnIntegrityCoreChecksum] + m.eventLog.CurrentChecksum = vmi.Annotations[annotations.AnnIntegrityCoreChecksumApplied] if vmi.Annotations[annotations.AnnIntegrityCoreChecksum] == vmi.Annotations[annotations.AnnIntegrityCoreChecksumApplied] { m.eventLog.shouldLog = false return nil } - m.eventLog.VirtualMachineName = vmi.Name - m.eventLog.ReferenceChecksum = vmi.Annotations[annotations.AnnIntegrityCoreChecksum] - m.eventLog.CurrentChecksum = vmi.Annotations[annotations.AnnIntegrityCoreChecksumApplied] - return nil } diff --git a/images/virtualization-artifact/pkg/audit/events/integrity/integrity_check_vm_test.go b/images/virtualization-artifact/pkg/audit/events/integrity/integrity_check_vm_test.go index 0423675ec3..177450d308 100644 --- a/images/virtualization-artifact/pkg/audit/events/integrity/integrity_check_vm_test.go +++ b/images/virtualization-artifact/pkg/audit/events/integrity/integrity_check_vm_test.go @@ -158,7 +158,7 @@ var _ = Describe("Integrity Check VM Events", func() { Expect(eventLog.eventLog.Type).To(Equal("Integrity check")) Expect(eventLog.eventLog.Level).To(Equal("critical")) - Expect(eventLog.eventLog.Name).To(Equal("VM config integrity check failed")) + Expect(eventLog.eventLog.Name).To(Equal("Virtual machine 'test-vm' config integrity check failed")) Expect(eventLog.eventLog.Datetime).To(Equal(currentTime.Format(time.RFC3339))) Expect(eventLog.eventLog.UID).To(Equal("0000-0000-0000")) Expect(eventLog.eventLog.OperationResult).To(Equal("allow")) diff --git a/images/virtualization-artifact/pkg/audit/events/module/module_component_control.go b/images/virtualization-artifact/pkg/audit/events/module/module_component_control.go index c79e2adbd2..b2630f10e4 100644 --- a/images/virtualization-artifact/pkg/audit/events/module/module_component_control.go +++ b/images/virtualization-artifact/pkg/audit/events/module/module_component_control.go @@ -17,6 +17,7 @@ limitations under the License. package module import ( + "fmt" "strings" "k8s.io/apiserver/pkg/apis/audit" @@ -61,8 +62,8 @@ func (m *ModuleComponentControl) IsMatched() bool { return false } - // Skip control requests from internal k8s controllers because we get them with almost empty ObjectRef - if strings.Contains(m.event.User.Username, kubeSystemUsername) { + if strings.HasPrefix(m.event.User.Username, "system:") && + !strings.HasPrefix(m.event.User.Username, "system:serviceaccount:d8-service-accounts") { return false } @@ -84,11 +85,11 @@ func (m *ModuleComponentControl) Fill() error { m.eventLog.Type = "Virtualization control" if m.event.Verb == "create" { - m.eventLog.Name = "Component creation" + m.eventLog.Name = fmt.Sprintf("Component '%s' has been created by '%s'", m.event.ObjectRef.Name, m.event.User.Username) m.eventLog.Level = "info" m.eventLog.Component = m.event.ObjectRef.Name } else { - m.eventLog.Name = "Component deletion" + m.eventLog.Name = fmt.Sprintf("Component '%s' has been deleted by '%s'", m.event.ObjectRef.Name, m.event.User.Username) m.eventLog.Level = "warn" m.eventLog.Component = m.event.ObjectRef.Name } diff --git a/images/virtualization-artifact/pkg/audit/events/module/module_component_control_test.go b/images/virtualization-artifact/pkg/audit/events/module/module_component_control_test.go index b8454f3df1..3caa27b18e 100644 --- a/images/virtualization-artifact/pkg/audit/events/module/module_component_control_test.go +++ b/images/virtualization-artifact/pkg/audit/events/module/module_component_control_test.go @@ -263,33 +263,33 @@ var _ = Describe("Module component control events", func() { }), Entry("Module Control creation event shouldn't failed fill", moduleComponentControlTestArgs{ eventVerb: "create", - expectedName: "Component creation", + expectedName: "Component 'virt-handler' has been created by 'test-user'", expectedLevel: "info", expectedActionType: "create", }), Entry("Module Control creation event shouldn't failed fill", moduleComponentControlTestArgs{ eventVerb: "delete", - expectedName: "Component deletion", + expectedName: "Component 'virt-handler' has been deleted by 'test-user'", expectedLevel: "warn", expectedActionType: "delete", }), Entry("Module Control creation event shouldn't failed fill with losted module", moduleComponentControlTestArgs{ eventVerb: "delete", - expectedName: "Component deletion", + expectedName: "Component 'virt-handler' has been deleted by 'test-user'", expectedLevel: "warn", expectedActionType: "delete", shouldLostModule: true, }), Entry("Module Control creation event shouldn't failed fill with losted node", moduleComponentControlTestArgs{ eventVerb: "delete", - expectedName: "Component deletion", + expectedName: "Component 'virt-handler' has been deleted by 'test-user'", expectedLevel: "warn", expectedActionType: "delete", shouldLostNode: true, }), Entry("Module Control creation event shouldn't failed fill with losted pod", moduleComponentControlTestArgs{ eventVerb: "delete", - expectedName: "Component deletion", + expectedName: "Component 'virt-handler' has been deleted by 'test-user'", expectedLevel: "warn", expectedActionType: "delete", shouldLostPod: true, diff --git a/images/virtualization-artifact/pkg/audit/events/module/module_control.go b/images/virtualization-artifact/pkg/audit/events/module/module_control.go index 5dfb69df57..e3ea8ee5f6 100644 --- a/images/virtualization-artifact/pkg/audit/events/module/module_control.go +++ b/images/virtualization-artifact/pkg/audit/events/module/module_control.go @@ -57,7 +57,8 @@ func (m *ModuleControl) IsMatched() bool { return false } - if strings.HasPrefix(m.event.User.Username, "system:serviceaccount:d8") { + if strings.HasPrefix(m.event.User.Username, "system:") && + !strings.HasPrefix(m.event.User.Username, "system:serviceaccount:d8-service-accounts") { return false } diff --git a/images/virtualization-artifact/pkg/audit/events/vm/vm_access.go b/images/virtualization-artifact/pkg/audit/events/vm/vm_access.go index d118ba89a0..a705cae145 100644 --- a/images/virtualization-artifact/pkg/audit/events/vm/vm_access.go +++ b/images/virtualization-artifact/pkg/audit/events/vm/vm_access.go @@ -18,6 +18,7 @@ package vm import ( "fmt" + "strings" "k8s.io/apiserver/pkg/apis/audit" @@ -58,10 +59,19 @@ func (m *VMAccess) IsMatched() bool { return false } + if strings.HasPrefix(m.event.User.Username, "system:") && + !strings.HasPrefix(m.event.User.Username, "system:serviceaccount:d8-service-accounts") { + return false + } + if m.event.ObjectRef.Resource != "virtualmachines" || m.event.ObjectRef.APIGroup != "subresources.virtualization.deckhouse.io" { return false } + if m.event.Stage == audit.StageResponseStarted { + return false + } + if m.event.ObjectRef.Subresource == "console" || m.event.ObjectRef.Subresource == "vnc" || m.event.ObjectRef.Subresource == "portforward" { return true } @@ -73,17 +83,15 @@ func (m *VMAccess) Fill() error { m.eventLog = NewVMEventLog(m.event) m.eventLog.Type = "Access to VM" - switch m.event.ObjectRef.Subresource { - case "console": - m.eventLog.Name = "Access to VM via serial console" - case "vnc": - m.eventLog.Name = "Access to VM via VNC" - case "portforward": - m.eventLog.Name = "Access to VM via portforward" + stage := "" + switch m.event.Stage { + case audit.StageResponseComplete: + stage = "finished" + case audit.StageRequestReceived: + stage = "initiated" } - m.eventLog.Name = fmt.Sprintf("%s: %s", m.eventLog.Name, m.event.Stage) - + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' connection has been %s via %s by '%s'", m.event.ObjectRef.Name, stage, m.event.ObjectRef.Subresource, m.event.User.Username) vm, err := util.GetVMFromInformer(m.ttlCache, m.informerList.GetVMInformer(), m.event.ObjectRef.Namespace+"/"+m.event.ObjectRef.Name) if err != nil { log.Debug("fail to get vm from informer", log.Err(err)) @@ -91,6 +99,8 @@ func (m *VMAccess) Fill() error { return nil } + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' connection has been %s via %s by '%s'", vm.Name, stage, m.event.ObjectRef.Subresource, m.event.User.Username) + m.eventLog.QemuVersion = vm.Status.Versions.Qemu m.eventLog.LibvirtVersion = vm.Status.Versions.Libvirt diff --git a/images/virtualization-artifact/pkg/audit/events/vm/vm_access_test.go b/images/virtualization-artifact/pkg/audit/events/vm/vm_access_test.go index cef7a71b7d..45ca61a73b 100644 --- a/images/virtualization-artifact/pkg/audit/events/vm/vm_access_test.go +++ b/images/virtualization-artifact/pkg/audit/events/vm/vm_access_test.go @@ -252,33 +252,33 @@ var _ = Describe("VMOP Events", func() { shouldFailMatch: true, }), Entry("VM Access with ResponseComplete should contain decision and fill without errors", vmAccessTestArgs{ - expectedName: "Access to VM via serial console: ResponseComplete", + expectedName: "Virtual machine 'test-vm' connection has been finished via console by 'test-user'", customSubresource: "console", }), Entry("VM Access with RequestReceived shouldn't contain decision and fill without errors", vmAccessTestArgs{ - expectedName: "Access to VM via serial console: RequestReceived", + expectedName: "Virtual machine 'test-vm' connection has been initiated via console by 'test-user'", customSubresource: "console", isRequestReceived: true, }), Entry("VM Access by Console event should filled without errors", vmAccessTestArgs{ - expectedName: "Access to VM via serial console: ResponseComplete", + expectedName: "Virtual machine 'test-vm' connection has been finished via console by 'test-user'", customSubresource: "console", }), Entry("VM Access by VNC event should filled without errors", vmAccessTestArgs{ - expectedName: "Access to VM via VNC: ResponseComplete", + expectedName: "Virtual machine 'test-vm' connection has been finished via vnc by 'test-user'", customSubresource: "vnc", }), Entry("VM Access by Portforward event should filled without errors", vmAccessTestArgs{ - expectedName: "Access to VM via portforward: ResponseComplete", + expectedName: "Virtual machine 'test-vm' connection has been finished via portforward by 'test-user'", customSubresource: "portforward", }), Entry("VM Access with losted VM event should filled without errors", vmAccessTestArgs{ - expectedName: "Access to VM via serial console: ResponseComplete", + expectedName: "Virtual machine 'virt-launcher-test-vm' connection has been finished via console by 'test-user'", customSubresource: "console", shouldLostVM: true, }), Entry("VM Access with losted VD and Node event should filled without errors", vmAccessTestArgs{ - expectedName: "Access to VM via serial console: ResponseComplete", + expectedName: "Virtual machine 'test-vm' connection has been finished via console by 'test-user'", customSubresource: "console", shouldLostVD: true, shouldLostNode: true, diff --git a/images/virtualization-artifact/pkg/audit/events/vm/vm_control.go b/images/virtualization-artifact/pkg/audit/events/vm/vm_control.go index 49284be6bf..92366a452a 100644 --- a/images/virtualization-artifact/pkg/audit/events/vm/vm_control.go +++ b/images/virtualization-artifact/pkg/audit/events/vm/vm_control.go @@ -79,6 +79,7 @@ func (m *VMControl) Fill() error { } } + vmName := pod.Labels["vm.kubevirt.internal.virtualization.deckhouse.io/name"] isControllerAction := strings.HasPrefix(m.event.User.Username, "system:serviceaccount:d8-virtualization") isNodeAction := strings.HasPrefix(m.event.User.Username, "system:node") @@ -88,22 +89,22 @@ func (m *VMControl) Fill() error { switch { case strings.Contains(terminatedStatuses, "guest-shutdown"): - m.eventLog.Name = "VM stoped from OS" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been stopped from OS", vmName) case strings.Contains(terminatedStatuses, "guest-reset"): - m.eventLog.Name = "VM restarted from OS" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been restarted from OS", vmName) default: - m.eventLog.Name = "VM stopped by system" + m.eventLog.shouldLog = false return nil } case isNodeAction: - m.eventLog.Name = "VM stopped by system" + m.eventLog.shouldLog = false return nil default: m.eventLog.Level = "critical" - m.eventLog.Name = "VM killed abnormal way" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been killed abnormal way by '%s'", vmName, m.event.User.Username) } - vm, err := util.GetVMFromInformer(m.ttlCache, m.informerList.GetVMInformer(), pod.Namespace+"/"+pod.Labels["vm.kubevirt.internal.virtualization.deckhouse.io/name"]) + vm, err := util.GetVMFromInformer(m.ttlCache, m.informerList.GetVMInformer(), pod.Namespace+"/"+vmName) if err != nil { log.Debug("fail to get vm from informer", log.Err(err)) return nil diff --git a/images/virtualization-artifact/pkg/audit/events/vm/vm_control_test.go b/images/virtualization-artifact/pkg/audit/events/vm/vm_control_test.go index c4987fb80f..d7ead20054 100644 --- a/images/virtualization-artifact/pkg/audit/events/vm/vm_control_test.go +++ b/images/virtualization-artifact/pkg/audit/events/vm/vm_control_test.go @@ -44,6 +44,7 @@ type vmControlTestArgs struct { shouldLostVM bool shouldLostVD bool shouldLostNode bool + shoulntLog bool customObjectRef *audit.ObjectReference customObjectRefNil bool customContainerStatusMessage string @@ -82,7 +83,14 @@ var _ = Describe("VMOP Events", func() { } pod = &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "virt-launcher-test-vm", Namespace: "test", UID: "0000-0000-4567"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "virt-launcher-test-vm", + Namespace: "test", + UID: "0000-0000-4567", + Labels: map[string]string{ + "vm.kubevirt.internal.virtualization.deckhouse.io/name": "test-vm", + }, + }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { @@ -230,6 +238,11 @@ var _ = Describe("VMOP Events", func() { err := eventLog.Fill() Expect(err).To(BeNil()) + if args.shoulntLog { + Expect(eventLog.ShouldLog()).To(BeFalse()) + return + } + Expect(eventLog.eventLog.Type).To(Equal("Control VM")) Expect(eventLog.eventLog.Level).To(Equal(args.expectedLevel)) Expect(eventLog.eventLog.Name).To(Equal(args.expectedName)) @@ -304,45 +317,41 @@ var _ = Describe("VMOP Events", func() { }), Entry("VM deleted by user event should filled without errors", vmControlTestArgs{ expectedLevel: "critical", - expectedName: "VM killed abnormal way", + expectedName: "Virtual machine 'test-vm' has been killed abnormal way by 'test-user'", expectedActionType: "delete", }), Entry("VM stopped from OS by controller event should filled without errors", vmControlTestArgs{ customEventUser: "system:serviceaccount:d8-virtualization", customContainerStatusMessage: "guest-shutdown", expectedLevel: "warn", - expectedName: "VM stoped from OS", + expectedName: "Virtual machine 'test-vm' has been stopped from OS", expectedActionType: "delete", }), Entry("VM restarted from OS by controller event should filled without errors", vmControlTestArgs{ customEventUser: "system:serviceaccount:d8-virtualization", customContainerStatusMessage: "guest-reset", expectedLevel: "warn", - expectedName: "VM restarted from OS", + expectedName: "Virtual machine 'test-vm' has been restarted from OS", expectedActionType: "delete", }), Entry("VM deleted by node event should filled without errors", vmControlTestArgs{ - customEventUser: "system:node", - expectedLevel: "info", - expectedName: "VM stopped by system", - expectedActionType: "delete", + customEventUser: "system:node", + shoulntLog: true, }), Entry("VM deleted by controller with unknown termination message event should filled without errors", vmControlTestArgs{ customContainerStatusMessage: "poped", customEventUser: "system:serviceaccount:d8-virtualization", - expectedLevel: "warn", - expectedName: "VM stopped by system", - expectedActionType: "delete", + shoulntLog: true, }), Entry("VM deleted by user event with losted VM should filled without errors", vmControlTestArgs{ expectedLevel: "critical", - expectedName: "VM killed abnormal way", + expectedName: "Virtual machine 'test-vm' has been killed abnormal way by 'test-user'", expectedActionType: "delete", shouldLostVM: true, }), Entry("VM deleted by user event with losted VD and Node should filled without errors", vmControlTestArgs{ expectedLevel: "critical", - expectedName: "VM killed abnormal way", + expectedName: "Virtual machine 'test-vm' has been killed abnormal way by 'test-user'", expectedActionType: "delete", shouldLostNode: true, shouldLostVD: true, diff --git a/images/virtualization-artifact/pkg/audit/events/vm/vm_manage.go b/images/virtualization-artifact/pkg/audit/events/vm/vm_manage.go index 6865ccee7e..607dece241 100644 --- a/images/virtualization-artifact/pkg/audit/events/vm/vm_manage.go +++ b/images/virtualization-artifact/pkg/audit/events/vm/vm_manage.go @@ -19,6 +19,7 @@ package vm import ( "fmt" "log/slog" + "strings" "k8s.io/apiserver/pkg/apis/audit" @@ -59,6 +60,11 @@ func (m *VMManage) IsMatched() bool { return false } + if strings.HasPrefix(m.event.User.Username, "system:") && + !strings.HasPrefix(m.event.User.Username, "system:serviceaccount:d8-service-accounts") { + return false + } + uriWithoutQueryParams, err := util.RemoveAllQueryParams(m.event.RequestURI) if err != nil { log.Debug("failed to remove query params from URI", err.Error(), slog.String("uri", m.event.RequestURI)) @@ -84,12 +90,12 @@ func (m *VMManage) Fill() error { switch m.event.Verb { case "create": - m.eventLog.Name = "VM creation" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been created by '%s'", m.event.ObjectRef.Name, m.event.User.Username) case "update", "patch": - m.eventLog.Name = "VM update" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been updated by '%s'", m.event.ObjectRef.Name, m.event.User.Username) case "delete": m.eventLog.Level = "warn" - m.eventLog.Name = "VM deletion" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been deleted by '%s'", m.event.ObjectRef.Name, m.event.User.Username) } vm, err := util.GetVMFromInformer(m.ttlCache, m.informerList.GetVMInformer(), m.event.ObjectRef.Namespace+"/"+m.event.ObjectRef.Name) diff --git a/images/virtualization-artifact/pkg/audit/events/vm/vm_manage_test.go b/images/virtualization-artifact/pkg/audit/events/vm/vm_manage_test.go index 8af16eed25..06de1ea16d 100644 --- a/images/virtualization-artifact/pkg/audit/events/vm/vm_manage_test.go +++ b/images/virtualization-artifact/pkg/audit/events/vm/vm_manage_test.go @@ -252,35 +252,35 @@ var _ = Describe("VMOP Events", func() { eventURI: "/apis/virtualization.deckhouse.io/v1alpha2/namespaces/test/virtualmachines/test-vm", eventVerb: "update", expectedLevel: "info", - expectedName: "VM update", + expectedName: "Virtual machine 'test-vm' has been updated by 'test-user'", expectedActionType: "update", }), Entry("VM patch event should filled without errors", vmManageTestArgs{ eventURI: "/apis/virtualization.deckhouse.io/v1alpha2/namespaces/test/virtualmachines/test-vm", eventVerb: "patch", expectedLevel: "info", - expectedName: "VM update", + expectedName: "Virtual machine 'test-vm' has been updated by 'test-user'", expectedActionType: "patch", }), Entry("VM delete event should filled without errors", vmManageTestArgs{ eventURI: "/apis/virtualization.deckhouse.io/v1alpha2/namespaces/test/virtualmachines/test-vm", eventVerb: "delete", expectedLevel: "warn", - expectedName: "VM deletion", + expectedName: "Virtual machine 'test-vm' has been deleted by 'test-user'", expectedActionType: "delete", }), Entry("VM create event should filled without errors", vmManageTestArgs{ eventURI: "/apis/virtualization.deckhouse.io/v1alpha2/namespaces/test/virtualmachines", eventVerb: "create", expectedLevel: "info", - expectedName: "VM creation", + expectedName: "Virtual machine 'test-vm' has been created by 'test-user'", expectedActionType: "create", }), Entry("VM manage event should filled without VM exist error", vmManageTestArgs{ eventURI: "/apis/virtualization.deckhouse.io/v1alpha2/namespaces/test/virtualmachines", eventVerb: "create", expectedLevel: "info", - expectedName: "VM creation", + expectedName: "Virtual machine 'test-vm' has been created by 'test-user'", expectedActionType: "create", shouldLostVM: true, }), @@ -288,7 +288,7 @@ var _ = Describe("VMOP Events", func() { eventURI: "/apis/virtualization.deckhouse.io/v1alpha2/namespaces/test/virtualmachines", eventVerb: "create", expectedLevel: "info", - expectedName: "VM creation", + expectedName: "Virtual machine 'test-vm' has been created by 'test-user'", expectedActionType: "create", shouldLostVD: true, shouldLostNode: true, diff --git a/images/virtualization-artifact/pkg/audit/events/vm/vmop_control.go b/images/virtualization-artifact/pkg/audit/events/vm/vmop_control.go index f27004adfc..8b9e8b4e50 100644 --- a/images/virtualization-artifact/pkg/audit/events/vm/vmop_control.go +++ b/images/virtualization-artifact/pkg/audit/events/vm/vmop_control.go @@ -19,6 +19,7 @@ package vm import ( "encoding/json" "fmt" + "strings" "k8s.io/apiserver/pkg/apis/audit" @@ -60,6 +61,11 @@ func (m *VMOPControl) IsMatched() bool { return false } + if strings.HasPrefix(m.event.User.Username, "system:") && + !strings.HasPrefix(m.event.User.Username, "system:serviceaccount:d8-service-accounts") { + return false + } + if m.event.ObjectRef.Resource == "virtualmachineoperations" && m.event.Verb == "create" { return true } @@ -93,23 +99,23 @@ func (m *VMOPControl) Fill() error { switch vmop.Spec.Type { case v1alpha2.VMOPTypeStart: - m.eventLog.Name = "VM started" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been started by '%s'", vmop.Spec.VirtualMachine, m.event.User.Username) m.eventLog.Level = "info" m.eventLog.ActionType = "start" case v1alpha2.VMOPTypeStop: - m.eventLog.Name = "VM stopped" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been stopped by '%s'", vmop.Spec.VirtualMachine, m.event.User.Username) m.eventLog.Level = "warn" m.eventLog.ActionType = "stop" case v1alpha2.VMOPTypeRestart: - m.eventLog.Name = "VM restarted" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been restarted by '%s'", vmop.Spec.VirtualMachine, m.event.User.Username) m.eventLog.Level = "warn" m.eventLog.ActionType = "restart" case v1alpha2.VMOPTypeMigrate: - m.eventLog.Name = "VM migrated" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been migrated by '%s'", vmop.Spec.VirtualMachine, m.event.User.Username) m.eventLog.Level = "warn" m.eventLog.ActionType = "migrate" case v1alpha2.VMOPTypeEvict: - m.eventLog.Name = "VM evicted" + m.eventLog.Name = fmt.Sprintf("Virtual machine '%s' has been evicted by '%s'", vmop.Spec.VirtualMachine, m.event.User.Username) m.eventLog.Level = "warn" m.eventLog.ActionType = "evict" } diff --git a/images/virtualization-artifact/pkg/audit/events/vm/vmop_control_test.go b/images/virtualization-artifact/pkg/audit/events/vm/vmop_control_test.go index 5f0dc9d177..2a599325ab 100644 --- a/images/virtualization-artifact/pkg/audit/events/vm/vmop_control_test.go +++ b/images/virtualization-artifact/pkg/audit/events/vm/vmop_control_test.go @@ -264,65 +264,65 @@ var _ = Describe("VMOP Events", func() { }), Entry("Start VMOP event should filled without errors", vmopTestArgs{ vmopType: v1alpha2.VMOPTypeStart, - expectedName: "VM started", + expectedName: "Virtual machine 'test-vm' has been started by 'test-user'", expectedLevel: "info", expectedActionType: "start", }), Entry("Stop VMOP event should filled without errors", vmopTestArgs{ vmopType: v1alpha2.VMOPTypeStop, - expectedName: "VM stopped", + expectedName: "Virtual machine 'test-vm' has been stopped by 'test-user'", expectedLevel: "warn", expectedActionType: "stop", }), Entry("Restart VMOP event should filled without errors", vmopTestArgs{ vmopType: v1alpha2.VMOPTypeRestart, - expectedName: "VM restarted", + expectedName: "Virtual machine 'test-vm' has been restarted by 'test-user'", expectedLevel: "warn", expectedActionType: "restart", }), Entry("Migrate VMOP event should filled without errors", vmopTestArgs{ vmopType: v1alpha2.VMOPTypeMigrate, - expectedName: "VM migrated", + expectedName: "Virtual machine 'test-vm' has been migrated by 'test-user'", expectedLevel: "warn", expectedActionType: "migrate", }), Entry("Evict VMOP event should filled without errors", vmopTestArgs{ vmopType: v1alpha2.VMOPTypeEvict, - expectedName: "VM evicted", + expectedName: "Virtual machine 'test-vm' has been evicted by 'test-user'", expectedLevel: "warn", expectedActionType: "evict", }), Entry("Evict VMOP event should filled without errors, but with unknown VDs", vmopTestArgs{ vmopType: v1alpha2.VMOPTypeStart, - expectedName: "VM started", + expectedName: "Virtual machine 'test-vm' has been started by 'test-user'", expectedLevel: "info", expectedActionType: "start", shouldLostVD: true, }), Entry("Evict VMOP event should filled without errors, but with unknown Node's IPs", vmopTestArgs{ vmopType: v1alpha2.VMOPTypeStart, - expectedName: "VM started", + expectedName: "Virtual machine 'test-vm' has been started by 'test-user'", expectedLevel: "info", expectedActionType: "start", shouldLostNode: true, }), Entry("VMOP event should filled with VM exist error", vmopTestArgs{ vmopType: v1alpha2.VMOPTypeStart, - expectedName: "VM started", + expectedName: "Virtual machine 'test-vm' has been started by 'test-user'", expectedLevel: "info", expectedActionType: "start", shouldLostVM: true, }), Entry("VMOP event should filled with VMOP exist error", vmopTestArgs{ vmopType: v1alpha2.VMOPTypeStart, - expectedName: "VM started", + expectedName: "Virtual machine 'test-vm' has been started by 'test-user'", expectedLevel: "info", expectedActionType: "start", shouldLostVMOP: true, }), Entry("VMOP event should filled with JSON encode error", vmopTestArgs{ vmopType: v1alpha2.VMOPTypeStart, - expectedName: "VM started", + expectedName: "Virtual machine 'test-vm' has been started by 'test-user'", expectedLevel: "info", expectedActionType: "start", shouldCorruptVMOPBytes: true, diff --git a/images/virtualization-artifact/pkg/audit/server/server.go b/images/virtualization-artifact/pkg/audit/server/server.go index 24e3948cd4..e30af24fc5 100644 --- a/images/virtualization-artifact/pkg/audit/server/server.go +++ b/images/virtualization-artifact/pkg/audit/server/server.go @@ -97,7 +97,7 @@ func (s *tcpServer) Run(ctx context.Context, opts ...Option) error { listener.Close() }() - log.Info("Server started", slog.String("address", s.addr)) + log.Debug("Server started", slog.String("address", s.addr)) for { conn, err := listener.Accept() @@ -120,7 +120,7 @@ func (s *tcpServer) Run(ctx context.Context, opts ...Option) error { func (s *tcpServer) handleConnection(ctx context.Context, conn net.Conn) { defer conn.Close() - log.Info("New connection", slog.String("remote", conn.RemoteAddr().String())) + log.Debug("New connection", slog.String("remote", conn.RemoteAddr().String())) scanner := bufio.NewScanner(conn) for scanner.Scan() {