Merge pull request #120416 from ardaguclu/move-interactive-delete-beta

KEP-3895: Promote interactive delete to beta
This commit is contained in:
Kubernetes Prow Robot 2023-10-23 12:30:44 +02:00 committed by GitHub
commit 68d55bc4fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 59 deletions

View File

@ -160,10 +160,8 @@ func (f *DeleteFlags) AddFlags(cmd *cobra.Command) {
if f.Raw != nil { if f.Raw != nil {
cmd.Flags().StringVar(f.Raw, "raw", *f.Raw, "Raw URI to DELETE to the server. Uses the transport specified by the kubeconfig file.") cmd.Flags().StringVar(f.Raw, "raw", *f.Raw, "Raw URI to DELETE to the server. Uses the transport specified by the kubeconfig file.")
} }
if cmdutil.InteractiveDelete.IsEnabled() { if f.Interactive != nil {
if f.Interactive != nil { cmd.Flags().BoolVarP(f.Interactive, "interactive", "i", *f.Interactive, "If true, delete resource only when user confirms. This flag is in Alpha.")
cmd.Flags().BoolVarP(f.Interactive, "interactive", "i", *f.Interactive, "If true, delete resource only when user confirms. This flag is in Alpha.")
}
} }
} }

View File

@ -54,41 +54,37 @@ func TestDeleteFlagValidation(t *testing.T) {
defer f.Cleanup() defer f.Cleanup()
tests := []struct { tests := []struct {
flags DeleteFlags flags DeleteFlags
enableAlphas []cmdutil.FeatureGate args [][]string
args [][]string expectedErr string
expectedErr string
}{ }{
{ {
flags: DeleteFlags{ flags: DeleteFlags{
Raw: pointer.String("test"), Raw: pointer.String("test"),
Interactive: pointer.Bool(true), Interactive: pointer.Bool(true),
}, },
enableAlphas: []cmdutil.FeatureGate{cmdutil.InteractiveDelete}, expectedErr: "--interactive can not be used with --raw",
expectedErr: "--interactive can not be used with --raw",
}, },
} }
for _, test := range tests { for _, test := range tests {
cmd := fakecmd() cmd := fakecmd()
cmdtesting.WithAlphaEnvs(test.enableAlphas, t, func(t *testing.T) { deleteOptions, err := test.flags.ToOptions(nil, genericiooptions.NewTestIOStreamsDiscard())
deleteOptions, err := test.flags.ToOptions(nil, genericiooptions.NewTestIOStreamsDiscard()) if err != nil {
if err != nil { t.Fatalf("unexpected error creating delete options: %s", err)
t.Fatalf("unexpected error creating delete options: %s", err) }
} deleteOptions.Filenames = []string{"../../../testdata/redis-master-controller.yaml"}
deleteOptions.Filenames = []string{"../../../testdata/redis-master-controller.yaml"} err = deleteOptions.Complete(f, nil, cmd)
err = deleteOptions.Complete(f, nil, cmd) if err != nil {
if err != nil { t.Fatalf("unexpected error creating delete options: %s", err)
t.Fatalf("unexpected error creating delete options: %s", err) }
} err = deleteOptions.Validate()
err = deleteOptions.Validate() if err == nil {
if err == nil { t.Fatalf("missing expected error")
t.Fatalf("missing expected error") }
} if test.expectedErr != err.Error() {
if test.expectedErr != err.Error() { t.Errorf("expected error %s, got %s", test.expectedErr, err)
t.Errorf("expected error %s, got %s", test.expectedErr, err) }
}
})
} }
} }
@ -362,34 +358,50 @@ func TestDeleteObjectWithInteractive(t *testing.T) {
}), }),
} }
cmdtesting.WithAlphaEnvs([]cmdutil.FeatureGate{cmdutil.InteractiveDelete}, t, func(t *testing.T) { streams, in, buf, _ := genericiooptions.NewTestIOStreams()
streams, in, buf, _ := genericiooptions.NewTestIOStreams() fmt.Fprint(in, "y")
fmt.Fprint(in, "y") cmd := NewCmdDelete(tf, streams)
cmd := NewCmdDelete(tf, streams) err := cmd.Flags().Set("filename", "../../../testdata/redis-master-controller.yaml")
cmd.Flags().Set("filename", "../../../testdata/redis-master-controller.yaml") if err != nil {
cmd.Flags().Set("output", "name") t.Errorf("unexpected error %v", err)
cmd.Flags().Set("interactive", "true") }
cmd.Run(cmd, []string{}) err = cmd.Flags().Set("output", "name")
if err != nil {
t.Errorf("unexpected error %v", err)
}
err = cmd.Flags().Set("interactive", "true")
if err != nil {
t.Errorf("unexpected error %v", err)
}
cmd.Run(cmd, []string{})
if buf.String() != "You are about to delete the following 1 resource(s):\nreplicationcontroller/redis-master\nDo you want to continue? (y/n): replicationcontroller/redis-master\n" { if buf.String() != "You are about to delete the following 1 resource(s):\nreplicationcontroller/redis-master\nDo you want to continue? (y/n): replicationcontroller/redis-master\n" {
t.Errorf("unexpected output: %s", buf.String()) t.Errorf("unexpected output: %s", buf.String())
} }
streams, in, buf, _ = genericiooptions.NewTestIOStreams() streams, in, buf, _ = genericiooptions.NewTestIOStreams()
fmt.Fprint(in, "n") fmt.Fprint(in, "n")
cmd = NewCmdDelete(tf, streams) cmd = NewCmdDelete(tf, streams)
cmd.Flags().Set("filename", "../../../testdata/redis-master-controller.yaml") err = cmd.Flags().Set("filename", "../../../testdata/redis-master-controller.yaml")
cmd.Flags().Set("output", "name") if err != nil {
cmd.Flags().Set("interactive", "true") t.Errorf("unexpected error %v", err)
cmd.Run(cmd, []string{}) }
err = cmd.Flags().Set("output", "name")
if err != nil {
t.Errorf("unexpected error %v", err)
}
err = cmd.Flags().Set("interactive", "true")
if err != nil {
t.Errorf("unexpected error %v", err)
}
cmd.Run(cmd, []string{})
if buf.String() != "You are about to delete the following 1 resource(s):\nreplicationcontroller/redis-master\nDo you want to continue? (y/n): deletion is cancelled\n" { if buf.String() != "You are about to delete the following 1 resource(s):\nreplicationcontroller/redis-master\nDo you want to continue? (y/n): deletion is cancelled\n" {
t.Errorf("unexpected output: %s", buf.String()) t.Errorf("unexpected output: %s", buf.String())
} }
if buf.String() == ": replicationcontroller/redis-master\n" { if buf.String() == ": replicationcontroller/redis-master\n" {
t.Errorf("unexpected output: %s", buf.String()) t.Errorf("unexpected output: %s", buf.String())
} }
})
} }
func TestGracePeriodScenarios(t *testing.T) { func TestGracePeriodScenarios(t *testing.T) {

View File

@ -427,7 +427,6 @@ type FeatureGate string
const ( const (
ApplySet FeatureGate = "KUBECTL_APPLYSET" ApplySet FeatureGate = "KUBECTL_APPLYSET"
CmdPluginAsSubcommand FeatureGate = "KUBECTL_ENABLE_CMD_SHADOW" CmdPluginAsSubcommand FeatureGate = "KUBECTL_ENABLE_CMD_SHADOW"
InteractiveDelete FeatureGate = "KUBECTL_INTERACTIVE_DELETE"
) )
func (f FeatureGate) IsEnabled() bool { func (f FeatureGate) IsEnabled() bool {

View File

@ -58,9 +58,6 @@ run_kubectl_delete_interactive_tests() {
set -o nounset set -o nounset
set -o errexit set -o errexit
# enable interactivity flag feature environment variable
export KUBECTL_INTERACTIVE_DELETE=true
ns_one="namespace-$(date +%s)-${RANDOM}" ns_one="namespace-$(date +%s)-${RANDOM}"
ns_two="namespace-$(date +%s)-${RANDOM}" ns_two="namespace-$(date +%s)-${RANDOM}"
kubectl create namespace "${ns_one}" kubectl create namespace "${ns_one}"
@ -119,8 +116,6 @@ run_kubectl_delete_interactive_tests() {
kubectl config set-context "${CONTEXT}" --namespace="${ns_one}" kubectl config set-context "${CONTEXT}" --namespace="${ns_one}"
kube::test::get_object_assert 'configmap -l deletetest3' "{{range.items}}{{${id_field:?}}}:{{end}}" '' kube::test::get_object_assert 'configmap -l deletetest3' "{{range.items}}{{${id_field:?}}}:{{end}}" ''
unset KUBECTL_INTERACTIVE_DELETE
set +o nounset set +o nounset
set +o errexit set +o errexit
} }