Skip to content

Commit 410706e

Browse files
Merge pull request #20291 from juanvallejo/jvallejo/update-observe-rollback
Update observe, rollback cmds
2 parents eb25ddd + ddf3118 commit 410706e

File tree

4 files changed

+142
-156
lines changed

4 files changed

+142
-156
lines changed

contrib/completions/bash/oc

-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contrib/completions/zsh/oc

-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/oc/cli/observe/observe.go

+80-78
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"github.com/golang/glog"
2222
"github.com/prometheus/client_golang/prometheus"
2323
"github.com/spf13/cobra"
24-
"k8s.io/kubernetes/pkg/api/legacyscheme"
2524

2625
"k8s.io/apimachinery/pkg/api/meta"
2726
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -34,6 +33,7 @@ import (
3433
"k8s.io/apiserver/pkg/server/healthz"
3534
"k8s.io/client-go/tools/cache"
3635
"k8s.io/client-go/util/jsonpath"
36+
"k8s.io/kubernetes/pkg/api/legacyscheme"
3737
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
3838
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
3939
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@@ -161,72 +161,9 @@ var (
161161
%[1]s observe services -a '{ .spec.clusterIP }' -- register_dns.sh`)
162162
)
163163

164-
// NewCmdObserve creates the observe command.
165-
func NewCmdObserve(fullName string, f kcmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
166-
options := &ObserveOptions{
167-
baseCommandName: fullName,
168-
retryCount: 2,
169-
templateType: "jsonpath",
170-
maximumErrors: 20,
171-
listenAddr: ":11251",
172-
}
173-
174-
cmd := &cobra.Command{
175-
Use: "observe RESOURCE [-- COMMAND ...]",
176-
Short: "Observe changes to resources and react to them (experimental)",
177-
Long: fmt.Sprintf(observeLong, fullName),
178-
Example: fmt.Sprintf(observeExample, fullName),
179-
Run: func(cmd *cobra.Command, args []string) {
180-
if err := options.Complete(f, cmd, args, streams.Out, streams.ErrOut); err != nil {
181-
cmdutil.CheckErr(err)
182-
}
183-
184-
if err := options.Validate(args); err != nil {
185-
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, err.Error()))
186-
}
187-
188-
if err := options.Run(); err != nil {
189-
cmdutil.CheckErr(err)
190-
}
191-
},
192-
}
193-
194-
// flags controlling what to select
195-
cmd.Flags().BoolVar(&options.allNamespaces, "all-namespaces", false, "If true, list the requested object(s) across all projects. Project in current context is ignored.")
196-
197-
// to perform deletion synchronization
198-
cmd.Flags().VarP(&options.deleteCommand, "delete", "d", "A command to run when resources are deleted. Specify multiple times to add arguments.")
199-
cmd.Flags().Var(&options.nameSyncCommand, "names", "A command that will list all of the currently known names, optional. Specify multiple times to add arguments. Use to get notifications when objects are deleted.")
200-
201-
// add additional arguments / info to the server
202-
cmd.Flags().StringVar(&options.templateType, "output", options.templateType, "Controls the template type used for the --argument flags. Supported values are gotemplate and jsonpath.")
203-
cmd.Flags().BoolVar(&options.strictTemplates, "strict-templates", false, "If true return an error on any field or map key that is not missing in a template.")
204-
cmd.Flags().VarP(&options.templates, "argument", "a", "Template for the arguments to be passed to each command in the format defined by --output.")
205-
cmd.Flags().StringVar(&options.typeEnvVar, "type-env-var", "", "The name of an env var to set with the type of event received ('Sync', 'Updated', 'Deleted', 'Added') to the reaction command or --delete.")
206-
cmd.Flags().StringVar(&options.objectEnvVar, "object-env-var", "", "The name of an env var to serialize the object to when calling the command, optional.")
207-
208-
// control retries of individual commands
209-
cmd.Flags().IntVar(&options.maximumErrors, "maximum-errors", options.maximumErrors, "Exit after this many errors have been detected with. May be set to -1 for no maximum.")
210-
cmd.Flags().IntVar(&options.retryExitStatus, "retry-on-exit-code", 0, "If any command returns this exit code, retry up to --retry-count times.")
211-
cmd.Flags().IntVar(&options.retryCount, "retry-count", options.retryCount, "The number of times to retry a failing command before continuing.")
212-
213-
// control observe program behavior
214-
cmd.Flags().BoolVar(&options.once, "once", false, "If true, exit with a status code 0 after all current objects have been processed.")
215-
cmd.Flags().DurationVar(&options.exitAfterPeriod, "exit-after", 0, "Exit with status code 0 after the provided duration, optional.")
216-
cmd.Flags().DurationVar(&options.resyncPeriod, "resync-period", 0, "When non-zero, periodically reprocess every item from the server as a Sync event. Use to ensure external systems are kept up to date.")
217-
cmd.Flags().BoolVar(&options.printMetricsOnExit, "print-metrics-on-exit", false, "If true, on exit write all metrics to stdout.")
218-
cmd.Flags().StringVar(&options.listenAddr, "listen-addr", options.listenAddr, "The name of an interface to listen on to expose metrics and health checking.")
219-
220-
// additional debug output
221-
cmd.Flags().BoolVar(&options.noHeaders, "no-headers", false, "If true, skip printing information about each event prior to executing the command.")
222-
223-
return cmd
224-
}
225-
226164
type ObserveOptions struct {
227-
out, errOut io.Writer
228-
debugOut io.Writer
229-
noHeaders bool
165+
debugOut io.Writer
166+
noHeaders bool
230167

231168
client resource.RESTClient
232169
mapping *meta.RESTMapping
@@ -270,10 +207,77 @@ type ObserveOptions struct {
270207
// knownObjects is nil if we do not need to track deletions
271208
knownObjects knownObjects
272209

273-
baseCommandName string
210+
genericclioptions.IOStreams
211+
}
212+
213+
func NewObserveOptions(streams genericclioptions.IOStreams) *ObserveOptions {
214+
return &ObserveOptions{
215+
IOStreams: streams,
216+
217+
retryCount: 2,
218+
templateType: "jsonpath",
219+
maximumErrors: 20,
220+
listenAddr: ":11251",
221+
}
222+
}
223+
224+
// NewCmdObserve creates the observe command.
225+
func NewCmdObserve(fullName string, f kcmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
226+
o := NewObserveOptions(streams)
227+
228+
cmd := &cobra.Command{
229+
Use: "observe RESOURCE [-- COMMAND ...]",
230+
Short: "Observe changes to resources and react to them (experimental)",
231+
Long: fmt.Sprintf(observeLong, fullName),
232+
Example: fmt.Sprintf(observeExample, fullName),
233+
Run: func(cmd *cobra.Command, args []string) {
234+
if err := o.Complete(f, cmd, args); err != nil {
235+
cmdutil.CheckErr(err)
236+
}
237+
238+
if err := o.Validate(args); err != nil {
239+
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, err.Error()))
240+
}
241+
242+
if err := o.Run(); err != nil {
243+
cmdutil.CheckErr(err)
244+
}
245+
},
246+
}
247+
248+
// flags controlling what to select
249+
cmd.Flags().BoolVar(&o.allNamespaces, "all-namespaces", false, "If true, list the requested object(s) across all projects. Project in current context is ignored.")
250+
251+
// to perform deletion synchronization
252+
cmd.Flags().VarP(&o.deleteCommand, "delete", "d", "A command to run when resources are deleted. Specify multiple times to add arguments.")
253+
cmd.Flags().Var(&o.nameSyncCommand, "names", "A command that will list all of the currently known names, optional. Specify multiple times to add arguments. Use to get notifications when objects are deleted.")
254+
255+
// add additional arguments / info to the server
256+
cmd.Flags().StringVar(&o.templateType, "output", o.templateType, "Controls the template type used for the --argument flags. Supported values are gotemplate and jsonpath.")
257+
cmd.Flags().BoolVar(&o.strictTemplates, "strict-templates", false, "If true return an error on any field or map key that is not missing in a template.")
258+
cmd.Flags().VarP(&o.templates, "argument", "a", "Template for the arguments to be passed to each command in the format defined by --output.")
259+
cmd.Flags().StringVar(&o.typeEnvVar, "type-env-var", "", "The name of an env var to set with the type of event received ('Sync', 'Updated', 'Deleted', 'Added') to the reaction command or --delete.")
260+
cmd.Flags().StringVar(&o.objectEnvVar, "object-env-var", "", "The name of an env var to serialize the object to when calling the command, optional.")
261+
262+
// control retries of individual commands
263+
cmd.Flags().IntVar(&o.maximumErrors, "maximum-errors", o.maximumErrors, "Exit after this many errors have been detected with. May be set to -1 for no maximum.")
264+
cmd.Flags().IntVar(&o.retryExitStatus, "retry-on-exit-code", 0, "If any command returns this exit code, retry up to --retry-count times.")
265+
cmd.Flags().IntVar(&o.retryCount, "retry-count", o.retryCount, "The number of times to retry a failing command before continuing.")
266+
267+
// control observe program behavior
268+
cmd.Flags().BoolVar(&o.once, "once", false, "If true, exit with a status code 0 after all current objects have been processed.")
269+
cmd.Flags().DurationVar(&o.exitAfterPeriod, "exit-after", 0, "Exit with status code 0 after the provided duration, optional.")
270+
cmd.Flags().DurationVar(&o.resyncPeriod, "resync-period", 0, "When non-zero, periodically reprocess every item from the server as a Sync event. Use to ensure external systems are kept up to date.")
271+
cmd.Flags().BoolVar(&o.printMetricsOnExit, "print-metrics-on-exit", false, "If true, on exit write all metrics to stdout.")
272+
cmd.Flags().StringVar(&o.listenAddr, "listen-addr", o.listenAddr, "The name of an interface to listen on to expose metrics and health checking.")
273+
274+
// additional debug output
275+
cmd.Flags().BoolVar(&o.noHeaders, "no-headers", false, "If true, skip printing information about each event prior to executing the command.")
276+
277+
return cmd
274278
}
275279

276-
func (o *ObserveOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string, out, errOut io.Writer) error {
280+
func (o *ObserveOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string) error {
277281
var err error
278282

279283
var command []string
@@ -313,11 +317,10 @@ func (o *ObserveOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args [
313317
o.mapping = mapping
314318
o.includeNamespace = mapping.Scope.Name() == meta.RESTScopeNamespace.Name()
315319

316-
client, err := f.ClientForMapping(mapping)
320+
o.client, err = f.ClientForMapping(mapping)
317321
if err != nil {
318322
return err
319323
}
320-
o.client = client
321324

322325
o.namespace, _, err = f.ToRawKubeConfigLoader().Namespace()
323326
if err != nil {
@@ -341,11 +344,10 @@ func (o *ObserveOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args [
341344
return fmt.Errorf("template type %q not recognized - valid values are jsonpath and gotemplate", o.templateType)
342345
}
343346
o.printer = NewVersionedColumnPrinter(o.printer, legacyscheme.Scheme, version.GroupVersion())
344-
o.out, o.errOut = out, errOut
345347
if o.noHeaders {
346348
o.debugOut = ioutil.Discard
347349
} else {
348-
o.debugOut = out
350+
o.debugOut = o.Out
349351
}
350352

351353
o.argumentStore = &objectArgumentsStore{}
@@ -398,7 +400,7 @@ func (o *ObserveOptions) Validate(args []string) error {
398400

399401
func (o *ObserveOptions) Run() error {
400402
if len(o.deleteCommand) > 0 && len(o.nameSyncCommand) == 0 {
401-
fmt.Fprintf(o.errOut, "warning: If you are modifying resources outside of %q, you should use the --names command to ensure you don't miss deletions that occur while the command is not running.\n", o.mapping.Resource)
403+
fmt.Fprintf(o.ErrOut, "warning: If you are modifying resources outside of %q, you should use the --names command to ensure you don't miss deletions that occur while the command is not running.\n", o.mapping.Resource)
402404
}
403405

404406
// watch the given resource for changes
@@ -439,7 +441,7 @@ func (o *ObserveOptions) Run() error {
439441
lock.Lock()
440442
defer lock.Unlock()
441443
o.dumpMetrics()
442-
fmt.Fprintf(o.errOut, "Shutting down after %s ...\n", o.exitAfterPeriod)
444+
fmt.Fprintf(o.ErrOut, "Shutting down after %s ...\n", o.exitAfterPeriod)
443445
os.Exit(0)
444446
}()
445447
}
@@ -471,7 +473,7 @@ func (o *ObserveOptions) Run() error {
471473
}
472474
// if the store is empty, there is nothing to sync
473475
if store.HasSynced() && len(store.ListKeys()) == 0 {
474-
fmt.Fprintf(o.errOut, "Nothing to sync, exiting immediately\n")
476+
fmt.Fprintf(o.ErrOut, "Nothing to sync, exiting immediately\n")
475477
return nil
476478
}
477479
}
@@ -673,7 +675,7 @@ func (o *ObserveOptions) next(deltaType cache.DeltaType, obj runtime.Object, out
673675

674676
fmt.Fprintf(o.debugOut, "# %s %s %s\t%s\n", time.Now().Format(time.RFC3339), outType, resourceVersion, printCommandLine(command, args...))
675677

676-
out, errOut := &newlineTrailingWriter{w: o.out}, &newlineTrailingWriter{w: o.errOut}
678+
out, errOut := &newlineTrailingWriter{w: o.Out}, &newlineTrailingWriter{w: o.ErrOut}
677679

678680
err = retryCommandError(o.retryExitStatus, o.retryCount, func() error {
679681
cmd := exec.Command(command, args...)
@@ -705,7 +707,7 @@ func (o *ObserveOptions) handleCommandError(err error) error {
705707
return nil
706708
}
707709
o.observedErrors++
708-
fmt.Fprintf(o.errOut, "error: %v\n", err)
710+
fmt.Fprintf(o.ErrOut, "error: %v\n", err)
709711
if o.maximumErrors == -1 || o.observedErrors < o.maximumErrors {
710712
return nil
711713
}
@@ -719,7 +721,7 @@ func (o *ObserveOptions) dumpMetrics() {
719721
w := httptest.NewRecorder()
720722
prometheus.UninstrumentedHandler().ServeHTTP(w, &http.Request{})
721723
if w.Code == http.StatusOK {
722-
fmt.Fprintf(o.out, w.Body.String())
724+
fmt.Fprintf(o.Out, w.Body.String())
723725
}
724726
}
725727

0 commit comments

Comments
 (0)