Skip to content

Commit

Permalink
Adds implementation of reject ApprovalTask commmand
Browse files Browse the repository at this point in the history
This also adds e2e test for reject CLI command

Signed-off-by: PuneetPunamiya <[email protected]>
  • Loading branch information
PuneetPunamiya authored and openshift-merge-bot[bot] committed May 14, 2024
1 parent 7039eba commit fb54786
Show file tree
Hide file tree
Showing 6 changed files with 309 additions and 0 deletions.
72 changes: 72 additions & 0 deletions pkg/cli/cmd/reject/reject.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package reject

import (
"fmt"
"io"

"github.com/openshift-pipelines/manual-approval-gate/pkg/actions"
cli "github.com/openshift-pipelines/manual-approval-gate/pkg/cli"
"github.com/openshift-pipelines/manual-approval-gate/pkg/cli/flags"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/runtime/schema"
)

var (
taskGroupResource = schema.GroupVersionResource{Group: "openshift-pipelines.org", Resource: "approvaltasks"}
)

func Command(p cli.Params) *cobra.Command {
opts := &cli.Options{}
c := &cobra.Command{
Use: "reject",
Short: "Reject the approvaltask",
Long: `This command rejects the approvaltask.`,
Annotations: map[string]string{
"commandType": "main",
},
Args: cobra.ExactArgs(1),
PersistentPreRunE: flags.PersistentPreRunE(p),
RunE: func(cmd *cobra.Command, args []string) error {
cs, err := p.Clients()
if err != nil {
return err
}

ns := p.Namespace()
if opts.AllNamespaces {
ns = ""
}

username, err := p.GetUserInfo()
if err != nil {
return err
}

message := opts.Message

opts = &cli.Options{
Name: args[0],
Namespace: ns,
Input: "reject",
Username: username,
Message: message,
}

if err := actions.Update(taskGroupResource, cs, opts); err != nil {
return fmt.Errorf("failed to reject approvalTask from namespace %s: %v", ns, err)
}

res := fmt.Sprintf("ApprovalTask %s is rejected in %s namespace\n", args[0], ns)
io.WriteString(cmd.OutOrStdout(), res)

return nil

},
}

c.Flags().StringVarP(&opts.Message, "message", "m", "", "message while approving the approvalTask")

flags.AddOptions(c)

return c
}
166 changes: 166 additions & 0 deletions pkg/cli/cmd/reject/reject_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package reject

import (
"fmt"
"testing"

"github.com/openshift-pipelines/manual-approval-gate/pkg/apis/approvaltask/v1alpha1"
"github.com/openshift-pipelines/manual-approval-gate/pkg/test"
cb "github.com/openshift-pipelines/manual-approval-gate/pkg/test/builder"
testDynamic "github.com/openshift-pipelines/manual-approval-gate/pkg/test/dynamic"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/dynamic"
)

func TestRejectApprovalTask(t *testing.T) {
approvaltasks := []*v1alpha1.ApprovalTask{
{
ObjectMeta: metav1.ObjectMeta{
Name: "at-1",
Namespace: "foo",
},
Spec: v1alpha1.ApprovalTaskSpec{
Approvers: []v1alpha1.ApproverDetails{
{
Name: "tekton",
Input: "pending",
},
{
Name: "cli",
Input: "pending",
},
},
NumberOfApprovalsRequired: 2,
},
Status: v1alpha1.ApprovalTaskStatus{
Approvers: []string{
"tekton",
"cli",
},
State: "pending",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "at-2",
Namespace: "foo",
},
Spec: v1alpha1.ApprovalTaskSpec{
Approvers: []v1alpha1.ApproverDetails{
{
Name: "tekton",
Input: "pending",
},
{
Name: "cli",
Input: "pending",
},
},
NumberOfApprovalsRequired: 2,
},
Status: v1alpha1.ApprovalTaskStatus{
Approvers: []string{
"tekton",
"cli",
},
State: "pending",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "at-3",
Namespace: "foo",
},
Spec: v1alpha1.ApprovalTaskSpec{
Approvers: []v1alpha1.ApproverDetails{
{
Name: "tekton",
Input: "pending",
},
{
Name: "cli",
Input: "pending",
},
},
NumberOfApprovalsRequired: 2,
},
Status: v1alpha1.ApprovalTaskStatus{
Approvers: []string{
"tekton",
"cli",
},
State: "pending",
},
},
}

ns := []*corev1.Namespace{
{
ObjectMeta: metav1.ObjectMeta{
Name: "namespace",
},
},
}

dc, err := testDynamic.Client(
cb.UnstructuredV1alpha1(approvaltasks[0], "v1alpha1"),
cb.UnstructuredV1alpha1(approvaltasks[1], "v1alpha1"),
cb.UnstructuredV1alpha1(approvaltasks[2], "v1alpha1"),
)
if err != nil {
t.Errorf("unable to create dynamic client: %v", err)
}

tests := []struct {
name string
command *cobra.Command
args []string
expectedOutput string
wantError bool
}{
{
name: "reject approval task",
command: command(t, approvaltasks, ns, dc, "tekton"),
args: []string{"at-1", "-n", "foo"},
expectedOutput: "ApprovalTask at-1 is rejected in foo namespace\n",
wantError: false,
},
{
name: "invalid username",
command: command(t, approvaltasks, ns, dc, "test-user"),
args: []string{"at-2", "-n", "foo"},
expectedOutput: "Error: failed to reject approvalTask from namespace foo: Approver: test-user, is not present in the approvers list\n",
wantError: true,
},
{
name: "approvaltask not found",
command: command(t, approvaltasks, ns, dc, "tekton"),
args: []string{"at-3", "-n", "test"},
expectedOutput: fmt.Sprintf("Error: failed to reject approvalTask from namespace %s: approvaltasks.openshift-pipelines.org \"%s\" not found\n", "test", "at-3"),
wantError: true,
},
}

for _, td := range tests {
t.Run(td.name, func(t *testing.T) {
output, err := test.ExecuteCommand(td.command, td.args...)
if err != nil && !td.wantError {
t.Errorf("Unexpected error: %v", err)
}

if output != td.expectedOutput {
t.Errorf("Expected output to be %q, but got %q", td.expectedOutput, output)
}
})
}
}

func command(t *testing.T, approvaltasks []*v1alpha1.ApprovalTask, ns []*corev1.Namespace, dc dynamic.Interface, username string) *cobra.Command {
cs, _ := test.SeedTestData(t, test.Data{Approvaltasks: approvaltasks, Namespaces: ns})
p := &test.Params{ApprovalTask: cs.ApprovalTask, Kube: cs.Kube, Dynamic: dc, Username: username}
cs.ApprovalTask.Resources = cb.APIResourceList("v1alpha1", []string{"approvaltask"})

return Command(p)
}
2 changes: 2 additions & 0 deletions pkg/cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/openshift-pipelines/manual-approval-gate/pkg/cli/cmd/approve"
"github.com/openshift-pipelines/manual-approval-gate/pkg/cli/cmd/describe"
"github.com/openshift-pipelines/manual-approval-gate/pkg/cli/cmd/list"
"github.com/openshift-pipelines/manual-approval-gate/pkg/cli/cmd/reject"
"github.com/openshift-pipelines/manual-approval-gate/pkg/cli/flags"
"github.com/spf13/cobra"
)
Expand All @@ -23,6 +24,7 @@ func Root(p cli.Params) *cobra.Command {
c.AddCommand(list.Command(p))
c.AddCommand(approve.Command(p))
c.AddCommand(describe.Command(p))
c.AddCommand(reject.Command(p))

return c
}
48 changes: 48 additions & 0 deletions test/cli/reject/reject_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//go:build e2e
// +build e2e

package approve

import (
"context"
"testing"

"github.com/openshift-pipelines/manual-approval-gate/test/cli"
"github.com/openshift-pipelines/manual-approval-gate/test/client"
"github.com/openshift-pipelines/manual-approval-gate/test/resources"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestApprovalTaskRejectCommand(t *testing.T) {
tknApprovaltask, err := cli.NewTknApprovalTaskRunner()
assert.Nil(t, err)

clients := client.Setup(t, "default")

t.Run("approve-approvaltask", func(t *testing.T) {
cr := resources.Create(t, clients, "./testdata/cr-1.yaml")

_, err := resources.WaitForApprovalTaskCreation(clients.ApprovalTaskClient, cr.GetName(), cr.GetNamespace())
if err != nil {
t.Fatal("Failed to get the approval task")
}

res := tknApprovaltask.MustSucceed(t, "reject", cr.GetName(), "-n", "test-4")

_, err = resources.WaitForApproverResponseUpdate(clients.ApprovalTaskClient, cr, "kubernetes-admin", "rejected")
if err != nil {
t.Fatal("Failed to get the approval task")
}

approvalTask, err := clients.ApprovalTaskClient.ApprovalTasks(cr.GetNamespace()).Get(context.TODO(), cr.GetName(), metav1.GetOptions{})
if err != nil {
t.Fatal("Failed to get the approval task")
}

assert.Equal(t, 1, len(approvalTask.Status.ApproversResponse))
assert.Equal(t, "ApprovalTask at-1 is rejected in test-4 namespace\n", res.Stdout())
assert.Equal(t, "kubernetes-admin", approvalTask.Status.ApproversResponse[0].Name)
assert.Equal(t, "rejected", approvalTask.Status.ApproversResponse[0].Response)
})
}
19 changes: 19 additions & 0 deletions test/cli/reject/testdata/cr-1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: tekton.dev/v1beta1
kind: CustomRun
metadata:
name: at-1
namespace: test-4
spec:
retries: 2
customRef:
apiVersion: openshift-pipelines.org/v1alpha1
kind: ApprovalTask
params:
- name: approvers
value:
- foo
- bar
- tekton
- kubernetes-admin
- name: numberOfApprovalsRequired
value: 2
2 changes: 2 additions & 0 deletions test/e2e-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ main() {
kubectl create ns test-1
kubectl create ns test-2
kubectl create ns test-3
kubectl create ns test-4
kubectl create ns test-5

go build -o tkn-approvaltask github.com/openshift-pipelines/manual-approval-gate/cmd/tkn-approvaltask
Expand All @@ -134,6 +135,7 @@ main() {
kubectl delete ns test-1
kubectl delete ns test-2
kubectl delete ns test-3
kubectl create ns test-4
kubectl create ns test-5

success
Expand Down

0 comments on commit fb54786

Please sign in to comment.