Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xds: support built-in Stdout audit logger type #6298

Merged
merged 21 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions authz/audit/stdout/stdout_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ type event struct {
Timestamp string `json:"timestamp"` // Time when the audit event is logged via Log method
}

// Logger implements the audit.Logger interface by logging to standard output.
type Logger struct {
// logger implements the audit.logger interface by logging to standard output.
type logger struct {
goLogger *log.Logger
}

// Log marshals the audit.Event to json and prints it to standard output.
func (l *Logger) Log(event *audit.Event) {
func (l *logger) Log(event *audit.Event) {
jsonContainer := map[string]interface{}{
"grpc_audit_log": convertEvent(event),
}
Expand Down Expand Up @@ -85,7 +85,7 @@ func (loggerBuilder) Name() string {
// Passed in configuration is ignored as the stdout logger does not
// expect any configuration to be provided.
func (lb *loggerBuilder) Build(audit.LoggerConfig) audit.Logger {
return &Logger{
return &logger{
goLogger: lb.goLogger,
}
}
Expand Down
36 changes: 11 additions & 25 deletions internal/xds/rbac/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@ import (
"google.golang.org/protobuf/types/known/structpb"
)

const (
udpaTypedStuctType = "type.googleapis.com/udpa.type.v1.TypedStruct"
xdsTypedStuctType = "type.googleapis.com/xds.type.v3.TypedStruct"
stdoutType = "type.googleapis.com/envoy.extensions.rbac.audit_loggers.stream.v3.StdoutAuditLog"
)

func buildLogger(loggerConfig *v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig) (audit.Logger, error) {
if loggerConfig.GetAuditLogger().GetTypedConfig() == nil {
return nil, fmt.Errorf("missing required field: TypedConfig")
Expand Down Expand Up @@ -65,25 +59,17 @@ func buildLogger(loggerConfig *v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConf
}

func getCustomConfig(config *anypb.Any) (json.RawMessage, string, error) {
switch config.GetTypeUrl() {
case udpaTypedStuctType:
typedStruct := &v1xdsudpatypepb.TypedStruct{}
if err := config.UnmarshalTo(typedStruct); err != nil {
return nil, "", fmt.Errorf("failed to unmarshal resource: %v", err)
}
return convertCustomConfig(typedStruct.TypeUrl, typedStruct.Value)
case xdsTypedStuctType:
typedStruct := &v3xdsxdstypepb.TypedStruct{}
if err := config.UnmarshalTo(typedStruct); err != nil {
return nil, "", fmt.Errorf("failed to unmarshal resource: %v", err)
}
return convertCustomConfig(typedStruct.TypeUrl, typedStruct.Value)
case stdoutType:
stdoutLoggerConfig := &v3auditloggersstreampb.StdoutAuditLog{}
if err := config.UnmarshalTo(stdoutLoggerConfig); err != nil {
return nil, "", fmt.Errorf("failed to unmarshal resource: %v", err)
}
return convertStdoutConfig(stdoutLoggerConfig)
any, err := config.UnmarshalNew()
if err != nil {
return nil, "", err
}
switch m := any.(type) {
case *v1xdsudpatypepb.TypedStruct:
return convertCustomConfig(m.TypeUrl, m.Value)
case *v3xdsxdstypepb.TypedStruct:
return convertCustomConfig(m.TypeUrl, m.Value)
case *v3auditloggersstreampb.StdoutAuditLog:
return convertStdoutConfig(m)
}
return nil, "", fmt.Errorf("custom config not implemented for type [%v]", config.GetTypeUrl())
}
Expand Down
41 changes: 27 additions & 14 deletions internal/xds/rbac/converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package rbac

import (
"reflect"
"strings"
"testing"

Expand Down Expand Up @@ -49,7 +50,7 @@ func (s) TestBuildLoggerErrors(t *testing.T) {
loggerConfig: &v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
AuditLogger: &v3corepb.TypedExtensionConfig{
Name: "TestAuditLoggerBuffer",
TypedConfig: &anypb.Any{},
TypedConfig: createUnsupportedPb(t),
},
},
expectedError: "custom config not implemented for type ",
Expand Down Expand Up @@ -104,10 +105,9 @@ func (s) TestBuildLoggerErrors(t *testing.T) {
logger, err := buildLogger(test.loggerConfig)
if err != nil && !strings.HasPrefix(err.Error(), test.expectedError) {
t.Fatalf("expected error: %v. got error: %v", test.expectedError, err)
} else {
if logger != test.expectedLogger {
t.Fatalf("expected logger: %v. got logger: %v", test.expectedLogger, logger)
}
}
if logger != test.expectedLogger {
t.Fatalf("expected logger: %v. got logger: %v", test.expectedLogger, logger)
}

})
Expand All @@ -118,6 +118,7 @@ func (s) TestBuildLoggerKnownTypes(t *testing.T) {
tests := []struct {
name string
loggerConfig *v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig
expectedType reflect.Type
}{
{
name: "stdout logger",
rockspore marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -128,6 +129,7 @@ func (s) TestBuildLoggerKnownTypes(t *testing.T) {
},
IsOptional: false,
},
expectedType: reflect.TypeOf(audit.GetLoggerBuilder(stdout.Name).Build(nil)),
},
{
name: "stdout logger with generic TypedConfig",
Expand All @@ -138,23 +140,19 @@ func (s) TestBuildLoggerKnownTypes(t *testing.T) {
},
IsOptional: false,
},
expectedType: reflect.TypeOf(audit.GetLoggerBuilder(stdout.Name).Build(nil)),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
logger, err := buildLogger(test.loggerConfig)
if err != nil {
t.Fatalf("expected success. got error: %v", err)
dfawley marked this conversation as resolved.
Show resolved Hide resolved
} else {
switch test.name {
case "stdout logger":
_, ok := logger.(*stdout.Logger)
if !ok {
t.Fatalf("expected logger to be type stdout.Logger but was not")
}
}
}

loggerType := reflect.TypeOf(logger)
if test.expectedType != loggerType {
t.Fatalf("logger not of expected type. want: %v got: %v", test.expectedType, loggerType)
}
})
}
}
Expand All @@ -169,3 +167,18 @@ func createStdoutPb(t *testing.T) *anypb.Any {
}
return customConfig
}

// Builds a config with a nonsensical type in the anypb.Any.
func createUnsupportedPb(t *testing.T) *anypb.Any {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you might be able to re-use

func MarshalAny(m proto.Message) *anypb.Any {
instead to simplify a little?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

t.Helper()
// This type doesn't make sense to have here, it could realistically be any
// proto that is not accepted in our custom config parsing. This was chosen
// because it is already imported.
pb := &v3rbacpb.RBAC_AuditLoggingOptions{}
customConfig, err := anypb.New(pb)
if err != nil {
t.Fatalf("createStdoutPb failed during anypb.New: %v", err)
}
return customConfig

}