Skip to content

Commit

Permalink
feat: implement client to send FinalizeCleanup requests to spectro-cl…
Browse files Browse the repository at this point in the history
…eanup (#155)

* feat: implement gRPC client to send FinalizeCleanup requests to spectro-cleanup

* test: add unit tests for emitFinalizeCleanup()
  • Loading branch information
ahmad-ibra committed Dec 18, 2023
1 parent 1e340c9 commit 2ae0348
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 1 deletion.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ module github.com/spectrocloud-labs/validator
go 1.20

require (
buf.build/gen/go/spectrocloud/spectro-cleanup/connectrpc/go v1.13.0-20231213011348-5645e27c876a.1
buf.build/gen/go/spectrocloud/spectro-cleanup/protocolbuffers/go v1.31.0-20231213011348-5645e27c876a.2
connectrpc.com/connect v1.13.0
github.com/go-logr/logr v1.3.0
github.com/onsi/ginkgo/v2 v2.13.2
github.com/onsi/gomega v1.30.0
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
buf.build/gen/go/spectrocloud/spectro-cleanup/connectrpc/go v1.13.0-20231213011348-5645e27c876a.1 h1:flYv+oyV4sGFTc8UrA6bSxCkGE7mvSUyydrCiXk5s7A=
buf.build/gen/go/spectrocloud/spectro-cleanup/connectrpc/go v1.13.0-20231213011348-5645e27c876a.1/go.mod h1:pNAXVmeA3b2y1Hi/j2poNtPTT0Bvo2LgRK7FThfG0oc=
buf.build/gen/go/spectrocloud/spectro-cleanup/protocolbuffers/go v1.31.0-20231213011348-5645e27c876a.2 h1:ub8BpTL/wC0JVAjnfKzSdqu3xjJBFn4ndVPGu0u3KHU=
buf.build/gen/go/spectrocloud/spectro-cleanup/protocolbuffers/go v1.31.0-20231213011348-5645e27c876a.2/go.mod h1:629c8Zj/8OXoFZZfqhsjqXJ0MIIVuonsR0x8/Nngi+U=
connectrpc.com/connect v1.13.0 h1:lGs5maZZzWOOD+PFFiOt5OncKmMsk9ZdPwpy5jcmaYg=
connectrpc.com/connect v1.13.0/go.mod h1:uHAFHtYgeSZJxXrkN1IunDpKghnTXhYbVh0wW4StPW0=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down
49 changes: 48 additions & 1 deletion internal/controller/validatorconfig_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ import (
"context"
"crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"net/http"
"os"
"strconv"
"strings"
"sync"
"time"

connect "connectrpc.com/connect"
"github.com/go-logr/logr"
"golang.org/x/exp/slices"
corev1 "k8s.io/api/core/v1"
Expand All @@ -35,6 +40,8 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

"buf.build/gen/go/spectrocloud/spectro-cleanup/connectrpc/go/cleanup/v1/cleanupv1connect"
cleanv1 "buf.build/gen/go/spectrocloud/spectro-cleanup/protocolbuffers/go/cleanup/v1"
v1alpha1 "github.com/spectrocloud-labs/validator/api/v1alpha1"
"github.com/spectrocloud-labs/validator/pkg/helm"
)
Expand Down Expand Up @@ -100,7 +107,14 @@ func (r *ValidatorConfigReconciler) Reconcile(ctx context.Context, req ctrl.Requ
if err := r.deletePlugins(ctx, vc); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, removeFinalizer(ctx, r.Client, vc, CleanupFinalizer)

err = removeFinalizer(ctx, r.Client, vc, CleanupFinalizer)

if emitErr := r.emitFinalizeCleanup(); emitErr != nil {
r.Log.Error(emitErr, "Failed to emit FinalizeCleanup request")
}

return ctrl.Result{}, err
}

// TODO: implement a proper patcher to avoid this hacky approach with global vars
Expand Down Expand Up @@ -373,3 +387,36 @@ func isConditionTrue(vc *v1alpha1.ValidatorConfig, chartName string, conditionTy
}
return vc.Status.Conditions[idx], vc.Status.Conditions[idx].Status == corev1.ConditionTrue
}

func (r *ValidatorConfigReconciler) emitFinalizeCleanup() error {
grpcEnabled := os.Getenv("CLEANUP_GRPC_SERVER_ENABLED")
if grpcEnabled != "true" {
r.Log.V(0).Info("Cleanup job gRPC server is not enabled")
return nil
}

host := os.Getenv("CLEANUP_GRPC_SERVER_HOST")
if host == "" {
return errors.New("CLEANUP_GRPC_SERVER_HOST is invalid")
}

port := os.Getenv("CLEANUP_GRPC_SERVER_PORT")
_, err := strconv.Atoi(port)
if err != nil {
return fmt.Errorf("CLEANUP_GRPC_SERVER_PORT is invalid: %w", err)
}

url := fmt.Sprintf("https://%s:%s", host, port)
client := cleanupv1connect.NewCleanupServiceClient(
http.DefaultClient,
url,
)
_, err = client.FinalizeCleanup(
context.Background(),
connect.NewRequest(&cleanv1.FinalizeCleanupRequest{}),
)
if err != nil {
return fmt.Errorf("FinalizeCleanup request to %s failed: %w", url, err)
}
return nil
}
73 changes: 73 additions & 0 deletions internal/controller/validatorconfig_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,76 @@ func TestConfigureHelmBasicAuth(t *testing.T) {
}
}
}

func TestEmitFinalizeCleanup(t *testing.T) {
cs := []struct {
name string
reconciler ValidatorConfigReconciler
env map[string]string
expected error
}{
{
name: "CLEANUP_GRPC_SERVER_ENABLED is empty",
reconciler: ValidatorConfigReconciler{},
env: map[string]string{},
expected: errors.New("CLEANUP_GRPC_SERVER_HOST is empty"),
},
{
name: "CLEANUP_GRPC_SERVER_ENABLED is disabled",
reconciler: ValidatorConfigReconciler{},
env: map[string]string{"CLEANUP_GRPC_SERVER_ENABLED": "false"},
expected: nil,
},
{
name: "CLEANUP_GRPC_SERVER_HOST is empty",
reconciler: ValidatorConfigReconciler{},
env: map[string]string{
"CLEANUP_GRPC_SERVER_ENABLED": "true",
"CLEANUP_GRPC_SERVER_PORT": "1234",
},
expected: errors.New("CLEANUP_GRPC_SERVER_HOST is invalid"),
},
{
name: "CLEANUP_GRPC_SERVER_PORT is empty",
reconciler: ValidatorConfigReconciler{},
env: map[string]string{
"CLEANUP_GRPC_SERVER_ENABLED": "true",
"CLEANUP_GRPC_SERVER_HOST": "localhost",
},
expected: errors.New(`CLEANUP_GRPC_SERVER_PORT is invalid: strconv.Atoi: parsing "": invalid syntax`),
},
{
name: "CLEANUP_GRPC_SERVER_PORT is invalid",
reconciler: ValidatorConfigReconciler{},
env: map[string]string{
"CLEANUP_GRPC_SERVER_ENABLED": "true",
"CLEANUP_GRPC_SERVER_HOST": "localhost",
"CLEANUP_GRPC_SERVER_PORT": "abcd",
},
expected: errors.New(`CLEANUP_GRPC_SERVER_PORT is invalid: strconv.Atoi: parsing "abcd": invalid syntax`),
},
{
name: "Request fails",
reconciler: ValidatorConfigReconciler{},
env: map[string]string{
"CLEANUP_GRPC_SERVER_ENABLED": "true",
"CLEANUP_GRPC_SERVER_HOST": "localhost",
"CLEANUP_GRPC_SERVER_PORT": "1234",
},
expected: errors.New(`FinalizeCleanup request to https://localhost:1234 failed: unavailable: dial tcp [::1]:1234: connect: connection refused`),
},
}
for _, c := range cs {
t.Log(c.name)

os.Clearenv()
for k, v := range c.env {
os.Setenv(k, v)
}

err := c.reconciler.emitFinalizeCleanup()
if err != nil && !reflect.DeepEqual(err.Error(), c.expected.Error()) {
t.Errorf("expected (%v), got (%v)", c.expected, err)
}
}
}

0 comments on commit 2ae0348

Please sign in to comment.