add a warning printer in cli-runtime to coordinate warning style
modified: staging/src/k8s.io/kubectl/pkg/cmd/auth/auth.go Kubernetes-commit: 272e245f06e425fc912b1e477e8b6763850b161e
This commit is contained in:
parent
335090af69
commit
ec9d0484e5
|
|
@ -43,6 +43,7 @@ import (
|
|||
"k8s.io/kubectl/pkg/describe"
|
||||
rbacutil "k8s.io/kubectl/pkg/util/rbac"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
)
|
||||
|
||||
// CanIOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
||||
|
|
@ -63,6 +64,7 @@ type CanIOptions struct {
|
|||
List bool
|
||||
|
||||
genericclioptions.IOStreams
|
||||
warningPrinter *printers.WarningPrinter
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -144,6 +146,8 @@ func NewCmdCanI(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
|
|||
|
||||
// Complete completes all the required options
|
||||
func (o *CanIOptions) Complete(f cmdutil.Factory, args []string) error {
|
||||
o.warningPrinter = printers.NewWarningPrinter(o.ErrOut, printers.WarningPrinterOptions{Color: term.AllowsColorOutput(o.ErrOut)})
|
||||
|
||||
if o.List {
|
||||
if len(args) != 0 {
|
||||
return errors.New("list option must be specified with no arguments")
|
||||
|
|
@ -201,6 +205,10 @@ func (o *CanIOptions) Validate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if o.warningPrinter == nil {
|
||||
return fmt.Errorf("warningPrinter can not be used without initialization")
|
||||
}
|
||||
|
||||
if o.NonResourceURL != "" {
|
||||
if o.Subresource != "" {
|
||||
return fmt.Errorf("--subresource can not be used with NonResourceURL")
|
||||
|
|
@ -209,20 +217,19 @@ func (o *CanIOptions) Validate() error {
|
|||
return fmt.Errorf("NonResourceURL and ResourceName can not specified together")
|
||||
}
|
||||
if !isKnownNonResourceVerb(o.Verb) {
|
||||
fmt.Fprintf(o.ErrOut, "Warning: verb '%s' is not a known verb\n", o.Verb)
|
||||
o.warningPrinter.Print(fmt.Sprintf("verb '%s' is not a known verb\n", o.Verb))
|
||||
}
|
||||
} else if !o.Resource.Empty() && !o.AllNamespaces && o.DiscoveryClient != nil {
|
||||
if namespaced, err := isNamespaced(o.Resource, o.DiscoveryClient); err == nil && !namespaced {
|
||||
if len(o.Resource.Group) == 0 {
|
||||
fmt.Fprintf(o.ErrOut, "Warning: resource '%s' is not namespace scoped\n", o.Resource.Resource)
|
||||
o.warningPrinter.Print(fmt.Sprintf("resource '%s' is not namespace scoped\n", o.Resource.Resource))
|
||||
} else {
|
||||
fmt.Fprintf(o.ErrOut, "Warning: resource '%s' is not namespace scoped in group '%s'\n", o.Resource.Resource, o.Resource.Group)
|
||||
o.warningPrinter.Print(fmt.Sprintf("resource '%s' is not namespace scoped in group '%s'\n", o.Resource.Resource, o.Resource.Group))
|
||||
}
|
||||
}
|
||||
if !isKnownResourceVerb(o.Verb) {
|
||||
fmt.Fprintf(o.ErrOut, "Warning: verb '%s' is not a known verb\n", o.Verb)
|
||||
o.warningPrinter.Print(fmt.Sprintf("verb '%s' is not a known verb\n", o.Verb))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if o.NoHeaders {
|
||||
|
|
@ -309,9 +316,9 @@ func (o *CanIOptions) resourceFor(mapper meta.RESTMapper, resourceArg string) sc
|
|||
if err != nil {
|
||||
if !nonStandardResourceNames.Has(groupResource.String()) {
|
||||
if len(groupResource.Group) == 0 {
|
||||
fmt.Fprintf(o.ErrOut, "Warning: the server doesn't have a resource type '%s'\n", groupResource.Resource)
|
||||
o.warningPrinter.Print(fmt.Sprintf("the server doesn't have a resource type '%s'\n", groupResource.Resource))
|
||||
} else {
|
||||
fmt.Fprintf(o.ErrOut, "Warning: the server doesn't have a resource type '%s' in group '%s'\n", groupResource.Resource, groupResource.Group)
|
||||
o.warningPrinter.Print(fmt.Sprintf("the server doesn't have a resource type '%s' in group '%s'\n", groupResource.Resource, groupResource.Group))
|
||||
}
|
||||
}
|
||||
return schema.GroupVersionResource{Resource: resourceArg}
|
||||
|
|
@ -323,7 +330,7 @@ func (o *CanIOptions) resourceFor(mapper meta.RESTMapper, resourceArg string) sc
|
|||
|
||||
func (o *CanIOptions) printStatus(status authorizationv1.SubjectRulesReviewStatus) error {
|
||||
if status.Incomplete {
|
||||
fmt.Fprintf(o.ErrOut, "warning: the list may be incomplete: %v\n", status.EvaluationError)
|
||||
o.warningPrinter.Print(fmt.Sprintf("the list may be incomplete: %v", status.EvaluationError))
|
||||
}
|
||||
|
||||
breakdownRules := []rbacv1.PolicyRule{}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/rest/fake"
|
||||
cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
|
||||
|
|
@ -281,7 +282,7 @@ func TestRunResourceFor(t *testing.T) {
|
|||
expectGVR: schema.GroupVersionResource{
|
||||
Resource: "invalid",
|
||||
},
|
||||
expectedErrOut: "Warning: the server doesn't have a resource type 'invalid'\n",
|
||||
expectedErrOut: "Warning: the server doesn't have a resource type 'invalid'\n\n",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -292,6 +293,7 @@ func TestRunResourceFor(t *testing.T) {
|
|||
|
||||
ioStreams, _, _, buf := genericclioptions.NewTestIOStreams()
|
||||
test.o.IOStreams = ioStreams
|
||||
test.o.warningPrinter = printers.NewWarningPrinter(test.o.IOStreams.ErrOut, printers.WarningPrinterOptions{Color: false})
|
||||
|
||||
restMapper, err := tf.ToRESTMapper()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
|
@ -50,6 +51,7 @@ import (
|
|||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/interrupt"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
|
|
@ -127,6 +129,7 @@ type DebugOptions struct {
|
|||
podClient corev1client.CoreV1Interface
|
||||
|
||||
genericclioptions.IOStreams
|
||||
warningPrinter *printers.WarningPrinter
|
||||
}
|
||||
|
||||
// NewDebugOptions returns a DebugOptions initialized with default values.
|
||||
|
|
@ -217,6 +220,9 @@ func (o *DebugOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
|
|||
o.attachChanged = cmd.Flags().Changed("attach")
|
||||
o.shareProcessedChanged = cmd.Flags().Changed("share-processes")
|
||||
|
||||
// Warning printer
|
||||
o.warningPrinter = printers.NewWarningPrinter(o.ErrOut, printers.WarningPrinterOptions{Color: term.AllowsColorOutput(o.ErrOut)})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -293,6 +299,11 @@ func (o *DebugOptions) Validate() error {
|
|||
return fmt.Errorf("-i/--stdin is required for containers with -t/--tty=true")
|
||||
}
|
||||
|
||||
// warningPrinter
|
||||
if o.warningPrinter == nil {
|
||||
return fmt.Errorf("warningPrinter can not be used without initialization")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -742,7 +753,7 @@ func (o *DebugOptions) waitForContainer(ctx context.Context, ns, podName, contai
|
|||
return true, nil
|
||||
}
|
||||
if !o.Quiet && s.State.Waiting != nil && s.State.Waiting.Message != "" {
|
||||
fmt.Fprintf(o.ErrOut, "Warning: container %s: %s\n", containerName, s.State.Waiting.Message)
|
||||
o.warningPrinter.Print(fmt.Sprintf("container %s: %s", containerName, s.State.Waiting.Message))
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import (
|
|||
"k8s.io/kubectl/pkg/util/completion"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -133,6 +134,7 @@ type DeleteOptions struct {
|
|||
Result *resource.Result
|
||||
|
||||
genericclioptions.IOStreams
|
||||
warningPrinter *printers.WarningPrinter
|
||||
}
|
||||
|
||||
func NewCmdDelete(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
|
|
@ -230,6 +232,8 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, args []string, cmd *cobra.Co
|
|||
}
|
||||
}
|
||||
|
||||
o.warningPrinter = printers.NewWarningPrinter(o.ErrOut, printers.WarningPrinterOptions{Color: term.AllowsColorOutput(o.ErrOut)})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -244,10 +248,13 @@ func (o *DeleteOptions) Validate() error {
|
|||
if o.DeleteAll && len(o.FieldSelector) > 0 {
|
||||
return fmt.Errorf("cannot set --all and --field-selector at the same time")
|
||||
}
|
||||
if o.warningPrinter == nil {
|
||||
return fmt.Errorf("warningPrinter can not be used without initialization")
|
||||
}
|
||||
|
||||
switch {
|
||||
case o.GracePeriod == 0 && o.ForceDeletion:
|
||||
fmt.Fprintf(o.ErrOut, "warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.\n")
|
||||
o.warningPrinter.Print("Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.")
|
||||
case o.GracePeriod > 0 && o.ForceDeletion:
|
||||
return fmt.Errorf("--force and --grace-period greater than 0 cannot be specified together")
|
||||
}
|
||||
|
|
@ -311,7 +318,7 @@ func (o *DeleteOptions) DeleteResult(r *resource.Result) error {
|
|||
options.PropagationPolicy = &o.CascadingStrategy
|
||||
|
||||
if warnClusterScope && info.Mapping.Scope.Name() == meta.RESTScopeNameRoot {
|
||||
fmt.Fprintf(o.ErrOut, "warning: deleting cluster-scoped resources, not scoped to the provided namespace\n")
|
||||
o.warningPrinter.Print("deleting cluster-scoped resources, not scoped to the provided namespace")
|
||||
warnClusterScope = false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ func TestGracePeriodScenarios(t *testing.T) {
|
|||
forceFlag: true,
|
||||
expectedGracePeriod: "0",
|
||||
expectedOut: "pod/foo\n",
|
||||
expectedErrOut: "warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.\n",
|
||||
expectedErrOut: "Warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.\n",
|
||||
expectedDeleteRequestPath: "/namespaces/test/pods/foo",
|
||||
},
|
||||
{
|
||||
|
|
@ -300,7 +300,7 @@ func TestGracePeriodScenarios(t *testing.T) {
|
|||
gracePeriodFlag: "0",
|
||||
expectedGracePeriod: "0",
|
||||
expectedOut: "pod/foo\n",
|
||||
expectedErrOut: "warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.\n",
|
||||
expectedErrOut: "Warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.\n",
|
||||
expectedDeleteRequestPath: "/namespaces/test/pods/foo",
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
|
|
@ -37,6 +36,7 @@ import (
|
|||
"k8s.io/kubectl/pkg/util/completion"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
)
|
||||
|
||||
type DrainCmdOptions struct {
|
||||
|
|
@ -49,6 +49,7 @@ type DrainCmdOptions struct {
|
|||
nodeInfos []*resource.Info
|
||||
|
||||
genericclioptions.IOStreams
|
||||
warningPrinter *printers.WarningPrinter
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -258,6 +259,8 @@ func (o *DrainCmdOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
|
|||
return printer.PrintObj, nil
|
||||
}
|
||||
|
||||
o.warningPrinter = printers.NewWarningPrinter(o.ErrOut, printers.WarningPrinterOptions{Color: term.AllowsColorOutput(o.ErrOut)})
|
||||
|
||||
builder := f.NewBuilder().
|
||||
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
|
||||
NamespaceParam(o.Namespace).DefaultNamespace().
|
||||
|
|
@ -338,7 +341,7 @@ func (o *DrainCmdOptions) deleteOrEvictPodsSimple(nodeInfo *resource.Info) error
|
|||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
if warnings := list.Warnings(); warnings != "" {
|
||||
fmt.Fprintf(o.ErrOut, "WARNING: %s\n", warnings)
|
||||
o.warningPrinter.Print(warnings)
|
||||
}
|
||||
if o.drainer.DryRunStrategy == cmdutil.DryRunClient {
|
||||
for _, pod := range list.Pods() {
|
||||
|
|
|
|||
|
|
@ -599,7 +599,7 @@ func TestDrain(t *testing.T) {
|
|||
args: []string{"node", "--force"},
|
||||
expectFatal: false,
|
||||
expectDelete: true,
|
||||
expectWarning: "WARNING: deleting Pods that declare no controller: default/bar",
|
||||
expectWarning: "Warning: deleting Pods that declare no controller: default/bar",
|
||||
expectOutputToContain: "node/node drained",
|
||||
},
|
||||
{
|
||||
|
|
@ -620,7 +620,7 @@ func TestDrain(t *testing.T) {
|
|||
pods: []corev1.Pod{dsPodWithEmptyDir},
|
||||
rcs: []corev1.ReplicationController{rc},
|
||||
args: []string{"node", "--ignore-daemonsets"},
|
||||
expectWarning: "WARNING: ignoring DaemonSet-managed Pods: default/bar",
|
||||
expectWarning: "Warning: ignoring DaemonSet-managed Pods: default/bar",
|
||||
expectFatal: false,
|
||||
expectDelete: false,
|
||||
expectOutputToContain: "node/node drained",
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import (
|
|||
"k8s.io/kubectl/pkg/scheme"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -130,6 +131,7 @@ type EnvOptions struct {
|
|||
clientset *kubernetes.Clientset
|
||||
|
||||
genericclioptions.IOStreams
|
||||
warningPrinter *printers.WarningPrinter
|
||||
}
|
||||
|
||||
// NewEnvOptions returns an EnvOptions indicating all containers in the selected
|
||||
|
|
@ -140,7 +142,6 @@ func NewEnvOptions(streams genericclioptions.IOStreams) *EnvOptions {
|
|||
|
||||
ContainerSelector: "*",
|
||||
Overwrite: true,
|
||||
|
||||
IOStreams: streams,
|
||||
}
|
||||
}
|
||||
|
|
@ -148,6 +149,7 @@ func NewEnvOptions(streams genericclioptions.IOStreams) *EnvOptions {
|
|||
// NewCmdEnv implements the OpenShift cli env command
|
||||
func NewCmdEnv(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
o := NewEnvOptions(streams)
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "env RESOURCE/NAME KEY_1=VAL_1 ... KEY_N=VAL_N",
|
||||
DisableFlagsInUseLine: true,
|
||||
|
|
@ -206,7 +208,7 @@ func contains(key string, keyList []string) bool {
|
|||
func (o *EnvOptions) keyToEnvName(key string) string {
|
||||
envName := strings.ToUpper(validEnvNameRegexp.ReplaceAllString(key, "_"))
|
||||
if envName != key {
|
||||
fmt.Fprintf(o.ErrOut, "warning: key %s transferred to %s\n", key, envName)
|
||||
o.warningPrinter.Print(fmt.Sprintf("key %s transferred to %s", key, envName))
|
||||
}
|
||||
return envName
|
||||
}
|
||||
|
|
@ -251,6 +253,7 @@ func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
|
|||
return err
|
||||
}
|
||||
o.builder = f.NewBuilder
|
||||
o.warningPrinter = printers.NewWarningPrinter(o.ErrOut, printers.WarningPrinterOptions{Color: term.AllowsColorOutput(o.ErrOut)})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -269,6 +272,9 @@ func (o *EnvOptions) Validate() error {
|
|||
if len(o.Keys) > 0 && len(o.From) == 0 {
|
||||
return fmt.Errorf("when specifying --keys, a configmap or secret must be provided with --from")
|
||||
}
|
||||
if o.warningPrinter == nil {
|
||||
return fmt.Errorf("warningPrinter can not be used without initialization")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -421,7 +427,7 @@ func (o *EnvOptions) RunEnv() error {
|
|||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(o.ErrOut, "warning: %s/%s does not have any containers matching %q\n", objKind, objName, o.ContainerSelector)
|
||||
o.warningPrinter.Print(fmt.Sprintf("%s/%s does not have any containers matching %q", objKind, objName, o.ContainerSelector))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -720,9 +720,9 @@ func TestSetEnvFromResource(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = opts.RunEnv()
|
||||
if input.warning {
|
||||
assert.Contains(t, errOut.String(), "warning")
|
||||
assert.Contains(t, errOut.String(), "Warning")
|
||||
} else {
|
||||
assert.NotContains(t, errOut.String(), "warning")
|
||||
assert.NotContains(t, errOut.String(), "Warning")
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue