Skip to content

Commit

Permalink
xds: support built-in Stdout audit logger type (#6298)
Browse files Browse the repository at this point in the history
This PR adds the functionality to parse and build the known StdoutLogger that we include as an implemented AuditLogger.
  • Loading branch information
gtcooke94 committed May 25, 2023
1 parent 59134c3 commit f19266c
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 32 deletions.
7 changes: 5 additions & 2 deletions authz/audit/stdout/stdout_logger.go
Expand Up @@ -31,6 +31,9 @@ import (

var grpcLogger = grpclog.Component("authz-audit")

// Name is the string to identify this logger type in the registry
const Name = "stdout_logger"

func init() {
audit.RegisterLoggerBuilder(&loggerBuilder{
goLogger: log.New(os.Stdout, "", 0),
Expand All @@ -46,7 +49,7 @@ 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.
// logger implements the audit.logger interface by logging to standard output.
type logger struct {
goLogger *log.Logger
}
Expand Down Expand Up @@ -75,7 +78,7 @@ type loggerBuilder struct {
}

func (loggerBuilder) Name() string {
return "stdout_logger"
return Name
}

// Build returns a new instance of the stdout logger.
Expand Down
2 changes: 1 addition & 1 deletion examples/go.mod
Expand Up @@ -17,7 +17,7 @@ require (
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
github.com/envoyproxy/go-control-plane v0.11.1-0.20230406144219-ba92d50b6596 // indirect
github.com/envoyproxy/go-control-plane v0.11.1-0.20230517004634-d1c5e72e4c41 // indirect
github.com/envoyproxy/protoc-gen-validate v0.10.1 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/sys v0.7.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions examples/go.sum
Expand Up @@ -636,8 +636,8 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230406144219-ba92d50b6596 h1:MDgbDqe1rWfGBa+yCcthuqDSHvXFyenZI1U7f1IbWI8=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230406144219-ba92d50b6596/go.mod h1:84cjSkVxFD9Pi/gvI5AOq5NPhGsmS8oPsJLtCON6eK8=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230517004634-d1c5e72e4c41 h1:TNyxMch3whemmD2xddvlcYav9UR0hUvFeWnMUMSdhHA=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230517004634-d1c5e72e4c41/go.mod h1:84cjSkVxFD9Pi/gvI5AOq5NPhGsmS8oPsJLtCON6eK8=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
Expand Down
2 changes: 1 addition & 1 deletion gcp/observability/go.sum
Expand Up @@ -647,7 +647,7 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230406144219-ba92d50b6596/go.mod h1:84cjSkVxFD9Pi/gvI5AOq5NPhGsmS8oPsJLtCON6eK8=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230517004634-d1c5e72e4c41/go.mod h1:84cjSkVxFD9Pi/gvI5AOq5NPhGsmS8oPsJLtCON6eK8=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -6,7 +6,7 @@ require (
github.com/cespare/xxhash/v2 v2.2.0
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe
github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195
github.com/envoyproxy/go-control-plane v0.11.1-0.20230406144219-ba92d50b6596
github.com/envoyproxy/go-control-plane v0.11.1-0.20230517004634-d1c5e72e4c41
github.com/golang/glog v1.1.0
github.com/golang/protobuf v1.5.3
github.com/google/go-cmp v0.5.9
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -17,8 +17,8 @@ github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195 h1:58f1tJ1ra+zFINPlwLW
github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230406144219-ba92d50b6596 h1:MDgbDqe1rWfGBa+yCcthuqDSHvXFyenZI1U7f1IbWI8=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230406144219-ba92d50b6596/go.mod h1:84cjSkVxFD9Pi/gvI5AOq5NPhGsmS8oPsJLtCON6eK8=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230517004634-d1c5e72e4c41 h1:TNyxMch3whemmD2xddvlcYav9UR0hUvFeWnMUMSdhHA=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230517004634-d1c5e72e4c41/go.mod h1:84cjSkVxFD9Pi/gvI5AOq5NPhGsmS8oPsJLtCON6eK8=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8=
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
Expand Down
35 changes: 19 additions & 16 deletions internal/xds/rbac/converter.go
Expand Up @@ -24,14 +24,14 @@ import (
v1xdsudpatypepb "github.com/cncf/xds/go/udpa/type/v1"
v3xdsxdstypepb "github.com/cncf/xds/go/xds/type/v3"
v3rbacpb "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3"
v3auditloggersstreampb "github.com/envoyproxy/go-control-plane/envoy/extensions/rbac/audit_loggers/stream/v3"
"google.golang.org/grpc/authz/audit"
"google.golang.org/grpc/authz/audit/stdout"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/structpb"
)

const udpaTypedStuctType = "type.googleapis.com/udpa.type.v1.TypedStruct"
const xdsTypedStuctType = "type.googleapis.com/xds.type.v3.TypedStruct"

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 @@ -59,23 +59,26 @@ 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)
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())
}

func convertStdoutConfig(config *v3auditloggersstreampb.StdoutAuditLog) (json.RawMessage, string, error) {
json, err := protojson.Marshal(config)
return json, stdout.Name, err
}

func convertCustomConfig(typeURL string, s *structpb.Struct) (json.RawMessage, string, error) {
// The gRPC policy name will be the "type name" part of the value of the
// type_url field in the TypedStruct. We get this by using the part after
Expand Down
66 changes: 61 additions & 5 deletions internal/xds/rbac/converter_test.go
Expand Up @@ -17,12 +17,16 @@
package rbac

import (
"reflect"
"strings"
"testing"

v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
v3rbacpb "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3"
v3auditloggersstreampb "github.com/envoyproxy/go-control-plane/envoy/extensions/rbac/audit_loggers/stream/v3"
"google.golang.org/grpc/authz/audit"
"google.golang.org/grpc/authz/audit/stdout"
"google.golang.org/grpc/internal/testutils"
"google.golang.org/protobuf/types/known/anypb"
)

Expand All @@ -47,7 +51,7 @@ func (s) TestBuildLoggerErrors(t *testing.T) {
loggerConfig: &v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
AuditLogger: &v3corepb.TypedExtensionConfig{
Name: "TestAuditLoggerBuffer",
TypedConfig: &anypb.Any{},
TypedConfig: testutils.MarshalAny(&v3rbacpb.RBAC_AuditLoggingOptions{}),
},
},
expectedError: "custom config not implemented for type ",
Expand Down Expand Up @@ -102,13 +106,65 @@ 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)
}

})
}
}

func (s) TestBuildLoggerKnownTypes(t *testing.T) {
tests := []struct {
name string
loggerConfig *v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig
expectedType reflect.Type
}{
{
name: "stdout logger",
loggerConfig: &v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
AuditLogger: &v3corepb.TypedExtensionConfig{
Name: stdout.Name,
TypedConfig: createStdoutPb(t),
},
IsOptional: false,
},
expectedType: reflect.TypeOf(audit.GetLoggerBuilder(stdout.Name).Build(nil)),
},
{
name: "stdout logger with generic TypedConfig",
loggerConfig: &v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
AuditLogger: &v3corepb.TypedExtensionConfig{
Name: stdout.Name,
TypedConfig: createXDSTypedStruct(t, map[string]interface{}{}, stdout.Name),
},
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)
}
loggerType := reflect.TypeOf(logger)
if test.expectedType != loggerType {
t.Fatalf("logger not of expected type. want: %v got: %v", test.expectedType, loggerType)
}
})
}
}

// Builds stdout config for audit logger proto.
func createStdoutPb(t *testing.T) *anypb.Any {
t.Helper()
pb := &v3auditloggersstreampb.StdoutAuditLog{}
customConfig, err := anypb.New(pb)
if err != nil {
t.Fatalf("createStdoutPb failed during anypb.New: %v", err)
}
return customConfig
}
2 changes: 1 addition & 1 deletion interop/observability/go.sum
Expand Up @@ -648,7 +648,7 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230406144219-ba92d50b6596/go.mod h1:84cjSkVxFD9Pi/gvI5AOq5NPhGsmS8oPsJLtCON6eK8=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230517004634-d1c5e72e4c41/go.mod h1:84cjSkVxFD9Pi/gvI5AOq5NPhGsmS8oPsJLtCON6eK8=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
Expand Down
2 changes: 1 addition & 1 deletion stats/opencensus/go.sum
Expand Up @@ -630,7 +630,7 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230406144219-ba92d50b6596/go.mod h1:84cjSkVxFD9Pi/gvI5AOq5NPhGsmS8oPsJLtCON6eK8=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230517004634-d1c5e72e4c41/go.mod h1:84cjSkVxFD9Pi/gvI5AOq5NPhGsmS8oPsJLtCON6eK8=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
Expand Down

0 comments on commit f19266c

Please sign in to comment.