From b523c915e4a6f71ac0a43b46d49670da56f9fbb7 Mon Sep 17 00:00:00 2001 From: David Eads Date: Wed, 18 Apr 2018 11:20:28 -0400 Subject: [PATCH] fix up record flags --- hack/import-restrictions.yaml | 4 +++ pkg/kubectl/genericclioptions/doc.go | 19 ++++++++++++ .../record_flags.go | 29 +++++++++++++++++-- 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 pkg/kubectl/genericclioptions/doc.go rename pkg/kubectl/{cmd => genericclioptions}/record_flags.go (71%) diff --git a/hack/import-restrictions.yaml b/hack/import-restrictions.yaml index c9b99ae2436..7294a8c3624 100644 --- a/hack/import-restrictions.yaml +++ b/hack/import-restrictions.yaml @@ -17,6 +17,10 @@ ignoredSubTrees: - "./pkg/apis/core/validation" +- baseImportPath: "./pkg/kubectl/genericclioptions/" + allowedImports: + - k8s.io/apimachinery + - baseImportPath: "./vendor/k8s.io/apimachinery/" allowedImports: - k8s.io/apimachinery diff --git a/pkg/kubectl/genericclioptions/doc.go b/pkg/kubectl/genericclioptions/doc.go new file mode 100644 index 00000000000..2bf32d25611 --- /dev/null +++ b/pkg/kubectl/genericclioptions/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2018 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 genericclioptions contains flags which can be added to you command, bound, completed, and produce +// useful helper functions. Nothing in this package can depend on kube/kube +package genericclioptions diff --git a/pkg/kubectl/cmd/record_flags.go b/pkg/kubectl/genericclioptions/record_flags.go similarity index 71% rename from pkg/kubectl/cmd/record_flags.go rename to pkg/kubectl/genericclioptions/record_flags.go index 0749eb8ffc5..20f88546926 100644 --- a/pkg/kubectl/cmd/record_flags.go +++ b/pkg/kubectl/genericclioptions/record_flags.go @@ -14,18 +14,21 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package genericclioptions import ( "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/kubernetes/pkg/kubectl" ) +// ChangeCauseAnnotation is the annotation indicating a guess at "why" something was changed +const ChangeCauseAnnotation = "kubernetes.io/change-cause" + // RecordFlags contains all flags associated with the "--record" operation type RecordFlags struct { + // Record indicates the state of the recording flag. It is a pointer so a caller can opt out or rebind Record *bool changeCause string @@ -34,6 +37,10 @@ type RecordFlags struct { // ToRecorder returns a ChangeCause recorder if --record=false was not // explicitly given by the user func (f *RecordFlags) ToRecorder() (Recorder, error) { + if f == nil { + return &NoopRecorder{}, nil + } + shouldRecord := false if f.Record != nil { shouldRecord = *f.Record @@ -50,17 +57,29 @@ func (f *RecordFlags) ToRecorder() (Recorder, error) { }, nil } +// Complete is called before the command is run, but after it is invoked to finish the state of the struct before use. func (f *RecordFlags) Complete(changeCause string) error { + if f == nil { + return nil + } + f.changeCause = changeCause return nil } +// AddFlags binds the requested flags to the provided flagset +// TODO have this only take a flagset func (f *RecordFlags) AddFlags(cmd *cobra.Command) { + if f == nil { + return + } + if f.Record != nil { cmd.Flags().BoolVar(f.Record, "record", *f.Record, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.") } } +// NewRecordFlags provides a RecordFlags with reasonable default values set for use func NewRecordFlags() *RecordFlags { record := false @@ -69,12 +88,16 @@ func NewRecordFlags() *RecordFlags { } } +// Recorder is used to record why a runtime.Object was changed in an annotation. type Recorder interface { + // Record records why a runtime.Object was changed in an annotation. Record(runtime.Object) error } +// NoopRecorder does nothing. It is a "do nothing" that can be returned so code doesn't switch on it. type NoopRecorder struct{} +// Record implements Recorder func (r *NoopRecorder) Record(obj runtime.Object) error { return nil } @@ -95,7 +118,7 @@ func (r *ChangeCauseRecorder) Record(obj runtime.Object) error { if annotations == nil { annotations = make(map[string]string) } - annotations[kubectl.ChangeCauseAnnotation] = r.changeCause + annotations[ChangeCauseAnnotation] = r.changeCause accessor.SetAnnotations(annotations) return nil }