diff --git a/docs/cmd/kn_revision.md b/docs/cmd/kn_revision.md index 1453bc048f..01f393e23d 100644 --- a/docs/cmd/kn_revision.md +++ b/docs/cmd/kn_revision.md @@ -22,6 +22,7 @@ Revision command group ### SEE ALSO * [kn](kn.md) - Knative client +* [kn revision delete](kn_revision_delete.md) - Delete a revision. * [kn revision describe](kn_revision_describe.md) - Describe revisions. * [kn revision list](kn_revision_list.md) - List available revisions. diff --git a/docs/cmd/kn_revision_delete.md b/docs/cmd/kn_revision_delete.md new file mode 100644 index 0000000000..e333fb2639 --- /dev/null +++ b/docs/cmd/kn_revision_delete.md @@ -0,0 +1,38 @@ +## kn revision delete + +Delete a revision. + +### Synopsis + +Delete a revision. + +``` +kn revision delete NAME [flags] +``` + +### Examples + +``` + + # Delete a revision 'svc1-abcde' in default namespace + kn revision delete svc1-abcde +``` + +### Options + +``` + -h, --help help for delete + -n, --namespace string List the requested object(s) in given namespace. +``` + +### Options inherited from parent commands + +``` + --config string config file (default is $HOME/.kn/config.yaml) + --kubeconfig string kubectl config file (default is $HOME/.kube/config) +``` + +### SEE ALSO + +* [kn revision](kn_revision.md) - Revision command group + diff --git a/hack/generate-docs.go b/hack/generate-docs.go index 10b9642d8a..d1f7c11148 100644 --- a/hack/generate-docs.go +++ b/hack/generate-docs.go @@ -29,9 +29,9 @@ func main() { if len(os.Args) > 1 { dir = os.Args[1] } - err := doc.GenMarkdownTree(rootCmd, dir + "/docs/cmd/") + err := doc.GenMarkdownTree(rootCmd, dir+"/docs/cmd/") if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } -} \ No newline at end of file +} diff --git a/pkg/kn/commands/revision/delete.go b/pkg/kn/commands/revision/delete.go new file mode 100644 index 0000000000..9742f41f2d --- /dev/null +++ b/pkg/kn/commands/revision/delete.go @@ -0,0 +1,59 @@ +// Copyright © 2019 The Knative 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 revision + +import ( + "errors" + "fmt" + + "github.com/knative/client/pkg/kn/commands" + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// NewRevisionDeleteCommand represent 'revision delete' command +func NewRevisionDeleteCommand(p *commands.KnParams) *cobra.Command { + RevisionDeleteCommand := &cobra.Command{ + Use: "delete NAME", + Short: "Delete a revision.", + Example: ` + # Delete a revision 'svc1-abcde' in default namespace + kn revision delete svc1-abcde`, + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return errors.New("'revision delete' requires the revision name given as single argument") + } + client, err := p.ServingFactory() + if err != nil { + return err + } + namespace, err := p.GetNamespace(cmd) + if err != nil { + return err + } + err = client.Revisions(namespace).Delete( + args[0], + &metav1.DeleteOptions{}, + ) + if err != nil { + return err + } + fmt.Fprintf(cmd.OutOrStdout(), "Revision '%s' successfully deleted in namespace '%s'.\n", args[0], namespace) + return nil + }, + } + commands.AddNamespaceFlags(RevisionDeleteCommand.Flags(), false) + return RevisionDeleteCommand +} diff --git a/pkg/kn/commands/revision/delete_test.go b/pkg/kn/commands/revision/delete_test.go new file mode 100644 index 0000000000..080eb71b4c --- /dev/null +++ b/pkg/kn/commands/revision/delete_test.go @@ -0,0 +1,59 @@ +// Copyright © 2019 The Knative 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 revision + +import ( + "testing" + + "github.com/knative/client/pkg/kn/commands" + "k8s.io/apimachinery/pkg/runtime" + client_testing "k8s.io/client-go/testing" +) + +func fakeRevisionDelete(args []string) (action client_testing.Action, name string, output string, err error) { + knParams := &commands.KnParams{} + cmd, fakeServing, buf := commands.CreateTestKnCommand(NewRevisionCommand(knParams), knParams) + fakeServing.AddReactor("delete", "revisions", + func(a client_testing.Action) (bool, runtime.Object, error) { + deleteAction, _ := a.(client_testing.DeleteAction) + action = deleteAction + name = deleteAction.GetName() + return true, nil, nil + }) + cmd.SetArgs(args) + err = cmd.Execute() + if err != nil { + return + } + output = buf.String() + return +} + +func TestRevisionDelete(t *testing.T) { + revName := "foo-12345" + action, name, output, err := fakeRevisionDelete([]string{"revision", "delete", revName}) + if err != nil { + t.Error(err) + return + } + if action == nil { + t.Errorf("No action") + } else if !action.Matches("delete", "revisions") { + t.Errorf("Bad action %v", action) + } else if name != revName { + t.Errorf("Bad revision name returned after delete.") + } + commands.TestContains(t, output, []string{"Revision", revName, "deleted", "namespace", commands.FakeNamespace}, "word in output") +} diff --git a/pkg/kn/commands/revision/revision.go b/pkg/kn/commands/revision/revision.go index 24519bfbe9..087f6c8927 100644 --- a/pkg/kn/commands/revision/revision.go +++ b/pkg/kn/commands/revision/revision.go @@ -26,5 +26,6 @@ func NewRevisionCommand(p *commands.KnParams) *cobra.Command { } revisionCmd.AddCommand(NewRevisionListCommand(p)) revisionCmd.AddCommand(NewRevisionDescribeCommand(p)) + revisionCmd.AddCommand(NewRevisionDeleteCommand(p)) return revisionCmd } diff --git a/pkg/kn/commands/service/service_create.go b/pkg/kn/commands/service/service_create.go index 19984766ec..2f7731e36a 100644 --- a/pkg/kn/commands/service/service_create.go +++ b/pkg/kn/commands/service/service_create.go @@ -17,12 +17,13 @@ package service import ( "errors" "fmt" + "io" + "time" + "github.com/knative/client/pkg/kn/commands" serving_v1alpha1_api "github.com/knative/serving/pkg/apis/serving/v1alpha1" serving_v1alpha1_client "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1" "github.com/spf13/cobra" - "io" - "time" corev1 "k8s.io/api/core/v1" api_errors "k8s.io/apimachinery/pkg/api/errors" diff --git a/pkg/kn/commands/service/wait_args.go b/pkg/kn/commands/service/wait_args.go index bad5a50ef5..8d985c26b6 100644 --- a/pkg/kn/commands/service/wait_args.go +++ b/pkg/kn/commands/service/wait_args.go @@ -16,6 +16,7 @@ package service import ( "fmt" + "github.com/knative/client/pkg/wait" "github.com/knative/pkg/apis" serving_v1alpha1_api "github.com/knative/serving/pkg/apis/serving/v1alpha1" diff --git a/pkg/kn/commands/test_helper.go b/pkg/kn/commands/test_helper.go index a0ec06c7dd..a294cd2289 100644 --- a/pkg/kn/commands/test_helper.go +++ b/pkg/kn/commands/test_helper.go @@ -17,6 +17,8 @@ package commands import ( "bytes" "flag" + "strings" + "testing" serving "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1" "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake" @@ -67,3 +69,13 @@ Eventing: Manage event subscriptions and channels. Connect up event sources.`, flag.CommandLine.Parse([]string{}) return rootCmd } + +// TestContains is a test helper function, checking if a substring is present in given +// output string +func TestContains(t *testing.T, output string, sub []string, element string) { + for _, each := range sub { + if !strings.Contains(output, each) { + t.Errorf("Missing %s: %s", element, each) + } + } +} diff --git a/pkg/kn/commands/wait_flags.go b/pkg/kn/commands/wait_flags.go index d10534f381..ecbf7cee92 100644 --- a/pkg/kn/commands/wait_flags.go +++ b/pkg/kn/commands/wait_flags.go @@ -16,6 +16,7 @@ package commands import ( "fmt" + "github.com/spf13/cobra" ) diff --git a/pkg/kn/commands/wait_flags_test.go b/pkg/kn/commands/wait_flags_test.go index 9156b4f2e2..e72d8924ef 100644 --- a/pkg/kn/commands/wait_flags_test.go +++ b/pkg/kn/commands/wait_flags_test.go @@ -15,9 +15,10 @@ package commands import ( - "github.com/spf13/cobra" "strings" "testing" + + "github.com/spf13/cobra" ) type waitTestCase struct { diff --git a/pkg/wait/wait_for_ready.go b/pkg/wait/wait_for_ready.go index be43157197..7baf6b2e64 100644 --- a/pkg/wait/wait_for_ready.go +++ b/pkg/wait/wait_for_ready.go @@ -16,14 +16,15 @@ package wait import ( "fmt" - "github.com/knative/pkg/apis" "io" + "time" + + "github.com/knative/pkg/apis" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" - "time" ) // Callbacks and configuration used while waiting diff --git a/test/e2e/revision_workflow_test.go b/test/e2e/revision_workflow_test.go new file mode 100644 index 0000000000..861319a812 --- /dev/null +++ b/test/e2e/revision_workflow_test.go @@ -0,0 +1,48 @@ +// Copyright 2019 The Knative 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 im +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build e2e + +package e2e + +import ( + "strings" + "testing" + + "github.com/knative/client/pkg/kn/commands" +) + +func TestRevisionWorkflow(t *testing.T) { + teardown := Setup(t) + defer teardown(t) + + testServiceCreate(t, k, "hello") + testDeleteRevision(t, k, "hello") + testServiceDelete(t, k, "hello") +} + +func testDeleteRevision(t *testing.T, k kn, serviceName string) { + revName, err := k.RunWithOpts([]string{"revision", "list", "-o=jsonpath={.items[0].metadata.name}"}, runOpts{}) + if err != nil { + t.Errorf("Error executing 'revision list -o' command. Error: %s", err.Error()) + } + if strings.Contains(revName, "No resources found.") { + t.Errorf("Could not find revision name.") + } + out, err := k.RunWithOpts([]string{"revision", "delete", revName}, runOpts{}) + if err != nil { + t.Errorf("Error executing 'revision delete %s' command. Error: %s", revName, err.Error()) + } + commands.TestContains(t, out, []string{"Revision", revName, "deleted", "namespace", k.namespace}, "word in output") +}