Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1beta1 support for clustertask delete #853

Merged
merged 1 commit into from
Apr 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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