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

apiserver: add a webhook implementation of the audit backend #45919

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions cmd/kube-apiserver/app/options/options.go
Expand Up @@ -45,7 +45,7 @@ type ServerRunOptions struct {
Etcd *genericoptions.EtcdOptions
SecureServing *genericoptions.SecureServingOptions
InsecureServing *kubeoptions.InsecureServingOptions
Audit *genericoptions.AuditLogOptions
Audit *genericoptions.AuditOptions
Features *genericoptions.FeatureOptions
Admission *genericoptions.AdmissionOptions
Authentication *kubeoptions.BuiltInAuthenticationOptions
Expand Down Expand Up @@ -79,7 +79,7 @@ func NewServerRunOptions() *ServerRunOptions {
Etcd: genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, api.Scheme, nil)),
SecureServing: kubeoptions.NewSecureServingOptions(),
InsecureServing: kubeoptions.NewInsecureServingOptions(),
Audit: genericoptions.NewAuditLogOptions(),
Audit: genericoptions.NewAuditOptions(),
Features: genericoptions.NewFeatureOptions(),
Admission: genericoptions.NewAdmissionOptions(),
Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),
Expand Down
4 changes: 2 additions & 2 deletions federation/cmd/federation-apiserver/app/options/options.go
Expand Up @@ -37,7 +37,7 @@ type ServerRunOptions struct {
Etcd *genericoptions.EtcdOptions
SecureServing *genericoptions.SecureServingOptions
InsecureServing *kubeoptions.InsecureServingOptions
Audit *genericoptions.AuditLogOptions
Audit *genericoptions.AuditOptions
Features *genericoptions.FeatureOptions
Admission *genericoptions.AdmissionOptions
Authentication *kubeoptions.BuiltInAuthenticationOptions
Expand All @@ -56,7 +56,7 @@ func NewServerRunOptions() *ServerRunOptions {
Etcd: genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, api.Scheme, nil)),
SecureServing: kubeoptions.NewSecureServingOptions(),
InsecureServing: kubeoptions.NewInsecureServingOptions(),
Audit: genericoptions.NewAuditLogOptions(),
Audit: genericoptions.NewAuditOptions(),
Features: genericoptions.NewFeatureOptions(),
Admission: genericoptions.NewAdmissionOptions(),
Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),
Expand Down
1 change: 1 addition & 0 deletions hack/.linted_packages
Expand Up @@ -358,6 +358,7 @@ staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory
staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/aes
staging/src/k8s.io/apiserver/pkg/util/flushwriter
staging/src/k8s.io/apiserver/pkg/util/logs
staging/src/k8s.io/apiserver/plugin/pkg/audit/webhook
staging/src/k8s.io/apiserver/plugin/pkg/authenticator
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/allow
Expand Down
2 changes: 2 additions & 0 deletions hack/verify-flags/known-flags.txt
Expand Up @@ -46,6 +46,8 @@ audit-log-maxage
audit-log-maxbackup
audit-log-maxsize
audit-log-path
audit-webhook-config-file
audit-webhook-mode
authentication-kubeconfig
authentication-token-webhook
authentication-token-webhook-cache-ttl
Expand Down
14 changes: 14 additions & 0 deletions staging/src/k8s.io/apiserver/pkg/audit/BUILD
Expand Up @@ -5,6 +5,7 @@ licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)

go_library(
Expand All @@ -13,6 +14,7 @@ go_library(
"request.go",
"scheme.go",
"types.go",
"union.go",
],
tags = ["automanaged"],
deps = [
Expand All @@ -23,10 +25,22 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//vendor/k8s.io/apiserver/pkg/apis/audit:go_default_library",
"//vendor/k8s.io/apiserver/pkg/apis/audit/v1alpha1:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//vendor/k8s.io/client-go/pkg/apis/authentication/v1:go_default_library",
],
)

go_test(
name = "go_default_test",
srcs = ["union_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apiserver/pkg/apis/audit:go_default_library",
],
)
51 changes: 51 additions & 0 deletions staging/src/k8s.io/apiserver/pkg/audit/union.go
@@ -0,0 +1,51 @@
/*
Copyright 2017 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package audit

import (
"k8s.io/apimachinery/pkg/util/errors"
auditinternal "k8s.io/apiserver/pkg/apis/audit"
)

// Union returns an audit Backend which logs events to a set of backends. The returned
// Sink implementation blocks in turn for each call to ProcessEvents.
func Union(backends ...Backend) Backend {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Union method added so users can enable both the audit log and webhook at the same time. Does this work or should we make them exclusive?

EDIT: also need to add unit tests for this.

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

Choose a reason for hiding this comment

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

lgtm. Having stderr output and webhook in parallel will be quite common I guess.

if len(backends) == 1 {
return backends[0]
}
return union{backends}
}

type union struct {
backends []Backend
}

func (u union) ProcessEvents(events ...*auditinternal.Event) {
for _, backend := range u.backends {
backend.ProcessEvents(events...)
}
}

func (u union) Run(stopCh <-chan struct{}) error {
var funcs []func() error
for _, backend := range u.backends {
funcs = append(funcs, func() error {
return backend.Run(stopCh)
})
}
return errors.AggregateGoroutines(funcs...)

Choose a reason for hiding this comment

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

Run may start go routines and shouldn't block, so I would say these don't need to be started in parallel. It's a nice interface though, so maybe this doesn't matter...

}
73 changes: 73 additions & 0 deletions staging/src/k8s.io/apiserver/pkg/audit/union_test.go
@@ -0,0 +1,73 @@
/*
Copyright 2017 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package audit

import (
"strconv"
"testing"

"k8s.io/apimachinery/pkg/types"
auditinternal "k8s.io/apiserver/pkg/apis/audit"
)

type fakeBackend struct {
events []*auditinternal.Event
}

func (f *fakeBackend) ProcessEvents(events ...*auditinternal.Event) {
f.events = append(f.events, events...)
}

func (f *fakeBackend) Run(stopCh <-chan struct{}) error {
return nil
}

func TestUnion(t *testing.T) {
backends := []Backend{
new(fakeBackend),
new(fakeBackend),
new(fakeBackend),
}

b := Union(backends...)

n := 5

var events []*auditinternal.Event
for i := 0; i < n; i++ {
events = append(events, &auditinternal.Event{
AuditID: types.UID(strconv.Itoa(i)),
})
}
b.ProcessEvents(events...)

for i, b := range backends {
// so we can inspect the underlying events.
backend := b.(*fakeBackend)

if got := len(backend.events); got != n {
t.Errorf("backend %d wanted %d events, got %d", i, n, got)
continue
}
for j, event := range backend.events {
wantID := types.UID(strconv.Itoa(j))
if event.AuditID != wantID {
t.Errorf("backend %d event %d wanted id %s, got %s", i, j, wantID, event.AuditID)
}
}
}
}
2 changes: 2 additions & 0 deletions staging/src/k8s.io/apiserver/pkg/server/options/BUILD
Expand Up @@ -54,6 +54,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
"//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
"//vendor/k8s.io/apiserver/pkg/audit:go_default_library",
"//vendor/k8s.io/apiserver/pkg/audit/policy:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authentication/authenticatorfactory:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
Expand All @@ -66,6 +67,7 @@ go_library(
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
"//vendor/k8s.io/apiserver/plugin/pkg/audit/log:go_default_library",
"//vendor/k8s.io/apiserver/plugin/pkg/audit/webhook:go_default_library",
"//vendor/k8s.io/client-go/informers:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1:go_default_library",
Expand Down