diff --git a/cmd/kube-apiserver/app/options/options_test.go b/cmd/kube-apiserver/app/options/options_test.go index f90c333a0a5..576ec51c813 100644 --- a/cmd/kube-apiserver/app/options/options_test.go +++ b/cmd/kube-apiserver/app/options/options_test.go @@ -61,6 +61,7 @@ func TestAddFlags(t *testing.T) { "--audit-log-batch-throttle-enable=true", "--audit-log-batch-throttle-qps=49.5", "--audit-log-batch-throttle-burst=50", + "--audit-log-version=audit.k8s.io/v1alpha1", "--audit-policy-file=/policy", "--audit-webhook-config-file=/webhook-config", "--audit-webhook-mode=blocking", @@ -71,6 +72,7 @@ func TestAddFlags(t *testing.T) { "--audit-webhook-batch-throttle-qps=43.5", "--audit-webhook-batch-throttle-burst=44", "--audit-webhook-initial-backoff=2s", + "--audit-webhook-version=audit.k8s.io/v1alpha1", "--authentication-token-webhook-cache-ttl=3m", "--authentication-token-webhook-config-file=/token-webhook-config", "--authorization-mode=AlwaysDeny", @@ -199,6 +201,7 @@ func TestAddFlags(t *testing.T) { ThrottleBurst: 50, }, }, + GroupVersionString: "audit.k8s.io/v1alpha1", }, WebhookOptions: apiserveroptions.AuditWebhookOptions{ ConfigFile: "/webhook-config", @@ -213,7 +216,8 @@ func TestAddFlags(t *testing.T) { ThrottleBurst: 44, }, }, - InitialBackoff: 2 * time.Second, + InitialBackoff: 2 * time.Second, + GroupVersionString: "audit.k8s.io/v1alpha1", }, PolicyFile: "/policy", }, diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/BUILD b/staging/src/k8s.io/apiserver/pkg/server/options/BUILD index 506e3eef800..812c8477718 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/server/options/BUILD @@ -39,6 +39,7 @@ go_library( "//vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/validating:go_default_library", "//vendor/k8s.io/apiserver/pkg/apis/apiserver:go_default_library", "//vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1:go_default_library", + "//vendor/k8s.io/apiserver/pkg/apis/audit/v1alpha1:go_default_library", "//vendor/k8s.io/apiserver/pkg/apis/audit/v1beta1:go_default_library", "//vendor/k8s.io/apiserver/pkg/audit:go_default_library", "//vendor/k8s.io/apiserver/pkg/audit/policy:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/audit.go b/staging/src/k8s.io/apiserver/pkg/server/options/audit.go index 887b52281f1..164b7ccce08 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/audit.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/audit.go @@ -27,6 +27,8 @@ import ( "github.com/spf13/pflag" "gopkg.in/natefinch/lumberjack.v2" + "k8s.io/apimachinery/pkg/runtime/schema" + auditv1alpha1 "k8s.io/apiserver/pkg/apis/audit/v1alpha1" auditv1beta1 "k8s.io/apiserver/pkg/apis/audit/v1beta1" "k8s.io/apiserver/pkg/audit" "k8s.io/apiserver/pkg/audit/policy" @@ -98,6 +100,9 @@ type AuditLogOptions struct { Format string BatchOptions AuditBatchOptions + + // API group version used for serializing audit events. + GroupVersionString string } // AuditWebhookOptions control the webhook configuration for audit events. @@ -106,6 +111,9 @@ type AuditWebhookOptions struct { InitialBackoff time.Duration BatchOptions AuditBatchOptions + + // API group version used for serializing audit events. + GroupVersionString string } func NewAuditOptions() *AuditOptions { @@ -118,7 +126,8 @@ func NewAuditOptions() *AuditOptions { Mode: ModeBatch, BatchConfig: pluginbuffered.NewDefaultBatchConfig(), }, - InitialBackoff: pluginwebhook.DefaultInitialBackoff, + InitialBackoff: pluginwebhook.DefaultInitialBackoff, + GroupVersionString: "audit.k8s.io/v1beta1", }, LogOptions: AuditLogOptions{ Format: pluginlog.FormatJson, @@ -126,6 +135,7 @@ func NewAuditOptions() *AuditOptions { Mode: ModeBlocking, BatchConfig: defaultLogBatchConfig, }, + GroupVersionString: "audit.k8s.io/v1beta1", }, } } @@ -186,6 +196,31 @@ func validateBackendBatchOptions(pluginName string, options AuditBatchOptions) e return nil } +var knownGroupVersions = []schema.GroupVersion{ + auditv1alpha1.SchemeGroupVersion, + auditv1beta1.SchemeGroupVersion, +} + +func validateGroupVersionString(groupVersion string) error { + gv, err := schema.ParseGroupVersion(groupVersion) + if err != nil { + return err + } + if !knownGroupVersion(gv) { + return fmt.Errorf("invalid group version, allowed versions are %q", knownGroupVersions) + } + return nil +} + +func knownGroupVersion(gv schema.GroupVersion) bool { + for _, knownGv := range knownGroupVersions { + if gv == knownGv { + return true + } + } + return false +} + func (o *AuditOptions) AddFlags(fs *pflag.FlagSet) { if o == nil { return @@ -287,6 +322,8 @@ func (o *AuditLogOptions) AddFlags(fs *pflag.FlagSet) { "Format of saved audits. \"legacy\" indicates 1-line text format for each event."+ " \"json\" indicates structured json format. Requires the 'AdvancedAuditing' feature"+ " gate. Known formats are "+strings.Join(pluginlog.AllowedFormats, ",")+".") + fs.StringVar(&o.GroupVersionString, "audit-log-version", o.GroupVersionString, + "API group and version used for serializing audit events written to log.") } func (o *AuditLogOptions) Validate() []error { @@ -301,6 +338,10 @@ func (o *AuditLogOptions) Validate() []error { allErrors = append(allErrors, err) } + if err := validateGroupVersionString(o.GroupVersionString); err != nil { + allErrors = append(allErrors, err) + } + // Check log format validFormat := false for _, f := range pluginlog.AllowedFormats { @@ -352,7 +393,8 @@ func (o *AuditLogOptions) getWriter() io.Writer { func (o *AuditLogOptions) advancedApplyTo(c *server.Config) error { if w := o.getWriter(); w != nil { - log := pluginlog.NewBackend(w, o.Format, auditv1beta1.SchemeGroupVersion) + groupVersion, _ := schema.ParseGroupVersion(o.GroupVersionString) + log := pluginlog.NewBackend(w, o.Format, groupVersion) c.AuditBackend = appendBackend(c.AuditBackend, o.BatchOptions.wrapBackend(log)) } return nil @@ -373,6 +415,8 @@ func (o *AuditWebhookOptions) AddFlags(fs *pflag.FlagSet) { o.InitialBackoff, "The amount of time to wait before retrying the first failed request.") fs.MarkDeprecated("audit-webhook-batch-initial-backoff", "Deprecated, use --audit-webhook-initial-backoff instead.") + fs.StringVar(&o.GroupVersionString, "audit-webhook-version", o.GroupVersionString, + "API group and version used for serializing audit events written to webhook.") } func (o *AuditWebhookOptions) Validate() []error { @@ -385,6 +429,10 @@ func (o *AuditWebhookOptions) Validate() []error { if err := validateBackendBatchOptions(pluginwebhook.PluginName, o.BatchOptions); err != nil { allErrors = append(allErrors, err) } + + if err := validateGroupVersionString(o.GroupVersionString); err != nil { + allErrors = append(allErrors, err) + } } return allErrors } @@ -398,7 +446,8 @@ func (o *AuditWebhookOptions) applyTo(c *server.Config) error { return nil } - webhook, err := pluginwebhook.NewBackend(o.ConfigFile, auditv1beta1.SchemeGroupVersion, o.InitialBackoff) + groupVersion, _ := schema.ParseGroupVersion(o.GroupVersionString) + webhook, err := pluginwebhook.NewBackend(o.ConfigFile, groupVersion, o.InitialBackoff) if err != nil { return fmt.Errorf("initializing audit webhook: %v", err) }