mirror of
https://github.com/siderolabs/omni.git
synced 2026-05-04 22:26:13 +02:00
feat: add more filters to audit logs
Add multiple new filters to audit logs. Through the UI, there will be a generic search box and the ability to sort columns. Through the CLI, there will be support for the same plus also direct filters for event_type, resource_type, resource_id, cluster_id, and actor. Signed-off-by: Edward Sammut Alessi <edward.sammutalessi@siderolabs.com>
This commit is contained in:
parent
590ea2e370
commit
488b020b2e
@ -78,6 +78,180 @@ func (SchematicBootloader) EnumDescriptor() ([]byte, []int) {
|
||||
return file_omni_management_management_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type AuditLogEventType int32
|
||||
|
||||
const (
|
||||
AuditLogEventType_AUDIT_LOG_EVENT_TYPE_UNSPECIFIED AuditLogEventType = 0
|
||||
AuditLogEventType_AUDIT_LOG_EVENT_TYPE_CREATE AuditLogEventType = 1
|
||||
AuditLogEventType_AUDIT_LOG_EVENT_TYPE_UPDATE AuditLogEventType = 2
|
||||
AuditLogEventType_AUDIT_LOG_EVENT_TYPE_UPDATE_WITH_CONFLICTS AuditLogEventType = 3
|
||||
AuditLogEventType_AUDIT_LOG_EVENT_TYPE_DESTROY AuditLogEventType = 4
|
||||
AuditLogEventType_AUDIT_LOG_EVENT_TYPE_TEARDOWN AuditLogEventType = 5
|
||||
AuditLogEventType_AUDIT_LOG_EVENT_TYPE_TALOS_ACCESS AuditLogEventType = 6
|
||||
AuditLogEventType_AUDIT_LOG_EVENT_TYPE_K8S_ACCESS AuditLogEventType = 7
|
||||
)
|
||||
|
||||
// Enum value maps for AuditLogEventType.
|
||||
var (
|
||||
AuditLogEventType_name = map[int32]string{
|
||||
0: "AUDIT_LOG_EVENT_TYPE_UNSPECIFIED",
|
||||
1: "AUDIT_LOG_EVENT_TYPE_CREATE",
|
||||
2: "AUDIT_LOG_EVENT_TYPE_UPDATE",
|
||||
3: "AUDIT_LOG_EVENT_TYPE_UPDATE_WITH_CONFLICTS",
|
||||
4: "AUDIT_LOG_EVENT_TYPE_DESTROY",
|
||||
5: "AUDIT_LOG_EVENT_TYPE_TEARDOWN",
|
||||
6: "AUDIT_LOG_EVENT_TYPE_TALOS_ACCESS",
|
||||
7: "AUDIT_LOG_EVENT_TYPE_K8S_ACCESS",
|
||||
}
|
||||
AuditLogEventType_value = map[string]int32{
|
||||
"AUDIT_LOG_EVENT_TYPE_UNSPECIFIED": 0,
|
||||
"AUDIT_LOG_EVENT_TYPE_CREATE": 1,
|
||||
"AUDIT_LOG_EVENT_TYPE_UPDATE": 2,
|
||||
"AUDIT_LOG_EVENT_TYPE_UPDATE_WITH_CONFLICTS": 3,
|
||||
"AUDIT_LOG_EVENT_TYPE_DESTROY": 4,
|
||||
"AUDIT_LOG_EVENT_TYPE_TEARDOWN": 5,
|
||||
"AUDIT_LOG_EVENT_TYPE_TALOS_ACCESS": 6,
|
||||
"AUDIT_LOG_EVENT_TYPE_K8S_ACCESS": 7,
|
||||
}
|
||||
)
|
||||
|
||||
func (x AuditLogEventType) Enum() *AuditLogEventType {
|
||||
p := new(AuditLogEventType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x AuditLogEventType) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (AuditLogEventType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_omni_management_management_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (AuditLogEventType) Type() protoreflect.EnumType {
|
||||
return &file_omni_management_management_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x AuditLogEventType) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuditLogEventType.Descriptor instead.
|
||||
func (AuditLogEventType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_omni_management_management_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type AuditLogOrderByField int32
|
||||
|
||||
const (
|
||||
AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_UNSPECIFIED AuditLogOrderByField = 0
|
||||
AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_DATE AuditLogOrderByField = 1
|
||||
AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_EVENT_TYPE AuditLogOrderByField = 2
|
||||
AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_TYPE AuditLogOrderByField = 3
|
||||
AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_ID AuditLogOrderByField = 4
|
||||
AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_CLUSTER_ID AuditLogOrderByField = 5
|
||||
AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_ACTOR AuditLogOrderByField = 6
|
||||
)
|
||||
|
||||
// Enum value maps for AuditLogOrderByField.
|
||||
var (
|
||||
AuditLogOrderByField_name = map[int32]string{
|
||||
0: "AUDIT_LOG_ORDER_BY_FIELD_UNSPECIFIED",
|
||||
1: "AUDIT_LOG_ORDER_BY_FIELD_DATE",
|
||||
2: "AUDIT_LOG_ORDER_BY_FIELD_EVENT_TYPE",
|
||||
3: "AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_TYPE",
|
||||
4: "AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_ID",
|
||||
5: "AUDIT_LOG_ORDER_BY_FIELD_CLUSTER_ID",
|
||||
6: "AUDIT_LOG_ORDER_BY_FIELD_ACTOR",
|
||||
}
|
||||
AuditLogOrderByField_value = map[string]int32{
|
||||
"AUDIT_LOG_ORDER_BY_FIELD_UNSPECIFIED": 0,
|
||||
"AUDIT_LOG_ORDER_BY_FIELD_DATE": 1,
|
||||
"AUDIT_LOG_ORDER_BY_FIELD_EVENT_TYPE": 2,
|
||||
"AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_TYPE": 3,
|
||||
"AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_ID": 4,
|
||||
"AUDIT_LOG_ORDER_BY_FIELD_CLUSTER_ID": 5,
|
||||
"AUDIT_LOG_ORDER_BY_FIELD_ACTOR": 6,
|
||||
}
|
||||
)
|
||||
|
||||
func (x AuditLogOrderByField) Enum() *AuditLogOrderByField {
|
||||
p := new(AuditLogOrderByField)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x AuditLogOrderByField) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (AuditLogOrderByField) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_omni_management_management_proto_enumTypes[2].Descriptor()
|
||||
}
|
||||
|
||||
func (AuditLogOrderByField) Type() protoreflect.EnumType {
|
||||
return &file_omni_management_management_proto_enumTypes[2]
|
||||
}
|
||||
|
||||
func (x AuditLogOrderByField) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuditLogOrderByField.Descriptor instead.
|
||||
func (AuditLogOrderByField) EnumDescriptor() ([]byte, []int) {
|
||||
return file_omni_management_management_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type AuditLogOrderByDir int32
|
||||
|
||||
const (
|
||||
AuditLogOrderByDir_AUDIT_LOG_ORDER_BY_DIR_UNSPECIFIED AuditLogOrderByDir = 0
|
||||
AuditLogOrderByDir_AUDIT_LOG_ORDER_BY_DIR_ASC AuditLogOrderByDir = 1
|
||||
AuditLogOrderByDir_AUDIT_LOG_ORDER_BY_DIR_DESC AuditLogOrderByDir = 2
|
||||
)
|
||||
|
||||
// Enum value maps for AuditLogOrderByDir.
|
||||
var (
|
||||
AuditLogOrderByDir_name = map[int32]string{
|
||||
0: "AUDIT_LOG_ORDER_BY_DIR_UNSPECIFIED",
|
||||
1: "AUDIT_LOG_ORDER_BY_DIR_ASC",
|
||||
2: "AUDIT_LOG_ORDER_BY_DIR_DESC",
|
||||
}
|
||||
AuditLogOrderByDir_value = map[string]int32{
|
||||
"AUDIT_LOG_ORDER_BY_DIR_UNSPECIFIED": 0,
|
||||
"AUDIT_LOG_ORDER_BY_DIR_ASC": 1,
|
||||
"AUDIT_LOG_ORDER_BY_DIR_DESC": 2,
|
||||
}
|
||||
)
|
||||
|
||||
func (x AuditLogOrderByDir) Enum() *AuditLogOrderByDir {
|
||||
p := new(AuditLogOrderByDir)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x AuditLogOrderByDir) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (AuditLogOrderByDir) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_omni_management_management_proto_enumTypes[3].Descriptor()
|
||||
}
|
||||
|
||||
func (AuditLogOrderByDir) Type() protoreflect.EnumType {
|
||||
return &file_omni_management_management_proto_enumTypes[3]
|
||||
}
|
||||
|
||||
func (x AuditLogOrderByDir) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuditLogOrderByDir.Descriptor instead.
|
||||
func (AuditLogOrderByDir) EnumDescriptor() ([]byte, []int) {
|
||||
return file_omni_management_management_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type KubernetesSSAOptions_InventoryPolicy int32
|
||||
|
||||
const (
|
||||
@ -111,11 +285,11 @@ func (x KubernetesSSAOptions_InventoryPolicy) String() string {
|
||||
}
|
||||
|
||||
func (KubernetesSSAOptions_InventoryPolicy) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_omni_management_management_proto_enumTypes[1].Descriptor()
|
||||
return file_omni_management_management_proto_enumTypes[4].Descriptor()
|
||||
}
|
||||
|
||||
func (KubernetesSSAOptions_InventoryPolicy) Type() protoreflect.EnumType {
|
||||
return &file_omni_management_management_proto_enumTypes[1]
|
||||
return &file_omni_management_management_proto_enumTypes[4]
|
||||
}
|
||||
|
||||
func (x KubernetesSSAOptions_InventoryPolicy) Number() protoreflect.EnumNumber {
|
||||
@ -160,11 +334,11 @@ func (x KubernetesSyncManifestResponse_ResponseType) String() string {
|
||||
}
|
||||
|
||||
func (KubernetesSyncManifestResponse_ResponseType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_omni_management_management_proto_enumTypes[2].Descriptor()
|
||||
return file_omni_management_management_proto_enumTypes[5].Descriptor()
|
||||
}
|
||||
|
||||
func (KubernetesSyncManifestResponse_ResponseType) Type() protoreflect.EnumType {
|
||||
return &file_omni_management_management_proto_enumTypes[2]
|
||||
return &file_omni_management_management_proto_enumTypes[5]
|
||||
}
|
||||
|
||||
func (x KubernetesSyncManifestResponse_ResponseType) Number() protoreflect.EnumNumber {
|
||||
@ -209,11 +383,11 @@ func (x CreateSchematicRequest_SiderolinkGRPCTunnelMode) String() string {
|
||||
}
|
||||
|
||||
func (CreateSchematicRequest_SiderolinkGRPCTunnelMode) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_omni_management_management_proto_enumTypes[3].Descriptor()
|
||||
return file_omni_management_management_proto_enumTypes[6].Descriptor()
|
||||
}
|
||||
|
||||
func (CreateSchematicRequest_SiderolinkGRPCTunnelMode) Type() protoreflect.EnumType {
|
||||
return &file_omni_management_management_proto_enumTypes[3]
|
||||
return &file_omni_management_management_proto_enumTypes[6]
|
||||
}
|
||||
|
||||
func (x CreateSchematicRequest_SiderolinkGRPCTunnelMode) Number() protoreflect.EnumNumber {
|
||||
@ -1497,6 +1671,14 @@ type ReadAuditLogRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
StartTime string `protobuf:"bytes,1,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"`
|
||||
EndTime string `protobuf:"bytes,2,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"`
|
||||
OrderByField AuditLogOrderByField `protobuf:"varint,3,opt,name=order_by_field,json=orderByField,proto3,enum=management.AuditLogOrderByField" json:"order_by_field,omitempty"`
|
||||
OrderByDir AuditLogOrderByDir `protobuf:"varint,4,opt,name=order_by_dir,json=orderByDir,proto3,enum=management.AuditLogOrderByDir" json:"order_by_dir,omitempty"`
|
||||
Search string `protobuf:"bytes,5,opt,name=search,proto3" json:"search,omitempty"`
|
||||
EventType AuditLogEventType `protobuf:"varint,6,opt,name=event_type,json=eventType,proto3,enum=management.AuditLogEventType" json:"event_type,omitempty"`
|
||||
ResourceType string `protobuf:"bytes,7,opt,name=resource_type,json=resourceType,proto3" json:"resource_type,omitempty"`
|
||||
ResourceId string `protobuf:"bytes,8,opt,name=resource_id,json=resourceId,proto3" json:"resource_id,omitempty"`
|
||||
ClusterId string `protobuf:"bytes,9,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"`
|
||||
Actor string `protobuf:"bytes,10,opt,name=actor,proto3" json:"actor,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@ -1545,6 +1727,62 @@ func (x *ReadAuditLogRequest) GetEndTime() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ReadAuditLogRequest) GetOrderByField() AuditLogOrderByField {
|
||||
if x != nil {
|
||||
return x.OrderByField
|
||||
}
|
||||
return AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *ReadAuditLogRequest) GetOrderByDir() AuditLogOrderByDir {
|
||||
if x != nil {
|
||||
return x.OrderByDir
|
||||
}
|
||||
return AuditLogOrderByDir_AUDIT_LOG_ORDER_BY_DIR_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *ReadAuditLogRequest) GetSearch() string {
|
||||
if x != nil {
|
||||
return x.Search
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ReadAuditLogRequest) GetEventType() AuditLogEventType {
|
||||
if x != nil {
|
||||
return x.EventType
|
||||
}
|
||||
return AuditLogEventType_AUDIT_LOG_EVENT_TYPE_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *ReadAuditLogRequest) GetResourceType() string {
|
||||
if x != nil {
|
||||
return x.ResourceType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ReadAuditLogRequest) GetResourceId() string {
|
||||
if x != nil {
|
||||
return x.ResourceId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ReadAuditLogRequest) GetClusterId() string {
|
||||
if x != nil {
|
||||
return x.ClusterId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ReadAuditLogRequest) GetActor() string {
|
||||
if x != nil {
|
||||
return x.Actor
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ReadAuditLogResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AuditLog []byte `protobuf:"bytes,1,opt,name=audit_log,json=auditLog,proto3" json:"audit_log,omitempty"`
|
||||
@ -2901,11 +3139,24 @@ const file_omni_management_management_proto_rawDesc = "" +
|
||||
"\x05error\x18\x02 \x01(\tR\x05error\x12\x14\n" +
|
||||
"\x05state\x18\x03 \x01(\tR\x05state\x12\x14\n" +
|
||||
"\x05total\x18\x04 \x01(\x05R\x05total\x12\x14\n" +
|
||||
"\x05value\x18\x05 \x01(\x05R\x05value\"O\n" +
|
||||
"\x05value\x18\x05 \x01(\x05R\x05value\"\xaa\x03\n" +
|
||||
"\x13ReadAuditLogRequest\x12\x1d\n" +
|
||||
"\n" +
|
||||
"start_time\x18\x01 \x01(\tR\tstartTime\x12\x19\n" +
|
||||
"\bend_time\x18\x02 \x01(\tR\aendTime\"3\n" +
|
||||
"\bend_time\x18\x02 \x01(\tR\aendTime\x12F\n" +
|
||||
"\x0eorder_by_field\x18\x03 \x01(\x0e2 .management.AuditLogOrderByFieldR\forderByField\x12@\n" +
|
||||
"\forder_by_dir\x18\x04 \x01(\x0e2\x1e.management.AuditLogOrderByDirR\n" +
|
||||
"orderByDir\x12\x16\n" +
|
||||
"\x06search\x18\x05 \x01(\tR\x06search\x12<\n" +
|
||||
"\n" +
|
||||
"event_type\x18\x06 \x01(\x0e2\x1d.management.AuditLogEventTypeR\teventType\x12#\n" +
|
||||
"\rresource_type\x18\a \x01(\tR\fresourceType\x12\x1f\n" +
|
||||
"\vresource_id\x18\b \x01(\tR\n" +
|
||||
"resourceId\x12\x1d\n" +
|
||||
"\n" +
|
||||
"cluster_id\x18\t \x01(\tR\tclusterId\x12\x14\n" +
|
||||
"\x05actor\x18\n" +
|
||||
" \x01(\tR\x05actor\"3\n" +
|
||||
"\x14ReadAuditLogResponse\x12\x1b\n" +
|
||||
"\taudit_log\x18\x01 \x01(\fR\bauditLog\"G\n" +
|
||||
"\x19ValidateJsonSchemaRequest\x12\x12\n" +
|
||||
@ -2969,7 +3220,28 @@ const file_omni_management_management_proto_rawDesc = "" +
|
||||
"\tBOOT_AUTO\x10\x00\x12\r\n" +
|
||||
"\tBOOT_DUAL\x10\x01\x12\v\n" +
|
||||
"\aBOOT_SD\x10\x02\x12\r\n" +
|
||||
"\tBOOT_GRUB\x10\x032\xa4\x10\n" +
|
||||
"\tBOOT_GRUB\x10\x03*\xbc\x02\n" +
|
||||
"\x11AuditLogEventType\x12$\n" +
|
||||
" AUDIT_LOG_EVENT_TYPE_UNSPECIFIED\x10\x00\x12\x1f\n" +
|
||||
"\x1bAUDIT_LOG_EVENT_TYPE_CREATE\x10\x01\x12\x1f\n" +
|
||||
"\x1bAUDIT_LOG_EVENT_TYPE_UPDATE\x10\x02\x12.\n" +
|
||||
"*AUDIT_LOG_EVENT_TYPE_UPDATE_WITH_CONFLICTS\x10\x03\x12 \n" +
|
||||
"\x1cAUDIT_LOG_EVENT_TYPE_DESTROY\x10\x04\x12!\n" +
|
||||
"\x1dAUDIT_LOG_EVENT_TYPE_TEARDOWN\x10\x05\x12%\n" +
|
||||
"!AUDIT_LOG_EVENT_TYPE_TALOS_ACCESS\x10\x06\x12#\n" +
|
||||
"\x1fAUDIT_LOG_EVENT_TYPE_K8S_ACCESS\x10\a*\xaf\x02\n" +
|
||||
"\x14AuditLogOrderByField\x12(\n" +
|
||||
"$AUDIT_LOG_ORDER_BY_FIELD_UNSPECIFIED\x10\x00\x12!\n" +
|
||||
"\x1dAUDIT_LOG_ORDER_BY_FIELD_DATE\x10\x01\x12'\n" +
|
||||
"#AUDIT_LOG_ORDER_BY_FIELD_EVENT_TYPE\x10\x02\x12*\n" +
|
||||
"&AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_TYPE\x10\x03\x12(\n" +
|
||||
"$AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_ID\x10\x04\x12'\n" +
|
||||
"#AUDIT_LOG_ORDER_BY_FIELD_CLUSTER_ID\x10\x05\x12\"\n" +
|
||||
"\x1eAUDIT_LOG_ORDER_BY_FIELD_ACTOR\x10\x06*}\n" +
|
||||
"\x12AuditLogOrderByDir\x12&\n" +
|
||||
"\"AUDIT_LOG_ORDER_BY_DIR_UNSPECIFIED\x10\x00\x12\x1e\n" +
|
||||
"\x1aAUDIT_LOG_ORDER_BY_DIR_ASC\x10\x01\x12\x1f\n" +
|
||||
"\x1bAUDIT_LOG_ORDER_BY_DIR_DESC\x10\x022\xa4\x10\n" +
|
||||
"\x11ManagementService\x12K\n" +
|
||||
"\n" +
|
||||
"Kubeconfig\x12\x1d.management.KubeconfigRequest\x1a\x1e.management.KubeconfigResponse\x12N\n" +
|
||||
@ -3011,138 +3283,144 @@ func file_omni_management_management_proto_rawDescGZIP() []byte {
|
||||
return file_omni_management_management_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_omni_management_management_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
||||
var file_omni_management_management_proto_enumTypes = make([]protoimpl.EnumInfo, 7)
|
||||
var file_omni_management_management_proto_msgTypes = make([]protoimpl.MessageInfo, 48)
|
||||
var file_omni_management_management_proto_goTypes = []any{
|
||||
(SchematicBootloader)(0), // 0: management.SchematicBootloader
|
||||
(KubernetesSSAOptions_InventoryPolicy)(0), // 1: management.KubernetesSSAOptions.InventoryPolicy
|
||||
(KubernetesSyncManifestResponse_ResponseType)(0), // 2: management.KubernetesSyncManifestResponse.ResponseType
|
||||
(CreateSchematicRequest_SiderolinkGRPCTunnelMode)(0), // 3: management.CreateSchematicRequest.SiderolinkGRPCTunnelMode
|
||||
(*KubeconfigResponse)(nil), // 4: management.KubeconfigResponse
|
||||
(*TalosconfigResponse)(nil), // 5: management.TalosconfigResponse
|
||||
(*OmniconfigResponse)(nil), // 6: management.OmniconfigResponse
|
||||
(*MachineLogsRequest)(nil), // 7: management.MachineLogsRequest
|
||||
(*ValidateConfigRequest)(nil), // 8: management.ValidateConfigRequest
|
||||
(*TalosconfigRequest)(nil), // 9: management.TalosconfigRequest
|
||||
(*CreateServiceAccountRequest)(nil), // 10: management.CreateServiceAccountRequest
|
||||
(*CreateServiceAccountResponse)(nil), // 11: management.CreateServiceAccountResponse
|
||||
(*RenewServiceAccountRequest)(nil), // 12: management.RenewServiceAccountRequest
|
||||
(*RenewServiceAccountResponse)(nil), // 13: management.RenewServiceAccountResponse
|
||||
(*DestroyServiceAccountRequest)(nil), // 14: management.DestroyServiceAccountRequest
|
||||
(*ListServiceAccountsResponse)(nil), // 15: management.ListServiceAccountsResponse
|
||||
(*KubeconfigRequest)(nil), // 16: management.KubeconfigRequest
|
||||
(*KubernetesUpgradePreChecksRequest)(nil), // 17: management.KubernetesUpgradePreChecksRequest
|
||||
(*KubernetesUpgradePreChecksResponse)(nil), // 18: management.KubernetesUpgradePreChecksResponse
|
||||
(*KubernetesSSAOptions)(nil), // 19: management.KubernetesSSAOptions
|
||||
(*KubernetesSyncManifestRequest)(nil), // 20: management.KubernetesSyncManifestRequest
|
||||
(*KubernetesSyncManifestResponse)(nil), // 21: management.KubernetesSyncManifestResponse
|
||||
(*CreateSchematicRequest)(nil), // 22: management.CreateSchematicRequest
|
||||
(*CreateSchematicResponse)(nil), // 23: management.CreateSchematicResponse
|
||||
(*GetSupportBundleRequest)(nil), // 24: management.GetSupportBundleRequest
|
||||
(*GetSupportBundleResponse)(nil), // 25: management.GetSupportBundleResponse
|
||||
(*ReadAuditLogRequest)(nil), // 26: management.ReadAuditLogRequest
|
||||
(*ReadAuditLogResponse)(nil), // 27: management.ReadAuditLogResponse
|
||||
(*ValidateJsonSchemaRequest)(nil), // 28: management.ValidateJsonSchemaRequest
|
||||
(*ValidateJsonSchemaResponse)(nil), // 29: management.ValidateJsonSchemaResponse
|
||||
(*MaintenanceUpgradeRequest)(nil), // 30: management.MaintenanceUpgradeRequest
|
||||
(*MaintenanceUpgradeResponse)(nil), // 31: management.MaintenanceUpgradeResponse
|
||||
(*GetMachineJoinConfigRequest)(nil), // 32: management.GetMachineJoinConfigRequest
|
||||
(*GetMachineJoinConfigResponse)(nil), // 33: management.GetMachineJoinConfigResponse
|
||||
(*GenJoinTokenResponse)(nil), // 34: management.GenJoinTokenResponse
|
||||
(*CreateJoinTokenRequest)(nil), // 35: management.CreateJoinTokenRequest
|
||||
(*CreateJoinTokenResponse)(nil), // 36: management.CreateJoinTokenResponse
|
||||
(*ResetNodeUniqueTokenRequest)(nil), // 37: management.ResetNodeUniqueTokenRequest
|
||||
(*ResetNodeUniqueTokenResponse)(nil), // 38: management.ResetNodeUniqueTokenResponse
|
||||
(*CreateUserRequest)(nil), // 39: management.CreateUserRequest
|
||||
(*CreateUserResponse)(nil), // 40: management.CreateUserResponse
|
||||
(*UpdateUserRequest)(nil), // 41: management.UpdateUserRequest
|
||||
(*DestroyUserRequest)(nil), // 42: management.DestroyUserRequest
|
||||
(*ListUsersResponse)(nil), // 43: management.ListUsersResponse
|
||||
(*ListServiceAccountsResponse_ServiceAccount)(nil), // 44: management.ListServiceAccountsResponse.ServiceAccount
|
||||
(*ListServiceAccountsResponse_ServiceAccount_PgpPublicKey)(nil), // 45: management.ListServiceAccountsResponse.ServiceAccount.PgpPublicKey
|
||||
(*CreateSchematicRequest_Overlay)(nil), // 46: management.CreateSchematicRequest.Overlay
|
||||
nil, // 47: management.CreateSchematicRequest.MetaValuesEntry
|
||||
(*GetSupportBundleResponse_Progress)(nil), // 48: management.GetSupportBundleResponse.Progress
|
||||
(*ValidateJsonSchemaResponse_Error)(nil), // 49: management.ValidateJsonSchemaResponse.Error
|
||||
(*ListUsersResponse_User)(nil), // 50: management.ListUsersResponse.User
|
||||
nil, // 51: management.ListUsersResponse.User.SamlLabelsEntry
|
||||
(*durationpb.Duration)(nil), // 52: google.protobuf.Duration
|
||||
(*timestamppb.Timestamp)(nil), // 53: google.protobuf.Timestamp
|
||||
(*emptypb.Empty)(nil), // 54: google.protobuf.Empty
|
||||
(*common.Data)(nil), // 55: common.Data
|
||||
(AuditLogEventType)(0), // 1: management.AuditLogEventType
|
||||
(AuditLogOrderByField)(0), // 2: management.AuditLogOrderByField
|
||||
(AuditLogOrderByDir)(0), // 3: management.AuditLogOrderByDir
|
||||
(KubernetesSSAOptions_InventoryPolicy)(0), // 4: management.KubernetesSSAOptions.InventoryPolicy
|
||||
(KubernetesSyncManifestResponse_ResponseType)(0), // 5: management.KubernetesSyncManifestResponse.ResponseType
|
||||
(CreateSchematicRequest_SiderolinkGRPCTunnelMode)(0), // 6: management.CreateSchematicRequest.SiderolinkGRPCTunnelMode
|
||||
(*KubeconfigResponse)(nil), // 7: management.KubeconfigResponse
|
||||
(*TalosconfigResponse)(nil), // 8: management.TalosconfigResponse
|
||||
(*OmniconfigResponse)(nil), // 9: management.OmniconfigResponse
|
||||
(*MachineLogsRequest)(nil), // 10: management.MachineLogsRequest
|
||||
(*ValidateConfigRequest)(nil), // 11: management.ValidateConfigRequest
|
||||
(*TalosconfigRequest)(nil), // 12: management.TalosconfigRequest
|
||||
(*CreateServiceAccountRequest)(nil), // 13: management.CreateServiceAccountRequest
|
||||
(*CreateServiceAccountResponse)(nil), // 14: management.CreateServiceAccountResponse
|
||||
(*RenewServiceAccountRequest)(nil), // 15: management.RenewServiceAccountRequest
|
||||
(*RenewServiceAccountResponse)(nil), // 16: management.RenewServiceAccountResponse
|
||||
(*DestroyServiceAccountRequest)(nil), // 17: management.DestroyServiceAccountRequest
|
||||
(*ListServiceAccountsResponse)(nil), // 18: management.ListServiceAccountsResponse
|
||||
(*KubeconfigRequest)(nil), // 19: management.KubeconfigRequest
|
||||
(*KubernetesUpgradePreChecksRequest)(nil), // 20: management.KubernetesUpgradePreChecksRequest
|
||||
(*KubernetesUpgradePreChecksResponse)(nil), // 21: management.KubernetesUpgradePreChecksResponse
|
||||
(*KubernetesSSAOptions)(nil), // 22: management.KubernetesSSAOptions
|
||||
(*KubernetesSyncManifestRequest)(nil), // 23: management.KubernetesSyncManifestRequest
|
||||
(*KubernetesSyncManifestResponse)(nil), // 24: management.KubernetesSyncManifestResponse
|
||||
(*CreateSchematicRequest)(nil), // 25: management.CreateSchematicRequest
|
||||
(*CreateSchematicResponse)(nil), // 26: management.CreateSchematicResponse
|
||||
(*GetSupportBundleRequest)(nil), // 27: management.GetSupportBundleRequest
|
||||
(*GetSupportBundleResponse)(nil), // 28: management.GetSupportBundleResponse
|
||||
(*ReadAuditLogRequest)(nil), // 29: management.ReadAuditLogRequest
|
||||
(*ReadAuditLogResponse)(nil), // 30: management.ReadAuditLogResponse
|
||||
(*ValidateJsonSchemaRequest)(nil), // 31: management.ValidateJsonSchemaRequest
|
||||
(*ValidateJsonSchemaResponse)(nil), // 32: management.ValidateJsonSchemaResponse
|
||||
(*MaintenanceUpgradeRequest)(nil), // 33: management.MaintenanceUpgradeRequest
|
||||
(*MaintenanceUpgradeResponse)(nil), // 34: management.MaintenanceUpgradeResponse
|
||||
(*GetMachineJoinConfigRequest)(nil), // 35: management.GetMachineJoinConfigRequest
|
||||
(*GetMachineJoinConfigResponse)(nil), // 36: management.GetMachineJoinConfigResponse
|
||||
(*GenJoinTokenResponse)(nil), // 37: management.GenJoinTokenResponse
|
||||
(*CreateJoinTokenRequest)(nil), // 38: management.CreateJoinTokenRequest
|
||||
(*CreateJoinTokenResponse)(nil), // 39: management.CreateJoinTokenResponse
|
||||
(*ResetNodeUniqueTokenRequest)(nil), // 40: management.ResetNodeUniqueTokenRequest
|
||||
(*ResetNodeUniqueTokenResponse)(nil), // 41: management.ResetNodeUniqueTokenResponse
|
||||
(*CreateUserRequest)(nil), // 42: management.CreateUserRequest
|
||||
(*CreateUserResponse)(nil), // 43: management.CreateUserResponse
|
||||
(*UpdateUserRequest)(nil), // 44: management.UpdateUserRequest
|
||||
(*DestroyUserRequest)(nil), // 45: management.DestroyUserRequest
|
||||
(*ListUsersResponse)(nil), // 46: management.ListUsersResponse
|
||||
(*ListServiceAccountsResponse_ServiceAccount)(nil), // 47: management.ListServiceAccountsResponse.ServiceAccount
|
||||
(*ListServiceAccountsResponse_ServiceAccount_PgpPublicKey)(nil), // 48: management.ListServiceAccountsResponse.ServiceAccount.PgpPublicKey
|
||||
(*CreateSchematicRequest_Overlay)(nil), // 49: management.CreateSchematicRequest.Overlay
|
||||
nil, // 50: management.CreateSchematicRequest.MetaValuesEntry
|
||||
(*GetSupportBundleResponse_Progress)(nil), // 51: management.GetSupportBundleResponse.Progress
|
||||
(*ValidateJsonSchemaResponse_Error)(nil), // 52: management.ValidateJsonSchemaResponse.Error
|
||||
(*ListUsersResponse_User)(nil), // 53: management.ListUsersResponse.User
|
||||
nil, // 54: management.ListUsersResponse.User.SamlLabelsEntry
|
||||
(*durationpb.Duration)(nil), // 55: google.protobuf.Duration
|
||||
(*timestamppb.Timestamp)(nil), // 56: google.protobuf.Timestamp
|
||||
(*emptypb.Empty)(nil), // 57: google.protobuf.Empty
|
||||
(*common.Data)(nil), // 58: common.Data
|
||||
}
|
||||
var file_omni_management_management_proto_depIdxs = []int32{
|
||||
44, // 0: management.ListServiceAccountsResponse.service_accounts:type_name -> management.ListServiceAccountsResponse.ServiceAccount
|
||||
52, // 1: management.KubeconfigRequest.service_account_ttl:type_name -> google.protobuf.Duration
|
||||
1, // 2: management.KubernetesSSAOptions.inventory_policy:type_name -> management.KubernetesSSAOptions.InventoryPolicy
|
||||
52, // 3: management.KubernetesSSAOptions.reconcile_timeout:type_name -> google.protobuf.Duration
|
||||
19, // 4: management.KubernetesSyncManifestRequest.ssa:type_name -> management.KubernetesSSAOptions
|
||||
2, // 5: management.KubernetesSyncManifestResponse.response_type:type_name -> management.KubernetesSyncManifestResponse.ResponseType
|
||||
47, // 6: management.CreateSchematicRequest.meta_values:type_name -> management.CreateSchematicRequest.MetaValuesEntry
|
||||
3, // 7: management.CreateSchematicRequest.siderolink_grpc_tunnel_mode:type_name -> management.CreateSchematicRequest.SiderolinkGRPCTunnelMode
|
||||
46, // 8: management.CreateSchematicRequest.overlay:type_name -> management.CreateSchematicRequest.Overlay
|
||||
47, // 0: management.ListServiceAccountsResponse.service_accounts:type_name -> management.ListServiceAccountsResponse.ServiceAccount
|
||||
55, // 1: management.KubeconfigRequest.service_account_ttl:type_name -> google.protobuf.Duration
|
||||
4, // 2: management.KubernetesSSAOptions.inventory_policy:type_name -> management.KubernetesSSAOptions.InventoryPolicy
|
||||
55, // 3: management.KubernetesSSAOptions.reconcile_timeout:type_name -> google.protobuf.Duration
|
||||
22, // 4: management.KubernetesSyncManifestRequest.ssa:type_name -> management.KubernetesSSAOptions
|
||||
5, // 5: management.KubernetesSyncManifestResponse.response_type:type_name -> management.KubernetesSyncManifestResponse.ResponseType
|
||||
50, // 6: management.CreateSchematicRequest.meta_values:type_name -> management.CreateSchematicRequest.MetaValuesEntry
|
||||
6, // 7: management.CreateSchematicRequest.siderolink_grpc_tunnel_mode:type_name -> management.CreateSchematicRequest.SiderolinkGRPCTunnelMode
|
||||
49, // 8: management.CreateSchematicRequest.overlay:type_name -> management.CreateSchematicRequest.Overlay
|
||||
0, // 9: management.CreateSchematicRequest.bootloader:type_name -> management.SchematicBootloader
|
||||
48, // 10: management.GetSupportBundleResponse.progress:type_name -> management.GetSupportBundleResponse.Progress
|
||||
49, // 11: management.ValidateJsonSchemaResponse.errors:type_name -> management.ValidateJsonSchemaResponse.Error
|
||||
53, // 12: management.CreateJoinTokenRequest.expiration_time:type_name -> google.protobuf.Timestamp
|
||||
50, // 13: management.ListUsersResponse.users:type_name -> management.ListUsersResponse.User
|
||||
45, // 14: management.ListServiceAccountsResponse.ServiceAccount.pgp_public_keys:type_name -> management.ListServiceAccountsResponse.ServiceAccount.PgpPublicKey
|
||||
53, // 15: management.ListServiceAccountsResponse.ServiceAccount.PgpPublicKey.expiration:type_name -> google.protobuf.Timestamp
|
||||
53, // 16: management.ListServiceAccountsResponse.ServiceAccount.PgpPublicKey.created:type_name -> google.protobuf.Timestamp
|
||||
53, // 17: management.ListServiceAccountsResponse.ServiceAccount.PgpPublicKey.last_used:type_name -> google.protobuf.Timestamp
|
||||
49, // 18: management.ValidateJsonSchemaResponse.Error.errors:type_name -> management.ValidateJsonSchemaResponse.Error
|
||||
51, // 19: management.ListUsersResponse.User.saml_labels:type_name -> management.ListUsersResponse.User.SamlLabelsEntry
|
||||
16, // 20: management.ManagementService.Kubeconfig:input_type -> management.KubeconfigRequest
|
||||
9, // 21: management.ManagementService.Talosconfig:input_type -> management.TalosconfigRequest
|
||||
54, // 22: management.ManagementService.Omniconfig:input_type -> google.protobuf.Empty
|
||||
7, // 23: management.ManagementService.MachineLogs:input_type -> management.MachineLogsRequest
|
||||
8, // 24: management.ManagementService.ValidateConfig:input_type -> management.ValidateConfigRequest
|
||||
28, // 25: management.ManagementService.ValidateJSONSchema:input_type -> management.ValidateJsonSchemaRequest
|
||||
10, // 26: management.ManagementService.CreateServiceAccount:input_type -> management.CreateServiceAccountRequest
|
||||
12, // 27: management.ManagementService.RenewServiceAccount:input_type -> management.RenewServiceAccountRequest
|
||||
54, // 28: management.ManagementService.ListServiceAccounts:input_type -> google.protobuf.Empty
|
||||
14, // 29: management.ManagementService.DestroyServiceAccount:input_type -> management.DestroyServiceAccountRequest
|
||||
17, // 30: management.ManagementService.KubernetesUpgradePreChecks:input_type -> management.KubernetesUpgradePreChecksRequest
|
||||
20, // 31: management.ManagementService.KubernetesSyncManifests:input_type -> management.KubernetesSyncManifestRequest
|
||||
22, // 32: management.ManagementService.CreateSchematic:input_type -> management.CreateSchematicRequest
|
||||
24, // 33: management.ManagementService.GetSupportBundle:input_type -> management.GetSupportBundleRequest
|
||||
26, // 34: management.ManagementService.ReadAuditLog:input_type -> management.ReadAuditLogRequest
|
||||
30, // 35: management.ManagementService.MaintenanceUpgrade:input_type -> management.MaintenanceUpgradeRequest
|
||||
32, // 36: management.ManagementService.GetMachineJoinConfig:input_type -> management.GetMachineJoinConfigRequest
|
||||
35, // 37: management.ManagementService.CreateJoinToken:input_type -> management.CreateJoinTokenRequest
|
||||
37, // 38: management.ManagementService.ResetNodeUniqueToken:input_type -> management.ResetNodeUniqueTokenRequest
|
||||
39, // 39: management.ManagementService.CreateUser:input_type -> management.CreateUserRequest
|
||||
54, // 40: management.ManagementService.ListUsers:input_type -> google.protobuf.Empty
|
||||
41, // 41: management.ManagementService.UpdateUser:input_type -> management.UpdateUserRequest
|
||||
42, // 42: management.ManagementService.DestroyUser:input_type -> management.DestroyUserRequest
|
||||
4, // 43: management.ManagementService.Kubeconfig:output_type -> management.KubeconfigResponse
|
||||
5, // 44: management.ManagementService.Talosconfig:output_type -> management.TalosconfigResponse
|
||||
6, // 45: management.ManagementService.Omniconfig:output_type -> management.OmniconfigResponse
|
||||
55, // 46: management.ManagementService.MachineLogs:output_type -> common.Data
|
||||
54, // 47: management.ManagementService.ValidateConfig:output_type -> google.protobuf.Empty
|
||||
29, // 48: management.ManagementService.ValidateJSONSchema:output_type -> management.ValidateJsonSchemaResponse
|
||||
11, // 49: management.ManagementService.CreateServiceAccount:output_type -> management.CreateServiceAccountResponse
|
||||
13, // 50: management.ManagementService.RenewServiceAccount:output_type -> management.RenewServiceAccountResponse
|
||||
15, // 51: management.ManagementService.ListServiceAccounts:output_type -> management.ListServiceAccountsResponse
|
||||
54, // 52: management.ManagementService.DestroyServiceAccount:output_type -> google.protobuf.Empty
|
||||
18, // 53: management.ManagementService.KubernetesUpgradePreChecks:output_type -> management.KubernetesUpgradePreChecksResponse
|
||||
21, // 54: management.ManagementService.KubernetesSyncManifests:output_type -> management.KubernetesSyncManifestResponse
|
||||
23, // 55: management.ManagementService.CreateSchematic:output_type -> management.CreateSchematicResponse
|
||||
25, // 56: management.ManagementService.GetSupportBundle:output_type -> management.GetSupportBundleResponse
|
||||
27, // 57: management.ManagementService.ReadAuditLog:output_type -> management.ReadAuditLogResponse
|
||||
31, // 58: management.ManagementService.MaintenanceUpgrade:output_type -> management.MaintenanceUpgradeResponse
|
||||
33, // 59: management.ManagementService.GetMachineJoinConfig:output_type -> management.GetMachineJoinConfigResponse
|
||||
36, // 60: management.ManagementService.CreateJoinToken:output_type -> management.CreateJoinTokenResponse
|
||||
38, // 61: management.ManagementService.ResetNodeUniqueToken:output_type -> management.ResetNodeUniqueTokenResponse
|
||||
40, // 62: management.ManagementService.CreateUser:output_type -> management.CreateUserResponse
|
||||
43, // 63: management.ManagementService.ListUsers:output_type -> management.ListUsersResponse
|
||||
54, // 64: management.ManagementService.UpdateUser:output_type -> google.protobuf.Empty
|
||||
54, // 65: management.ManagementService.DestroyUser:output_type -> google.protobuf.Empty
|
||||
43, // [43:66] is the sub-list for method output_type
|
||||
20, // [20:43] is the sub-list for method input_type
|
||||
20, // [20:20] is the sub-list for extension type_name
|
||||
20, // [20:20] is the sub-list for extension extendee
|
||||
0, // [0:20] is the sub-list for field type_name
|
||||
51, // 10: management.GetSupportBundleResponse.progress:type_name -> management.GetSupportBundleResponse.Progress
|
||||
2, // 11: management.ReadAuditLogRequest.order_by_field:type_name -> management.AuditLogOrderByField
|
||||
3, // 12: management.ReadAuditLogRequest.order_by_dir:type_name -> management.AuditLogOrderByDir
|
||||
1, // 13: management.ReadAuditLogRequest.event_type:type_name -> management.AuditLogEventType
|
||||
52, // 14: management.ValidateJsonSchemaResponse.errors:type_name -> management.ValidateJsonSchemaResponse.Error
|
||||
56, // 15: management.CreateJoinTokenRequest.expiration_time:type_name -> google.protobuf.Timestamp
|
||||
53, // 16: management.ListUsersResponse.users:type_name -> management.ListUsersResponse.User
|
||||
48, // 17: management.ListServiceAccountsResponse.ServiceAccount.pgp_public_keys:type_name -> management.ListServiceAccountsResponse.ServiceAccount.PgpPublicKey
|
||||
56, // 18: management.ListServiceAccountsResponse.ServiceAccount.PgpPublicKey.expiration:type_name -> google.protobuf.Timestamp
|
||||
56, // 19: management.ListServiceAccountsResponse.ServiceAccount.PgpPublicKey.created:type_name -> google.protobuf.Timestamp
|
||||
56, // 20: management.ListServiceAccountsResponse.ServiceAccount.PgpPublicKey.last_used:type_name -> google.protobuf.Timestamp
|
||||
52, // 21: management.ValidateJsonSchemaResponse.Error.errors:type_name -> management.ValidateJsonSchemaResponse.Error
|
||||
54, // 22: management.ListUsersResponse.User.saml_labels:type_name -> management.ListUsersResponse.User.SamlLabelsEntry
|
||||
19, // 23: management.ManagementService.Kubeconfig:input_type -> management.KubeconfigRequest
|
||||
12, // 24: management.ManagementService.Talosconfig:input_type -> management.TalosconfigRequest
|
||||
57, // 25: management.ManagementService.Omniconfig:input_type -> google.protobuf.Empty
|
||||
10, // 26: management.ManagementService.MachineLogs:input_type -> management.MachineLogsRequest
|
||||
11, // 27: management.ManagementService.ValidateConfig:input_type -> management.ValidateConfigRequest
|
||||
31, // 28: management.ManagementService.ValidateJSONSchema:input_type -> management.ValidateJsonSchemaRequest
|
||||
13, // 29: management.ManagementService.CreateServiceAccount:input_type -> management.CreateServiceAccountRequest
|
||||
15, // 30: management.ManagementService.RenewServiceAccount:input_type -> management.RenewServiceAccountRequest
|
||||
57, // 31: management.ManagementService.ListServiceAccounts:input_type -> google.protobuf.Empty
|
||||
17, // 32: management.ManagementService.DestroyServiceAccount:input_type -> management.DestroyServiceAccountRequest
|
||||
20, // 33: management.ManagementService.KubernetesUpgradePreChecks:input_type -> management.KubernetesUpgradePreChecksRequest
|
||||
23, // 34: management.ManagementService.KubernetesSyncManifests:input_type -> management.KubernetesSyncManifestRequest
|
||||
25, // 35: management.ManagementService.CreateSchematic:input_type -> management.CreateSchematicRequest
|
||||
27, // 36: management.ManagementService.GetSupportBundle:input_type -> management.GetSupportBundleRequest
|
||||
29, // 37: management.ManagementService.ReadAuditLog:input_type -> management.ReadAuditLogRequest
|
||||
33, // 38: management.ManagementService.MaintenanceUpgrade:input_type -> management.MaintenanceUpgradeRequest
|
||||
35, // 39: management.ManagementService.GetMachineJoinConfig:input_type -> management.GetMachineJoinConfigRequest
|
||||
38, // 40: management.ManagementService.CreateJoinToken:input_type -> management.CreateJoinTokenRequest
|
||||
40, // 41: management.ManagementService.ResetNodeUniqueToken:input_type -> management.ResetNodeUniqueTokenRequest
|
||||
42, // 42: management.ManagementService.CreateUser:input_type -> management.CreateUserRequest
|
||||
57, // 43: management.ManagementService.ListUsers:input_type -> google.protobuf.Empty
|
||||
44, // 44: management.ManagementService.UpdateUser:input_type -> management.UpdateUserRequest
|
||||
45, // 45: management.ManagementService.DestroyUser:input_type -> management.DestroyUserRequest
|
||||
7, // 46: management.ManagementService.Kubeconfig:output_type -> management.KubeconfigResponse
|
||||
8, // 47: management.ManagementService.Talosconfig:output_type -> management.TalosconfigResponse
|
||||
9, // 48: management.ManagementService.Omniconfig:output_type -> management.OmniconfigResponse
|
||||
58, // 49: management.ManagementService.MachineLogs:output_type -> common.Data
|
||||
57, // 50: management.ManagementService.ValidateConfig:output_type -> google.protobuf.Empty
|
||||
32, // 51: management.ManagementService.ValidateJSONSchema:output_type -> management.ValidateJsonSchemaResponse
|
||||
14, // 52: management.ManagementService.CreateServiceAccount:output_type -> management.CreateServiceAccountResponse
|
||||
16, // 53: management.ManagementService.RenewServiceAccount:output_type -> management.RenewServiceAccountResponse
|
||||
18, // 54: management.ManagementService.ListServiceAccounts:output_type -> management.ListServiceAccountsResponse
|
||||
57, // 55: management.ManagementService.DestroyServiceAccount:output_type -> google.protobuf.Empty
|
||||
21, // 56: management.ManagementService.KubernetesUpgradePreChecks:output_type -> management.KubernetesUpgradePreChecksResponse
|
||||
24, // 57: management.ManagementService.KubernetesSyncManifests:output_type -> management.KubernetesSyncManifestResponse
|
||||
26, // 58: management.ManagementService.CreateSchematic:output_type -> management.CreateSchematicResponse
|
||||
28, // 59: management.ManagementService.GetSupportBundle:output_type -> management.GetSupportBundleResponse
|
||||
30, // 60: management.ManagementService.ReadAuditLog:output_type -> management.ReadAuditLogResponse
|
||||
34, // 61: management.ManagementService.MaintenanceUpgrade:output_type -> management.MaintenanceUpgradeResponse
|
||||
36, // 62: management.ManagementService.GetMachineJoinConfig:output_type -> management.GetMachineJoinConfigResponse
|
||||
39, // 63: management.ManagementService.CreateJoinToken:output_type -> management.CreateJoinTokenResponse
|
||||
41, // 64: management.ManagementService.ResetNodeUniqueToken:output_type -> management.ResetNodeUniqueTokenResponse
|
||||
43, // 65: management.ManagementService.CreateUser:output_type -> management.CreateUserResponse
|
||||
46, // 66: management.ManagementService.ListUsers:output_type -> management.ListUsersResponse
|
||||
57, // 67: management.ManagementService.UpdateUser:output_type -> google.protobuf.Empty
|
||||
57, // 68: management.ManagementService.DestroyUser:output_type -> google.protobuf.Empty
|
||||
46, // [46:69] is the sub-list for method output_type
|
||||
23, // [23:46] is the sub-list for method input_type
|
||||
23, // [23:23] is the sub-list for extension type_name
|
||||
23, // [23:23] is the sub-list for extension extendee
|
||||
0, // [0:23] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_omni_management_management_proto_init() }
|
||||
@ -3155,7 +3433,7 @@ func file_omni_management_management_proto_init() {
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_omni_management_management_proto_rawDesc), len(file_omni_management_management_proto_rawDesc)),
|
||||
NumEnums: 4,
|
||||
NumEnums: 7,
|
||||
NumMessages: 48,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
|
||||
@ -112,7 +112,7 @@ message KubernetesUpgradePreChecksResponse {
|
||||
}
|
||||
|
||||
message KubernetesSSAOptions {
|
||||
enum InventoryPolicy {
|
||||
enum InventoryPolicy {
|
||||
MUST_MATCH = 0;
|
||||
ADOPT_IF_NO_INVENTORY = 1;
|
||||
ADOPT_ALL = 2;
|
||||
@ -199,10 +199,45 @@ message GetSupportBundleResponse {
|
||||
bytes bundle_data = 2;
|
||||
}
|
||||
|
||||
enum AuditLogEventType {
|
||||
AUDIT_LOG_EVENT_TYPE_UNSPECIFIED = 0;
|
||||
AUDIT_LOG_EVENT_TYPE_CREATE = 1;
|
||||
AUDIT_LOG_EVENT_TYPE_UPDATE = 2;
|
||||
AUDIT_LOG_EVENT_TYPE_UPDATE_WITH_CONFLICTS = 3;
|
||||
AUDIT_LOG_EVENT_TYPE_DESTROY = 4;
|
||||
AUDIT_LOG_EVENT_TYPE_TEARDOWN = 5;
|
||||
AUDIT_LOG_EVENT_TYPE_TALOS_ACCESS = 6;
|
||||
AUDIT_LOG_EVENT_TYPE_K8S_ACCESS = 7;
|
||||
}
|
||||
|
||||
enum AuditLogOrderByField {
|
||||
AUDIT_LOG_ORDER_BY_FIELD_UNSPECIFIED = 0;
|
||||
AUDIT_LOG_ORDER_BY_FIELD_DATE = 1;
|
||||
AUDIT_LOG_ORDER_BY_FIELD_EVENT_TYPE = 2;
|
||||
AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_TYPE = 3;
|
||||
AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_ID = 4;
|
||||
AUDIT_LOG_ORDER_BY_FIELD_CLUSTER_ID = 5;
|
||||
AUDIT_LOG_ORDER_BY_FIELD_ACTOR = 6;
|
||||
}
|
||||
|
||||
enum AuditLogOrderByDir {
|
||||
AUDIT_LOG_ORDER_BY_DIR_UNSPECIFIED = 0;
|
||||
AUDIT_LOG_ORDER_BY_DIR_ASC = 1;
|
||||
AUDIT_LOG_ORDER_BY_DIR_DESC = 2;
|
||||
}
|
||||
|
||||
// specifies start and end time (inclusive range) in <year>-<month>-<day> format. We pass time as string to avoid timezone issues.
|
||||
message ReadAuditLogRequest {
|
||||
string start_time = 1;
|
||||
string end_time = 2;
|
||||
AuditLogOrderByField order_by_field = 3;
|
||||
AuditLogOrderByDir order_by_dir = 4;
|
||||
string search = 5;
|
||||
AuditLogEventType event_type = 6;
|
||||
string resource_type = 7;
|
||||
string resource_id = 8;
|
||||
string cluster_id = 9;
|
||||
string actor = 10;
|
||||
}
|
||||
|
||||
message ReadAuditLogResponse {
|
||||
|
||||
@ -572,6 +572,14 @@ func (m *ReadAuditLogRequest) CloneVT() *ReadAuditLogRequest {
|
||||
r := new(ReadAuditLogRequest)
|
||||
r.StartTime = m.StartTime
|
||||
r.EndTime = m.EndTime
|
||||
r.OrderByField = m.OrderByField
|
||||
r.OrderByDir = m.OrderByDir
|
||||
r.Search = m.Search
|
||||
r.EventType = m.EventType
|
||||
r.ResourceType = m.ResourceType
|
||||
r.ResourceId = m.ResourceId
|
||||
r.ClusterId = m.ClusterId
|
||||
r.Actor = m.Actor
|
||||
if len(m.unknownFields) > 0 {
|
||||
r.unknownFields = make([]byte, len(m.unknownFields))
|
||||
copy(r.unknownFields, m.unknownFields)
|
||||
@ -1658,6 +1666,30 @@ func (this *ReadAuditLogRequest) EqualVT(that *ReadAuditLogRequest) bool {
|
||||
if this.EndTime != that.EndTime {
|
||||
return false
|
||||
}
|
||||
if this.OrderByField != that.OrderByField {
|
||||
return false
|
||||
}
|
||||
if this.OrderByDir != that.OrderByDir {
|
||||
return false
|
||||
}
|
||||
if this.Search != that.Search {
|
||||
return false
|
||||
}
|
||||
if this.EventType != that.EventType {
|
||||
return false
|
||||
}
|
||||
if this.ResourceType != that.ResourceType {
|
||||
return false
|
||||
}
|
||||
if this.ResourceId != that.ResourceId {
|
||||
return false
|
||||
}
|
||||
if this.ClusterId != that.ClusterId {
|
||||
return false
|
||||
}
|
||||
if this.Actor != that.Actor {
|
||||
return false
|
||||
}
|
||||
return string(this.unknownFields) == string(that.unknownFields)
|
||||
}
|
||||
|
||||
@ -3613,6 +3645,56 @@ func (m *ReadAuditLogRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
|
||||
i -= len(m.unknownFields)
|
||||
copy(dAtA[i:], m.unknownFields)
|
||||
}
|
||||
if len(m.Actor) > 0 {
|
||||
i -= len(m.Actor)
|
||||
copy(dAtA[i:], m.Actor)
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Actor)))
|
||||
i--
|
||||
dAtA[i] = 0x52
|
||||
}
|
||||
if len(m.ClusterId) > 0 {
|
||||
i -= len(m.ClusterId)
|
||||
copy(dAtA[i:], m.ClusterId)
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ClusterId)))
|
||||
i--
|
||||
dAtA[i] = 0x4a
|
||||
}
|
||||
if len(m.ResourceId) > 0 {
|
||||
i -= len(m.ResourceId)
|
||||
copy(dAtA[i:], m.ResourceId)
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ResourceId)))
|
||||
i--
|
||||
dAtA[i] = 0x42
|
||||
}
|
||||
if len(m.ResourceType) > 0 {
|
||||
i -= len(m.ResourceType)
|
||||
copy(dAtA[i:], m.ResourceType)
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ResourceType)))
|
||||
i--
|
||||
dAtA[i] = 0x3a
|
||||
}
|
||||
if m.EventType != 0 {
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(m.EventType))
|
||||
i--
|
||||
dAtA[i] = 0x30
|
||||
}
|
||||
if len(m.Search) > 0 {
|
||||
i -= len(m.Search)
|
||||
copy(dAtA[i:], m.Search)
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Search)))
|
||||
i--
|
||||
dAtA[i] = 0x2a
|
||||
}
|
||||
if m.OrderByDir != 0 {
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(m.OrderByDir))
|
||||
i--
|
||||
dAtA[i] = 0x20
|
||||
}
|
||||
if m.OrderByField != 0 {
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(m.OrderByField))
|
||||
i--
|
||||
dAtA[i] = 0x18
|
||||
}
|
||||
if len(m.EndTime) > 0 {
|
||||
i -= len(m.EndTime)
|
||||
copy(dAtA[i:], m.EndTime)
|
||||
@ -5076,6 +5158,35 @@ func (m *ReadAuditLogRequest) SizeVT() (n int) {
|
||||
if l > 0 {
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
if m.OrderByField != 0 {
|
||||
n += 1 + protohelpers.SizeOfVarint(uint64(m.OrderByField))
|
||||
}
|
||||
if m.OrderByDir != 0 {
|
||||
n += 1 + protohelpers.SizeOfVarint(uint64(m.OrderByDir))
|
||||
}
|
||||
l = len(m.Search)
|
||||
if l > 0 {
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
if m.EventType != 0 {
|
||||
n += 1 + protohelpers.SizeOfVarint(uint64(m.EventType))
|
||||
}
|
||||
l = len(m.ResourceType)
|
||||
if l > 0 {
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
l = len(m.ResourceId)
|
||||
if l > 0 {
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
l = len(m.ClusterId)
|
||||
if l > 0 {
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
l = len(m.Actor)
|
||||
if l > 0 {
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
n += len(m.unknownFields)
|
||||
return n
|
||||
}
|
||||
@ -9092,6 +9203,223 @@ func (m *ReadAuditLogRequest) UnmarshalVT(dAtA []byte) error {
|
||||
}
|
||||
m.EndTime = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field OrderByField", wireType)
|
||||
}
|
||||
m.OrderByField = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.OrderByField |= AuditLogOrderByField(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field OrderByDir", wireType)
|
||||
}
|
||||
m.OrderByDir = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.OrderByDir |= AuditLogOrderByDir(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 5:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Search", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Search = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 6:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field EventType", wireType)
|
||||
}
|
||||
m.EventType = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.EventType |= AuditLogEventType(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 7:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ResourceType", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ResourceType = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 8:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ResourceId", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ResourceId = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 9:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ClusterId", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ClusterId = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 10:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Actor", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Actor = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
|
||||
|
||||
@ -275,12 +275,9 @@ func (client *Client) GetSupportBundle(ctx context.Context, cluster string, prog
|
||||
}
|
||||
|
||||
// ReadAuditLog reads the audit log from the backend.
|
||||
func (client *Client) ReadAuditLog(ctx context.Context, start, end string) iter.Seq2[*management.ReadAuditLogResponse, error] {
|
||||
func (client *Client) ReadAuditLog(ctx context.Context, req *management.ReadAuditLogRequest) iter.Seq2[*management.ReadAuditLogResponse, error] {
|
||||
return func(yield func(*management.ReadAuditLogResponse, error) bool) {
|
||||
streamingResponse, err := client.conn.ReadAuditLog(ctx, &management.ReadAuditLogRequest{
|
||||
StartTime: start,
|
||||
EndTime: end,
|
||||
})
|
||||
streamingResponse, err := client.conn.ReadAuditLog(ctx, req)
|
||||
if err != nil {
|
||||
yield(nil, err)
|
||||
|
||||
|
||||
@ -6,14 +6,30 @@ package omnictl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/siderolabs/omni/client/api/omni/management"
|
||||
"github.com/siderolabs/omni/client/pkg/client"
|
||||
"github.com/siderolabs/omni/client/pkg/omnictl/internal/access"
|
||||
)
|
||||
|
||||
var auditLogFlags struct {
|
||||
search string
|
||||
eventType enumFlag[management.AuditLogEventType]
|
||||
orderByField enumFlag[management.AuditLogOrderByField]
|
||||
orderByDir enumFlag[management.AuditLogOrderByDir]
|
||||
resourceType string
|
||||
resourceID string
|
||||
clusterID string
|
||||
actor string
|
||||
}
|
||||
|
||||
// auditLog represents audit-log command.
|
||||
var auditLog = &cobra.Command{
|
||||
Use: "audit-log [start] [end]",
|
||||
@ -25,7 +41,18 @@ var auditLog = &cobra.Command{
|
||||
end := safeGet(arg, 1)
|
||||
|
||||
return access.WithClient(func(ctx context.Context, client *client.Client, _ access.ServerInfo) error {
|
||||
for resp, err := range client.Management().ReadAuditLog(ctx, start, end) {
|
||||
for resp, err := range client.Management().ReadAuditLog(ctx, &management.ReadAuditLogRequest{
|
||||
StartTime: start,
|
||||
EndTime: end,
|
||||
Search: auditLogFlags.search,
|
||||
EventType: auditLogFlags.eventType.value,
|
||||
OrderByField: auditLogFlags.orderByField.value,
|
||||
OrderByDir: auditLogFlags.orderByDir.value,
|
||||
ResourceType: auditLogFlags.resourceType,
|
||||
ResourceId: auditLogFlags.resourceID,
|
||||
ClusterId: auditLogFlags.clusterID,
|
||||
Actor: auditLogFlags.actor,
|
||||
}) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -41,6 +68,42 @@ var auditLog = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
// enumFlag is a pflag.Value implementation for proto enum types. It validates
|
||||
// the input against a fixed set of allowed string values and stores the
|
||||
// corresponding proto enum value.
|
||||
type enumFlag[T ~int32] struct {
|
||||
value T
|
||||
allowed map[string]T
|
||||
}
|
||||
|
||||
// String implements pflag.Value.
|
||||
func (f *enumFlag[T]) String() string {
|
||||
for k, v := range f.allowed {
|
||||
if v == f.value {
|
||||
return k
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// Set implements pflag.Value.
|
||||
func (f *enumFlag[T]) Set(s string) error {
|
||||
v, ok := f.allowed[s]
|
||||
if !ok {
|
||||
return fmt.Errorf("must be one of: %s", strings.Join(slices.Sorted(maps.Keys(f.allowed)), ", "))
|
||||
}
|
||||
|
||||
f.value = v
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type implements pflag.Value.
|
||||
func (f *enumFlag[T]) Type() string {
|
||||
return strings.Join(slices.Sorted(maps.Keys(f.allowed)), "|")
|
||||
}
|
||||
|
||||
func safeGet[T any](slc []T, pos int) T {
|
||||
if pos < len(slc) {
|
||||
return slc[pos]
|
||||
@ -50,5 +113,44 @@ func safeGet[T any](slc []T, pos int) T {
|
||||
}
|
||||
|
||||
func init() {
|
||||
auditLogFlags.eventType = enumFlag[management.AuditLogEventType]{
|
||||
allowed: map[string]management.AuditLogEventType{
|
||||
"create": management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_CREATE,
|
||||
"update": management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_UPDATE,
|
||||
"update_with_conflicts": management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_UPDATE_WITH_CONFLICTS,
|
||||
"destroy": management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_DESTROY,
|
||||
"teardown": management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_TEARDOWN,
|
||||
"talos_access": management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_TALOS_ACCESS,
|
||||
"k8s_access": management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_K8S_ACCESS,
|
||||
},
|
||||
}
|
||||
|
||||
auditLogFlags.orderByField = enumFlag[management.AuditLogOrderByField]{
|
||||
allowed: map[string]management.AuditLogOrderByField{
|
||||
"event_ts_ms": management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_DATE,
|
||||
"event_type": management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_EVENT_TYPE,
|
||||
"resource_type": management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_TYPE,
|
||||
"resource_id": management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_ID,
|
||||
"cluster_id": management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_CLUSTER_ID,
|
||||
"actor": management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_ACTOR,
|
||||
},
|
||||
}
|
||||
|
||||
auditLogFlags.orderByDir = enumFlag[management.AuditLogOrderByDir]{
|
||||
allowed: map[string]management.AuditLogOrderByDir{
|
||||
"asc": management.AuditLogOrderByDir_AUDIT_LOG_ORDER_BY_DIR_ASC,
|
||||
"desc": management.AuditLogOrderByDir_AUDIT_LOG_ORDER_BY_DIR_DESC,
|
||||
},
|
||||
}
|
||||
|
||||
auditLog.Flags().StringVar(&auditLogFlags.search, "search", "", "filter events by a search string")
|
||||
auditLog.Flags().Var(&auditLogFlags.eventType, "event-type", "filter events by event type")
|
||||
auditLog.Flags().Var(&auditLogFlags.orderByField, "order-by-field", "field to sort results by")
|
||||
auditLog.Flags().Var(&auditLogFlags.orderByDir, "order-by-dir", "sort direction")
|
||||
auditLog.Flags().StringVar(&auditLogFlags.resourceType, "resource-type", "", "filter events by resource type")
|
||||
auditLog.Flags().StringVar(&auditLogFlags.resourceID, "resource-id", "", "filter events by resource ID")
|
||||
auditLog.Flags().StringVar(&auditLogFlags.clusterID, "cluster-id", "", "filter events by cluster ID")
|
||||
auditLog.Flags().StringVar(&auditLogFlags.actor, "actor", "", "filter events by actor email")
|
||||
|
||||
RootCmd.AddCommand(auditLog)
|
||||
}
|
||||
|
||||
17
frontend/package-lock.json
generated
17
frontend/package-lock.json
generated
@ -18,6 +18,7 @@
|
||||
"@vueuse/components": "^14.2.1",
|
||||
"@vueuse/core": "^14.2.1",
|
||||
"@vueuse/integrations": "^14.2.1",
|
||||
"@vueuse/router": "^14.2.1",
|
||||
"apexcharts": "^5.10.6",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
@ -4149,6 +4150,22 @@
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/router": {
|
||||
"version": "14.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/router/-/router-14.2.1.tgz",
|
||||
"integrity": "sha512-SbZfJe+qn5bj78zNOXT4nYbnp8OIFMyAsdcJb4Y0y9vXi1TsOfglF+YIazi5DPO2lk6/ZukpN5DEQe6KrNOjMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vueuse/shared": "14.2.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.5.0",
|
||||
"vue-router": "^4.0.0 || ^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/shared": {
|
||||
"version": "14.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-14.2.1.tgz",
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
"@vueuse/components": "^14.2.1",
|
||||
"@vueuse/core": "^14.2.1",
|
||||
"@vueuse/integrations": "^14.2.1",
|
||||
"@vueuse/router": "^14.2.1",
|
||||
"apexcharts": "^5.10.6",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
|
||||
@ -17,6 +17,33 @@ export enum SchematicBootloader {
|
||||
BOOT_GRUB = 3,
|
||||
}
|
||||
|
||||
export enum AuditLogEventType {
|
||||
AUDIT_LOG_EVENT_TYPE_UNSPECIFIED = 0,
|
||||
AUDIT_LOG_EVENT_TYPE_CREATE = 1,
|
||||
AUDIT_LOG_EVENT_TYPE_UPDATE = 2,
|
||||
AUDIT_LOG_EVENT_TYPE_UPDATE_WITH_CONFLICTS = 3,
|
||||
AUDIT_LOG_EVENT_TYPE_DESTROY = 4,
|
||||
AUDIT_LOG_EVENT_TYPE_TEARDOWN = 5,
|
||||
AUDIT_LOG_EVENT_TYPE_TALOS_ACCESS = 6,
|
||||
AUDIT_LOG_EVENT_TYPE_K8S_ACCESS = 7,
|
||||
}
|
||||
|
||||
export enum AuditLogOrderByField {
|
||||
AUDIT_LOG_ORDER_BY_FIELD_UNSPECIFIED = 0,
|
||||
AUDIT_LOG_ORDER_BY_FIELD_DATE = 1,
|
||||
AUDIT_LOG_ORDER_BY_FIELD_EVENT_TYPE = 2,
|
||||
AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_TYPE = 3,
|
||||
AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_ID = 4,
|
||||
AUDIT_LOG_ORDER_BY_FIELD_CLUSTER_ID = 5,
|
||||
AUDIT_LOG_ORDER_BY_FIELD_ACTOR = 6,
|
||||
}
|
||||
|
||||
export enum AuditLogOrderByDir {
|
||||
AUDIT_LOG_ORDER_BY_DIR_UNSPECIFIED = 0,
|
||||
AUDIT_LOG_ORDER_BY_DIR_ASC = 1,
|
||||
AUDIT_LOG_ORDER_BY_DIR_DESC = 2,
|
||||
}
|
||||
|
||||
export enum KubernetesSSAOptionsInventoryPolicy {
|
||||
MUST_MATCH = 0,
|
||||
ADOPT_IF_NO_INVENTORY = 1,
|
||||
@ -191,6 +218,14 @@ export type GetSupportBundleResponse = {
|
||||
export type ReadAuditLogRequest = {
|
||||
start_time?: string
|
||||
end_time?: string
|
||||
order_by_field?: AuditLogOrderByField
|
||||
order_by_dir?: AuditLogOrderByDir
|
||||
search?: string
|
||||
event_type?: AuditLogEventType
|
||||
resource_type?: string
|
||||
resource_id?: string
|
||||
cluster_id?: string
|
||||
actor?: string
|
||||
}
|
||||
|
||||
export type ReadAuditLogResponse = {
|
||||
|
||||
@ -11,13 +11,14 @@ const decoder = new TextDecoder()
|
||||
<script setup lang="ts">
|
||||
import { CollapsibleContent, CollapsibleRoot, CollapsibleTrigger } from 'reka-ui'
|
||||
import { computed } from 'vue'
|
||||
import WordHighlighter from 'vue-word-highlighter'
|
||||
|
||||
import CodeBlock from '@/components/CodeBlock/CodeBlock.vue'
|
||||
import TIcon from '@/components/Icon/TIcon.vue'
|
||||
import { formatISO } from '@/methods/time'
|
||||
import type { AuditLogEvent } from '@/pages/(authenticated)/settings/audit-logs.vue'
|
||||
|
||||
const { data } = defineProps<{ data: Uint8Array<ArrayBuffer> }>()
|
||||
const { data } = defineProps<{ data: Uint8Array<ArrayBuffer>; search: string }>()
|
||||
|
||||
const open = defineModel<boolean>({ default: false })
|
||||
|
||||
@ -72,29 +73,46 @@ function toggleRow() {
|
||||
</div>
|
||||
|
||||
<div role="cell">
|
||||
<span class="resource-label" :class="getLabelClassForEvent(item.event_type)">
|
||||
{{ item.event_type.toUpperCase() }}
|
||||
</span>
|
||||
<WordHighlighter
|
||||
v-if="item.event_type.toUpperCase()"
|
||||
:query="search"
|
||||
:text-to-highlight="item.event_type.toUpperCase()"
|
||||
highlight-class="bg-naturals-n14"
|
||||
class="resource-label"
|
||||
:class="getLabelClassForEvent(item.event_type)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div role="cell" class="truncate text-naturals-n10">
|
||||
{{ item.resource_type }}
|
||||
<WordHighlighter
|
||||
:query="search"
|
||||
:text-to-highlight="item.resource_type"
|
||||
highlight-class="bg-naturals-n14"
|
||||
class="text-naturals-n14"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div role="cell" class="min-w-20 space-x-2 truncate whitespace-nowrap">
|
||||
<span class="text-naturals-n14">
|
||||
{{
|
||||
item.event_data.session.role ? item.event_data.session.role : 'System / Service Account'
|
||||
}}
|
||||
</span>
|
||||
<WordHighlighter
|
||||
v-if="item.event_data.session.role"
|
||||
:query="search"
|
||||
:text-to-highlight="item.event_data.session.role"
|
||||
highlight-class="bg-naturals-n14"
|
||||
class="text-naturals-n14"
|
||||
/>
|
||||
|
||||
<span class="text-naturals-n10">
|
||||
{{
|
||||
<span v-else class="text-naturals-n14">System / Service Account</span>
|
||||
|
||||
<WordHighlighter
|
||||
:query="search"
|
||||
:text-to-highlight="
|
||||
item.event_data.session.email
|
||||
? item.event_data.session.email
|
||||
: item.event_data.session.user_agent
|
||||
}}
|
||||
</span>
|
||||
"
|
||||
highlight-class="bg-naturals-n14"
|
||||
class="text-naturals-n10"
|
||||
/>
|
||||
</div>
|
||||
</CollapsibleTrigger>
|
||||
|
||||
@ -103,7 +121,14 @@ function toggleRow() {
|
||||
class="collapsible-content col-span-full overflow-hidden group-hover/root:bg-white/5"
|
||||
>
|
||||
<div role="cell" class="px-2 pb-2">
|
||||
<CodeBlock :code="JSON.stringify(item, null, 2)" />
|
||||
<CodeBlock>
|
||||
<WordHighlighter
|
||||
:query="search"
|
||||
:text-to-highlight="JSON.stringify(item, null, 2)"
|
||||
highlight-class="bg-naturals-n14"
|
||||
class="text-naturals-n10"
|
||||
/>
|
||||
</CodeBlock>
|
||||
</div>
|
||||
</CollapsibleContent>
|
||||
</CollapsibleRoot>
|
||||
|
||||
@ -26,7 +26,9 @@ const { code = '', buttonAttrs } = defineProps<Props>()
|
||||
</div>
|
||||
|
||||
<div class="p-1">
|
||||
<pre class="overflow-auto px-3 py-1 font-mono text-xs/6 whitespace-pre">{{ code }}</pre>
|
||||
<pre
|
||||
class="overflow-auto px-3 py-1 font-mono text-xs/6 whitespace-pre"
|
||||
><slot v-if="!code"></slot><template v-else>{{ code }}</template></pre>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -37,6 +37,7 @@ import TIcon from '@/components/Icon/TIcon.vue'
|
||||
interface Props extends DateRangePickerRootProps {
|
||||
title: string
|
||||
hiddenTitle?: boolean
|
||||
inlineTitle?: boolean
|
||||
}
|
||||
|
||||
// eslint-disable-next-line vue/define-props-destructuring
|
||||
@ -50,7 +51,7 @@ const id = useId()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="inline-flex flex-col gap-2">
|
||||
<div class="inline-flex gap-2" :class="inlineTitle ? 'items-center' : 'flex-col'">
|
||||
<Label class="text-sm text-naturals-n14" :class="{ 'sr-only': hiddenTitle }" :for="id">
|
||||
{{ title }}
|
||||
</Label>
|
||||
|
||||
@ -32,6 +32,8 @@ export interface AuditLogMsg {
|
||||
<script setup lang="ts">
|
||||
import { getLocalTimeZone, today } from '@internationalized/date'
|
||||
import { useVirtualizer } from '@tanstack/vue-virtual'
|
||||
import { refDebounced } from '@vueuse/core'
|
||||
import { useRouteQuery } from '@vueuse/router'
|
||||
import { differenceInDays } from 'date-fns'
|
||||
import { type DateRange } from 'reka-ui'
|
||||
import {
|
||||
@ -44,12 +46,15 @@ import {
|
||||
watch,
|
||||
} from 'vue'
|
||||
|
||||
import { AuditLogOrderByDir, AuditLogOrderByField } from '@/api/omni/management/management.pb'
|
||||
import AuditLogItem from '@/components/AuditLogs/AuditLogItem.vue'
|
||||
import TButton from '@/components/Button/TButton.vue'
|
||||
import DateRangePicker from '@/components/DateRangePicker/DateRangePicker.vue'
|
||||
import TIcon from '@/components/Icon/TIcon.vue'
|
||||
import PageContainer from '@/components/PageContainer/PageContainer.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
import TAlert from '@/components/TAlert.vue'
|
||||
import TInput from '@/components/TInput/TInput.vue'
|
||||
import { useReadAuditLog } from '@/views/Settings/useReadAuditLog'
|
||||
|
||||
definePage({ name: 'AuditLogs' })
|
||||
@ -59,10 +64,44 @@ const dateRange = shallowRef<DateRange>({
|
||||
end: today(getLocalTimeZone()).add({ days: 1 }),
|
||||
})
|
||||
|
||||
const { data, loading } = useReadAuditLog(() => ({
|
||||
const searchInput = useRouteQuery('search', '')
|
||||
const search = refDebounced(searchInput, 500)
|
||||
|
||||
const orderByField = useRouteQuery(
|
||||
'orderByField',
|
||||
AuditLogOrderByField.AUDIT_LOG_ORDER_BY_FIELD_DATE,
|
||||
{ transform: (v) => Number(v) as AuditLogOrderByField },
|
||||
)
|
||||
|
||||
const orderByDir = useRouteQuery('orderByDir', AuditLogOrderByDir.AUDIT_LOG_ORDER_BY_DIR_ASC, {
|
||||
transform: (v) => Number(v) as AuditLogOrderByDir,
|
||||
})
|
||||
|
||||
const tableHeaders = [
|
||||
{ label: 'Timestamp', value: AuditLogOrderByField.AUDIT_LOG_ORDER_BY_FIELD_DATE },
|
||||
{ label: 'Type', value: AuditLogOrderByField.AUDIT_LOG_ORDER_BY_FIELD_EVENT_TYPE },
|
||||
{ label: 'Resource', value: AuditLogOrderByField.AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_TYPE },
|
||||
{ label: 'Actor', value: AuditLogOrderByField.AUDIT_LOG_ORDER_BY_FIELD_ACTOR },
|
||||
]
|
||||
|
||||
function toggleSort(value: AuditLogOrderByField) {
|
||||
if (orderByField.value !== value) {
|
||||
orderByField.value = value
|
||||
orderByDir.value = AuditLogOrderByDir.AUDIT_LOG_ORDER_BY_DIR_ASC
|
||||
} else if (orderByDir.value === AuditLogOrderByDir.AUDIT_LOG_ORDER_BY_DIR_ASC) {
|
||||
orderByDir.value = AuditLogOrderByDir.AUDIT_LOG_ORDER_BY_DIR_DESC
|
||||
} else {
|
||||
orderByDir.value = AuditLogOrderByDir.AUDIT_LOG_ORDER_BY_DIR_ASC
|
||||
}
|
||||
}
|
||||
|
||||
const { data, loading, error } = useReadAuditLog(() => ({
|
||||
options: {
|
||||
start_time: dateRange.value.start?.toString(),
|
||||
end_time: dateRange.value.end?.toString(),
|
||||
search: search.value,
|
||||
order_by_field: orderByField.value,
|
||||
order_by_dir: orderByDir.value,
|
||||
},
|
||||
}))
|
||||
|
||||
@ -118,8 +157,12 @@ function measureElement(el: Element | ComponentPublicInstance | null) {
|
||||
</TButton>
|
||||
</div>
|
||||
|
||||
<TAlert v-if="error" type="error" title="Error" class="mb-4">{{ error.message }}</TAlert>
|
||||
|
||||
<TInput v-model="searchInput" class="mb-2" title="Search" />
|
||||
|
||||
<div class="mb-4 flex justify-end gap-2">
|
||||
<DateRangePicker v-model="dateRange" title="Date range" hidden-title />
|
||||
<DateRangePicker v-model="dateRange" title="Date range" inline-title />
|
||||
</div>
|
||||
|
||||
<TAlert
|
||||
@ -145,10 +188,26 @@ function measureElement(el: Element | ComponentPublicInstance | null) {
|
||||
class="grid shrink-0 grid-cols-[36px_160px_180px_220px_1fr] gap-x-0.5 bg-naturals-n2 px-2 text-left"
|
||||
>
|
||||
<div role="columnheader" aria-hidden="true" class="py-2 uppercase"></div>
|
||||
<div role="columnheader" class="py-2 uppercase">Timestamp</div>
|
||||
<div role="columnheader" class="py-2 uppercase">Type</div>
|
||||
<div role="columnheader" class="py-2 uppercase">Resource</div>
|
||||
<div role="columnheader" class="py-2 uppercase">Actor</div>
|
||||
<div
|
||||
v-for="{ label, value } in tableHeaders"
|
||||
:key="value"
|
||||
role="columnheader"
|
||||
class="cursor-pointer py-2 uppercase transition-colors select-none hover:text-naturals-n11 active:text-naturals-n9"
|
||||
@click="toggleSort(value)"
|
||||
>
|
||||
<span class="inline-flex items-center">
|
||||
{{ label }}
|
||||
|
||||
<TIcon
|
||||
class="size-5 text-naturals-n10 transition-transform"
|
||||
icon="dropdown"
|
||||
:class="{
|
||||
invisible: orderByField !== value,
|
||||
'rotate-180': orderByDir === AuditLogOrderByDir.AUDIT_LOG_ORDER_BY_DIR_ASC,
|
||||
}"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ref="scrollContainer" role="rowgroup" class="min-h-0 flex-1 overflow-y-auto">
|
||||
@ -167,6 +226,7 @@ function measureElement(el: Element | ComponentPublicInstance | null) {
|
||||
<AuditLogItem
|
||||
:data="data[vRow.index]"
|
||||
:model-value="expandedRows.has(vRow.index)"
|
||||
:search
|
||||
@update:model-value="toggleRow(vRow.index)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -507,23 +507,35 @@ func (s *managementServer) KubernetesUpgradePreChecks(ctx context.Context, req *
|
||||
func (s *managementServer) ReadAuditLog(req *management.ReadAuditLogRequest, srv grpc.ServerStreamingServer[management.ReadAuditLogResponse]) error {
|
||||
ctx := srv.Context()
|
||||
|
||||
if _, err := s.authCheckGRPC(ctx, auth.WithRole(role.Admin)); err != nil {
|
||||
_, err := s.authCheckGRPC(ctx, auth.WithRole(role.Admin))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
start, err := parseTime(req.GetStartTime(), now.AddDate(0, 0, -29))
|
||||
filters := auditlog.ReadFilters{
|
||||
OrderByField: auditLogOrderByField(req.GetOrderByField()),
|
||||
OrderByDir: auditLogOrderByDir(req.GetOrderByDir()),
|
||||
Search: req.GetSearch(),
|
||||
EventType: auditLogEventType(req.GetEventType()),
|
||||
ResourceType: req.GetResourceType(),
|
||||
ResourceID: req.GetResourceId(),
|
||||
ClusterID: req.GetClusterId(),
|
||||
Actor: req.GetActor(),
|
||||
}
|
||||
|
||||
filters.Start, err = parseTime(req.GetStartTime(), now.AddDate(0, 0, -29))
|
||||
if err != nil {
|
||||
return status.Errorf(codes.InvalidArgument, "invalid start time: %v", err)
|
||||
}
|
||||
|
||||
end, err := parseTime(req.GetEndTime(), now)
|
||||
filters.End, err = parseTime(req.GetEndTime(), now)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.InvalidArgument, "invalid end time: %v", err)
|
||||
}
|
||||
|
||||
rdr, err := s.auditor.Reader(ctx, start, end)
|
||||
rdr, err := s.auditor.Reader(ctx, filters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -819,5 +831,62 @@ func generateDest(apiurl string) (string, error) {
|
||||
|
||||
// AuditLogger is an interface for reading the audit log.
|
||||
type AuditLogger interface {
|
||||
Reader(ctx context.Context, start, end time.Time) (auditlog.Reader, error)
|
||||
Reader(ctx context.Context, filters auditlog.ReadFilters) (auditlog.Reader, error)
|
||||
}
|
||||
|
||||
func auditLogOrderByField(f management.AuditLogOrderByField) auditlog.OrderByField {
|
||||
switch f {
|
||||
case management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_UNSPECIFIED:
|
||||
return auditlog.OrderByFieldDate
|
||||
case management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_DATE:
|
||||
return auditlog.OrderByFieldDate
|
||||
case management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_EVENT_TYPE:
|
||||
return auditlog.OrderByFieldEventType
|
||||
case management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_TYPE:
|
||||
return auditlog.OrderByFieldResourceType
|
||||
case management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_RESOURCE_ID:
|
||||
return auditlog.OrderByFieldResourceID
|
||||
case management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_CLUSTER_ID:
|
||||
return auditlog.OrderByFieldClusterID
|
||||
case management.AuditLogOrderByField_AUDIT_LOG_ORDER_BY_FIELD_ACTOR:
|
||||
return auditlog.OrderByFieldActor
|
||||
}
|
||||
|
||||
return auditlog.OrderByFieldDate
|
||||
}
|
||||
|
||||
func auditLogOrderByDir(d management.AuditLogOrderByDir) auditlog.OrderByDir {
|
||||
switch d {
|
||||
case management.AuditLogOrderByDir_AUDIT_LOG_ORDER_BY_DIR_UNSPECIFIED:
|
||||
return auditlog.OrderByDirASC
|
||||
case management.AuditLogOrderByDir_AUDIT_LOG_ORDER_BY_DIR_ASC:
|
||||
return auditlog.OrderByDirASC
|
||||
case management.AuditLogOrderByDir_AUDIT_LOG_ORDER_BY_DIR_DESC:
|
||||
return auditlog.OrderByDirDESC
|
||||
}
|
||||
|
||||
return auditlog.OrderByDirASC
|
||||
}
|
||||
|
||||
func auditLogEventType(e management.AuditLogEventType) auditlog.EventType {
|
||||
switch e {
|
||||
case management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_UNSPECIFIED:
|
||||
return auditlog.EventTypeUnspecified
|
||||
case management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_CREATE:
|
||||
return auditlog.EventTypeCreate
|
||||
case management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_UPDATE:
|
||||
return auditlog.EventTypeUpdate
|
||||
case management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_UPDATE_WITH_CONFLICTS:
|
||||
return auditlog.EventTypeUpdateWithConflicts
|
||||
case management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_DESTROY:
|
||||
return auditlog.EventTypeDestroy
|
||||
case management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_TEARDOWN:
|
||||
return auditlog.EventTypeTeardown
|
||||
case management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_TALOS_ACCESS:
|
||||
return auditlog.EventTypeTalosAccess
|
||||
case management.AuditLogEventType_AUDIT_LOG_EVENT_TYPE_K8S_ACCESS:
|
||||
return auditlog.EventTypeK8SAccess
|
||||
}
|
||||
|
||||
return auditlog.EventTypeUnspecified
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ import (
|
||||
type Logger interface {
|
||||
Write(ctx context.Context, event auditlog.Event) error
|
||||
Remove(ctx context.Context, start, end time.Time) error
|
||||
Reader(ctx context.Context, start, end time.Time) (auditlog.Reader, error)
|
||||
Reader(ctx context.Context, filters auditlog.ReadFilters) (auditlog.Reader, error)
|
||||
}
|
||||
|
||||
// LogOption configures optional Log behavior.
|
||||
@ -107,8 +107,8 @@ func hooksResourceTypes[T any](l *Log, m map[resource.Type]T) []resource.Type {
|
||||
|
||||
// Reader reads the audit log file by file, oldest to newest within the given time range. The time range
|
||||
// is inclusive, and truncated to the day.
|
||||
func (l *Log) Reader(ctx context.Context, start, end time.Time) (auditlog.Reader, error) {
|
||||
return l.auditLogger.Reader(ctx, start, end)
|
||||
func (l *Log) Reader(ctx context.Context, filters auditlog.ReadFilters) (auditlog.Reader, error) {
|
||||
return l.auditLogger.Reader(ctx, filters)
|
||||
}
|
||||
|
||||
// LogCreate logs the resource creation if there is a hook for this type.
|
||||
|
||||
@ -108,7 +108,7 @@ func TestAudit(t *testing.T) {
|
||||
action(t)
|
||||
}
|
||||
|
||||
rdr, err := l.Reader(t.Context(), time.Time{}, time.Now().Add(5*time.Second))
|
||||
rdr, err := l.Reader(t.Context(), auditlog.ReadFilters{End: time.Now().Add(5 * time.Second)})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
@ -172,7 +172,7 @@ func TestPhaseChangeIsAudited(t *testing.T) {
|
||||
require.NoError(t, updateFn(createCtx(), res, newRes))
|
||||
|
||||
// Read all events and verify we got a teardown event.
|
||||
rdr, err := l.Reader(t.Context(), time.Time{}, time.Now().Add(5*time.Second))
|
||||
rdr, err := l.Reader(t.Context(), auditlog.ReadFilters{End: time.Now().Add(5 * time.Second)})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
|
||||
@ -18,6 +18,80 @@ type Reader interface {
|
||||
Read() ([]byte, error)
|
||||
}
|
||||
|
||||
// EventType represents the type of audit log event.
|
||||
type EventType int
|
||||
|
||||
const (
|
||||
EventTypeUnspecified EventType = iota
|
||||
EventTypeCreate // "create"
|
||||
EventTypeUpdate // "update"
|
||||
EventTypeUpdateWithConflicts // "update_with_conflicts"
|
||||
EventTypeDestroy // "destroy"
|
||||
EventTypeTeardown // "teardown"
|
||||
EventTypeTalosAccess // "talos_access"
|
||||
EventTypeK8SAccess // "k8s_access"
|
||||
)
|
||||
|
||||
// SQLString returns the string stored in the database for this event type.
|
||||
func (e EventType) SQLString() string {
|
||||
switch e {
|
||||
case EventTypeUnspecified:
|
||||
return ""
|
||||
case EventTypeCreate:
|
||||
return "create"
|
||||
case EventTypeUpdate:
|
||||
return "update"
|
||||
case EventTypeUpdateWithConflicts:
|
||||
return "update_with_conflicts"
|
||||
case EventTypeDestroy:
|
||||
return "destroy"
|
||||
case EventTypeTeardown:
|
||||
return "teardown"
|
||||
case EventTypeTalosAccess:
|
||||
return "talos_access"
|
||||
case EventTypeK8SAccess:
|
||||
return "k8s_access"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// OrderByField represents the audit log field to sort by.
|
||||
type OrderByField int
|
||||
|
||||
const (
|
||||
OrderByFieldUnspecified OrderByField = iota
|
||||
OrderByFieldDate
|
||||
OrderByFieldEventType
|
||||
OrderByFieldResourceType
|
||||
OrderByFieldResourceID
|
||||
OrderByFieldClusterID
|
||||
OrderByFieldActor
|
||||
)
|
||||
|
||||
// OrderByDir represents the sort direction for audit log queries.
|
||||
type OrderByDir int
|
||||
|
||||
const (
|
||||
OrderByDirUnspecified OrderByDir = iota
|
||||
OrderByDirASC
|
||||
OrderByDirDESC
|
||||
)
|
||||
|
||||
// ReadFilters holds optional filters for reading audit log events.
|
||||
type ReadFilters struct {
|
||||
Start time.Time
|
||||
End time.Time
|
||||
Search string
|
||||
ResourceType string
|
||||
ResourceID string
|
||||
ClusterID string
|
||||
Actor string
|
||||
EventType EventType
|
||||
OrderByField OrderByField
|
||||
OrderByDir OrderByDir
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
Data *Data `json:"event_data,omitempty"`
|
||||
Type string `json:"event_type,omitempty"`
|
||||
|
||||
@ -361,15 +361,69 @@ func (s *Store) removeBySize(conn *zombiesqlite.Conn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) Reader(ctx context.Context, start, end time.Time) (auditlog.Reader, error) {
|
||||
func (s *Store) Reader(ctx context.Context, filters auditlog.ReadFilters) (auditlog.Reader, error) {
|
||||
// we take the connection here, but it will be released in logReader.Close()
|
||||
conn, err := s.db.Take(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to take connection from pool: %w", err)
|
||||
}
|
||||
|
||||
query := fmt.Sprintf(`SELECT %s, %s, %s, %s, %s FROM %s WHERE %s >= $start AND %s <= $end ORDER BY %s ASC, %s ASC`, eventTypeColumn,
|
||||
resourceTypeColumn, resourceIDColumn, eventTSMillisColumn, eventDataColumn, TableName, eventTSMillisColumn, eventTSMillisColumn, eventTSMillisColumn, idColumn)
|
||||
conditions := []string{
|
||||
fmt.Sprintf("%s >= $start", eventTSMillisColumn),
|
||||
fmt.Sprintf("%s <= $end", eventTSMillisColumn),
|
||||
}
|
||||
|
||||
if filters.Search != "" {
|
||||
searchCols := []string{
|
||||
eventTypeColumn,
|
||||
resourceTypeColumn,
|
||||
actorEmailColumn,
|
||||
resourceIDColumn,
|
||||
clusterIDColumn,
|
||||
fmt.Sprintf("CAST(%s AS TEXT)", eventDataColumn),
|
||||
}
|
||||
|
||||
orParts := make([]string, 0, len(searchCols))
|
||||
|
||||
for _, col := range searchCols {
|
||||
orParts = append(orParts, fmt.Sprintf("%s LIKE '%%' || $search || '%%'", col))
|
||||
}
|
||||
|
||||
conditions = append(conditions, "("+strings.Join(orParts, " OR ")+")")
|
||||
}
|
||||
|
||||
eventTypeSQLStr := filters.EventType.SQLString()
|
||||
if eventTypeSQLStr != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("%s = $event_type", eventTypeColumn))
|
||||
}
|
||||
|
||||
if filters.ResourceType != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("%s = $resource_type", resourceTypeColumn))
|
||||
}
|
||||
|
||||
if filters.ResourceID != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("%s = $resource_id", resourceIDColumn))
|
||||
}
|
||||
|
||||
if filters.ClusterID != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("%s = $cluster_id", clusterIDColumn))
|
||||
}
|
||||
|
||||
if filters.Actor != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("%s = $actor", actorEmailColumn))
|
||||
}
|
||||
|
||||
orderByCol := orderByFieldColumn(filters.OrderByField)
|
||||
orderByDir := orderByDirSQL(filters.OrderByDir)
|
||||
|
||||
query := fmt.Sprintf(
|
||||
`SELECT %s, %s, %s, %s, %s FROM %s WHERE %s ORDER BY %s %s, %s ASC`,
|
||||
eventTypeColumn, resourceTypeColumn, resourceIDColumn, eventTSMillisColumn, eventDataColumn,
|
||||
TableName,
|
||||
strings.Join(conditions, " AND "),
|
||||
orderByCol, orderByDir,
|
||||
idColumn,
|
||||
)
|
||||
|
||||
q, err := sqlitexx.NewQuery(conn, query)
|
||||
if err != nil {
|
||||
@ -379,8 +433,14 @@ func (s *Store) Reader(ctx context.Context, start, end time.Time) (auditlog.Read
|
||||
}
|
||||
|
||||
it := q.
|
||||
BindInt64("$start", start.UnixMilli()).
|
||||
BindInt64("$end", end.UnixMilli()).
|
||||
BindInt64("$start", filters.Start.UnixMilli()).
|
||||
BindInt64("$end", filters.End.UnixMilli()).
|
||||
BindStringIfSet("$search", filters.Search).
|
||||
BindStringIfSet("$event_type", eventTypeSQLStr).
|
||||
BindStringIfSet("$resource_type", filters.ResourceType).
|
||||
BindStringIfSet("$resource_id", filters.ResourceID).
|
||||
BindStringIfSet("$cluster_id", filters.ClusterID).
|
||||
BindStringIfSet("$actor", filters.Actor).
|
||||
QueryIter()
|
||||
|
||||
next, stop := iter.Pull2(it)
|
||||
@ -490,6 +550,35 @@ func (l *logReader) Read() ([]byte, error) {
|
||||
return append(marshaled, '\n'), nil
|
||||
}
|
||||
|
||||
func orderByFieldColumn(f auditlog.OrderByField) string {
|
||||
switch f {
|
||||
case auditlog.OrderByFieldUnspecified:
|
||||
return eventTSMillisColumn
|
||||
case auditlog.OrderByFieldDate:
|
||||
return eventTSMillisColumn
|
||||
case auditlog.OrderByFieldEventType:
|
||||
return eventTypeColumn
|
||||
case auditlog.OrderByFieldResourceType:
|
||||
return resourceTypeColumn
|
||||
case auditlog.OrderByFieldResourceID:
|
||||
return resourceIDColumn
|
||||
case auditlog.OrderByFieldClusterID:
|
||||
return clusterIDColumn
|
||||
case auditlog.OrderByFieldActor:
|
||||
return actorEmailColumn
|
||||
}
|
||||
|
||||
return eventTSMillisColumn
|
||||
}
|
||||
|
||||
func orderByDirSQL(d auditlog.OrderByDir) string {
|
||||
if d == auditlog.OrderByDirDESC {
|
||||
return "DESC"
|
||||
}
|
||||
|
||||
return "ASC"
|
||||
}
|
||||
|
||||
func extractClusterID(d *auditlog.Data) string {
|
||||
switch {
|
||||
case d.Cluster != nil:
|
||||
|
||||
@ -71,7 +71,7 @@ func TestReadWrite(t *testing.T) {
|
||||
t.Run("read all", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
rdr, err := store.Reader(ctx, time.Time{}, time.Now().Add(time.Hour))
|
||||
rdr, err := store.Reader(ctx, auditlog.ReadFilters{End: time.Now().Add(time.Hour)})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
@ -124,7 +124,7 @@ func TestRemove(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// 3. Verify only the last event remains
|
||||
rdr, err := store.Reader(ctx, time.Time{}, time.Now().Add(24*time.Hour))
|
||||
rdr, err := store.Reader(ctx, auditlog.ReadFilters{End: time.Now().Add(24 * time.Hour)})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
@ -172,7 +172,7 @@ func TestRemoveByRetentionPeriod(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify only the 3 recent events remain.
|
||||
rdr, err := store.Reader(ctx, time.Time{}, now.Add(time.Hour))
|
||||
rdr, err := store.Reader(ctx, auditlog.ReadFilters{End: now.Add(time.Hour)})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
@ -250,7 +250,7 @@ func TestRemoveByMaxSize(t *testing.T) {
|
||||
}))
|
||||
|
||||
// Verify some events were deleted.
|
||||
rdr, err := sizedStore.Reader(ctx, time.Time{}, time.Now().Add(24*time.Hour))
|
||||
rdr, err := sizedStore.Reader(ctx, auditlog.ReadFilters{End: time.Now().Add(24 * time.Hour)})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
@ -293,7 +293,7 @@ func TestRemoveByMaxSizeUnlimited(t *testing.T) {
|
||||
require.NoError(t, store.Write(ctx, evt))
|
||||
}
|
||||
|
||||
rdr, err := store.Reader(ctx, time.Time{}, time.Now().Add(24*time.Hour))
|
||||
rdr, err := store.Reader(ctx, auditlog.ReadFilters{End: time.Now().Add(24 * time.Hour)})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
@ -346,7 +346,7 @@ func TestRemoveByMaxSizeBatchCap(t *testing.T) {
|
||||
|
||||
// Count remaining rows. The batch cap is 1000, so roughly 1000 should have been
|
||||
// deleted, leaving ~501 rows (1500 - 1000 + 1 trigger event).
|
||||
rdr, err := sizedStore.Reader(ctx, time.Time{}, time.Now().Add(24*time.Hour))
|
||||
rdr, err := sizedStore.Reader(ctx, auditlog.ReadFilters{End: time.Now().Add(24 * time.Hour)})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
@ -415,7 +415,7 @@ func TestRemoveBatching(t *testing.T) {
|
||||
require.NoError(t, store.Remove(ctx, rangeStart, rangeEnd))
|
||||
|
||||
// Verify only out-of-range events remain.
|
||||
rdr, err := store.Reader(ctx, time.Time{}, time.Now().Add(24*time.Hour))
|
||||
rdr, err := store.Reader(ctx, auditlog.ReadFilters{End: time.Now().Add(24 * time.Hour)})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
@ -494,7 +494,7 @@ func TestReaderParameters(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
rdr, err := store.Reader(ctx, tt.start, tt.end)
|
||||
rdr, err := store.Reader(ctx, auditlog.ReadFilters{Start: tt.start, End: tt.end})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
@ -600,6 +600,167 @@ func TestExtractedColumns(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReaderFilters(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx, cancel := context.WithTimeout(t.Context(), 15*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
logger := zaptest.NewLogger(t)
|
||||
store, _ := setupStore(ctx, t, logger)
|
||||
|
||||
base := time.Date(2024, 3, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
events := []auditlog.Event{
|
||||
{
|
||||
Type: "create",
|
||||
ResourceType: "omni.Cluster",
|
||||
ResourceID: "cluster-a",
|
||||
TimeMillis: base.Add(1 * time.Second).UnixMilli(),
|
||||
Data: &auditlog.Data{
|
||||
Session: auditlog.Session{Email: "alice@example.com"},
|
||||
Cluster: &auditlog.Cluster{ID: "cluster-a"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: "update",
|
||||
ResourceType: "omni.Cluster",
|
||||
ResourceID: "cluster-b",
|
||||
TimeMillis: base.Add(2 * time.Second).UnixMilli(),
|
||||
Data: &auditlog.Data{
|
||||
Session: auditlog.Session{Email: "bob@example.com"},
|
||||
Cluster: &auditlog.Cluster{ID: "cluster-b"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: "create",
|
||||
ResourceType: "omni.MachineSetNode",
|
||||
ResourceID: "node-1",
|
||||
TimeMillis: base.Add(3 * time.Second).UnixMilli(),
|
||||
Data: &auditlog.Data{
|
||||
Session: auditlog.Session{Email: "alice@example.com"},
|
||||
MachineSetNode: &auditlog.MachineSetNode{ID: "node-1", ClusterID: "cluster-a"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, evt := range events {
|
||||
require.NoError(t, store.Write(ctx, evt))
|
||||
}
|
||||
|
||||
timeFilters := auditlog.ReadFilters{
|
||||
Start: base,
|
||||
End: base.Add(1 * time.Minute),
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
filters auditlog.ReadFilters
|
||||
wantCount int
|
||||
}{
|
||||
{
|
||||
name: "EventType=create",
|
||||
filters: auditlog.ReadFilters{EventType: auditlog.EventTypeCreate},
|
||||
wantCount: 2,
|
||||
},
|
||||
{
|
||||
name: "EventType=update",
|
||||
filters: auditlog.ReadFilters{EventType: auditlog.EventTypeUpdate},
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "ResourceType=omni.Cluster",
|
||||
filters: auditlog.ReadFilters{ResourceType: "omni.Cluster"},
|
||||
wantCount: 2,
|
||||
},
|
||||
{
|
||||
name: "ResourceType=omni.MachineSetNode",
|
||||
filters: auditlog.ReadFilters{ResourceType: "omni.MachineSetNode"},
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "ResourceID=cluster-a",
|
||||
filters: auditlog.ReadFilters{ResourceID: "cluster-a"},
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "ClusterID=cluster-a",
|
||||
filters: auditlog.ReadFilters{ClusterID: "cluster-a"},
|
||||
wantCount: 2,
|
||||
},
|
||||
{
|
||||
name: "Actor=alice@example.com",
|
||||
filters: auditlog.ReadFilters{Actor: "alice@example.com"},
|
||||
wantCount: 2,
|
||||
},
|
||||
{
|
||||
name: "Actor=bob@example.com",
|
||||
filters: auditlog.ReadFilters{Actor: "bob@example.com"},
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "Actor=alice + EventType=update (no match)",
|
||||
filters: auditlog.ReadFilters{Actor: "alice@example.com", EventType: auditlog.EventTypeUpdate},
|
||||
wantCount: 0,
|
||||
},
|
||||
{
|
||||
name: "Actor=alice + EventType=create",
|
||||
filters: auditlog.ReadFilters{Actor: "alice@example.com", EventType: auditlog.EventTypeCreate},
|
||||
wantCount: 2,
|
||||
},
|
||||
{
|
||||
name: "Search=alice (matches actor_email)",
|
||||
filters: auditlog.ReadFilters{Search: "alice"},
|
||||
wantCount: 2,
|
||||
},
|
||||
{
|
||||
name: "Search=cluster-b (matches resource_id and cluster_id)",
|
||||
filters: auditlog.ReadFilters{Search: "cluster-b"},
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "Search=omni.Cluster (matches resource_type)",
|
||||
filters: auditlog.ReadFilters{Search: "omni.Cluster"},
|
||||
wantCount: 2,
|
||||
},
|
||||
{
|
||||
name: "Search=update (matches event_type)",
|
||||
filters: auditlog.ReadFilters{Search: "update"},
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "Search=node-1 (matches resource_id in event_data JSON)",
|
||||
filters: auditlog.ReadFilters{Search: "node-1"},
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "Search=no-match",
|
||||
filters: auditlog.ReadFilters{Search: "zzz-no-match-zzz"},
|
||||
wantCount: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
f := tt.filters
|
||||
f.Start = timeFilters.Start
|
||||
f.End = timeFilters.End
|
||||
|
||||
rdr, err := store.Reader(ctx, f)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, rdr.Close())
|
||||
})
|
||||
|
||||
got := readAllEvents(t, rdr)
|
||||
assert.Len(t, got, tt.wantCount)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func setupStore(ctx context.Context, t *testing.T, logger *zap.Logger) (*auditlogsqlite.Store, *sqlitexx.Pool) {
|
||||
return setupStoreWithOpts(ctx, t, logger, 0, 0)
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ func (n *nopLogger) Write(context.Context, auditlog.Event) error { return nil }
|
||||
|
||||
func (n *nopLogger) Remove(context.Context, time.Time, time.Time) error { return nil }
|
||||
|
||||
func (n *nopLogger) Reader(context.Context, time.Time, time.Time) (auditlog.Reader, error) {
|
||||
func (n *nopLogger) Reader(context.Context, auditlog.ReadFilters) (auditlog.Reader, error) {
|
||||
return &nopReader{}, nil
|
||||
}
|
||||
|
||||
|
||||
@ -359,12 +359,12 @@ type AuditWrap struct {
|
||||
}
|
||||
|
||||
// Reader reads the audit log file by file, oldest to newest.
|
||||
func (w *AuditWrap) Reader(ctx context.Context, start, end time.Time) (auditlog.Reader, error) {
|
||||
func (w *AuditWrap) Reader(ctx context.Context, filters auditlog.ReadFilters) (auditlog.Reader, error) {
|
||||
if w.log == nil {
|
||||
return nil, errors.New("audit log is disabled")
|
||||
}
|
||||
|
||||
return w.log.Reader(ctx, start, end)
|
||||
return w.log.Reader(ctx, filters)
|
||||
}
|
||||
|
||||
// RunCleanup runs wrapped [audit.Log.RunCleanup] if the audit log is enabled. Otherwise, blocks until context is
|
||||
|
||||
@ -710,7 +710,7 @@ func AssertAPIAuthz(rootCtx context.Context, rootCli *client.Client, clientFacto
|
||||
assertSuccess: assertSuccess,
|
||||
assertFailure: assertMissingRoleFailure,
|
||||
fn: func(ctx context.Context, cli *client.Client) error {
|
||||
for _, err := range cli.Management().ReadAuditLog(ctx, "", "") {
|
||||
for _, err := range cli.Management().ReadAuditLog(ctx, nil) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user