Matthias Andreas Benkard | 832a54e | 2019-01-29 09:27:38 +0100 | [diff] [blame] | 1 | /* |
| 2 | Copyright 2017 The Kubernetes Authors. |
| 3 | |
| 4 | Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | you may not use this file except in compliance with the License. |
| 6 | You may obtain a copy of the License at |
| 7 | |
| 8 | http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | |
| 10 | Unless required by applicable law or agreed to in writing, software |
| 11 | distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | See the License for the specific language governing permissions and |
| 14 | limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package log |
| 18 | |
| 19 | import ( |
| 20 | "fmt" |
| 21 | "io" |
| 22 | "strings" |
| 23 | |
| 24 | "k8s.io/apimachinery/pkg/runtime" |
| 25 | "k8s.io/apimachinery/pkg/runtime/schema" |
| 26 | auditinternal "k8s.io/apiserver/pkg/apis/audit" |
| 27 | "k8s.io/apiserver/pkg/audit" |
| 28 | ) |
| 29 | |
| 30 | const ( |
| 31 | // FormatLegacy saves event in 1-line text format. |
| 32 | FormatLegacy = "legacy" |
| 33 | // FormatJson saves event in structured json format. |
| 34 | FormatJson = "json" |
| 35 | |
| 36 | // PluginName is the name of this plugin, to be used in help and logs. |
| 37 | PluginName = "log" |
| 38 | ) |
| 39 | |
| 40 | // AllowedFormats are the formats known by log backend. |
| 41 | var AllowedFormats = []string{ |
| 42 | FormatLegacy, |
| 43 | FormatJson, |
| 44 | } |
| 45 | |
| 46 | type backend struct { |
| 47 | out io.Writer |
| 48 | format string |
| 49 | groupVersion schema.GroupVersion |
| 50 | } |
| 51 | |
| 52 | var _ audit.Backend = &backend{} |
| 53 | |
| 54 | func NewBackend(out io.Writer, format string, groupVersion schema.GroupVersion) audit.Backend { |
| 55 | return &backend{ |
| 56 | out: out, |
| 57 | format: format, |
| 58 | groupVersion: groupVersion, |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | func (b *backend) ProcessEvents(events ...*auditinternal.Event) { |
| 63 | for _, ev := range events { |
| 64 | b.logEvent(ev) |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | func (b *backend) logEvent(ev *auditinternal.Event) { |
| 69 | line := "" |
| 70 | switch b.format { |
| 71 | case FormatLegacy: |
| 72 | line = audit.EventString(ev) + "\n" |
| 73 | case FormatJson: |
| 74 | bs, err := runtime.Encode(audit.Codecs.LegacyCodec(b.groupVersion), ev) |
| 75 | if err != nil { |
| 76 | audit.HandlePluginError(PluginName, err, ev) |
| 77 | return |
| 78 | } |
| 79 | line = string(bs[:]) |
| 80 | default: |
| 81 | audit.HandlePluginError(PluginName, fmt.Errorf("log format %q is not in list of known formats (%s)", |
| 82 | b.format, strings.Join(AllowedFormats, ",")), ev) |
| 83 | return |
| 84 | } |
| 85 | if _, err := fmt.Fprint(b.out, line); err != nil { |
| 86 | audit.HandlePluginError(PluginName, err, ev) |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | func (b *backend) Run(stopCh <-chan struct{}) error { |
| 91 | return nil |
| 92 | } |
| 93 | |
| 94 | func (b *backend) Shutdown() { |
| 95 | // Nothing to do here. |
| 96 | } |
| 97 | |
| 98 | func (b *backend) String() string { |
| 99 | return PluginName |
| 100 | } |