Skip to content

Commit

Permalink
v1beta1 support for clustertask delete
Browse files Browse the repository at this point in the history
Signed-off-by: Pradeep Kumar <[email protected]>
  • Loading branch information
pradeepitm12 authored and tekton-robot committed Apr 1, 2020
1 parent 2219bd9 commit a282ea2
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 25 deletions.
8 changes: 6 additions & 2 deletions pkg/cmd/clustertask/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ import (
"fmt"

"github.com/spf13/cobra"
ctaction "github.com/tektoncd/cli/pkg/actions/delete"
"github.com/tektoncd/cli/pkg/cli"
"github.com/tektoncd/cli/pkg/deleter"
"github.com/tektoncd/cli/pkg/options"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
cliopts "k8s.io/cli-runtime/pkg/genericclioptions"
)

Expand Down Expand Up @@ -69,12 +71,14 @@ or
}

func deleteClusterTasks(s *cli.Stream, p cli.Params, tNames []string, deleteAll bool) error {
ctGroupResource := schema.GroupVersionResource{Group: "tekton.dev", Resource: "clustertasks"}

cs, err := p.Clients()
if err != nil {
return fmt.Errorf("Failed to create tekton client")
}
d := deleter.New("ClusterTask", func(taskName string) error {
return cs.Tekton.TektonV1alpha1().ClusterTasks().Delete(taskName, &metav1.DeleteOptions{})
return ctaction.Delete(ctGroupResource, cs, taskName, "", &metav1.DeleteOptions{})
})
if deleteAll {
cts, err := allClusterTaskNames(cs)
Expand All @@ -97,7 +101,7 @@ func deleteClusterTasks(s *cli.Stream, p cli.Params, tNames []string, deleteAll
}

func allClusterTaskNames(cs *cli.Clients) ([]string, error) {
clusterTasks, err := cs.Tekton.TektonV1alpha1().ClusterTasks().List(metav1.ListOptions{})
clusterTasks, err := List(cs, metav1.ListOptions{})
if err != nil {
return nil, err
}
Expand Down
233 changes: 218 additions & 15 deletions pkg/cmd/clustertask/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,219 @@ import (
"github.com/jonboulle/clockwork"
"github.com/tektoncd/cli/pkg/test"
cb "github.com/tektoncd/cli/pkg/test/builder"
testDynamic "github.com/tektoncd/cli/pkg/test/dynamic"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
pipelinetest "github.com/tektoncd/pipeline/test"
tb "github.com/tektoncd/pipeline/test/builder"
"k8s.io/client-go/dynamic"
)

func TestClusterTaskDelete(t *testing.T) {
version := "v1alpha1"
clock := clockwork.NewFakeClock()

seeds := make([]pipelinetest.Clients, 0)
type clients struct {
pipelineClient pipelinetest.Clients
dynamicClient dynamic.Interface
}

seeds := make([]clients, 0)
for i := 0; i < 5; i++ {
clustertasks := []*v1alpha1.ClusterTask{
tb.ClusterTask("tomatoes", cb.ClusterTaskCreationTime(clock.Now().Add(-1*time.Minute))),
tb.ClusterTask("tomatoes2", cb.ClusterTaskCreationTime(clock.Now().Add(-1*time.Minute))),
tb.ClusterTask("tomatoes3", cb.ClusterTaskCreationTime(clock.Now().Add(-1*time.Minute))),
}
cs, _ := test.SeedTestData(t, pipelinetest.Data{ClusterTasks: clustertasks})
seeds = append(seeds, cs)
cs.Pipeline.Resources = cb.APIResourceList(version, []string{"clustertask"})
dc, err := testDynamic.Client(
cb.UnstructuredCT(clustertasks[0], version),
cb.UnstructuredCT(clustertasks[1], version),
cb.UnstructuredCT(clustertasks[2], version),
)
if err != nil {
t.Errorf("unable to create dynamic clinet: %v", err)
}
seeds = append(seeds, clients{cs, dc})
}

testParams := []struct {
name string
command []string
dynamic dynamic.Interface
input pipelinetest.Clients
inputStream io.Reader
wantError bool
want string
}{
{
name: "With force delete flag (shorthand)",
command: []string{"rm", "tomatoes", "-f"},
dynamic: seeds[0].dynamicClient,
input: seeds[0].pipelineClient,
inputStream: nil,
wantError: false,
want: "ClusterTasks deleted: \"tomatoes\"\n",
},
{
name: "With force delete flag",
command: []string{"rm", "tomatoes", "--force"},
dynamic: seeds[1].dynamicClient,
input: seeds[1].pipelineClient,
inputStream: nil,
wantError: false,
want: "ClusterTasks deleted: \"tomatoes\"\n",
},
{
name: "Without force delete flag, reply no",
command: []string{"rm", "tomatoes"},
dynamic: seeds[2].dynamicClient,
input: seeds[2].pipelineClient,
inputStream: strings.NewReader("n"),
wantError: true,
want: "canceled deleting clustertask \"tomatoes\"",
},
{
name: "Without force delete flag, reply yes",
command: []string{"rm", "tomatoes"},
dynamic: seeds[3].dynamicClient,
input: seeds[3].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: false,
want: "Are you sure you want to delete clustertask \"tomatoes\" (y/n): ClusterTasks deleted: \"tomatoes\"\n",
},
{
name: "Remove non existent resource",
command: []string{"rm", "nonexistent"},
dynamic: seeds[2].dynamicClient,
input: seeds[2].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: true,
want: "failed to delete clustertask \"nonexistent\": clustertasks.tekton.dev \"nonexistent\" not found",
},
{
name: "Remove multiple non existent resources",
command: []string{"rm", "nonexistent", "nonexistent2", "-n", "ns"},
dynamic: seeds[2].dynamicClient,
input: seeds[2].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: true,
want: "failed to delete clustertask \"nonexistent\": clustertasks.tekton.dev \"nonexistent\" not found; failed to delete clustertask \"nonexistent2\": clustertasks.tekton.dev \"nonexistent2\" not found",
},
{
name: "With force delete flag, reply yes, multiple clustertasks",
command: []string{"rm", "tomatoes2", "tomatoes3", "-f"},
dynamic: seeds[1].dynamicClient,
input: seeds[1].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: false,
want: "ClusterTasks deleted: \"tomatoes2\", \"tomatoes3\"\n",
},
{
name: "Without force delete flag, reply yes, multiple clustertasks",
command: []string{"rm", "tomatoes2", "tomatoes3"},
dynamic: seeds[2].dynamicClient,
input: seeds[2].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: false,
want: "Are you sure you want to delete clustertask \"tomatoes2\", \"tomatoes3\" (y/n): ClusterTasks deleted: \"tomatoes2\", \"tomatoes3\"\n",
},
{
name: "Delete all with prompt",
command: []string{"delete", "--all"},
dynamic: seeds[3].dynamicClient,
input: seeds[3].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: false,
want: "Are you sure you want to delete all clustertasks (y/n): All ClusterTasks deleted\n",
},
{
name: "Delete all with -f",
command: []string{"delete", "--all", "-f"},
dynamic: seeds[4].dynamicClient,
input: seeds[4].pipelineClient,
inputStream: nil,
wantError: false,
want: "All ClusterTasks deleted\n",
},
{
name: "Error from using clustertask name with --all",
command: []string{"delete", "ct", "--all"},
dynamic: seeds[4].dynamicClient,
input: seeds[4].pipelineClient,
inputStream: nil,
wantError: true,
want: "--all flag should not have any arguments or flags specified with it",
},
{
name: "Error from using clustertask delete with no names or --all",
command: []string{"delete"},
dynamic: seeds[4].dynamicClient,
input: seeds[4].pipelineClient,
inputStream: nil,
wantError: true,
want: "must provide clustertask name(s) or use --all flag with delete",
},
}

for _, tp := range testParams {
t.Run(tp.name, func(t *testing.T) {
p := &test.Params{Tekton: tp.input.Pipeline, Dynamic: tp.dynamic}
clustertask := Command(p)

if tp.inputStream != nil {
clustertask.SetIn(tp.inputStream)
}

out, err := test.ExecuteCommand(clustertask, tp.command...)
if tp.wantError {
if err == nil {
t.Errorf("Error expected here")
}
test.AssertOutput(t, tp.want, err.Error())
} else {
if err != nil {
t.Errorf("Unexpected Error")
}
test.AssertOutput(t, tp.want, out)
}
})
}
}

func TestClusterTaskDelete_v1beta1(t *testing.T) {
version := "v1beta1"
clock := clockwork.NewFakeClock()

type clients struct {
pipelineClient pipelinetest.Clients
dynamicClient dynamic.Interface
}

seeds := make([]clients, 0)
for i := 0; i < 5; i++ {
clustertasks := []*v1alpha1.ClusterTask{
tb.ClusterTask("tomatoes", cb.ClusterTaskCreationTime(clock.Now().Add(-1*time.Minute))),
tb.ClusterTask("tomatoes2", cb.ClusterTaskCreationTime(clock.Now().Add(-1*time.Minute))),
tb.ClusterTask("tomatoes3", cb.ClusterTaskCreationTime(clock.Now().Add(-1*time.Minute))),
}
cs, _ := test.SeedTestData(t, pipelinetest.Data{ClusterTasks: clustertasks})
cs.Pipeline.Resources = cb.APIResourceList(version, []string{"clustertask"})
dc, err := testDynamic.Client(
cb.UnstructuredCT(clustertasks[0], version),
cb.UnstructuredCT(clustertasks[1], version),
cb.UnstructuredCT(clustertasks[2], version),
)
if err != nil {
t.Errorf("unable to create dynamic clinet: %v", err)
}
seeds = append(seeds, clients{cs, dc})
}

testParams := []struct {
name string
command []string
dynamic dynamic.Interface
input pipelinetest.Clients
inputStream io.Reader
wantError bool
Expand All @@ -53,95 +244,107 @@ func TestClusterTaskDelete(t *testing.T) {
{
name: "With force delete flag (shorthand)",
command: []string{"rm", "tomatoes", "-f"},
input: seeds[0],
dynamic: seeds[0].dynamicClient,
input: seeds[0].pipelineClient,
inputStream: nil,
wantError: false,
want: "ClusterTasks deleted: \"tomatoes\"\n",
},
{
name: "With force delete flag",
command: []string{"rm", "tomatoes", "--force"},
input: seeds[1],
dynamic: seeds[1].dynamicClient,
input: seeds[1].pipelineClient,
inputStream: nil,
wantError: false,
want: "ClusterTasks deleted: \"tomatoes\"\n",
},
{
name: "Without force delete flag, reply no",
command: []string{"rm", "tomatoes"},
input: seeds[2],
dynamic: seeds[2].dynamicClient,
input: seeds[2].pipelineClient,
inputStream: strings.NewReader("n"),
wantError: true,
want: "canceled deleting clustertask \"tomatoes\"",
},
{
name: "Without force delete flag, reply yes",
command: []string{"rm", "tomatoes"},
input: seeds[2],
dynamic: seeds[3].dynamicClient,
input: seeds[3].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: false,
want: "Are you sure you want to delete clustertask \"tomatoes\" (y/n): ClusterTasks deleted: \"tomatoes\"\n",
},
{
name: "Remove non existent resource",
command: []string{"rm", "nonexistent"},
input: seeds[2],
dynamic: seeds[2].dynamicClient,
input: seeds[2].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: true,
want: "failed to delete clustertask \"nonexistent\": clustertasks.tekton.dev \"nonexistent\" not found",
},
{
name: "Remove multiple non existent resources",
command: []string{"rm", "nonexistent", "nonexistent2", "-n", "ns"},
input: seeds[2],
dynamic: seeds[2].dynamicClient,
input: seeds[2].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: true,
want: "failed to delete clustertask \"nonexistent\": clustertasks.tekton.dev \"nonexistent\" not found; failed to delete clustertask \"nonexistent2\": clustertasks.tekton.dev \"nonexistent2\" not found",
},
{
name: "With force delete flag, reply yes, multiple clustertasks",
command: []string{"rm", "tomatoes2", "tomatoes3", "-f"},
input: seeds[1],
dynamic: seeds[1].dynamicClient,
input: seeds[1].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: false,
want: "ClusterTasks deleted: \"tomatoes2\", \"tomatoes3\"\n",
},
{
name: "Without force delete flag, reply yes, multiple clustertasks",
command: []string{"rm", "tomatoes2", "tomatoes3"},
input: seeds[2],
dynamic: seeds[2].dynamicClient,
input: seeds[2].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: false,
want: "Are you sure you want to delete clustertask \"tomatoes2\", \"tomatoes3\" (y/n): ClusterTasks deleted: \"tomatoes2\", \"tomatoes3\"\n",
},
{
name: "Delete all with prompt",
command: []string{"delete", "--all"},
input: seeds[3],
dynamic: seeds[3].dynamicClient,
input: seeds[3].pipelineClient,
inputStream: strings.NewReader("y"),
wantError: false,
want: "Are you sure you want to delete all clustertasks (y/n): All ClusterTasks deleted\n",
},
{
name: "Delete all with -f",
command: []string{"delete", "--all", "-f"},
input: seeds[4],
dynamic: seeds[4].dynamicClient,
input: seeds[4].pipelineClient,
inputStream: nil,
wantError: false,
want: "All ClusterTasks deleted\n",
},
{
name: "Error from using clustertask name with --all",
command: []string{"delete", "ct", "--all"},
input: seeds[4],
dynamic: seeds[4].dynamicClient,
input: seeds[4].pipelineClient,
inputStream: nil,
wantError: true,
want: "--all flag should not have any arguments or flags specified with it",
},
{
name: "Error from using clustertask delete with no names or --all",
command: []string{"delete"},
input: seeds[4],
dynamic: seeds[4].dynamicClient,
input: seeds[4].pipelineClient,
inputStream: nil,
wantError: true,
want: "must provide clustertask name(s) or use --all flag with delete",
Expand All @@ -150,7 +353,7 @@ func TestClusterTaskDelete(t *testing.T) {

for _, tp := range testParams {
t.Run(tp.name, func(t *testing.T) {
p := &test.Params{Tekton: tp.input.Pipeline}
p := &test.Params{Tekton: tp.input.Pipeline, Dynamic: tp.dynamic}
clustertask := Command(p)

if tp.inputStream != nil {
Expand Down
Loading

0 comments on commit a282ea2

Please sign in to comment.