Matthias Andreas Benkard | 832a54e | 2019-01-29 09:27:38 +0100 | [diff] [blame^] | 1 | /* |
| 2 | Copyright 2018 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 admission |
| 18 | |
| 19 | import ( |
| 20 | "fmt" |
| 21 | |
| 22 | auditinternal "k8s.io/apiserver/pkg/apis/audit" |
| 23 | "k8s.io/apiserver/pkg/audit" |
| 24 | ) |
| 25 | |
| 26 | // auditHandler logs annotations set by other admission handlers |
| 27 | type auditHandler struct { |
| 28 | Interface |
| 29 | ae *auditinternal.Event |
| 30 | } |
| 31 | |
| 32 | var _ Interface = &auditHandler{} |
| 33 | var _ MutationInterface = &auditHandler{} |
| 34 | var _ ValidationInterface = &auditHandler{} |
| 35 | |
| 36 | // WithAudit is a decorator for a admission phase. It saves annotations |
| 37 | // of attribute into the audit event. Attributes passed to the Admit and |
| 38 | // Validate function must be instance of privateAnnotationsGetter or |
| 39 | // AnnotationsGetter, otherwise an error is returned. |
| 40 | func WithAudit(i Interface, ae *auditinternal.Event) Interface { |
| 41 | if i == nil { |
| 42 | return i |
| 43 | } |
| 44 | return &auditHandler{i, ae} |
| 45 | } |
| 46 | |
| 47 | func (handler auditHandler) Admit(a Attributes) error { |
| 48 | if !handler.Interface.Handles(a.GetOperation()) { |
| 49 | return nil |
| 50 | } |
| 51 | if err := ensureAnnotationGetter(a); err != nil { |
| 52 | return err |
| 53 | } |
| 54 | var err error |
| 55 | if mutator, ok := handler.Interface.(MutationInterface); ok { |
| 56 | err = mutator.Admit(a) |
| 57 | handler.logAnnotations(a) |
| 58 | } |
| 59 | return err |
| 60 | } |
| 61 | |
| 62 | func (handler auditHandler) Validate(a Attributes) error { |
| 63 | if !handler.Interface.Handles(a.GetOperation()) { |
| 64 | return nil |
| 65 | } |
| 66 | if err := ensureAnnotationGetter(a); err != nil { |
| 67 | return err |
| 68 | } |
| 69 | var err error |
| 70 | if validator, ok := handler.Interface.(ValidationInterface); ok { |
| 71 | err = validator.Validate(a) |
| 72 | handler.logAnnotations(a) |
| 73 | } |
| 74 | return err |
| 75 | } |
| 76 | |
| 77 | func ensureAnnotationGetter(a Attributes) error { |
| 78 | _, okPrivate := a.(privateAnnotationsGetter) |
| 79 | _, okPublic := a.(AnnotationsGetter) |
| 80 | if okPrivate || okPublic { |
| 81 | return nil |
| 82 | } |
| 83 | return fmt.Errorf("attributes must be an instance of privateAnnotationsGetter or AnnotationsGetter") |
| 84 | } |
| 85 | |
| 86 | func (handler auditHandler) logAnnotations(a Attributes) { |
| 87 | switch a := a.(type) { |
| 88 | case privateAnnotationsGetter: |
| 89 | audit.LogAnnotations(handler.ae, a.getAnnotations()) |
| 90 | case AnnotationsGetter: |
| 91 | audit.LogAnnotations(handler.ae, a.GetAnnotations()) |
| 92 | default: |
| 93 | // this will never happen, because we have already checked it in ensureAnnotationGetter |
| 94 | } |
| 95 | } |