mirror of
https://dev.azure.com/schwarzit/schwarzit.stackit-public/_git/audit-go
synced 2026-02-18 21:51:55 +00:00
Update schema and fix tests
This commit is contained in:
parent
da9ef5f707
commit
ed68f3c6d9
17 changed files with 1796 additions and 1453 deletions
|
|
@ -185,9 +185,11 @@ In the future related code and configurations for both additional languages (Jav
|
||||||
Python) will be extracted into separate repositories.
|
Python) will be extracted into separate repositories.
|
||||||
|
|
||||||
### Open Issues
|
### Open Issues
|
||||||
|
- Check TODOs in the code
|
||||||
- Finalizing messaging schema
|
- Finalizing messaging schema
|
||||||
- Extraction of python / java configurations and code
|
- Check if fields and constraints are correct and compatible with expected use cases
|
||||||
|
- Check that routing api specific parameters are independent of AuditEventLog
|
||||||
|
- Clarify if a mutex is needed? Should we provide a MutexMessagingApi?
|
||||||
- Clarify if `client.go` file can be used for licence / legal reasons
|
- Clarify if `client.go` file can be used for licence / legal reasons
|
||||||
|
- Extraction of python / java configurations and code
|
||||||
- Clean up repo (delete main.go, etc. files)
|
- Clean up repo (delete main.go, etc. files)
|
||||||
- Finalizing API Design
|
|
||||||
- Decision whether serialized payload should be replaced with []byte or base64 encoded string
|
|
||||||
|
|
@ -119,6 +119,24 @@ type CloudEvent struct {
|
||||||
|
|
||||||
// The serialized payload
|
// The serialized payload
|
||||||
data []byte
|
data []byte
|
||||||
|
|
||||||
|
// Optional W3C conform trace parent:
|
||||||
|
// https://www.w3.org/TR/trace-context/#traceparent-header
|
||||||
|
//
|
||||||
|
// Format: <version>-<trace-id>-<parent-id>-<trace-flags>
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
|
||||||
|
traceParent *string
|
||||||
|
|
||||||
|
// Optional W3C conform trace state header:
|
||||||
|
// https://www.w3.org/TR/trace-context/#tracestate-header
|
||||||
|
//
|
||||||
|
// Format: <key1>=<value1>[,<keyN>=<valueN>]
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE"
|
||||||
|
traceState *string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RoutingIdentifierType is an enumeration of allowed identifier types.
|
// RoutingIdentifierType is an enumeration of allowed identifier types.
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ import (
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ContentTypeProtobuf = "application/x-protobuf"
|
// ContentTypeCloudEventsProtobuf the cloudevents protobuf content-type sent in metadata of messages
|
||||||
|
const ContentTypeCloudEventsProtobuf = "application/cloudevents+protobuf"
|
||||||
|
|
||||||
// ErrEventNil indicates that the event was nil
|
// ErrEventNil indicates that the event was nil
|
||||||
var ErrEventNil = errors.New("event is nil")
|
var ErrEventNil = errors.New("event is nil")
|
||||||
|
|
@ -109,7 +110,7 @@ func validateAndSerializePartially(
|
||||||
}
|
}
|
||||||
|
|
||||||
routableEvent := auditV1.RoutableAuditEvent{
|
routableEvent := auditV1.RoutableAuditEvent{
|
||||||
EventName: event.LogName,
|
EventName: event.ProtoPayload.MethodName,
|
||||||
Visibility: visibility,
|
Visibility: visibility,
|
||||||
Data: &auditV1.RoutableAuditEvent_UnencryptedData{UnencryptedData: &payload},
|
Data: &auditV1.RoutableAuditEvent_UnencryptedData{UnencryptedData: &payload},
|
||||||
}
|
}
|
||||||
|
|
@ -155,6 +156,8 @@ func send(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Naming according to AMQP protocol binding spec
|
||||||
|
// https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/amqp-protocol-binding.md
|
||||||
applicationAttributes := make(map[string]any)
|
applicationAttributes := make(map[string]any)
|
||||||
applicationAttributes["cloudEvents:specversion"] = cloudEvent.specVersion
|
applicationAttributes["cloudEvents:specversion"] = cloudEvent.specVersion
|
||||||
applicationAttributes["cloudEvents:source"] = cloudEvent.source
|
applicationAttributes["cloudEvents:source"] = cloudEvent.source
|
||||||
|
|
@ -163,6 +166,12 @@ func send(
|
||||||
applicationAttributes["cloudEvents:datacontenttype"] = cloudEvent.dataContentType
|
applicationAttributes["cloudEvents:datacontenttype"] = cloudEvent.dataContentType
|
||||||
applicationAttributes["cloudEvents:type"] = cloudEvent.dataType
|
applicationAttributes["cloudEvents:type"] = cloudEvent.dataType
|
||||||
applicationAttributes["cloudEvents:subject"] = cloudEvent.subject
|
applicationAttributes["cloudEvents:subject"] = cloudEvent.subject
|
||||||
|
if cloudEvent.traceParent != nil {
|
||||||
|
applicationAttributes["cloudEvents:traceparent"] = cloudEvent.traceParent
|
||||||
|
}
|
||||||
|
if cloudEvent.traceState != nil {
|
||||||
|
applicationAttributes["cloudEvents:tracestate"] = cloudEvent.traceState
|
||||||
|
}
|
||||||
|
|
||||||
return (*messagingApi).Send(
|
return (*messagingApi).Send(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,10 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
|
||||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/audit/messaging"
|
"dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/audit/messaging"
|
||||||
auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/gen/go/audit/v1"
|
auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/gen/go/audit/v1"
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/bufbuild/protovalidate-go"
|
"github.com/bufbuild/protovalidate-go"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
@ -69,104 +65,16 @@ func Test_ValidateAndSerializePartially_EventNil(t *testing.T) {
|
||||||
assert.ErrorIs(t, err, ErrEventNil)
|
assert.ErrorIs(t, err, ErrEventNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_ValidateAndSerializePartially_AuditEventSequenceNumber(t *testing.T) {
|
|
||||||
validator := NewValidator(t)
|
|
||||||
|
|
||||||
t.Run("Sequence number too low", func(t *testing.T) {
|
|
||||||
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
|
|
||||||
event.SequenceNumber = wrapperspb.Int64(-2)
|
|
||||||
|
|
||||||
_, err := validateAndSerializePartially(
|
|
||||||
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
|
|
||||||
|
|
||||||
assert.EqualError(t, err, "validation error:\n - sequence_number: value must be greater than or equal to -1 [int64.gte]")
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Sequence number is minimum", func(t *testing.T) {
|
|
||||||
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
|
|
||||||
event.SequenceNumber = wrapperspb.Int64(-1)
|
|
||||||
|
|
||||||
e, err := validateAndSerializePartially(
|
|
||||||
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
validateSequenceNumber(t, e, -1)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Sequence number is default", func(t *testing.T) {
|
|
||||||
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
|
|
||||||
event.SequenceNumber = wrapperspb.Int64(0)
|
|
||||||
|
|
||||||
e, err := validateAndSerializePartially(
|
|
||||||
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
validateSequenceNumber(t, e, 0)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Sequence number is greater than default", func(t *testing.T) {
|
|
||||||
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
|
|
||||||
event.SequenceNumber = wrapperspb.Int64(1)
|
|
||||||
|
|
||||||
e, err := validateAndSerializePartially(
|
|
||||||
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
validateSequenceNumber(t, e, 1)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Sequence number not set", func(t *testing.T) {
|
|
||||||
event := &auditV1.AuditEvent{
|
|
||||||
EventSource: "resource-manager",
|
|
||||||
Region: auditV1.Region_REGION_EU01,
|
|
||||||
EventName: "ORGANIZATION_CREATED",
|
|
||||||
EventTimeStamp: timestamppb.New(time.Now()),
|
|
||||||
EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_EVENT,
|
|
||||||
Initiator: &auditV1.Principal{
|
|
||||||
Id: uuid.NewString(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
identifier := uuid.New()
|
|
||||||
routingIdentifier := &RoutingIdentifier{
|
|
||||||
Identifier: identifier,
|
|
||||||
Type: RoutingIdentifierTypeOrganization,
|
|
||||||
}
|
|
||||||
|
|
||||||
objectIdentifier := &auditV1.ObjectIdentifier{
|
|
||||||
Identifier: identifier.String(),
|
|
||||||
Type: auditV1.ObjectType_OBJECT_TYPE_ORGANIZATION,
|
|
||||||
}
|
|
||||||
event.ResourceContainerReference = &auditV1.AuditEvent_ObjectIdentifier{ObjectIdentifier: objectIdentifier}
|
|
||||||
|
|
||||||
_, err := validateAndSerializePartially(
|
|
||||||
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
|
|
||||||
|
|
||||||
assert.EqualError(t, err, "validation error:\n - sequence_number: value is required [required]")
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
func validateSequenceNumber(t *testing.T, event *auditV1.RoutableAuditEvent, expectedNumber int64) {
|
|
||||||
switch data := event.GetData().(type) {
|
|
||||||
case *auditV1.RoutableAuditEvent_UnencryptedData:
|
|
||||||
var auditEvent auditV1.AuditEvent
|
|
||||||
assert.NoError(t, proto.Unmarshal(data.UnencryptedData.Data, &auditEvent))
|
|
||||||
assert.Equal(t, expectedNumber, auditEvent.SequenceNumber.Value)
|
|
||||||
default:
|
|
||||||
assert.Fail(t, "expected unencrypted data")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_ValidateAndSerializePartially_AuditEventValidationFailed(t *testing.T) {
|
func Test_ValidateAndSerializePartially_AuditEventValidationFailed(t *testing.T) {
|
||||||
validator := NewValidator(t)
|
validator := NewValidator(t)
|
||||||
|
|
||||||
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
|
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
|
||||||
event.EventName = ""
|
event.LogName = ""
|
||||||
|
|
||||||
_, err := validateAndSerializePartially(
|
_, err := validateAndSerializePartially(
|
||||||
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
|
&validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier)
|
||||||
|
|
||||||
assert.EqualError(t, err, "validation error:\n - event_name: value is required [required]")
|
assert.EqualError(t, err, "validation error:\n - log_name: value is required [required]")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_ValidateAndSerializePartially_RoutableEventValidationFailed(t *testing.T) {
|
func Test_ValidateAndSerializePartially_RoutableEventValidationFailed(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import (
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrUnsupportedSeverity = errors.New("unsupported severity level")
|
||||||
|
|
||||||
// LegacyTopicNameResolver implements TopicNameResolver.
|
// LegacyTopicNameResolver implements TopicNameResolver.
|
||||||
// A hard-coded topic name is used, routing identifiers are ignored.
|
// A hard-coded topic name is used, routing identifiers are ignored.
|
||||||
type LegacyTopicNameResolver struct {
|
type LegacyTopicNameResolver struct {
|
||||||
|
|
@ -50,7 +52,7 @@ func NewLegacyAuditApi(
|
||||||
) (*AuditApi, error) {
|
) (*AuditApi, error) {
|
||||||
|
|
||||||
if messagingApi == nil {
|
if messagingApi == nil {
|
||||||
return nil, errors.New("messaging api nil")
|
return nil, ErrMessagingApiNil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Topic resolver
|
// Topic resolver
|
||||||
|
|
@ -115,11 +117,14 @@ func (a *LegacyAuditApi) ValidateAndSerialize(
|
||||||
// TODO what is the correct id?
|
// TODO what is the correct id?
|
||||||
id: uuid.NewString(),
|
id: uuid.NewString(),
|
||||||
time: event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(),
|
time: event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(),
|
||||||
dataContentType: "application/cloudevents+protobuf",
|
dataContentType: ContentTypeCloudEventsProtobuf,
|
||||||
dataType: fmt.Sprintf("%v", routableEvent.ProtoReflect().Descriptor().FullName()),
|
dataType: fmt.Sprintf("%v", routableEvent.ProtoReflect().Descriptor().FullName()),
|
||||||
// TODO check if this is correct
|
// TODO check if this is correct
|
||||||
subject: event.ProtoPayload.ResourceName,
|
subject: event.ProtoPayload.ResourceName,
|
||||||
data: legacyBytes,
|
data: legacyBytes,
|
||||||
|
// TODO set trace fields
|
||||||
|
traceParent: nil,
|
||||||
|
traceState: nil,
|
||||||
}
|
}
|
||||||
return &message, nil
|
return &message, nil
|
||||||
}
|
}
|
||||||
|
|
@ -160,13 +165,14 @@ func (a *LegacyAuditApi) convertAndSerializeIntoLegacyFormat(
|
||||||
case *auditV1.ServiceAccountDelegationInfo_IdpPrincipal_:
|
case *auditV1.ServiceAccountDelegationInfo_IdpPrincipal_:
|
||||||
principals = append(principals, LegacyAuditEventPrincipal{
|
principals = append(principals, LegacyAuditEventPrincipal{
|
||||||
Id: principalValue.IdpPrincipal.PrincipalId,
|
Id: principalValue.IdpPrincipal.PrincipalId,
|
||||||
Email: principalValue.IdpPrincipal.PrincipalEmail,
|
Email: &principalValue.IdpPrincipal.PrincipalEmail,
|
||||||
})
|
})
|
||||||
case *auditV1.ServiceAccountDelegationInfo_SystemPrincipal_:
|
case *auditV1.ServiceAccountDelegationInfo_SystemPrincipal_:
|
||||||
principals = append(principals, LegacyAuditEventPrincipal{
|
principals = append(principals, LegacyAuditEventPrincipal{
|
||||||
Id: "system",
|
Id: "system",
|
||||||
})
|
})
|
||||||
|
default:
|
||||||
|
return nil, errors.New("unsupported principal type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
serviceAccountDelegationInfo = &LegacyAuditEventServiceAccountDelegationInfo{Principals: principals}
|
serviceAccountDelegationInfo = &LegacyAuditEventServiceAccountDelegationInfo{Principals: principals}
|
||||||
|
|
@ -179,11 +185,18 @@ func (a *LegacyAuditApi) convertAndSerializeIntoLegacyFormat(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var parameters map[string]interface{} = nil
|
var parameters map[string]interface{} = nil
|
||||||
if event.ProtoPayload.RequestMetadata.RequestAttributes.Path != "" && event.ProtoPayload.RequestMetadata.RequestAttributes.Query != "" {
|
if event.ProtoPayload.RequestMetadata.RequestAttributes.Path != "" &&
|
||||||
parsedUrl, err := url.Parse(fmt.Sprintf("%s?%s", event.ProtoPayload.RequestMetadata.RequestAttributes.Path, event.ProtoPayload.RequestMetadata.RequestAttributes.Query))
|
event.ProtoPayload.RequestMetadata.RequestAttributes.Query != nil &&
|
||||||
|
*event.ProtoPayload.RequestMetadata.RequestAttributes.Query != "" {
|
||||||
|
parameters = map[string]interface{}{}
|
||||||
|
|
||||||
|
parsedUrl, err := url.Parse(fmt.Sprintf("%s?%s",
|
||||||
|
event.ProtoPayload.RequestMetadata.RequestAttributes.Path,
|
||||||
|
*event.ProtoPayload.RequestMetadata.RequestAttributes.Query))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range parsedUrl.Query() {
|
for k, v := range parsedUrl.Query() {
|
||||||
parameters[k] = v
|
parameters[k] = v
|
||||||
}
|
}
|
||||||
|
|
@ -258,13 +271,38 @@ func (a *LegacyAuditApi) convertAndSerializeIntoLegacyFormat(
|
||||||
// Result
|
// Result
|
||||||
var result = event.ProtoPayload.Response.AsMap()
|
var result = event.ProtoPayload.Response.AsMap()
|
||||||
|
|
||||||
|
// Severity
|
||||||
|
var severity string
|
||||||
|
switch event.Severity {
|
||||||
|
case auditV1.LogSeverity_DEFAULT:
|
||||||
|
fallthrough
|
||||||
|
case auditV1.LogSeverity_DEBUG:
|
||||||
|
fallthrough
|
||||||
|
case auditV1.LogSeverity_INFO:
|
||||||
|
fallthrough
|
||||||
|
case auditV1.LogSeverity_NOTICE:
|
||||||
|
fallthrough
|
||||||
|
case auditV1.LogSeverity_WARNING:
|
||||||
|
severity = "INFO"
|
||||||
|
case auditV1.LogSeverity_ERROR:
|
||||||
|
fallthrough
|
||||||
|
case auditV1.LogSeverity_CRITICAL:
|
||||||
|
fallthrough
|
||||||
|
case auditV1.LogSeverity_ALERT:
|
||||||
|
fallthrough
|
||||||
|
case auditV1.LogSeverity_EMERGENCY:
|
||||||
|
severity = "ERROR"
|
||||||
|
default:
|
||||||
|
return nil, ErrUnsupportedSeverity
|
||||||
|
}
|
||||||
|
|
||||||
// Instantiate the legacy event - missing values are filled with defaults
|
// Instantiate the legacy event - missing values are filled with defaults
|
||||||
legacyAuditEvent := LegacyAuditEvent{
|
legacyAuditEvent := LegacyAuditEvent{
|
||||||
Severity: "INFO",
|
Severity: severity,
|
||||||
Visibility: visibility,
|
Visibility: visibility,
|
||||||
EventType: eventType,
|
EventType: eventType,
|
||||||
EventTimeStamp: event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(),
|
EventTimeStamp: event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(),
|
||||||
EventName: event.LogName,
|
EventName: event.ProtoPayload.MethodName,
|
||||||
SourceIpAddress: sourceIpAddress,
|
SourceIpAddress: sourceIpAddress,
|
||||||
UserAgent: userAgent,
|
UserAgent: userAgent,
|
||||||
Initiator: LegacyAuditEventPrincipal{
|
Initiator: LegacyAuditEventPrincipal{
|
||||||
|
|
@ -274,11 +312,12 @@ func (a *LegacyAuditApi) convertAndSerializeIntoLegacyFormat(
|
||||||
ServiceAccountDelegationInfo: serviceAccountDelegationInfo,
|
ServiceAccountDelegationInfo: serviceAccountDelegationInfo,
|
||||||
Request: request,
|
Request: request,
|
||||||
Context: messageContext,
|
Context: messageContext,
|
||||||
ResourceId: &event.LogName,
|
// TODO clarify
|
||||||
ResourceName: &event.ProtoPayload.ResourceName,
|
ResourceId: &event.LogName,
|
||||||
CorrelationId: &event.CorrelationId,
|
ResourceName: &event.ProtoPayload.ResourceName,
|
||||||
Result: &result,
|
CorrelationId: event.CorrelationId,
|
||||||
Details: &details,
|
Result: &result,
|
||||||
|
Details: &details,
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes, err := json.Marshal(legacyAuditEvent)
|
bytes, err := json.Marshal(legacyAuditEvent)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -320,14 +322,14 @@ func TestLegacyAuditApi(t *testing.T) {
|
||||||
var auditEvent LegacyAuditEvent
|
var auditEvent LegacyAuditEvent
|
||||||
assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent))
|
assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent))
|
||||||
|
|
||||||
assert.Equal(t, event.EventName, auditEvent.EventName)
|
assert.Equal(t, event.ProtoPayload.MethodName, auditEvent.EventName)
|
||||||
assert.Equal(t, event.EventTimeStamp.AsTime(), auditEvent.EventTimeStamp)
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), auditEvent.EventTimeStamp)
|
||||||
assert.Equal(t, event.Initiator.Id, auditEvent.Initiator.Id)
|
assert.Equal(t, event.ProtoPayload.AuthenticationInfo.PrincipalId, auditEvent.Initiator.Id)
|
||||||
assert.Equal(t, "SYSTEM_EVENT", auditEvent.EventType)
|
assert.Equal(t, "SYSTEM_EVENT", auditEvent.EventType)
|
||||||
assert.Equal(t, "INFO", auditEvent.Severity)
|
assert.Equal(t, "INFO", auditEvent.Severity)
|
||||||
assert.Equal(t, "none", auditEvent.Request.Endpoint)
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Path, auditEvent.Request.Endpoint)
|
||||||
assert.Equal(t, "0.0.0.0", auditEvent.SourceIpAddress)
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerIp, auditEvent.SourceIpAddress)
|
||||||
assert.Equal(t, "none", auditEvent.UserAgent)
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerSuppliedUserAgent, auditEvent.UserAgent)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Log event with details", func(t *testing.T) {
|
t.Run("Log event with details", func(t *testing.T) {
|
||||||
|
|
@ -350,7 +352,7 @@ func TestLegacyAuditApi(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Instantiate test data
|
// Instantiate test data
|
||||||
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEventWithDetails()
|
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
||||||
|
|
@ -369,7 +371,7 @@ func TestLegacyAuditApi(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateSentMessage(t *testing.T, topicName string, message *amqp.Message, event *auditV1.AuditEvent) {
|
func validateSentMessage(t *testing.T, topicName string, message *amqp.Message, event *auditV1.AuditLogEntry) {
|
||||||
// Check topic name
|
// Check topic name
|
||||||
assert.Equal(t, topicName, *message.Properties.To)
|
assert.Equal(t, topicName, *message.Properties.To)
|
||||||
|
|
||||||
|
|
@ -377,43 +379,88 @@ func validateSentMessage(t *testing.T, topicName string, message *amqp.Message,
|
||||||
var auditEvent LegacyAuditEvent
|
var auditEvent LegacyAuditEvent
|
||||||
assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent))
|
assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent))
|
||||||
|
|
||||||
assert.Equal(t, event.EventName, auditEvent.EventName)
|
var severity string
|
||||||
assert.Equal(t, event.EventTimeStamp.AsTime(), auditEvent.EventTimeStamp)
|
switch event.Severity {
|
||||||
assert.Equal(t, event.Initiator.Id, auditEvent.Initiator.Id)
|
case auditV1.LogSeverity_DEFAULT:
|
||||||
assert.Equal(t, "ADMIN_ACTIVITY", auditEvent.EventType)
|
fallthrough
|
||||||
assert.Equal(t, "INFO", auditEvent.Severity)
|
case auditV1.LogSeverity_DEBUG:
|
||||||
assert.Equal(t, "none", auditEvent.Request.Endpoint)
|
fallthrough
|
||||||
assert.Equal(t, "0.0.0.0", auditEvent.SourceIpAddress)
|
case auditV1.LogSeverity_INFO:
|
||||||
assert.Equal(t, "none", auditEvent.UserAgent)
|
fallthrough
|
||||||
}
|
case auditV1.LogSeverity_NOTICE:
|
||||||
|
fallthrough
|
||||||
func validateSentMessageWithDetails(t *testing.T, topicName string, message *amqp.Message, event *auditV1.AuditEvent) {
|
case auditV1.LogSeverity_WARNING:
|
||||||
// Check topic name
|
severity = "INFO"
|
||||||
assert.Equal(t, topicName, *message.Properties.To)
|
case auditV1.LogSeverity_ERROR:
|
||||||
|
fallthrough
|
||||||
// Check deserialized message
|
case auditV1.LogSeverity_CRITICAL:
|
||||||
var auditEvent LegacyAuditEvent
|
fallthrough
|
||||||
assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent))
|
case auditV1.LogSeverity_ALERT:
|
||||||
|
fallthrough
|
||||||
assert.Equal(t, event.EventName, auditEvent.EventName)
|
case auditV1.LogSeverity_EMERGENCY:
|
||||||
assert.Equal(t, event.EventTimeStamp.AsTime(), auditEvent.EventTimeStamp)
|
severity = "ERROR"
|
||||||
assert.Equal(t, event.Initiator.Id, auditEvent.Initiator.Id)
|
default:
|
||||||
assert.Equal(t, "ADMIN_ACTIVITY", auditEvent.EventType)
|
assert.Fail(t, "unknown log severity")
|
||||||
assert.Equal(t, "INFO", auditEvent.Severity)
|
|
||||||
assert.Equal(t, event.Request.Endpoint, auditEvent.Request.Endpoint)
|
|
||||||
assert.Equal(t, event.Request.SourceIpAddress, auditEvent.SourceIpAddress)
|
|
||||||
assert.Equal(t, *event.Request.UserAgent, auditEvent.UserAgent)
|
|
||||||
assert.Equal(t, event.Request.Body.AsMap(), *auditEvent.Request.Body)
|
|
||||||
assert.Equal(t, event.Request.Parameters.AsMap(), *auditEvent.Request.Parameters)
|
|
||||||
assert.Equal(t, event.Details.AsMap(), *auditEvent.Details)
|
|
||||||
assert.Equal(t, event.Result.AsMap(), *auditEvent.Result)
|
|
||||||
for _, header := range event.Request.Headers {
|
|
||||||
assert.Equal(t, header.Value, (*auditEvent.Request.Headers)[header.Key])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for idx := range event.Principals {
|
assert.Equal(t, event.ProtoPayload.MethodName, auditEvent.EventName)
|
||||||
assert.Equal(t, event.Principals[idx].Id, auditEvent.ServiceAccountDelegationInfo.Principals[idx].Id)
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), auditEvent.EventTimeStamp)
|
||||||
assert.Equal(t, event.Principals[idx].Email, auditEvent.ServiceAccountDelegationInfo.Principals[idx].Email)
|
assert.Equal(t, event.ProtoPayload.AuthenticationInfo.PrincipalId, auditEvent.Initiator.Id)
|
||||||
|
assert.Equal(t, "ADMIN_ACTIVITY", auditEvent.EventType)
|
||||||
|
assert.Equal(t, severity, auditEvent.Severity)
|
||||||
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Path, auditEvent.Request.Endpoint)
|
||||||
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerIp, auditEvent.SourceIpAddress)
|
||||||
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerSuppliedUserAgent, auditEvent.UserAgent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateSentMessageWithDetails(t *testing.T, topicName string, message *amqp.Message, event *auditV1.AuditLogEntry) {
|
||||||
|
// Check topic name
|
||||||
|
assert.Equal(t, topicName, *message.Properties.To)
|
||||||
|
|
||||||
|
// Check deserialized message
|
||||||
|
var auditEvent LegacyAuditEvent
|
||||||
|
assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent))
|
||||||
|
|
||||||
|
assert.Equal(t, event.ProtoPayload.MethodName, auditEvent.EventName)
|
||||||
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), auditEvent.EventTimeStamp)
|
||||||
|
assert.Equal(t, event.ProtoPayload.AuthenticationInfo.PrincipalId, auditEvent.Initiator.Id)
|
||||||
|
assert.Equal(t, "ADMIN_ACTIVITY", auditEvent.EventType)
|
||||||
|
assert.Equal(t, "INFO", auditEvent.Severity)
|
||||||
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Path, auditEvent.Request.Endpoint)
|
||||||
|
var parameters map[string]interface{} = nil
|
||||||
|
if event.ProtoPayload.RequestMetadata.RequestAttributes.Path != "" &&
|
||||||
|
event.ProtoPayload.RequestMetadata.RequestAttributes.Query != nil &&
|
||||||
|
*event.ProtoPayload.RequestMetadata.RequestAttributes.Query != "" {
|
||||||
|
parameters = map[string]interface{}{}
|
||||||
|
|
||||||
|
parsedUrl, err := url.Parse(fmt.Sprintf("%s?%s",
|
||||||
|
event.ProtoPayload.RequestMetadata.RequestAttributes.Path,
|
||||||
|
*event.ProtoPayload.RequestMetadata.RequestAttributes.Query))
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
for k, v := range parsedUrl.Query() {
|
||||||
|
parameters[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert.Equal(t, event.ProtoPayload.Request.AsMap(), *auditEvent.Request.Body)
|
||||||
|
assert.Equal(t, parameters, *auditEvent.Request.Parameters)
|
||||||
|
for key, value := range event.ProtoPayload.RequestMetadata.RequestAttributes.Headers {
|
||||||
|
assert.Equal(t, value, (*auditEvent.Request.Headers)[key])
|
||||||
|
}
|
||||||
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerIp, auditEvent.SourceIpAddress)
|
||||||
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerSuppliedUserAgent, auditEvent.UserAgent)
|
||||||
|
assert.Equal(t, event.ProtoPayload.Request.AsMap(), *auditEvent.Details)
|
||||||
|
assert.Equal(t, event.ProtoPayload.Response.AsMap(), *auditEvent.Result)
|
||||||
|
assert.True(t, auditEvent.Context.OrganizationId != nil || auditEvent.Context.FolderId != nil || auditEvent.Context.ProjectId != nil)
|
||||||
|
|
||||||
|
for idx, principal := range event.ProtoPayload.AuthenticationInfo.ServiceAccountDelegationInfo {
|
||||||
|
switch principalValue := principal.Authority.(type) {
|
||||||
|
case *auditV1.ServiceAccountDelegationInfo_IdpPrincipal_:
|
||||||
|
assert.Equal(t, principalValue.IdpPrincipal.PrincipalId, auditEvent.ServiceAccountDelegationInfo.Principals[idx].Id)
|
||||||
|
assert.Equal(t, principalValue.IdpPrincipal.PrincipalEmail, auditEvent.ServiceAccountDelegationInfo.Principals[idx].Email)
|
||||||
|
case *auditV1.ServiceAccountDelegationInfo_SystemPrincipal_:
|
||||||
|
assert.Equal(t, "system", auditEvent.ServiceAccountDelegationInfo.Principals[idx].Id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -458,7 +505,7 @@ func TestLegacyAuditApi_Log_NilEvent(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLegacyAuditApi_ConvertAndSerializeIntoLegacyFormatInvalidObjectIdentifierType(t *testing.T) {
|
func TestLegacyAuditApi_ConvertAndSerializeIntoLegacyFormatInvalidObjectIdentifierType(t *testing.T) {
|
||||||
customization := func(event *auditV1.AuditEvent,
|
customization := func(event *auditV1.AuditLogEntry,
|
||||||
routingIdentifier *RoutingIdentifier,
|
routingIdentifier *RoutingIdentifier,
|
||||||
objectIdentifier *auditV1.ObjectIdentifier) {
|
objectIdentifier *auditV1.ObjectIdentifier) {
|
||||||
objectIdentifier.Type = 4
|
objectIdentifier.Type = 4
|
||||||
|
|
@ -477,7 +524,7 @@ func TestLegacyAuditApi_ConvertAndSerializeIntoLegacyFormatInvalidObjectIdentifi
|
||||||
func TestLegacyAuditApi_ConvertAndSerializeIntoLegacyFormat_NoResourceReference(t *testing.T) {
|
func TestLegacyAuditApi_ConvertAndSerializeIntoLegacyFormat_NoResourceReference(t *testing.T) {
|
||||||
event, _, _ := NewProjectAuditEvent(nil)
|
event, _, _ := NewProjectAuditEvent(nil)
|
||||||
routableEvent := auditV1.RoutableAuditEvent{
|
routableEvent := auditV1.RoutableAuditEvent{
|
||||||
EventName: event.EventName,
|
EventName: event.ProtoPayload.MethodName,
|
||||||
Visibility: auditV1.Visibility_VISIBILITY_PUBLIC,
|
Visibility: auditV1.Visibility_VISIBILITY_PUBLIC,
|
||||||
ResourceReference: nil,
|
ResourceReference: nil,
|
||||||
Data: nil,
|
Data: nil,
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,9 @@ func (a *MockAuditApi) ValidateAndSerialize(
|
||||||
// TODO check if this is correct
|
// TODO check if this is correct
|
||||||
subject: event.ProtoPayload.ResourceName,
|
subject: event.ProtoPayload.ResourceName,
|
||||||
data: routableEventBytes,
|
data: routableEventBytes,
|
||||||
|
// TODO set trace fields
|
||||||
|
traceParent: nil,
|
||||||
|
traceState: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &message, nil
|
return &message, nil
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ func TestMockAuditApi_Log(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
validateRoutableEventPayload(
|
validateRoutableEventPayload(
|
||||||
t, cloudEvent.data, routingIdentifier, objectIdentifier, event, event.EventName, visibility)
|
t, cloudEvent.data, routingIdentifier, objectIdentifier, event, event.ProtoPayload.MethodName, visibility)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("ValidateAndSerialize event nil", func(t *testing.T) {
|
t.Run("ValidateAndSerialize event nil", func(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -128,11 +128,14 @@ func (a *routableAuditApi) ValidateAndSerialize(
|
||||||
// TODO what is the correct id?
|
// TODO what is the correct id?
|
||||||
id: uuid.NewString(),
|
id: uuid.NewString(),
|
||||||
time: event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(),
|
time: event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(),
|
||||||
dataContentType: "application/cloudevents+protobuf",
|
dataContentType: ContentTypeCloudEventsProtobuf,
|
||||||
dataType: fmt.Sprintf("%v", routableEvent.ProtoReflect().Descriptor().FullName()),
|
dataType: fmt.Sprintf("%v", routableEvent.ProtoReflect().Descriptor().FullName()),
|
||||||
// TODO check if this is correct
|
// TODO check if this is correct
|
||||||
subject: event.ProtoPayload.ResourceName,
|
subject: event.ProtoPayload.ResourceName,
|
||||||
data: routableEventBytes,
|
data: routableEventBytes,
|
||||||
|
// TODO set trace fields
|
||||||
|
traceParent: nil,
|
||||||
|
traceState: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &message, nil
|
return &message, nil
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ func TestRoutableAuditApi(t *testing.T) {
|
||||||
routingIdentifier,
|
routingIdentifier,
|
||||||
objectIdentifier,
|
objectIdentifier,
|
||||||
event,
|
event,
|
||||||
"ORGANIZATION_CREATED",
|
"stackit.resourcemanager.v2.organization.created",
|
||||||
visibility)
|
visibility)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -123,7 +123,7 @@ func TestRoutableAuditApi(t *testing.T) {
|
||||||
routingIdentifier,
|
routingIdentifier,
|
||||||
objectIdentifier,
|
objectIdentifier,
|
||||||
event,
|
event,
|
||||||
"ORGANIZATION_CREATED",
|
"stackit.resourcemanager.v2.organization.created",
|
||||||
visibility)
|
visibility)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -159,7 +159,7 @@ func TestRoutableAuditApi(t *testing.T) {
|
||||||
routingIdentifier,
|
routingIdentifier,
|
||||||
objectIdentifier,
|
objectIdentifier,
|
||||||
event,
|
event,
|
||||||
"FOLDER_CREATED",
|
"stackit.resourcemanager.v2.folder.created",
|
||||||
visibility)
|
visibility)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -197,7 +197,7 @@ func TestRoutableAuditApi(t *testing.T) {
|
||||||
routingIdentifier,
|
routingIdentifier,
|
||||||
objectIdentifier,
|
objectIdentifier,
|
||||||
event,
|
event,
|
||||||
"FOLDER_CREATED",
|
"stackit.resourcemanager.v2.folder.created",
|
||||||
visibility)
|
visibility)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -234,7 +234,7 @@ func TestRoutableAuditApi(t *testing.T) {
|
||||||
routingIdentifier,
|
routingIdentifier,
|
||||||
objectIdentifier,
|
objectIdentifier,
|
||||||
event,
|
event,
|
||||||
"PROJECT_CREATED",
|
"stackit.resourcemanager.v2.project.created",
|
||||||
visibility)
|
visibility)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -270,7 +270,7 @@ func TestRoutableAuditApi(t *testing.T) {
|
||||||
routingIdentifier,
|
routingIdentifier,
|
||||||
objectIdentifier,
|
objectIdentifier,
|
||||||
event,
|
event,
|
||||||
"PROJECT_CREATED",
|
"stackit.resourcemanager.v2.project.created",
|
||||||
visibility)
|
visibility)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -309,7 +309,7 @@ func TestRoutableAuditApi(t *testing.T) {
|
||||||
assert.Equal(t, "resource-manager", applicationProperties["cloudEvents:source"])
|
assert.Equal(t, "resource-manager", applicationProperties["cloudEvents:source"])
|
||||||
_, isUuid := uuid.Parse(fmt.Sprintf("%s", applicationProperties["cloudEvents:id"]))
|
_, isUuid := uuid.Parse(fmt.Sprintf("%s", applicationProperties["cloudEvents:id"]))
|
||||||
assert.True(t, true, isUuid)
|
assert.True(t, true, isUuid)
|
||||||
assert.Equal(t, event.EventTimeStamp.AsTime().UnixMilli(), applicationProperties["cloudEvents:time"])
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime().UnixMilli(), applicationProperties["cloudEvents:time"])
|
||||||
assert.Equal(t, "application/cloudevents+protobuf", applicationProperties["cloudEvents:datacontenttype"])
|
assert.Equal(t, "application/cloudevents+protobuf", applicationProperties["cloudEvents:datacontenttype"])
|
||||||
assert.Equal(t, "audit.v1.RoutableAuditEvent", applicationProperties["cloudEvents:type"])
|
assert.Equal(t, "audit.v1.RoutableAuditEvent", applicationProperties["cloudEvents:type"])
|
||||||
|
|
||||||
|
|
@ -320,7 +320,7 @@ func TestRoutableAuditApi(t *testing.T) {
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
event,
|
event,
|
||||||
"SYSTEM_CHANGED",
|
"stackit.resourcemanager.v2.system.changed",
|
||||||
visibility)
|
visibility)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -334,7 +334,7 @@ func TestRoutableAuditApi(t *testing.T) {
|
||||||
assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, "org/*"))
|
assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, "org/*"))
|
||||||
|
|
||||||
// Instantiate test data
|
// Instantiate test data
|
||||||
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEventWithDetails()
|
event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil)
|
||||||
|
|
||||||
// Log the event to solace
|
// Log the event to solace
|
||||||
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
visibility := auditV1.Visibility_VISIBILITY_PUBLIC
|
||||||
|
|
@ -356,7 +356,7 @@ func TestRoutableAuditApi(t *testing.T) {
|
||||||
routingIdentifier,
|
routingIdentifier,
|
||||||
objectIdentifier,
|
objectIdentifier,
|
||||||
event,
|
event,
|
||||||
"ORGANIZATION_CREATED",
|
"stackit.resourcemanager.v2.organization.created",
|
||||||
visibility)
|
visibility)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -367,7 +367,7 @@ func validateSentEvent(
|
||||||
message *amqp.Message,
|
message *amqp.Message,
|
||||||
routingIdentifier *RoutingIdentifier,
|
routingIdentifier *RoutingIdentifier,
|
||||||
objectIdentifier *auditV1.ObjectIdentifier,
|
objectIdentifier *auditV1.ObjectIdentifier,
|
||||||
event *auditV1.AuditEvent,
|
event *auditV1.AuditLogEntry,
|
||||||
eventName string,
|
eventName string,
|
||||||
visibility auditV1.Visibility,
|
visibility auditV1.Visibility,
|
||||||
) {
|
) {
|
||||||
|
|
@ -383,7 +383,7 @@ func validateSentEvent(
|
||||||
assert.Equal(t, "resource-manager", applicationProperties["cloudEvents:source"])
|
assert.Equal(t, "resource-manager", applicationProperties["cloudEvents:source"])
|
||||||
_, isUuid := uuid.Parse(fmt.Sprintf("%s", applicationProperties["cloudEvents:id"]))
|
_, isUuid := uuid.Parse(fmt.Sprintf("%s", applicationProperties["cloudEvents:id"]))
|
||||||
assert.True(t, true, isUuid)
|
assert.True(t, true, isUuid)
|
||||||
assert.Equal(t, event.EventTimeStamp.AsTime().UnixMilli(), applicationProperties["cloudEvents:time"])
|
assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime().UnixMilli(), applicationProperties["cloudEvents:time"])
|
||||||
assert.Equal(t, "application/cloudevents+protobuf", applicationProperties["cloudEvents:datacontenttype"])
|
assert.Equal(t, "application/cloudevents+protobuf", applicationProperties["cloudEvents:datacontenttype"])
|
||||||
assert.Equal(t, "audit.v1.RoutableAuditEvent", applicationProperties["cloudEvents:type"])
|
assert.Equal(t, "audit.v1.RoutableAuditEvent", applicationProperties["cloudEvents:type"])
|
||||||
|
|
||||||
|
|
@ -397,7 +397,7 @@ func validateRoutableEventPayload(
|
||||||
payload []byte,
|
payload []byte,
|
||||||
routingIdentifier *RoutingIdentifier,
|
routingIdentifier *RoutingIdentifier,
|
||||||
objectIdentifier *auditV1.ObjectIdentifier,
|
objectIdentifier *auditV1.ObjectIdentifier,
|
||||||
event *auditV1.AuditEvent,
|
event *auditV1.AuditLogEntry,
|
||||||
eventName string,
|
eventName string,
|
||||||
visibility auditV1.Visibility,
|
visibility auditV1.Visibility,
|
||||||
) {
|
) {
|
||||||
|
|
@ -432,7 +432,7 @@ func validateRoutableEventPayload(
|
||||||
assert.Fail(t, "Object name not expected")
|
assert.Fail(t, "Object name not expected")
|
||||||
}
|
}
|
||||||
|
|
||||||
var auditEvent auditV1.AuditEvent
|
var auditEvent auditV1.AuditLogEntry
|
||||||
switch data := routableAuditEvent.Data.(type) {
|
switch data := routableAuditEvent.Data.(type) {
|
||||||
case *auditV1.RoutableAuditEvent_UnencryptedData:
|
case *auditV1.RoutableAuditEvent_UnencryptedData:
|
||||||
assert.NoError(t, proto.Unmarshal(data.UnencryptedData.Data, &auditEvent))
|
assert.NoError(t, proto.Unmarshal(data.UnencryptedData.Data, &auditEvent))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -22,19 +23,74 @@ func NewOrganizationAuditEvent(
|
||||||
*auditV1.ObjectIdentifier,
|
*auditV1.ObjectIdentifier,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
identifier := uuid.New()
|
||||||
|
permission := "resourcemanager.organization.edit"
|
||||||
|
permissionGranted := true
|
||||||
|
requestId := fmt.Sprintf("%s/1", identifier)
|
||||||
|
claims, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
request, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
response, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
correlationId := "cad100e2-e139-43b9-8c3b-335731e032bc"
|
||||||
|
headers := make(map[string]string)
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
labels := make(map[string]string)
|
||||||
|
labels["label1"] = "value1"
|
||||||
auditEvent := &auditV1.AuditLogEntry{
|
auditEvent := &auditV1.AuditLogEntry{
|
||||||
EventSource: "resource-manager",
|
LogName: fmt.Sprintf("organizations/%s/logs/admin-activity", identifier),
|
||||||
Region: auditV1.Region_REGION_EU01,
|
ProtoPayload: &auditV1.AuditLog{
|
||||||
SequenceNumber: wrapperspb.Int64(0),
|
ServiceName: "resource-manager",
|
||||||
EventName: "ORGANIZATION_CREATED",
|
MethodName: "stackit.resourcemanager.v2.organization.created",
|
||||||
EventTimeStamp: timestamppb.New(time.Now()),
|
ResourceName: fmt.Sprintf("organizations/%s", identifier),
|
||||||
EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_EVENT,
|
AuthenticationInfo: &auditV1.AuthenticationInfo{
|
||||||
Initiator: &auditV1.Principal{
|
PrincipalId: uuid.NewString(),
|
||||||
Id: uuid.NewString(),
|
PrincipalEmail: "user@example.com",
|
||||||
|
ServiceAccountName: nil,
|
||||||
|
ServiceAccountDelegationInfo: nil,
|
||||||
|
},
|
||||||
|
AuthorizationInfo: []*auditV1.AuthorizationInfo{{
|
||||||
|
Resource: fmt.Sprintf("organizations/%s", identifier),
|
||||||
|
Permission: &permission,
|
||||||
|
Granted: &permissionGranted,
|
||||||
|
}},
|
||||||
|
RequestMetadata: &auditV1.RequestMetadata{
|
||||||
|
CallerIp: "127.0.0.1",
|
||||||
|
CallerSuppliedUserAgent: "OpenAPI-Generator/ 1.0.0/ go",
|
||||||
|
RequestAttributes: &auditV1.AttributeContext_Request{
|
||||||
|
Id: &requestId,
|
||||||
|
Method: "POST",
|
||||||
|
Headers: headers,
|
||||||
|
Path: "/v2/organizations",
|
||||||
|
Host: "stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud",
|
||||||
|
Scheme: "https",
|
||||||
|
Query: nil,
|
||||||
|
Time: timestamppb.New(time.Now().UTC()),
|
||||||
|
Protocol: "http/1.1",
|
||||||
|
Auth: &auditV1.AttributeContext_Auth{
|
||||||
|
Principal: "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev",
|
||||||
|
Audiences: []string{"https:// stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"},
|
||||||
|
Claims: claims,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Request: request,
|
||||||
|
Status: &auditV1.ResponseStatus{
|
||||||
|
Code: wrapperspb.Int32(200),
|
||||||
|
Message: nil,
|
||||||
|
Details: nil,
|
||||||
|
},
|
||||||
|
NumResponseItems: nil,
|
||||||
|
Response: response,
|
||||||
|
Metadata: nil,
|
||||||
},
|
},
|
||||||
|
InsertId: fmt.Sprintf("%d/eu01/e72182e8-0bb9-4be2-a19f-87fc0dd6e738/00000000001", time.Now().UnixNano()),
|
||||||
|
Labels: labels,
|
||||||
|
CorrelationId: &correlationId,
|
||||||
|
Timestamp: timestamppb.New(time.Now()),
|
||||||
|
Severity: auditV1.LogSeverity_DEFAULT,
|
||||||
|
TraceParent: nil,
|
||||||
|
TraceState: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
identifier := uuid.New()
|
|
||||||
routingIdentifier := &RoutingIdentifier{
|
routingIdentifier := &RoutingIdentifier{
|
||||||
Identifier: identifier,
|
Identifier: identifier,
|
||||||
Type: RoutingIdentifierTypeOrganization,
|
Type: RoutingIdentifierTypeOrganization,
|
||||||
|
|
@ -44,7 +100,6 @@ func NewOrganizationAuditEvent(
|
||||||
Identifier: identifier.String(),
|
Identifier: identifier.String(),
|
||||||
Type: auditV1.ObjectType_OBJECT_TYPE_ORGANIZATION,
|
Type: auditV1.ObjectType_OBJECT_TYPE_ORGANIZATION,
|
||||||
}
|
}
|
||||||
auditEvent.ResourceContainerReference = &auditV1.AuditEvent_ObjectIdentifier{ObjectIdentifier: objectIdentifier}
|
|
||||||
|
|
||||||
if customization != nil {
|
if customization != nil {
|
||||||
(*customization)(auditEvent, routingIdentifier, objectIdentifier)
|
(*customization)(auditEvent, routingIdentifier, objectIdentifier)
|
||||||
|
|
@ -53,51 +108,6 @@ func NewOrganizationAuditEvent(
|
||||||
return auditEvent, routingIdentifier, objectIdentifier
|
return auditEvent, routingIdentifier, objectIdentifier
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOrganizationAuditEventWithDetails() (*auditV1.AuditLogEntry,
|
|
||||||
*RoutingIdentifier,
|
|
||||||
*auditV1.ObjectIdentifier) {
|
|
||||||
customization := func(event *auditV1.AuditLogEntry,
|
|
||||||
routingIdentifier *RoutingIdentifier,
|
|
||||||
objectIdentifier *auditV1.ObjectIdentifier) {
|
|
||||||
userAgent := "firefox"
|
|
||||||
parameters, _ := structpb.NewStruct(map[string]any{"parameter1": "value"})
|
|
||||||
body, _ := structpb.NewStruct(map[string]any{"body": "value"})
|
|
||||||
|
|
||||||
event.Request = &auditV1.RequestDetails{
|
|
||||||
Endpoint: "/test",
|
|
||||||
SourceIpAddress: "127.0.0.1",
|
|
||||||
UserAgent: &userAgent,
|
|
||||||
Parameters: parameters,
|
|
||||||
Body: body,
|
|
||||||
Headers: []*auditV1.RequestHeader{
|
|
||||||
{
|
|
||||||
Key: "header1",
|
|
||||||
Value: "value",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
email := "test@example.com"
|
|
||||||
event.Principals = []*auditV1.Principal{
|
|
||||||
{
|
|
||||||
Id: "id",
|
|
||||||
Email: &email,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
details, _ := structpb.NewStruct(map[string]interface{}{
|
|
||||||
"detail": "value",
|
|
||||||
})
|
|
||||||
event.Details = details
|
|
||||||
|
|
||||||
result, _ := structpb.NewStruct(map[string]interface{}{
|
|
||||||
"result": "value",
|
|
||||||
})
|
|
||||||
event.Result = result
|
|
||||||
}
|
|
||||||
return NewOrganizationAuditEvent(&customization)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFolderAuditEvent(
|
func NewFolderAuditEvent(
|
||||||
customization *func(
|
customization *func(
|
||||||
*auditV1.AuditLogEntry,
|
*auditV1.AuditLogEntry,
|
||||||
|
|
@ -109,28 +119,83 @@ func NewFolderAuditEvent(
|
||||||
*auditV1.ObjectIdentifier,
|
*auditV1.ObjectIdentifier,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
identifier := uuid.New()
|
||||||
|
permission := "resourcemanager.folder.edit"
|
||||||
|
permissionGranted := true
|
||||||
|
requestId := fmt.Sprintf("%s/1", identifier)
|
||||||
|
claims, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
request, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
response, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
correlationId := "9c71cedf-ca52-4f9c-a519-ed006e810cdd"
|
||||||
|
headers := make(map[string]string)
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
labels := make(map[string]string)
|
||||||
|
labels["label1"] = "value1"
|
||||||
auditEvent := &auditV1.AuditLogEntry{
|
auditEvent := &auditV1.AuditLogEntry{
|
||||||
EventSource: "resource-manager",
|
LogName: fmt.Sprintf("folders/%s/logs/admin-activity", identifier),
|
||||||
Region: auditV1.Region_REGION_EU01,
|
ProtoPayload: &auditV1.AuditLog{
|
||||||
SequenceNumber: wrapperspb.Int64(0),
|
ServiceName: "resource-manager",
|
||||||
EventName: "FOLDER_CREATED",
|
MethodName: "stackit.resourcemanager.v2.folder.created",
|
||||||
EventTimeStamp: timestamppb.New(time.Now()),
|
ResourceName: fmt.Sprintf("folders/%s", identifier),
|
||||||
EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_EVENT,
|
AuthenticationInfo: &auditV1.AuthenticationInfo{
|
||||||
Initiator: &auditV1.Principal{
|
PrincipalId: uuid.NewString(),
|
||||||
Id: uuid.NewString(),
|
PrincipalEmail: "user@example.com",
|
||||||
|
ServiceAccountName: nil,
|
||||||
|
ServiceAccountDelegationInfo: nil,
|
||||||
|
},
|
||||||
|
AuthorizationInfo: []*auditV1.AuthorizationInfo{{
|
||||||
|
Resource: fmt.Sprintf("folders/%s", identifier),
|
||||||
|
Permission: &permission,
|
||||||
|
Granted: &permissionGranted,
|
||||||
|
}},
|
||||||
|
RequestMetadata: &auditV1.RequestMetadata{
|
||||||
|
CallerIp: "127.0.0.1",
|
||||||
|
CallerSuppliedUserAgent: "OpenAPI-Generator/ 1.0.0/ go",
|
||||||
|
RequestAttributes: &auditV1.AttributeContext_Request{
|
||||||
|
Id: &requestId,
|
||||||
|
Method: "POST",
|
||||||
|
Headers: headers,
|
||||||
|
Path: "/v2/folders",
|
||||||
|
Host: "stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud",
|
||||||
|
Scheme: "https",
|
||||||
|
Query: nil,
|
||||||
|
Time: timestamppb.New(time.Now().UTC()),
|
||||||
|
Protocol: "http/1.1",
|
||||||
|
Auth: &auditV1.AttributeContext_Auth{
|
||||||
|
Principal: "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev",
|
||||||
|
Audiences: []string{"https:// stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"},
|
||||||
|
Claims: claims,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Request: request,
|
||||||
|
Status: &auditV1.ResponseStatus{
|
||||||
|
Code: wrapperspb.Int32(200),
|
||||||
|
Message: nil,
|
||||||
|
Details: nil,
|
||||||
|
},
|
||||||
|
NumResponseItems: nil,
|
||||||
|
Response: response,
|
||||||
|
Metadata: nil,
|
||||||
},
|
},
|
||||||
|
InsertId: fmt.Sprintf("%d/eu01/e72182e8-0bb9-4be2-a19f-87fc0dd6e738/00000000001", time.Now().UnixNano()),
|
||||||
|
Labels: labels,
|
||||||
|
CorrelationId: &correlationId,
|
||||||
|
Timestamp: timestamppb.New(time.Now()),
|
||||||
|
Severity: auditV1.LogSeverity_DEFAULT,
|
||||||
|
TraceParent: nil,
|
||||||
|
TraceState: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
routingIdentifier := &RoutingIdentifier{
|
routingIdentifier := &RoutingIdentifier{
|
||||||
Identifier: uuid.New(),
|
Identifier: identifier,
|
||||||
Type: RoutingIdentifierTypeOrganization,
|
Type: RoutingIdentifierTypeOrganization,
|
||||||
}
|
}
|
||||||
|
|
||||||
objectIdentifier := &auditV1.ObjectIdentifier{
|
objectIdentifier := &auditV1.ObjectIdentifier{
|
||||||
Identifier: uuid.New().String(),
|
Identifier: identifier.String(),
|
||||||
Type: auditV1.ObjectType_OBJECT_TYPE_FOLDER,
|
Type: auditV1.ObjectType_OBJECT_TYPE_FOLDER,
|
||||||
}
|
}
|
||||||
auditEvent.ResourceContainerReference = &auditV1.AuditEvent_ObjectIdentifier{ObjectIdentifier: objectIdentifier}
|
|
||||||
|
|
||||||
if customization != nil {
|
if customization != nil {
|
||||||
(*customization)(auditEvent, routingIdentifier, objectIdentifier)
|
(*customization)(auditEvent, routingIdentifier, objectIdentifier)
|
||||||
|
|
@ -150,19 +215,74 @@ func NewProjectAuditEvent(
|
||||||
*auditV1.ObjectIdentifier,
|
*auditV1.ObjectIdentifier,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
identifier := uuid.New()
|
||||||
|
permission := "resourcemanager.project.edit"
|
||||||
|
permissionGranted := true
|
||||||
|
requestId := fmt.Sprintf("%s/1", identifier)
|
||||||
|
claims, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
request, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
response, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
correlationId := "14d5b611-ccce-4cfa-9085-9ccbfccce3cb"
|
||||||
|
headers := make(map[string]string)
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
labels := make(map[string]string)
|
||||||
|
labels["label1"] = "value1"
|
||||||
auditEvent := &auditV1.AuditLogEntry{
|
auditEvent := &auditV1.AuditLogEntry{
|
||||||
EventSource: "resource-manager",
|
LogName: fmt.Sprintf("projects/%s/logs/admin-activity", identifier),
|
||||||
Region: auditV1.Region_REGION_EU01,
|
ProtoPayload: &auditV1.AuditLog{
|
||||||
SequenceNumber: wrapperspb.Int64(0),
|
ServiceName: "resource-manager",
|
||||||
EventName: "PROJECT_CREATED",
|
MethodName: "stackit.resourcemanager.v2.project.created",
|
||||||
EventTimeStamp: timestamppb.New(time.Now()),
|
ResourceName: fmt.Sprintf("projects/%s", identifier),
|
||||||
EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_EVENT,
|
AuthenticationInfo: &auditV1.AuthenticationInfo{
|
||||||
Initiator: &auditV1.Principal{
|
PrincipalId: uuid.NewString(),
|
||||||
Id: uuid.NewString(),
|
PrincipalEmail: "user@example.com",
|
||||||
|
ServiceAccountName: nil,
|
||||||
|
ServiceAccountDelegationInfo: nil,
|
||||||
|
},
|
||||||
|
AuthorizationInfo: []*auditV1.AuthorizationInfo{{
|
||||||
|
Resource: fmt.Sprintf("projects/%s", identifier),
|
||||||
|
Permission: &permission,
|
||||||
|
Granted: &permissionGranted,
|
||||||
|
}},
|
||||||
|
RequestMetadata: &auditV1.RequestMetadata{
|
||||||
|
CallerIp: "127.0.0.1",
|
||||||
|
CallerSuppliedUserAgent: "OpenAPI-Generator/ 1.0.0/ go",
|
||||||
|
RequestAttributes: &auditV1.AttributeContext_Request{
|
||||||
|
Id: &requestId,
|
||||||
|
Method: "POST",
|
||||||
|
Headers: headers,
|
||||||
|
Path: "/v2/projects",
|
||||||
|
Host: "stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud",
|
||||||
|
Scheme: "https",
|
||||||
|
Query: nil,
|
||||||
|
Time: timestamppb.New(time.Now().UTC()),
|
||||||
|
Protocol: "http/1.1",
|
||||||
|
Auth: &auditV1.AttributeContext_Auth{
|
||||||
|
Principal: "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev",
|
||||||
|
Audiences: []string{"https:// stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"},
|
||||||
|
Claims: claims,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Request: request,
|
||||||
|
Status: &auditV1.ResponseStatus{
|
||||||
|
Code: wrapperspb.Int32(200),
|
||||||
|
Message: nil,
|
||||||
|
Details: nil,
|
||||||
|
},
|
||||||
|
NumResponseItems: nil,
|
||||||
|
Response: response,
|
||||||
|
Metadata: nil,
|
||||||
},
|
},
|
||||||
|
InsertId: fmt.Sprintf("%d/eu01/e72182e8-0bb9-4be2-a19f-87fc0dd6e738/00000000001", time.Now().UnixNano()),
|
||||||
|
Labels: labels,
|
||||||
|
CorrelationId: &correlationId,
|
||||||
|
Timestamp: timestamppb.New(time.Now()),
|
||||||
|
Severity: auditV1.LogSeverity_DEFAULT,
|
||||||
|
TraceParent: nil,
|
||||||
|
TraceState: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
identifier := uuid.New()
|
|
||||||
routingIdentifier := &RoutingIdentifier{
|
routingIdentifier := &RoutingIdentifier{
|
||||||
Identifier: identifier,
|
Identifier: identifier,
|
||||||
Type: RoutingIdentifierTypeProject,
|
Type: RoutingIdentifierTypeProject,
|
||||||
|
|
@ -172,7 +292,6 @@ func NewProjectAuditEvent(
|
||||||
Identifier: identifier.String(),
|
Identifier: identifier.String(),
|
||||||
Type: auditV1.ObjectType_OBJECT_TYPE_PROJECT,
|
Type: auditV1.ObjectType_OBJECT_TYPE_PROJECT,
|
||||||
}
|
}
|
||||||
auditEvent.ResourceContainerReference = &auditV1.AuditEvent_ObjectIdentifier{ObjectIdentifier: objectIdentifier}
|
|
||||||
|
|
||||||
if customization != nil {
|
if customization != nil {
|
||||||
(*customization)(auditEvent, routingIdentifier, objectIdentifier)
|
(*customization)(auditEvent, routingIdentifier, objectIdentifier)
|
||||||
|
|
@ -184,19 +303,74 @@ func NewProjectAuditEvent(
|
||||||
func NewSystemAuditEvent(
|
func NewSystemAuditEvent(
|
||||||
customization *func(*auditV1.AuditLogEntry)) *auditV1.AuditLogEntry {
|
customization *func(*auditV1.AuditLogEntry)) *auditV1.AuditLogEntry {
|
||||||
|
|
||||||
|
identifier := uuid.New()
|
||||||
|
requestId := fmt.Sprintf("%s/1", identifier)
|
||||||
|
claims, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
request, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
response, _ := structpb.NewStruct(map[string]interface{}{})
|
||||||
|
correlationId := "14d5b611-ccce-4cfa-9085-9ccbfccce3cb"
|
||||||
|
headers := make(map[string]string)
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
labels := make(map[string]string)
|
||||||
|
labels["label1"] = "value1"
|
||||||
|
serviceAccountId := uuid.NewString()
|
||||||
|
serviceAccountName := fmt.Sprintf("projects/%s/serviceAccounts/%s", identifier, serviceAccountId)
|
||||||
|
delegationPrincipal := auditV1.ServiceAccountDelegationInfo{Authority: &auditV1.ServiceAccountDelegationInfo_SystemPrincipal_{}}
|
||||||
auditEvent := &auditV1.AuditLogEntry{
|
auditEvent := &auditV1.AuditLogEntry{
|
||||||
EventSource: "resource-manager",
|
LogName: fmt.Sprintf("projects/%s/logs/system-event", identifier),
|
||||||
Region: auditV1.Region_REGION_EU01,
|
ProtoPayload: &auditV1.AuditLog{
|
||||||
SequenceNumber: wrapperspb.Int64(0),
|
ServiceName: "resource-manager",
|
||||||
EventName: "SYSTEM_CHANGED",
|
MethodName: "stackit.resourcemanager.v2.system.changed",
|
||||||
EventTimeStamp: timestamppb.New(time.Now()),
|
ResourceName: fmt.Sprintf("projects/%s", identifier),
|
||||||
EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_EVENT,
|
AuthenticationInfo: &auditV1.AuthenticationInfo{
|
||||||
Initiator: &auditV1.Principal{
|
PrincipalId: serviceAccountId,
|
||||||
Id: uuid.NewString(),
|
PrincipalEmail: "service-account@sa.stackit.cloud",
|
||||||
|
ServiceAccountName: &serviceAccountName,
|
||||||
|
ServiceAccountDelegationInfo: []*auditV1.ServiceAccountDelegationInfo{&delegationPrincipal},
|
||||||
|
},
|
||||||
|
AuthorizationInfo: []*auditV1.AuthorizationInfo{{
|
||||||
|
Resource: fmt.Sprintf("projects/%s", identifier),
|
||||||
|
Permission: nil,
|
||||||
|
Granted: nil,
|
||||||
|
}},
|
||||||
|
RequestMetadata: &auditV1.RequestMetadata{
|
||||||
|
CallerIp: "127.0.0.1",
|
||||||
|
CallerSuppliedUserAgent: "OpenAPI-Generator/ 1.0.0/ go",
|
||||||
|
RequestAttributes: &auditV1.AttributeContext_Request{
|
||||||
|
Id: &requestId,
|
||||||
|
Method: "POST",
|
||||||
|
Headers: headers,
|
||||||
|
Path: "/v2/projects",
|
||||||
|
Host: "stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud",
|
||||||
|
Scheme: "https",
|
||||||
|
Query: nil,
|
||||||
|
Time: timestamppb.New(time.Now().UTC()),
|
||||||
|
Protocol: "http/1.1",
|
||||||
|
Auth: &auditV1.AttributeContext_Auth{
|
||||||
|
Principal: "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev",
|
||||||
|
Audiences: []string{"https:// stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"},
|
||||||
|
Claims: claims,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Request: request,
|
||||||
|
Status: &auditV1.ResponseStatus{
|
||||||
|
Code: wrapperspb.Int32(200),
|
||||||
|
Message: nil,
|
||||||
|
Details: nil,
|
||||||
|
},
|
||||||
|
NumResponseItems: nil,
|
||||||
|
Response: response,
|
||||||
|
Metadata: nil,
|
||||||
},
|
},
|
||||||
|
InsertId: fmt.Sprintf("%d/eu01/e72182e8-0bb9-4be2-a19f-87fc0dd6e738/00000000001", time.Now().UnixNano()),
|
||||||
|
Labels: labels,
|
||||||
|
CorrelationId: &correlationId,
|
||||||
|
Timestamp: timestamppb.New(time.Now()),
|
||||||
|
Severity: auditV1.LogSeverity_DEFAULT,
|
||||||
|
TraceParent: nil,
|
||||||
|
TraceState: nil,
|
||||||
}
|
}
|
||||||
auditEvent.ResourceContainerReference = &auditV1.AuditEvent_ObjectName{
|
|
||||||
ObjectName: auditV1.ObjectName_OBJECT_NAME_SYSTEM}
|
|
||||||
|
|
||||||
if customization != nil {
|
if customization != nil {
|
||||||
(*customization)(auditEvent)
|
(*customization)(auditEvent)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -92,8 +92,6 @@ func (m *AuditLogEntry) validate(all bool) error {
|
||||||
|
|
||||||
// no validation rules for Labels
|
// no validation rules for Labels
|
||||||
|
|
||||||
// no validation rules for CorrelationId
|
|
||||||
|
|
||||||
if all {
|
if all {
|
||||||
switch v := interface{}(m.GetTimestamp()).(type) {
|
switch v := interface{}(m.GetTimestamp()).(type) {
|
||||||
case interface{ ValidateAll() error }:
|
case interface{ ValidateAll() error }:
|
||||||
|
|
@ -125,9 +123,17 @@ func (m *AuditLogEntry) validate(all bool) error {
|
||||||
|
|
||||||
// no validation rules for Severity
|
// no validation rules for Severity
|
||||||
|
|
||||||
// no validation rules for TraceParent
|
if m.CorrelationId != nil {
|
||||||
|
// no validation rules for CorrelationId
|
||||||
|
}
|
||||||
|
|
||||||
// no validation rules for TraceState
|
if m.TraceParent != nil {
|
||||||
|
// no validation rules for TraceParent
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.TraceState != nil {
|
||||||
|
// no validation rules for TraceState
|
||||||
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
return AuditLogEntryMultiError(errors)
|
return AuditLogEntryMultiError(errors)
|
||||||
|
|
@ -231,6 +237,8 @@ func (m *AuditLog) validate(all bool) error {
|
||||||
|
|
||||||
// no validation rules for ServiceName
|
// no validation rules for ServiceName
|
||||||
|
|
||||||
|
// no validation rules for MethodName
|
||||||
|
|
||||||
// no validation rules for ResourceName
|
// no validation rules for ResourceName
|
||||||
|
|
||||||
if all {
|
if all {
|
||||||
|
|
@ -412,41 +420,70 @@ func (m *AuditLog) validate(all bool) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if all {
|
|
||||||
switch v := interface{}(m.GetMetadata()).(type) {
|
|
||||||
case interface{ ValidateAll() error }:
|
|
||||||
if err := v.ValidateAll(); err != nil {
|
|
||||||
errors = append(errors, AuditLogValidationError{
|
|
||||||
field: "Metadata",
|
|
||||||
reason: "embedded message failed validation",
|
|
||||||
cause: err,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
case interface{ Validate() error }:
|
|
||||||
if err := v.Validate(); err != nil {
|
|
||||||
errors = append(errors, AuditLogValidationError{
|
|
||||||
field: "Metadata",
|
|
||||||
reason: "embedded message failed validation",
|
|
||||||
cause: err,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if v, ok := interface{}(m.GetMetadata()).(interface{ Validate() error }); ok {
|
|
||||||
if err := v.Validate(); err != nil {
|
|
||||||
return AuditLogValidationError{
|
|
||||||
field: "Metadata",
|
|
||||||
reason: "embedded message failed validation",
|
|
||||||
cause: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.MethodName != nil {
|
|
||||||
// no validation rules for MethodName
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.NumResponseItems != nil {
|
if m.NumResponseItems != nil {
|
||||||
// no validation rules for NumResponseItems
|
|
||||||
|
if all {
|
||||||
|
switch v := interface{}(m.GetNumResponseItems()).(type) {
|
||||||
|
case interface{ ValidateAll() error }:
|
||||||
|
if err := v.ValidateAll(); err != nil {
|
||||||
|
errors = append(errors, AuditLogValidationError{
|
||||||
|
field: "NumResponseItems",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case interface{ Validate() error }:
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
errors = append(errors, AuditLogValidationError{
|
||||||
|
field: "NumResponseItems",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if v, ok := interface{}(m.GetNumResponseItems()).(interface{ Validate() error }); ok {
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
return AuditLogValidationError{
|
||||||
|
field: "NumResponseItems",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Metadata != nil {
|
||||||
|
|
||||||
|
if all {
|
||||||
|
switch v := interface{}(m.GetMetadata()).(type) {
|
||||||
|
case interface{ ValidateAll() error }:
|
||||||
|
if err := v.ValidateAll(); err != nil {
|
||||||
|
errors = append(errors, AuditLogValidationError{
|
||||||
|
field: "Metadata",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case interface{ Validate() error }:
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
errors = append(errors, AuditLogValidationError{
|
||||||
|
field: "Metadata",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if v, ok := interface{}(m.GetMetadata()).(interface{ Validate() error }); ok {
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
return AuditLogValidationError{
|
||||||
|
field: "Metadata",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
|
|
@ -694,37 +731,12 @@ func (m *AuthorizationInfo) validate(all bool) error {
|
||||||
|
|
||||||
// no validation rules for Resource
|
// no validation rules for Resource
|
||||||
|
|
||||||
// no validation rules for Permission
|
if m.Permission != nil {
|
||||||
|
// no validation rules for Permission
|
||||||
|
}
|
||||||
|
|
||||||
// no validation rules for Granted
|
if m.Granted != nil {
|
||||||
|
// no validation rules for Granted
|
||||||
if all {
|
|
||||||
switch v := interface{}(m.GetResourceAttributes()).(type) {
|
|
||||||
case interface{ ValidateAll() error }:
|
|
||||||
if err := v.ValidateAll(); err != nil {
|
|
||||||
errors = append(errors, AuthorizationInfoValidationError{
|
|
||||||
field: "ResourceAttributes",
|
|
||||||
reason: "embedded message failed validation",
|
|
||||||
cause: err,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
case interface{ Validate() error }:
|
|
||||||
if err := v.Validate(); err != nil {
|
|
||||||
errors = append(errors, AuthorizationInfoValidationError{
|
|
||||||
field: "ResourceAttributes",
|
|
||||||
reason: "embedded message failed validation",
|
|
||||||
cause: err,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if v, ok := interface{}(m.GetResourceAttributes()).(interface{ Validate() error }); ok {
|
|
||||||
if err := v.Validate(); err != nil {
|
|
||||||
return AuthorizationInfoValidationError{
|
|
||||||
field: "ResourceAttributes",
|
|
||||||
reason: "embedded message failed validation",
|
|
||||||
cause: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
|
|
@ -1062,9 +1074,34 @@ func (m *ResponseStatus) validate(all bool) error {
|
||||||
|
|
||||||
var errors []error
|
var errors []error
|
||||||
|
|
||||||
// no validation rules for Code
|
if all {
|
||||||
|
switch v := interface{}(m.GetCode()).(type) {
|
||||||
// no validation rules for Message
|
case interface{ ValidateAll() error }:
|
||||||
|
if err := v.ValidateAll(); err != nil {
|
||||||
|
errors = append(errors, ResponseStatusValidationError{
|
||||||
|
field: "Code",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case interface{ Validate() error }:
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
errors = append(errors, ResponseStatusValidationError{
|
||||||
|
field: "Code",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if v, ok := interface{}(m.GetCode()).(interface{ Validate() error }); ok {
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
return ResponseStatusValidationError{
|
||||||
|
field: "Code",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for idx, item := range m.GetDetails() {
|
for idx, item := range m.GetDetails() {
|
||||||
_, _ = idx, item
|
_, _ = idx, item
|
||||||
|
|
@ -1100,6 +1137,10 @@ func (m *ResponseStatus) validate(all bool) error {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.Message != nil {
|
||||||
|
// no validation rules for Message
|
||||||
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
return ResponseStatusMultiError(errors)
|
return ResponseStatusMultiError(errors)
|
||||||
}
|
}
|
||||||
|
|
@ -1392,8 +1433,6 @@ func (m *AttributeContext_Auth) validate(all bool) error {
|
||||||
|
|
||||||
// no validation rules for Principal
|
// no validation rules for Principal
|
||||||
|
|
||||||
// no validation rules for Presenter
|
|
||||||
|
|
||||||
if all {
|
if all {
|
||||||
switch v := interface{}(m.GetClaims()).(type) {
|
switch v := interface{}(m.GetClaims()).(type) {
|
||||||
case interface{ ValidateAll() error }:
|
case interface{ ValidateAll() error }:
|
||||||
|
|
@ -1525,8 +1564,6 @@ func (m *AttributeContext_Request) validate(all bool) error {
|
||||||
|
|
||||||
var errors []error
|
var errors []error
|
||||||
|
|
||||||
// no validation rules for Id
|
|
||||||
|
|
||||||
// no validation rules for Method
|
// no validation rules for Method
|
||||||
|
|
||||||
// no validation rules for Headers
|
// no validation rules for Headers
|
||||||
|
|
@ -1537,8 +1574,6 @@ func (m *AttributeContext_Request) validate(all bool) error {
|
||||||
|
|
||||||
// no validation rules for Scheme
|
// no validation rules for Scheme
|
||||||
|
|
||||||
// no validation rules for Query
|
|
||||||
|
|
||||||
if all {
|
if all {
|
||||||
switch v := interface{}(m.GetTime()).(type) {
|
switch v := interface{}(m.GetTime()).(type) {
|
||||||
case interface{ ValidateAll() error }:
|
case interface{ ValidateAll() error }:
|
||||||
|
|
@ -1599,6 +1634,14 @@ func (m *AttributeContext_Request) validate(all bool) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.Id != nil {
|
||||||
|
// no validation rules for Id
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Query != nil {
|
||||||
|
// no validation rules for Query
|
||||||
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
return AttributeContext_RequestMultiError(errors)
|
return AttributeContext_RequestMultiError(errors)
|
||||||
}
|
}
|
||||||
|
|
@ -1701,10 +1744,6 @@ func (m *AttributeContext_Response) validate(all bool) error {
|
||||||
|
|
||||||
var errors []error
|
var errors []error
|
||||||
|
|
||||||
// no validation rules for Code
|
|
||||||
|
|
||||||
// no validation rules for Size
|
|
||||||
|
|
||||||
// no validation rules for Headers
|
// no validation rules for Headers
|
||||||
|
|
||||||
if all {
|
if all {
|
||||||
|
|
@ -1736,6 +1775,39 @@ func (m *AttributeContext_Response) validate(all bool) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.Size != nil {
|
||||||
|
|
||||||
|
if all {
|
||||||
|
switch v := interface{}(m.GetSize()).(type) {
|
||||||
|
case interface{ ValidateAll() error }:
|
||||||
|
if err := v.ValidateAll(); err != nil {
|
||||||
|
errors = append(errors, AttributeContext_ResponseValidationError{
|
||||||
|
field: "Size",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case interface{ Validate() error }:
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
errors = append(errors, AttributeContext_ResponseValidationError{
|
||||||
|
field: "Size",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if v, ok := interface{}(m.GetSize()).(interface{ Validate() error }); ok {
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
return AttributeContext_ResponseValidationError{
|
||||||
|
field: "Size",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
return AttributeContext_ResponseMultiError(errors)
|
return AttributeContext_ResponseMultiError(errors)
|
||||||
}
|
}
|
||||||
|
|
@ -1816,116 +1888,6 @@ var _ interface {
|
||||||
ErrorName() string
|
ErrorName() string
|
||||||
} = AttributeContext_ResponseValidationError{}
|
} = AttributeContext_ResponseValidationError{}
|
||||||
|
|
||||||
// Validate checks the field values on AttributeContext_Resource with the rules
|
|
||||||
// defined in the proto definition for this message. If any rules are
|
|
||||||
// violated, the first error encountered is returned, or nil if there are no violations.
|
|
||||||
func (m *AttributeContext_Resource) Validate() error {
|
|
||||||
return m.validate(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateAll checks the field values on AttributeContext_Resource with the
|
|
||||||
// rules defined in the proto definition for this message. If any rules are
|
|
||||||
// violated, the result is a list of violation errors wrapped in
|
|
||||||
// AttributeContext_ResourceMultiError, or nil if none found.
|
|
||||||
func (m *AttributeContext_Resource) ValidateAll() error {
|
|
||||||
return m.validate(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *AttributeContext_Resource) validate(all bool) error {
|
|
||||||
if m == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var errors []error
|
|
||||||
|
|
||||||
// no validation rules for Service
|
|
||||||
|
|
||||||
// no validation rules for Name
|
|
||||||
|
|
||||||
// no validation rules for Type
|
|
||||||
|
|
||||||
// no validation rules for Labels
|
|
||||||
|
|
||||||
if len(errors) > 0 {
|
|
||||||
return AttributeContext_ResourceMultiError(errors)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AttributeContext_ResourceMultiError is an error wrapping multiple validation
|
|
||||||
// errors returned by AttributeContext_Resource.ValidateAll() if the
|
|
||||||
// designated constraints aren't met.
|
|
||||||
type AttributeContext_ResourceMultiError []error
|
|
||||||
|
|
||||||
// Error returns a concatenation of all the error messages it wraps.
|
|
||||||
func (m AttributeContext_ResourceMultiError) Error() string {
|
|
||||||
var msgs []string
|
|
||||||
for _, err := range m {
|
|
||||||
msgs = append(msgs, err.Error())
|
|
||||||
}
|
|
||||||
return strings.Join(msgs, "; ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AllErrors returns a list of validation violation errors.
|
|
||||||
func (m AttributeContext_ResourceMultiError) AllErrors() []error { return m }
|
|
||||||
|
|
||||||
// AttributeContext_ResourceValidationError is the validation error returned by
|
|
||||||
// AttributeContext_Resource.Validate if the designated constraints aren't met.
|
|
||||||
type AttributeContext_ResourceValidationError struct {
|
|
||||||
field string
|
|
||||||
reason string
|
|
||||||
cause error
|
|
||||||
key bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field function returns field value.
|
|
||||||
func (e AttributeContext_ResourceValidationError) Field() string { return e.field }
|
|
||||||
|
|
||||||
// Reason function returns reason value.
|
|
||||||
func (e AttributeContext_ResourceValidationError) Reason() string { return e.reason }
|
|
||||||
|
|
||||||
// Cause function returns cause value.
|
|
||||||
func (e AttributeContext_ResourceValidationError) Cause() error { return e.cause }
|
|
||||||
|
|
||||||
// Key function returns key value.
|
|
||||||
func (e AttributeContext_ResourceValidationError) Key() bool { return e.key }
|
|
||||||
|
|
||||||
// ErrorName returns error name.
|
|
||||||
func (e AttributeContext_ResourceValidationError) ErrorName() string {
|
|
||||||
return "AttributeContext_ResourceValidationError"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error satisfies the builtin error interface
|
|
||||||
func (e AttributeContext_ResourceValidationError) Error() string {
|
|
||||||
cause := ""
|
|
||||||
if e.cause != nil {
|
|
||||||
cause = fmt.Sprintf(" | caused by: %v", e.cause)
|
|
||||||
}
|
|
||||||
|
|
||||||
key := ""
|
|
||||||
if e.key {
|
|
||||||
key = "key for "
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf(
|
|
||||||
"invalid %sAttributeContext_Resource.%s: %s%s",
|
|
||||||
key,
|
|
||||||
e.field,
|
|
||||||
e.reason,
|
|
||||||
cause)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ error = AttributeContext_ResourceValidationError{}
|
|
||||||
|
|
||||||
var _ interface {
|
|
||||||
Field() string
|
|
||||||
Reason() string
|
|
||||||
Key() bool
|
|
||||||
Cause() error
|
|
||||||
ErrorName() string
|
|
||||||
} = AttributeContext_ResourceValidationError{}
|
|
||||||
|
|
||||||
// Validate checks the field values on
|
// Validate checks the field values on
|
||||||
// ServiceAccountDelegationInfo_SystemPrincipal with the rules defined in the
|
// ServiceAccountDelegationInfo_SystemPrincipal with the rules defined in the
|
||||||
// proto definition for this message. If any rules are violated, the first
|
// proto definition for this message. If any rules are violated, the first
|
||||||
|
|
@ -1950,33 +1912,37 @@ func (m *ServiceAccountDelegationInfo_SystemPrincipal) validate(all bool) error
|
||||||
|
|
||||||
var errors []error
|
var errors []error
|
||||||
|
|
||||||
if all {
|
if m.ServiceMetadata != nil {
|
||||||
switch v := interface{}(m.GetServiceMetadata()).(type) {
|
|
||||||
case interface{ ValidateAll() error }:
|
if all {
|
||||||
if err := v.ValidateAll(); err != nil {
|
switch v := interface{}(m.GetServiceMetadata()).(type) {
|
||||||
errors = append(errors, ServiceAccountDelegationInfo_SystemPrincipalValidationError{
|
case interface{ ValidateAll() error }:
|
||||||
field: "ServiceMetadata",
|
if err := v.ValidateAll(); err != nil {
|
||||||
reason: "embedded message failed validation",
|
errors = append(errors, ServiceAccountDelegationInfo_SystemPrincipalValidationError{
|
||||||
cause: err,
|
field: "ServiceMetadata",
|
||||||
})
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case interface{ Validate() error }:
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
errors = append(errors, ServiceAccountDelegationInfo_SystemPrincipalValidationError{
|
||||||
|
field: "ServiceMetadata",
|
||||||
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case interface{ Validate() error }:
|
} else if v, ok := interface{}(m.GetServiceMetadata()).(interface{ Validate() error }); ok {
|
||||||
if err := v.Validate(); err != nil {
|
if err := v.Validate(); err != nil {
|
||||||
errors = append(errors, ServiceAccountDelegationInfo_SystemPrincipalValidationError{
|
return ServiceAccountDelegationInfo_SystemPrincipalValidationError{
|
||||||
field: "ServiceMetadata",
|
field: "ServiceMetadata",
|
||||||
reason: "embedded message failed validation",
|
reason: "embedded message failed validation",
|
||||||
cause: err,
|
cause: err,
|
||||||
})
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if v, ok := interface{}(m.GetServiceMetadata()).(interface{ Validate() error }); ok {
|
|
||||||
if err := v.Validate(); err != nil {
|
|
||||||
return ServiceAccountDelegationInfo_SystemPrincipalValidationError{
|
|
||||||
field: "ServiceMetadata",
|
|
||||||
reason: "embedded message failed validation",
|
|
||||||
cause: err,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
|
|
@ -2088,37 +2054,39 @@ func (m *ServiceAccountDelegationInfo_IdpPrincipal) validate(all bool) error {
|
||||||
|
|
||||||
// no validation rules for PrincipalId
|
// no validation rules for PrincipalId
|
||||||
|
|
||||||
if all {
|
// no validation rules for PrincipalEmail
|
||||||
switch v := interface{}(m.GetServiceMetadata()).(type) {
|
|
||||||
case interface{ ValidateAll() error }:
|
if m.ServiceMetadata != nil {
|
||||||
if err := v.ValidateAll(); err != nil {
|
|
||||||
errors = append(errors, ServiceAccountDelegationInfo_IdpPrincipalValidationError{
|
if all {
|
||||||
field: "ServiceMetadata",
|
switch v := interface{}(m.GetServiceMetadata()).(type) {
|
||||||
reason: "embedded message failed validation",
|
case interface{ ValidateAll() error }:
|
||||||
cause: err,
|
if err := v.ValidateAll(); err != nil {
|
||||||
})
|
errors = append(errors, ServiceAccountDelegationInfo_IdpPrincipalValidationError{
|
||||||
}
|
field: "ServiceMetadata",
|
||||||
case interface{ Validate() error }:
|
reason: "embedded message failed validation",
|
||||||
if err := v.Validate(); err != nil {
|
cause: err,
|
||||||
errors = append(errors, ServiceAccountDelegationInfo_IdpPrincipalValidationError{
|
})
|
||||||
field: "ServiceMetadata",
|
}
|
||||||
reason: "embedded message failed validation",
|
case interface{ Validate() error }:
|
||||||
cause: err,
|
if err := v.Validate(); err != nil {
|
||||||
})
|
errors = append(errors, ServiceAccountDelegationInfo_IdpPrincipalValidationError{
|
||||||
}
|
field: "ServiceMetadata",
|
||||||
}
|
reason: "embedded message failed validation",
|
||||||
} else if v, ok := interface{}(m.GetServiceMetadata()).(interface{ Validate() error }); ok {
|
cause: err,
|
||||||
if err := v.Validate(); err != nil {
|
})
|
||||||
return ServiceAccountDelegationInfo_IdpPrincipalValidationError{
|
}
|
||||||
field: "ServiceMetadata",
|
}
|
||||||
reason: "embedded message failed validation",
|
} else if v, ok := interface{}(m.GetServiceMetadata()).(interface{ Validate() error }); ok {
|
||||||
cause: err,
|
if err := v.Validate(); err != nil {
|
||||||
}
|
return ServiceAccountDelegationInfo_IdpPrincipalValidationError{
|
||||||
}
|
field: "ServiceMetadata",
|
||||||
}
|
reason: "embedded message failed validation",
|
||||||
|
cause: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if m.PrincipalEmail != nil {
|
|
||||||
// no validation rules for PrincipalEmail
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
|
|
|
||||||
|
|
@ -380,50 +380,53 @@ var file_audit_v1_routable_event_proto_rawDesc = []byte{
|
||||||
0x10, 0x01, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x74,
|
0x10, 0x01, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x74,
|
||||||
0x6f, 0x62, 0x75, 0x66, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42,
|
0x6f, 0x62, 0x75, 0x66, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42,
|
||||||
0x0a, 0xba, 0x48, 0x07, 0xc8, 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x70, 0x72, 0x6f,
|
0x0a, 0xba, 0x48, 0x07, 0xc8, 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x70, 0x72, 0x6f,
|
||||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x54, 0x79, 0x70, 0x65, 0x22, 0xcb, 0x03, 0x0a, 0x12, 0x52, 0x6f,
|
0x74, 0x6f, 0x62, 0x75, 0x66, 0x54, 0x79, 0x70, 0x65, 0x22, 0xf4, 0x03, 0x0a, 0x12, 0x52, 0x6f,
|
||||||
0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x75, 0x64, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74,
|
0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x75, 0x64, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74,
|
||||||
0x12, 0x38, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
0x12, 0x61, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
||||||
0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xba, 0x48, 0x16, 0xc8, 0x01, 0x01, 0x72, 0x11, 0x32, 0x0f,
|
0x20, 0x01, 0x28, 0x09, 0x42, 0x42, 0xba, 0x48, 0x3f, 0xc8, 0x01, 0x01, 0x72, 0x3a, 0x32, 0x38,
|
||||||
0x5e, 0x5b, 0x41, 0x2d, 0x5a, 0x5d, 0x2b, 0x5f, 0x5b, 0x41, 0x2d, 0x5a, 0x5d, 0x2b, 0x24, 0x52,
|
0x5e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, 0x74, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d,
|
||||||
0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x76, 0x69,
|
0x39, 0x5d, 0x2b, 0x5c, 0x2e, 0x76, 0x5b, 0x31, 0x2d, 0x39, 0x5d, 0x5b, 0x30, 0x2d, 0x39, 0x5d,
|
||||||
0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14,
|
0x2a, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x5c, 0x2e, 0x5b, 0x61,
|
||||||
0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69,
|
0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4e,
|
||||||
0x6c, 0x69, 0x74, 0x79, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0x82, 0x01, 0x02, 0x10,
|
0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74,
|
||||||
0x01, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x37, 0x0a,
|
0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e,
|
||||||
0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
|
0x76, 0x31, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x0b, 0xba,
|
||||||
0x28, 0x0e, 0x32, 0x14, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62,
|
0x48, 0x08, 0xc8, 0x01, 0x01, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69,
|
||||||
0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65,
|
0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x37, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||||
0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x49, 0x0a, 0x11, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x61, 0x75,
|
||||||
0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28,
|
0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d,
|
||||||
0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a,
|
0x65, 0x48, 0x00, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12,
|
||||||
0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52,
|
0x49, 0x0a, 0x11, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||||
0x10, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65,
|
0x66, 0x69, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x64,
|
||||||
0x72, 0x12, 0x46, 0x0a, 0x10, 0x75, 0x6e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64,
|
0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e,
|
||||||
0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x75,
|
0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||||
0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
|
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x46, 0x0a, 0x10, 0x75, 0x6e,
|
||||||
0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x48, 0x01, 0x52, 0x0f, 0x75, 0x6e, 0x65, 0x6e, 0x63, 0x72,
|
0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05,
|
||||||
0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x12, 0x40, 0x0a, 0x0e, 0x65, 0x6e, 0x63,
|
0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e,
|
||||||
0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28,
|
0x55, 0x6e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x48,
|
||||||
0x0b, 0x32, 0x17, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63,
|
0x01, 0x52, 0x0f, 0x75, 0x6e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61,
|
||||||
0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x48, 0x01, 0x52, 0x0d, 0x65, 0x6e,
|
0x74, 0x61, 0x12, 0x40, 0x0a, 0x0e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f,
|
||||||
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x42, 0x1b, 0x0a, 0x12, 0x72,
|
0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x75, 0x64,
|
||||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,
|
0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44,
|
||||||
0x65, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x42, 0x0d, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
|
0x61, 0x74, 0x61, 0x48, 0x01, 0x52, 0x0d, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64,
|
||||||
0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x2a, 0x57, 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62,
|
0x44, 0x61, 0x74, 0x61, 0x42, 0x1b, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||||
0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c,
|
0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08,
|
||||||
0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
|
0x01, 0x42, 0x0d, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01,
|
||||||
0x00, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f,
|
0x2a, 0x57, 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a,
|
||||||
0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x49, 0x53, 0x49,
|
0x0a, 0x16, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53,
|
||||||
0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x02,
|
0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x49,
|
||||||
0x42, 0x84, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x63, 0x68, 0x77, 0x61, 0x72, 0x7a,
|
0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10,
|
||||||
0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, 0x74, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76,
|
0x01, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f,
|
||||||
0x31, 0x42, 0x12, 0x52, 0x6f, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74,
|
0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x02, 0x42, 0x84, 0x01, 0x0a, 0x1c, 0x63, 0x6f,
|
||||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0f, 0x2e, 0x2f, 0x61, 0x75, 0x64, 0x69, 0x74,
|
0x6d, 0x2e, 0x73, 0x63, 0x68, 0x77, 0x61, 0x72, 0x7a, 0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x69,
|
||||||
0x3b, 0x61, 0x75, 0x64, 0x69, 0x74, 0x56, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02,
|
0x74, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x12, 0x52, 0x6f, 0x75, 0x74,
|
||||||
0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x41, 0x75, 0x64, 0x69,
|
0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
|
||||||
0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x14, 0x41, 0x75, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0x5c,
|
0x5a, 0x0f, 0x2e, 0x2f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x3b, 0x61, 0x75, 0x64, 0x69, 0x74, 0x56,
|
||||||
0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x41, 0x75,
|
0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x2e,
|
||||||
0x64, 0x69, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x56, 0x31, 0xca, 0x02, 0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x14,
|
||||||
|
0x41, 0x75, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61,
|
||||||
|
0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x41, 0x75, 0x64, 0x69, 0x74, 0x3a, 0x3a, 0x56, 0x31,
|
||||||
|
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
117
main.go
117
main.go
|
|
@ -1,117 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/gen/go/audit/v1"
|
|
||||||
|
|
||||||
"github.com/bufbuild/protovalidate-go"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
"google.golang.org/protobuf/reflect/protoregistry"
|
|
||||||
"google.golang.org/protobuf/types/known/structpb"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
agent := "aaa"
|
|
||||||
parameters, _ := structpb.NewValue(map[string]any{
|
|
||||||
"parameter": "b",
|
|
||||||
})
|
|
||||||
body, _ := structpb.NewValue(map[string]any{
|
|
||||||
"body": "b",
|
|
||||||
})
|
|
||||||
auditEvent := auditV1.AuditEvent{
|
|
||||||
EventName: "XXX",
|
|
||||||
EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_REQUEST,
|
|
||||||
Request: &auditV1.RequestDetails{
|
|
||||||
Endpoint: "XXX",
|
|
||||||
SourceIpAddress: "127.0.0.1",
|
|
||||||
UserAgent: &agent,
|
|
||||||
Parameters: parameters.GetStructValue(),
|
|
||||||
Body: body.GetStructValue(),
|
|
||||||
Headers: []*auditV1.RequestHeader{
|
|
||||||
{
|
|
||||||
Key: "abc",
|
|
||||||
Value: "def",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
EventTimeStamp: nil,
|
|
||||||
Initiator: nil,
|
|
||||||
Principals: nil,
|
|
||||||
ResourceId: nil,
|
|
||||||
ResourceName: nil,
|
|
||||||
CorrelationId: nil,
|
|
||||||
Details: nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
auditEventBytes, err := proto.Marshal(&auditEvent)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
payload := auditV1.UnencryptedData{
|
|
||||||
Data: auditEventBytes,
|
|
||||||
ProtobufType: fmt.Sprintf("%v", auditEvent.ProtoReflect().Descriptor().FullName()),
|
|
||||||
}
|
|
||||||
|
|
||||||
//var version int32 = 0
|
|
||||||
routableEvent := auditV1.RoutableAuditEvent{
|
|
||||||
EventName: "A_V1",
|
|
||||||
Visibility: auditV1.Visibility_VISIBILITY_PRIVATE,
|
|
||||||
ResourceReference: &auditV1.RoutableAuditEvent_ObjectName{ObjectName: auditV1.ObjectName_OBJECT_NAME_SYSTEM},
|
|
||||||
Data: &auditV1.RoutableAuditEvent_UnencryptedData{UnencryptedData: &payload},
|
|
||||||
}
|
|
||||||
|
|
||||||
validator, err := protovalidate.New()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("failed to initialize validator:", err)
|
|
||||||
}
|
|
||||||
err = validator.Validate(&auditEvent)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
err = validator.Validate(&routableEvent)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
routableEventBytes, err := proto.Marshal(&routableEvent)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var deserializedRoutableEvent auditV1.RoutableAuditEvent
|
|
||||||
err = proto.Unmarshal(routableEventBytes, &deserializedRoutableEvent)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if proto.Equal(&routableEvent, &deserializedRoutableEvent) {
|
|
||||||
fmt.Println("Event Matched")
|
|
||||||
} else {
|
|
||||||
fmt.Println("Event Not Matched")
|
|
||||||
}
|
|
||||||
//fmt.Println(deserializedRoutableEvent.String())
|
|
||||||
|
|
||||||
protoMessage := getProto(deserializedRoutableEvent.GetUnencryptedData().ProtobufType)
|
|
||||||
err = proto.Unmarshal(deserializedRoutableEvent.GetUnencryptedData().Data, protoMessage)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
deserializedAuditEvent, isAuditEvent := protoMessage.(*auditV1.AuditEvent)
|
|
||||||
if isAuditEvent {
|
|
||||||
fmt.Println(deserializedAuditEvent.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(string(auditEventBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getProto(dataType string) protoreflect.ProtoMessage {
|
|
||||||
t, _ := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(dataType))
|
|
||||||
m := t.New().Interface()
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
@ -4,6 +4,7 @@ import "buf/validate/validate.proto";
|
||||||
import "google/protobuf/any.proto";
|
import "google/protobuf/any.proto";
|
||||||
import "google/protobuf/struct.proto";
|
import "google/protobuf/struct.proto";
|
||||||
import "google/protobuf/timestamp.proto";
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "google/protobuf/wrappers.proto";
|
||||||
|
|
||||||
import "audit/v1/common.proto";
|
import "audit/v1/common.proto";
|
||||||
|
|
||||||
|
|
@ -13,66 +14,123 @@ option go_package = "./audit;auditV1";
|
||||||
option java_multiple_files = true;
|
option java_multiple_files = true;
|
||||||
option java_package = "com.schwarz.stackit.audit.v1";
|
option java_package = "com.schwarz.stackit.audit.v1";
|
||||||
|
|
||||||
// TODO update numbers of elements in messages
|
// TODO max attribute length
|
||||||
// TODO decide which fields should be optional
|
// TODO check regex patterns
|
||||||
|
// TODO check if gRPC, messaging ans scheduled triggered events work with the schema
|
||||||
|
|
||||||
// The audit log entry can be used to record an incident in the audit log.
|
// The audit log entry can be used to record an incident in the audit log.
|
||||||
message AuditLogEntry {
|
message AuditLogEntry {
|
||||||
|
|
||||||
// The resource name of the log to which this log entry belongs.
|
// The resource name of the log to which this log entry belongs.
|
||||||
// Example: projects/<identifier>/logs/<eventType>
|
//
|
||||||
string log_name = 12;
|
// Format: <type>/<identifier>/logs/<eventType>
|
||||||
|
// Where:
|
||||||
|
// Event-Types: admin-activity, system-event, policy-denied, data-access
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// "projects/00b0f972-59ff-48f2-a4f9-29c57b75c2fa/logs/admin-activity"
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
string log_name = 1 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.pattern = "^[a-z]+/[a-z0-9-]+/logs/(?:admin-activity|system-event|policy-denied|data-access)$"
|
||||||
|
];
|
||||||
|
|
||||||
// The log entry payload, which is always an AuditLog for STACKIT Audit Log events.
|
// The log entry payload, which is always an AuditLog for STACKIT Audit Log events.
|
||||||
AuditLog proto_payload = 2;
|
//
|
||||||
|
// Required: true
|
||||||
|
AuditLog proto_payload = 2 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
|
|
||||||
// TODO can we specify how the format should look like?
|
|
||||||
// TODO Encode sequence number into it?
|
|
||||||
// https://softwaremind.com/blog/the-unique-features-of-snowflake-id-and-its-comparison-to-uuid/
|
|
||||||
// A unique identifier for the log entry.
|
// A unique identifier for the log entry.
|
||||||
// Is generated and set by the SDK.
|
// Is used to check completeness of audit events over time.
|
||||||
// Format:
|
//
|
||||||
// <timestamp>/<region>/<worker-id>/<sequence-number>
|
// Format: <unix-timestamp>/<region-zone>/<worker-id>/<sequence-number>
|
||||||
string insert_id = 4;
|
// Where:
|
||||||
|
// Unix-Timestamp: A UTC unix timestamp in seconds is expected
|
||||||
|
// Region-Zone: The region and (optional) zone id. If both, separated with a - (dash)
|
||||||
|
// Worker-Id: The ID of the K8s Pod, Service-Instance, etc (must be unique for a sending service)
|
||||||
|
// Sequence-Number: Increasing number, representing the message offset per Worker-Id
|
||||||
|
// If the Worker-Id changes, the sequence-number has to be reset to 0.
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// "1721899117/eu01/319a7fb9-edd2-46c6-953a-a724bb377c61/8792726390909855142"
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
string insert_id = 3[
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
// TODO how do worker ids look like?
|
||||||
|
(buf.validate.field).string.pattern = "^[0-9]+/[a-z0-9]+/[a-z0-9-]+/[0-9]+$"
|
||||||
|
];
|
||||||
|
|
||||||
// A set of user-defined (key, value) data that provides additional
|
// A set of user-defined (key, value) data that provides additional
|
||||||
// information about the log entry.
|
// information about the log entry.
|
||||||
map<string, string> labels = 11;
|
//
|
||||||
|
// Required: true
|
||||||
|
map<string, string> labels = 4 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
|
|
||||||
// Correlate multiple audit logs by setting the same id
|
// Correlate multiple audit logs by setting the same id
|
||||||
string correlation_id = 15;
|
//
|
||||||
|
// Required: false
|
||||||
|
optional string correlation_id = 5 [
|
||||||
|
(buf.validate.field).string.min_len = 1
|
||||||
|
];
|
||||||
|
|
||||||
// The time the event described by the log entry occurred.
|
// The time the event described by the log entry occurred.
|
||||||
google.protobuf.Timestamp timestamp = 9;
|
//
|
||||||
|
// Required: true
|
||||||
|
google.protobuf.Timestamp timestamp = 6 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).timestamp.lt_now = true
|
||||||
|
];
|
||||||
|
|
||||||
// The severity of the log entry.
|
// The severity of the log entry.
|
||||||
LogSeverity severity = 10;
|
//
|
||||||
|
// Required: true
|
||||||
|
LogSeverity severity = 7 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).enum.defined_only = true
|
||||||
|
];
|
||||||
|
|
||||||
// W3C conform trace parent header:
|
// Customer set W3C conform trace parent header:
|
||||||
// https://www.w3.org/TR/trace-context/#traceparent-header
|
// https://www.w3.org/TR/trace-context/#traceparent-header
|
||||||
//
|
//
|
||||||
// Example:
|
// Format: <version>-<trace-id>-<parent-id>-<trace-flags>
|
||||||
// `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01`
|
//
|
||||||
string trace_parent = 22;
|
// Examples:
|
||||||
|
// "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
|
||||||
|
//
|
||||||
|
// Required: false
|
||||||
|
optional string trace_parent = 8 [
|
||||||
|
(buf.validate.field).string.pattern = "^[0-9]+-[a-z0-9]+-[a-z0-9]+-[0-9]+$"
|
||||||
|
];
|
||||||
|
|
||||||
// W3C conform trace state header:
|
// Customer set W3C conform trace state header:
|
||||||
// https://www.w3.org/TR/trace-context/#tracestate-header
|
// https://www.w3.org/TR/trace-context/#tracestate-header
|
||||||
//
|
//
|
||||||
// Example:
|
// Format: <key1>=<value1>[,<keyN>=<valueN>]
|
||||||
// `rojo=00f067aa0ba902b7,congo=t61rcWkgMzE`.
|
//
|
||||||
string trace_state = 27;
|
// Examples:
|
||||||
|
// "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE"
|
||||||
|
//
|
||||||
|
// Required: false
|
||||||
|
optional string trace_state = 9 [
|
||||||
|
(buf.validate.field).string.pattern = "[a-zA-Z0-9]+=[a-zA-Z0-9]+(?:,[a-zA-Z0-9]+=[a-zA-Z0-9]+)*"
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// The severity of the event described in a log entry, expressed as one of the
|
// The severity of the event described in a log entry, expressed as one of the
|
||||||
// standard severity levels listed below. For your reference, the levels are
|
// standard severity levels listed below.
|
||||||
// assigned the listed numeric values. The effect of using numeric values other
|
|
||||||
// than those listed is undefined.
|
|
||||||
// Copied from
|
|
||||||
// https://github.com/googleapis/googleapis/blob/master/google/logging/type/log_severity.proto
|
|
||||||
enum LogSeverity {
|
enum LogSeverity {
|
||||||
|
|
||||||
// (0) The log entry has no assigned severity level.
|
UNSPECIFIED = 0;
|
||||||
DEFAULT = 0;
|
|
||||||
|
// (1) The log entry has no assigned severity level.
|
||||||
|
// TODO check index
|
||||||
|
DEFAULT = 1;
|
||||||
|
|
||||||
// (100) Debug or trace information.
|
// (100) Debug or trace information.
|
||||||
DEBUG = 100;
|
DEBUG = 100;
|
||||||
|
|
@ -103,87 +161,156 @@ enum LogSeverity {
|
||||||
// Common audit log format for STACKIT API operations.
|
// Common audit log format for STACKIT API operations.
|
||||||
message AuditLog {
|
message AuditLog {
|
||||||
|
|
||||||
// The name of the API service performing the operation. For example,
|
// The name of the API service performing the operation.
|
||||||
// `"resource-manager"`.
|
//
|
||||||
string service_name = 7;
|
// Examples:
|
||||||
|
// "resource-manager"
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
string service_name = 1 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1
|
||||||
|
];
|
||||||
|
|
||||||
// TODO: Add extra field to open api spec for the method_name
|
// TODO rename into operation?
|
||||||
// The name of the service method or operation.
|
// The name of the service method or operation.
|
||||||
// The format should is:
|
|
||||||
// stackit.<product>.<version>.<object>.<operation>
|
|
||||||
//
|
//
|
||||||
// For example,
|
// Format: stackit.<product>.<version>.<type>.<operation>
|
||||||
//
|
//
|
||||||
// "stackit.resourcemanager.v1.organization.created"
|
// Examples:
|
||||||
// "stackit.authorization.v2.organization.moved"
|
// "stackit.resourcemanager.v1.organization.created"
|
||||||
// "stackit.authorization.v2.folder.moved"
|
// "stackit.authorization.v2.organization.moved"
|
||||||
optional string method_name = 8;
|
// "stackit.authorization.v2.folder.moved"
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
string method_name = 2 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.pattern = "^stackit\\.[a-z0-9]+\\.v[1-9][0-9]*\\.[a-z0-9]+\\.[a-z0-9]+$"
|
||||||
|
];
|
||||||
|
|
||||||
// The resource or collection that is the target of the operation.
|
// The resource or collection that is the target of the operation.
|
||||||
// The name is a scheme-less URI, not including the API service name.
|
// The name is a scheme-less URI, not including the API service name.
|
||||||
// For example:
|
|
||||||
//
|
//
|
||||||
// "projects/<id>/zones/<region-zone>/vms/<vm-id>"
|
// Format: <type>/<id>[/locations/<region-zone>][/<details>]
|
||||||
// "projects/<id>/zones/<region-zone>/vms/<vm-id>/ports/<port-id>"
|
// Where:
|
||||||
// "projects/<id>/zones/<region-zone>/instances/instance-20240723-184227
|
// Region-Zone: Optional region and zone id. If both, separated with a - (dash). Alternatively _ (underscore).
|
||||||
string resource_name = 11;
|
// Details: Optional "<key>/<id>" pairs
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// "organizations/40ab14ad-b7b0-4b1c-be41-5bc820a968d1"
|
||||||
|
// "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/_/instances/instance-20240723-174217"
|
||||||
|
// "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/instances/instance-20240723-174217"
|
||||||
|
// "projects/dd7d1807-54e9-4426-8994-721758b5b554/locations/eu01/vms/b6851b4e-7a9d-4973-ab0f-a80a13ee3060/ports/78f8bad4-a291-4fa3-b07f-4a1985d3dbe8"
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
string resource_name = 3[
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.pattern = "^[a-z]+/[a-z0-9-]+(?:/locations/(?:(?:[a-z0-9]+(?:-[a-z0-9]+)?)|_))?(?:/[a-z0-9]+/[a-z0-9-]+)*$"
|
||||||
|
];
|
||||||
|
|
||||||
// Authentication information.
|
// Authentication information.
|
||||||
AuthenticationInfo authentication_info = 3;
|
//
|
||||||
|
// Required: true
|
||||||
|
AuthenticationInfo authentication_info = 4 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
|
|
||||||
// Authorization information. If there are multiple
|
// Authorization information. If there are multiple resources or permissions involved, then there is
|
||||||
// resources or permissions involved, then there is
|
|
||||||
// one AuthorizationInfo element for each {resource, permission} tuple.
|
// one AuthorizationInfo element for each {resource, permission} tuple.
|
||||||
repeated AuthorizationInfo authorization_info = 9;
|
//
|
||||||
|
// Required: false
|
||||||
|
repeated AuthorizationInfo authorization_info = 5;
|
||||||
|
|
||||||
// Metadata about the operation.
|
// Metadata about the operation.
|
||||||
RequestMetadata request_metadata = 4;
|
//
|
||||||
|
// Required: true
|
||||||
|
RequestMetadata request_metadata = 6 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
|
|
||||||
// The operation request. This may not include all request parameters,
|
// The operation request. This may not include all request parameters,
|
||||||
// such as those that are too large, privacy-sensitive, or duplicated
|
// such as those that are too large, privacy-sensitive, or duplicated
|
||||||
// elsewhere in the log record.
|
// elsewhere in the log record.
|
||||||
// It should never include user-generated data, such as file contents.
|
// It should never include user-generated data, such as file contents.
|
||||||
google.protobuf.Struct request = 16;
|
//
|
||||||
|
// Required: true
|
||||||
|
google.protobuf.Struct request = 7 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
|
|
||||||
// The status of the overall operation.
|
// The status of the overall operation.
|
||||||
ResponseStatus status = 2;
|
//
|
||||||
|
// Required: true
|
||||||
|
ResponseStatus status = 8 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
|
|
||||||
// The number of items returned from a List or Query API method,
|
// The number of items returned from a List or Query API method,
|
||||||
// if applicable.
|
// if applicable.
|
||||||
optional int64 num_response_items = 12;
|
//
|
||||||
|
// Required: false
|
||||||
|
optional google.protobuf.Int64Value num_response_items = 9 [
|
||||||
|
(buf.validate.field).int64.gte = 0
|
||||||
|
];
|
||||||
|
|
||||||
// The operation response. This may not include all response elements,
|
// The operation response. This may not include all response elements,
|
||||||
// such as those that are too large, privacy-sensitive, or duplicated
|
// such as those that are too large, privacy-sensitive, or duplicated
|
||||||
// elsewhere in the log record.
|
// elsewhere in the log record.
|
||||||
google.protobuf.Struct response = 17;
|
//
|
||||||
|
// Required: true
|
||||||
|
google.protobuf.Struct response = 10 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
|
|
||||||
// Other service-specific data about the request, response, and other
|
// Other service-specific data about the request, response, and other
|
||||||
// information associated with the current audited event.
|
// information associated with the current audited event.
|
||||||
google.protobuf.Struct metadata = 18;
|
//
|
||||||
|
// Required: false
|
||||||
|
optional google.protobuf.Struct metadata = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authentication information for the operation.
|
// Authentication information for the operation.
|
||||||
message AuthenticationInfo {
|
message AuthenticationInfo {
|
||||||
|
|
||||||
// Principal id
|
// STACKIT principal id
|
||||||
string principal_id = 1;
|
//
|
||||||
|
// Required: true
|
||||||
|
string principal_id = 1 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1
|
||||||
|
];
|
||||||
|
|
||||||
// The email address of the authenticated user
|
// The email address of the authenticated user.
|
||||||
string principal_email = 2;
|
// Service accounts have email addresses that can be used.
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
string principal_email = 2 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1,
|
||||||
|
(buf.validate.field).string.max_len = 255
|
||||||
|
];
|
||||||
|
|
||||||
// The name of the service account used to create or exchange
|
// The name of the service account used to create or exchange
|
||||||
// credentials for authenticating the service account making the request.
|
// credentials for authenticating the service account making the request.
|
||||||
// Example:
|
|
||||||
//
|
//
|
||||||
// "projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}"
|
// Format: projects/<id>/serviceAccounts/<account>
|
||||||
optional string service_account_name = 5;
|
//
|
||||||
|
// Examples:
|
||||||
|
// "projects/29b2c56f-f712-4a9c-845b-f0907158e53c/serviceAccounts/a606dc68-8b97-421b-89a9-116bcbd004df"
|
||||||
|
//
|
||||||
|
// Required: false
|
||||||
|
optional string service_account_name = 3 [
|
||||||
|
(buf.validate.field).string.pattern = "^[a-z]+/[a-z0-9-]+/serviceAccounts/[a-zA-Z0-9-]+$"
|
||||||
|
];
|
||||||
|
|
||||||
// Identity delegation history of an authenticated service account that makes
|
// Identity delegation history of an authenticated service account that makes
|
||||||
// the request. It contains information on the real authorities that try to
|
// the request. It contains information on the real authorities that try to
|
||||||
// access STACKIT resources by delegating on a service account. When multiple
|
// access STACKIT resources by delegating on a service account. When multiple
|
||||||
// authorities present, they are guaranteed to be sorted based on the original
|
// authorities present, they are guaranteed to be sorted based on the original
|
||||||
// ordering of the identity delegation events.
|
// ordering of the identity delegation events.
|
||||||
repeated ServiceAccountDelegationInfo service_account_delegation_info = 6;
|
//
|
||||||
|
// Required: false
|
||||||
|
repeated ServiceAccountDelegationInfo service_account_delegation_info = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authorization information for the operation.
|
// Authorization information for the operation.
|
||||||
|
|
@ -191,37 +318,44 @@ message AuthorizationInfo {
|
||||||
|
|
||||||
// The resource being accessed, as a REST-style string.
|
// The resource being accessed, as a REST-style string.
|
||||||
//
|
//
|
||||||
// For example:
|
// Format: <type>/<id>[/locations/<region-zone>][/<details>]
|
||||||
// Project scoped resource: projects/test-project-123/zones/us-central1-b/instances/instance-20240723-174217
|
// Where:
|
||||||
// Global Resource: projects/_/buckets/adfeaf
|
// Region-Zone: Optional region and zone id. If both, separated with a - (dash). Alternatively _ (underscore).
|
||||||
string resource = 1;
|
// Details: Optional "<key>/<id>" pairs
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// "organizations/40ab14ad-b7b0-4b1c-be41-5bc820a968d1"
|
||||||
|
// "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/_/instances/instance-20240723-174217"
|
||||||
|
// "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/instances/instance-20240723-174217"
|
||||||
|
// "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/vms/b6851b4e-7a9d-4973-ab0f-a80a13ee3060/ports/78f8bad4-a291-4fa3-b07f-4a1985d3dbe8"
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
string resource = 1 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.pattern = "^[a-z]+/[a-z0-9-]+(?:/locations/(?:(?:[a-z0-9]+(?:-[a-z0-9]+)?)|_))?(?:/[a-z0-9]+/[a-z0-9-]+)*$"
|
||||||
|
];
|
||||||
|
|
||||||
// The required IAM permission.
|
// The required IAM permission.
|
||||||
string permission = 2;
|
//
|
||||||
|
// Examples:
|
||||||
|
// "resourcemanager.project.edit"
|
||||||
|
//
|
||||||
|
// Required: false
|
||||||
|
optional string permission = 2 [
|
||||||
|
(buf.validate.field).string.pattern = "^[a-z-]+(?:\\.[a-z-]+)*\\.[a-z-]+$"
|
||||||
|
];
|
||||||
|
|
||||||
// Whether or not authorization for `resource` and `permission`
|
// Whether or not authorization for `resource` and `permission`
|
||||||
// was granted.
|
// was granted.
|
||||||
bool granted = 3;
|
//
|
||||||
|
// Required: false
|
||||||
|
optional bool granted = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check description
|
|
||||||
// This message defines the standard attribute vocabulary for STACKIT APIs.
|
// This message defines the standard attribute vocabulary for STACKIT APIs.
|
||||||
//
|
//
|
||||||
// An attribute is a piece of metadata that describes an activity on a network
|
// An attribute is a piece of metadata that describes an activity on a network
|
||||||
// service. For example, the size of an HTTP request, or the status code of
|
// service.
|
||||||
// an HTTP response.
|
|
||||||
//
|
|
||||||
// Each attribute has a type and a name, which is logically defined as
|
|
||||||
// a proto message field in `AttributeContext`. The field type becomes the
|
|
||||||
// attribute type, and the field path becomes the attribute name. For example,
|
|
||||||
// the attribute `source.ip` maps to field `AttributeContext.source.ip`.
|
|
||||||
//
|
|
||||||
// This message definition is guaranteed not to have any wire breaking change.
|
|
||||||
// So you can use it directly for passing attributes across different systems.
|
|
||||||
//
|
|
||||||
// NOTE: Different system may generate different subset of attributes. Please
|
|
||||||
// verify the system specification before relying on an attribute generated
|
|
||||||
// a system.
|
|
||||||
message AttributeContext {
|
message AttributeContext {
|
||||||
|
|
||||||
// This message defines request authentication attributes. Terminology is
|
// This message defines request authentication attributes. Terminology is
|
||||||
|
|
@ -229,55 +363,57 @@ message AttributeContext {
|
||||||
// correlate to concepts in other standards.
|
// correlate to concepts in other standards.
|
||||||
message Auth {
|
message Auth {
|
||||||
|
|
||||||
// TODO check description
|
// The authenticated principal. Reflects the issuer ("iss") and subject
|
||||||
// The authenticated principal. Reflects the issuer (`iss`) and subject
|
// ("sub") claims within a JWT.
|
||||||
// (`sub`) claims within a JWT. The issuer and subject should be `/`
|
//
|
||||||
// delimited, with `/` percent-encoded within the subject fragment. For
|
// Format: <sub-claim>/<iss-claim>
|
||||||
// Google accounts, the principal format is:
|
// Where:
|
||||||
// "https://accounts.google.com/{id}"
|
// Sub-Claim: Sub-Claim from JWT with `/` percent-encoded (url-encoded)
|
||||||
string principal = 1;
|
//
|
||||||
|
// Examples:
|
||||||
|
// "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev"
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
string principal = 1 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.pattern = "^[a-zA-Z0-9-%.]+/[a-zA-Z0-9-%.]+$"
|
||||||
|
];
|
||||||
|
|
||||||
// TODO check description
|
|
||||||
// The intended audience(s) for this authentication information. Reflects
|
// The intended audience(s) for this authentication information. Reflects
|
||||||
// the audience (`aud`) claim within a JWT. The audience
|
// the audience ("aud") claim within a JWT, typically the services intended
|
||||||
// value(s) depends on the `issuer`, but typically include one or more of
|
// to receive the credential.
|
||||||
// the following pieces of information:
|
|
||||||
//
|
//
|
||||||
// * The services intended to receive the credential such as
|
// Examples:
|
||||||
// ["pubsub.googleapis.com", "storage.googleapis.com"]
|
// ["https://stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"]
|
||||||
// * A set of service-based scopes. For example,
|
|
||||||
// ["https://www.googleapis.com/auth/cloud-platform"]
|
|
||||||
// * The client id of an app, such as the Firebase project id for JWTs
|
|
||||||
// from Firebase Auth.
|
|
||||||
//
|
//
|
||||||
// Consult the documentation for the credential issuer to determine the
|
// Required: false
|
||||||
// information provided.
|
|
||||||
repeated string audiences = 2;
|
repeated string audiences = 2;
|
||||||
|
|
||||||
// TODO check description
|
|
||||||
// The authorized presenter of the credential. Reflects the optional
|
|
||||||
// Authorized Presenter (`azp`) claim within a JWT or the
|
|
||||||
// OAuth client id. For example, a Google Cloud Platform client id looks
|
|
||||||
// as follows: "123456789012.apps.googleusercontent.com".
|
|
||||||
string presenter = 3;
|
|
||||||
|
|
||||||
// TODO check description
|
|
||||||
// Structured claims presented with the credential. JWTs include
|
// Structured claims presented with the credential. JWTs include
|
||||||
// `{key: value}` pairs for standard and private claims. The following
|
// {"key": <value>} pairs for standard and private claims.
|
||||||
// is a subset of the standard required and optional claims that would
|
|
||||||
// typically be presented for a Google-based JWT:
|
|
||||||
//
|
//
|
||||||
// {'iss': 'accounts.google.com',
|
// The following is a subset of the standard required and optional claims that would
|
||||||
// 'sub': '113289723416554971153',
|
// typically be presented for a STACKIT JWT:
|
||||||
// 'aud': ['123456789012', 'pubsub.googleapis.com'],
|
|
||||||
// 'azp': '123456789012.apps.googleusercontent.com',
|
|
||||||
// 'email': 'jsmith@example.com',
|
|
||||||
// 'iat': 1353601026,
|
|
||||||
// 'exp': 1353604926}
|
|
||||||
//
|
//
|
||||||
// SAML assertions are similarly specified, but with an identity provider
|
// {
|
||||||
// dependent structure.
|
// "aud": "https://stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud",
|
||||||
google.protobuf.Struct claims = 4;
|
// "email": "max@mail.schwarz",
|
||||||
|
// "exp": 1721905449,
|
||||||
|
// "iat": 1721901849,
|
||||||
|
// "iss": "https://api.dev.stackit.cloud",
|
||||||
|
// "jti": "45a196e0-480f-4c34-a592-dc5db81c8c3a",
|
||||||
|
// "nbf": 1721900462,
|
||||||
|
// "roles": null,
|
||||||
|
// "sub": "cd94f01a-df2e-4456-902f-48f5e57f0b63",
|
||||||
|
// "user_id": "",
|
||||||
|
// "x_client_id": "",
|
||||||
|
// "zid": ""
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
google.protobuf.Struct claims = 3 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// This message defines attributes for an HTTP request. If the actual
|
// This message defines attributes for an HTTP request. If the actual
|
||||||
|
|
@ -288,62 +424,126 @@ message AttributeContext {
|
||||||
// The unique ID for a request, which can be propagated to downstream
|
// The unique ID for a request, which can be propagated to downstream
|
||||||
// systems. The ID should have low probability of collision
|
// systems. The ID should have low probability of collision
|
||||||
// within a single day for a specific service.
|
// within a single day for a specific service.
|
||||||
string id = 1;
|
//
|
||||||
|
// More information can be found here: https://google.aip.dev/155
|
||||||
|
//
|
||||||
|
// Format: <idempotency-key>
|
||||||
|
// Where:
|
||||||
|
// Idempotency-key: Typically consists of a id + version
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// 5e3952a9-b628-4be6-ac61-b1c6eb4a110c/5
|
||||||
|
//
|
||||||
|
// Required: false
|
||||||
|
optional string id = 1;
|
||||||
|
|
||||||
// The HTTP request method, such as `GET`, `POST`.
|
// The HTTP request method, such as `GET`, `POST`.
|
||||||
string method = 2;
|
//
|
||||||
|
// Required: true
|
||||||
|
// TODO does it make sense to define an enum?
|
||||||
|
string method = 2 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1
|
||||||
|
];
|
||||||
|
|
||||||
// The HTTP request headers. If multiple headers share the same key, they
|
// The HTTP request headers. If multiple headers share the same key, they
|
||||||
// must be merged according to the HTTP spec. All header keys must be
|
// must be merged according to the HTTP spec. All header keys must be
|
||||||
// lowercased, because HTTP header keys are case-insensitive.
|
// lowercased, because HTTP header keys are case-insensitive.
|
||||||
map<string, string> headers = 3;
|
//
|
||||||
|
// Required: true
|
||||||
|
map<string, string> headers = 3 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
|
|
||||||
// The HTTP URL path.
|
// The HTTP URL path.
|
||||||
string path = 4;
|
//
|
||||||
|
// Required: true
|
||||||
|
string path = 4 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1
|
||||||
|
];
|
||||||
|
|
||||||
// The HTTP request `Host` header value.
|
// The HTTP request `Host` header value.
|
||||||
string host = 5;
|
//
|
||||||
|
// Required: true
|
||||||
|
string host = 5 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1
|
||||||
|
];
|
||||||
|
|
||||||
// The HTTP URL scheme, such as `http` and `https`.
|
// The HTTP URL scheme, such as `http` and `https`.
|
||||||
string scheme = 6;
|
//
|
||||||
|
// Required: true
|
||||||
|
string scheme = 6 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1
|
||||||
|
];
|
||||||
|
|
||||||
// The HTTP URL query in the format of `name1=value1&name2=value2`, as it
|
// The HTTP URL query in the format of "name1=value1&name2=value2", as it
|
||||||
// appears in the first line of the HTTP request. No decoding is performed.
|
// appears in the first line of the HTTP request. No decoding is performed.
|
||||||
string query = 7;
|
//
|
||||||
|
// Required: false
|
||||||
|
optional string query = 7 [
|
||||||
|
(buf.validate.field).string.pattern = "^[a-zA-Z0-9]+=[a-zA-Z0-9]+(?:&[a-zA-Z0-9]+=[a-zA-Z0-9]+)*$"
|
||||||
|
];
|
||||||
|
|
||||||
// The timestamp when the `destination` service receives the first byte of
|
// The timestamp when the `destination` service receives the first byte of
|
||||||
// the request.
|
// the request.
|
||||||
google.protobuf.Timestamp time = 9;
|
//
|
||||||
|
// Required: true
|
||||||
|
google.protobuf.Timestamp time = 8 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).timestamp.lt_now = true
|
||||||
|
];
|
||||||
|
|
||||||
// The network protocol used with the request, such as "http/1.1",
|
// The network protocol used with the request, such as "http/1.1",
|
||||||
// "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See
|
// "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See
|
||||||
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
|
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
|
||||||
// for details.
|
// for details.
|
||||||
string protocol = 11;
|
//
|
||||||
|
// Required: true
|
||||||
|
string protocol = 9 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1
|
||||||
|
];
|
||||||
|
|
||||||
// The request authentication. May be absent for unauthenticated requests.
|
// The request authentication.
|
||||||
// Derived from the HTTP request `Authorization` header or equivalent.
|
//
|
||||||
Auth auth = 13;
|
// Required: true
|
||||||
|
Auth auth = 10 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// This message defines attributes for a typical network response. It
|
// This message defines attributes for a typical network response. It
|
||||||
// generally models semantics of an HTTP response.
|
// generally models semantics of an HTTP response.
|
||||||
|
// TODO do we need another status code attribute in the Response?
|
||||||
message Response {
|
message Response {
|
||||||
|
|
||||||
// The HTTP response status code, such as `200` and `404`.
|
// The HTTP response size in bytes.
|
||||||
int64 code = 1;
|
//
|
||||||
|
// Required: false
|
||||||
// The HTTP response size in bytes. If unknown, it must be -1.
|
optional google.protobuf.Int64Value size = 1 [
|
||||||
int64 size = 2;
|
(buf.validate.field).int64.gte = 0
|
||||||
|
];
|
||||||
|
|
||||||
// The HTTP response headers. If multiple headers share the same key, they
|
// The HTTP response headers. If multiple headers share the same key, they
|
||||||
// must be merged according to HTTP spec. All header keys must be
|
// must be merged according to HTTP spec. All header keys must be
|
||||||
// lowercased, because HTTP header keys are case-insensitive.
|
// lowercased, because HTTP header keys are case-insensitive.
|
||||||
map<string, string> headers = 3;
|
//
|
||||||
|
// Required: true
|
||||||
|
map<string, string> headers = 2 [
|
||||||
|
(buf.validate.field).required = true
|
||||||
|
];
|
||||||
|
|
||||||
// The timestamp when the `destination` service generates the first byte of
|
// The timestamp when the "destination" service generates the first byte of
|
||||||
// the response.
|
// the response.
|
||||||
google.protobuf.Timestamp time = 4;
|
//
|
||||||
|
// Required: true
|
||||||
|
google.protobuf.Timestamp time = 3 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).timestamp.lt_now = true
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -352,33 +552,34 @@ message RequestMetadata {
|
||||||
|
|
||||||
// The IP address of the caller.
|
// The IP address of the caller.
|
||||||
// For caller from internet, this will be public IPv4 or IPv6 address.
|
// For caller from internet, this will be public IPv4 or IPv6 address.
|
||||||
// For caller from a VM / K8s Service / etc, this
|
// For caller from a VM / K8s Service / etc, this will be the SIT proxy's IPv4 address.
|
||||||
// will be the SIT proxy's IPv4 address.
|
//
|
||||||
string caller_ip = 1;
|
// Required: true
|
||||||
|
string caller_ip = 1 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.ip = true
|
||||||
|
];
|
||||||
|
|
||||||
// TODO check description
|
|
||||||
// The user agent of the caller.
|
// The user agent of the caller.
|
||||||
// This information is not authenticated and should be treated accordingly.
|
|
||||||
// For example:
|
|
||||||
//
|
//
|
||||||
// + `google-api-python-client/1.4.0`:
|
// Examples:
|
||||||
// The request was made by the Google API client for Python.
|
// "OpenAPI-Generator/1.0.0/go"
|
||||||
// + `Cloud SDK Command Line Tool apitools-client/1.0 gcloud/0.9.62`:
|
// -> The request was made by the STACKIT SDK GO client or STACKIT CLI
|
||||||
// The request was made by the Google Cloud SDK CLI (gcloud).
|
// "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
|
||||||
// + `AppEngine-Google; (+http://code.google.com/appengine; appid:
|
// -> The request was made by a web browser.
|
||||||
// s~my-project`:
|
//
|
||||||
// The request was made from the `my-project` App Engine app.
|
// Required: true
|
||||||
string caller_supplied_user_agent = 2;
|
string caller_supplied_user_agent = 2 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1
|
||||||
|
];
|
||||||
|
|
||||||
// TODO check description
|
// This field contains request attributes like request url, time, etc.
|
||||||
// Request attributes used in IAM condition evaluation. This field contains
|
|
||||||
// request attributes like request time and access levels associated with
|
|
||||||
// the request.
|
|
||||||
//
|
//
|
||||||
// To get the whole view of the attributes used in IAM
|
// Required: true
|
||||||
// condition evaluation, the user must also look into
|
AttributeContext.Request request_attributes = 3 [
|
||||||
// `AuditLog.authentication_info.resource_attributes`.
|
(buf.validate.field).required = true
|
||||||
AttributeContext.Request request_attributes = 7;
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// The `Status` type defines a logical error model that is suitable for
|
// The `Status` type defines a logical error model that is suitable for
|
||||||
|
|
@ -388,12 +589,25 @@ message RequestMetadata {
|
||||||
message ResponseStatus {
|
message ResponseStatus {
|
||||||
|
|
||||||
// The http or gRPC status code.
|
// The http or gRPC status code.
|
||||||
int32 code = 1;
|
//
|
||||||
|
// Examples:
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
|
||||||
|
// https://grpc.github.io/grpc/core/md_doc_statuscodes.html
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
google.protobuf.Int32Value code = 1 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).int32.gte = 0
|
||||||
|
];
|
||||||
|
|
||||||
// Short description of the error
|
// Short description of the error
|
||||||
string message = 2;
|
//
|
||||||
|
// Required: false
|
||||||
|
optional string message = 2;
|
||||||
|
|
||||||
// Error details
|
// Error details
|
||||||
|
//
|
||||||
|
// Required: false
|
||||||
repeated google.protobuf.Struct details = 3;
|
repeated google.protobuf.Struct details = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -404,25 +618,42 @@ message ServiceAccountDelegationInfo {
|
||||||
message SystemPrincipal {
|
message SystemPrincipal {
|
||||||
|
|
||||||
// Metadata about the service that uses the service account.
|
// Metadata about the service that uses the service account.
|
||||||
google.protobuf.Struct service_metadata = 3;
|
//
|
||||||
|
// Required: false
|
||||||
|
optional google.protobuf.Struct service_metadata = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STACKIT idp principal.
|
// STACKIT idp principal.
|
||||||
message IdpPrincipal {
|
message IdpPrincipal {
|
||||||
|
|
||||||
// STACKIT principal id
|
// STACKIT principal id
|
||||||
string principal_id = 1;
|
//
|
||||||
|
// Required: true
|
||||||
|
string principal_id = 1 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1
|
||||||
|
];
|
||||||
|
|
||||||
// Optional email address
|
// The email address of the authenticated user.
|
||||||
optional string principal_email = 2;
|
// Service accounts have email addresses that can be used.
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
string principal_email = 2 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.min_len = 1,
|
||||||
|
(buf.validate.field).string.max_len = 255
|
||||||
|
];
|
||||||
|
|
||||||
// Metadata about the service that uses the service account.
|
// Metadata about the service that uses the service account.
|
||||||
google.protobuf.Struct service_metadata = 3;
|
//
|
||||||
|
// Required: false
|
||||||
|
optional google.protobuf.Struct service_metadata = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entity that creates credentials for service account and assumes its
|
// Entity that creates credentials for service account and assumes its
|
||||||
// identity for authentication.
|
// identity for authentication.
|
||||||
oneof Authority {
|
oneof Authority {
|
||||||
|
option (buf.validate.oneof).required = true;
|
||||||
|
|
||||||
// System identity
|
// System identity
|
||||||
SystemPrincipal system_principal = 1;
|
SystemPrincipal system_principal = 1;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,10 @@ message RoutableAuditEvent {
|
||||||
|
|
||||||
// Functional event name with pattern <TYPE>_<ACTION>, e.g. ORGANIZATION_CREATED
|
// Functional event name with pattern <TYPE>_<ACTION>, e.g. ORGANIZATION_CREATED
|
||||||
// Will be copied over by the SDK from the AuditEvent
|
// Will be copied over by the SDK from the AuditEvent
|
||||||
string event_name = 1 [(buf.validate.field).required = true, (buf.validate.field).string.pattern = "^[A-Z]+_[A-Z]+$"];
|
string event_name = 1 [
|
||||||
|
(buf.validate.field).required = true,
|
||||||
|
(buf.validate.field).string.pattern = "^stackit\\.[a-z0-9]+\\.v[1-9][0-9]*\\.[a-z0-9]+\\.[a-z0-9]+$"
|
||||||
|
];
|
||||||
|
|
||||||
// Visibility relevant for differentiating between internal and public events
|
// Visibility relevant for differentiating between internal and public events
|
||||||
Visibility visibility = 2 [(buf.validate.field).required = true, (buf.validate.field).enum.defined_only = true];
|
Visibility visibility = 2 [(buf.validate.field).required = true, (buf.validate.field).enum.defined_only = true];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue