diff --git a/test/images/BUILD b/test/images/BUILD index a7f93f6cf3c..bf4e0b639bd 100644 --- a/test/images/BUILD +++ b/test/images/BUILD @@ -12,6 +12,7 @@ filegroup( srcs = [ ":package-srcs", "//test/images/apparmor-loader:all-srcs", + "//test/images/audit-proxy:all-srcs", "//test/images/crd-conversion-webhook:all-srcs", "//test/images/echoserver:all-srcs", "//test/images/entrypoint-tester:all-srcs", diff --git a/test/images/audit-proxy/BUILD b/test/images/audit-proxy/BUILD new file mode 100644 index 00000000000..20b59a82153 --- /dev/null +++ b/test/images/audit-proxy/BUILD @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go_default_library", + srcs = ["main.go"], + importpath = "k8s.io/kubernetes/test/images/audit-proxy", + visibility = ["//visibility:private"], + deps = [ + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/apis/audit/install:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/apis/audit/v1:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/audit:go_default_library", + ], +) + +go_binary( + name = "audit-proxy", + embed = [":go_default_library"], + visibility = ["//visibility:public"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/test/images/audit-proxy/Dockerfile b/test/images/audit-proxy/Dockerfile new file mode 100644 index 00000000000..7bbeb62b45d --- /dev/null +++ b/test/images/audit-proxy/Dockerfile @@ -0,0 +1,17 @@ +# Copyright 2019 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. + +FROM scratch +COPY audit-proxy / +ENTRYPOINT ["/audit-proxy"] diff --git a/test/images/audit-proxy/Makefile b/test/images/audit-proxy/Makefile new file mode 100644 index 00000000000..3f7976a459f --- /dev/null +++ b/test/images/audit-proxy/Makefile @@ -0,0 +1,26 @@ +# Copyright 2019 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. + +SRCS=audit-proxy +ARCH ?= amd64 +TARGET ?= $(CURDIR) +GOARM=7 +GOLANG_VERSION ?= latest +SRC_DIR = $(notdir $(shell pwd)) +export + +bin: + ../image-util.sh bin $(SRCS) + +.PHONY: bin diff --git a/test/images/audit-proxy/README.md b/test/images/audit-proxy/README.md new file mode 100644 index 00000000000..488d9b4176b --- /dev/null +++ b/test/images/audit-proxy/README.md @@ -0,0 +1,4 @@ +# Audit Proxy + +The audit proxy is used to test dynamic auditing. It listens on port 8080 for incoming audit events and +writes them in a uniform manner to stdout. \ No newline at end of file diff --git a/test/images/audit-proxy/VERSION b/test/images/audit-proxy/VERSION new file mode 100644 index 00000000000..d3827e75a5c --- /dev/null +++ b/test/images/audit-proxy/VERSION @@ -0,0 +1 @@ +1.0 diff --git a/test/images/audit-proxy/main.go b/test/images/audit-proxy/main.go new file mode 100644 index 00000000000..8438e5eda96 --- /dev/null +++ b/test/images/audit-proxy/main.go @@ -0,0 +1,74 @@ +/* +Copyright 2019 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 main + +import ( + "io/ioutil" + "log" + "net/http" + "os" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer/json" + auditinstall "k8s.io/apiserver/pkg/apis/audit/install" + auditv1 "k8s.io/apiserver/pkg/apis/audit/v1" + "k8s.io/apiserver/pkg/audit" +) + +var ( + encoder runtime.Encoder + decoder runtime.Decoder +) + +func main() { + scheme := runtime.NewScheme() + auditinstall.Install(scheme) + serializer := json.NewSerializer(json.DefaultMetaFactory, scheme, scheme, false) + encoder = audit.Codecs.EncoderForVersion(serializer, auditv1.SchemeGroupVersion) + decoder = audit.Codecs.UniversalDecoder(auditv1.SchemeGroupVersion) + + http.HandleFunc("/", handler) + log.Fatal(http.ListenAndServe(":8080", nil)) +} + +func handler(w http.ResponseWriter, req *http.Request) { + body, err := ioutil.ReadAll(req.Body) + if err != nil { + log.Printf("could not read request body: %v", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + el := &auditv1.EventList{} + + if err := runtime.DecodeInto(decoder, body, el); err != nil { + log.Printf("failed decoding buf: %b, apiVersion: %s", body, auditv1.SchemeGroupVersion) + w.WriteHeader(http.StatusInternalServerError) + return + } + defer req.Body.Close() + + // write events to stdout + for _, event := range el.Items { + err := encoder.Encode(&event, os.Stdout) + if err != nil { + log.Printf("could not encode audit event: %v", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + } + w.WriteHeader(http.StatusOK) +}