Ctrl K
ComunidadGuías…

internal/resources/helmflux_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package resources

import (
	"context"
	"errors"
	"strings"
	"testing"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/dynamic/fake"
	"k8s.io/client-go/kubernetes"
	k8sfake "k8s.io/client-go/kubernetes/fake"
	"k8s.io/client-go/metadata"
	metadatafake "k8s.io/client-go/metadata/fake"

	"github.com/sophotechlabs/spinoza/internal/api"
	"github.com/sophotechlabs/spinoza/internal/discovery"
	"github.com/sophotechlabs/spinoza/internal/helm"
)

func helmStorageSecret(namespace, name string) *corev1.Secret {
	payload := `{"name":"` + name + `","namespace":"` + namespace + `","version":1,` +
		`"info":{"status":"deployed"},"chart":{"metadata":{"name":"podinfo","version":"6.9.2"}}}`
	return &corev1.Secret{
		Name:      "sh.helm.release.v1." + name + ".v1",
		Namespace: namespace,
		Labels:    map[string]string{"owner": "helm", "name": name, "version": "1", "status": "deployed"},
		Type:      "helm.sh/release.v1",
		Data:      map[string][]byte{"release": []byte(payload)},
	}
}

func helmReleaseCR(namespace, name string, spec map[string]any) *unstructured.Unstructured {
	object := map[string]any{
		"apiVersion": "helm.toolkit.fluxcd.io/v2",
		"kind":       "HelmRelease",
		"metadata": map[string]any{
			"name":      name,
			"namespace": namespace,
		},
	}
	if spec != nil {
		object["spec"] = spec
	}
	return &unstructured.Unstructured{Object: object}
}

func fluxManager(t *testing.T, secrets []*corev1.Secret, crs ...*unstructured.Unstructured) *Manager {
	t.Helper()
	gvr := schema.GroupVersionResource{Group: "helm.toolkit.fluxcd.io", Version: "v2", Resource: "helmreleases"}
	kinds := map[schema.GroupVersionResource]string{gvr: "HelmReleaseList"}
	objs := make([]runtime.Object, 0, len(crs))
	for _, cr := range crs {
		objs = append(objs, cr)
	}
	dyn := fake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), kinds, objs...)
	seeds := make([]runtime.Object, 0, len(secrets))
	for _, secret := range secrets {
		seeds = append(seeds, secret)
	}
	cs := k8sfake.NewClientset(seeds...)
	releases := helm.NewService(cs, helmMeta(t, cs), nil, nil, nil, api.ContextRef{Name: "kind-spinoza"})
	descs := map[string]api.ResourceDescriptor{
		discovery.Key("helm.toolkit.fluxcd.io", "v2", "helmreleases"): {
			Group:      "helm.toolkit.fluxcd.io",
			Version:    "v2",
			Resource:   "helmreleases",
			Kind:       "HelmRelease",
			Namespaced: true,
		},
	}
	return NewManager(t.Context(), Deps{Dynamic: dyn, Clientset: cs, Helm: releases, Descriptors: descs})
}

func TestHelmReleasesCarryTheirFluxOwner(t *testing.T) {
	mgr := fluxManager(
		t,
		[]*corev1.Secret{helmStorageSecret("demo", "podinfo")},
		helmReleaseCR("demo", "podinfo", nil),
	)

	got, err := mgr.HelmReleases(context.Background())
	if err != nil {
		t.Fatalf("list: %v", err)
	}

	ref := got.Releases[0].FluxRef
	if ref == nil {
		t.Fatal("a flux-owned release carried no owner ref")
	}
	if ref.Group != "helm.toolkit.fluxcd.io" || ref.Version != "v2" || ref.Resource != "helmreleases" {
		t.Fatalf("ref = %+v, want the resolved helmreleases gvr", ref)
	}
	if ref.Namespace != "demo" || ref.Name != "podinfo" {
		t.Fatalf("ref = %+v, want the owning object's identity", ref)
	}
}

func TestHelmReleasesMatchAComposedFluxReleaseName(t *testing.T) {
	mgr := fluxManager(
		t,
		[]*corev1.Secret{helmStorageSecret("flux-system", "demo-podinfo")},
		helmReleaseCR("flux-system", "podinfo", map[string]any{"targetNamespace": "demo"}),
	)

	got, err := mgr.HelmReleases(context.Background())
	if err != nil {
		t.Fatalf("list: %v", err)
	}

	if got.Releases[0].FluxRef == nil {
		t.Fatal("a release stored under the composed [targetNamespace-]name was not matched")
	}
}

func TestHelmReleasesLeaveAHandInstalledReleaseAlone(t *testing.T) {
	mgr := fluxManager(
		t,
		[]*corev1.Secret{helmStorageSecret("demo", "podinfo")},
		helmReleaseCR("flux-system", "something-else", nil),
	)

	got, err := mgr.HelmReleases(context.Background())
	if err != nil {
		t.Fatalf("list: %v", err)
	}

	if got.Releases[0].FluxRef != nil {
		t.Fatalf("fluxRef = %+v, want none for a hand-installed release", got.Releases[0].FluxRef)
	}
}

func TestHelmReleaseDetailCarriesTheFluxOwner(t *testing.T) {
	mgr := fluxManager(
		t,
		[]*corev1.Secret{helmStorageSecret("demo", "podinfo")},
		helmReleaseCR("demo", "podinfo", nil),
	)

	got, err := mgr.HelmRelease(context.Background(), "demo", "podinfo", 0)
	if err != nil {
		t.Fatalf("detail: %v", err)
	}

	if got.Release.FluxRef == nil {
		t.Fatal("the detail view lost the owner ref")
	}
}

func TestHelmUpgradeRefusesAFluxOwnedRelease(t *testing.T) {
	mgr := fluxManager(
		t,
		[]*corev1.Secret{helmStorageSecret("demo", "podinfo")},
		helmReleaseCR("demo", "podinfo", nil),
	)

	_, err := mgr.HelmUpgrade(context.Background(), helm.UpgradeRequest{
		Namespace: "demo",
		Name:      "podinfo",
		Chart:     "podinfo",
		Version:   "6.10.0",
		RepoURL:   "https://charts.example.com",
	})

	if !errors.Is(err, helm.ErrFluxManaged) {
		t.Fatalf("err = %v, want ErrFluxManaged", err)
	}
	if !strings.Contains(err.Error(), "demo/podinfo") {
		t.Fatalf("err = %v, want the owning object named", err)
	}
}

func TestHelmUpgradeWithoutAFluxOwnerReachesTheService(t *testing.T) {
	mgr := fluxManager(t, []*corev1.Secret{helmStorageSecret("demo", "podinfo")})

	_, err := mgr.HelmUpgrade(context.Background(), helm.UpgradeRequest{
		Namespace: "demo",
		Name:      "podinfo",
		Chart:     "podinfo",
		Version:   "6.10.0",
		RepoURL:   "https://charts.example.com",
	})

	if err == nil {
		t.Fatal("a service with no runner reported success")
	}
	if errors.Is(err, helm.ErrFluxManaged) {
		t.Fatal("an unowned release was refused as flux-managed")
	}
}

func TestHelmUpgradeAndVersionsSayWhenHelmIsNotWiredUp(t *testing.T) {
	mgr := viewManager(t, nil)

	_, upgradeErr := mgr.HelmUpgrade(context.Background(), helm.UpgradeRequest{})
	_, versionsErr := mgr.HelmVersions(context.Background(), "podinfo")

	if !errors.Is(upgradeErr, api.ErrInternal) {
		t.Fatalf("upgrade err = %v, want an internal failure", upgradeErr)
	}
	if !errors.Is(versionsErr, api.ErrInternal) {
		t.Fatalf("versions err = %v, want an internal failure", versionsErr)
	}
}

func TestHelmVersionsReachTheService(t *testing.T) {
	mgr := fluxManager(t, nil)

	got, err := mgr.HelmVersions(context.Background(), "podinfo")
	if err != nil {
		t.Fatalf("versions: %v", err)
	}

	if got.Chart != "podinfo" {
		t.Fatalf("chart = %q", got.Chart)
	}
	if got.Error == "" {
		t.Fatal("a service with no repositories reported nothing to say")
	}
}

func helmMeta(t *testing.T, cs kubernetes.Interface) metadata.Interface {
	t.Helper()
	scheme := runtime.NewScheme()
	err := metav1.AddMetaToScheme(scheme)
	if err != nil {
		t.Fatalf("scheme: %v", err)
	}
	objs := []runtime.Object{}
	secrets, listErr := cs.CoreV1().Secrets("").List(context.Background(), metav1.ListOptions{})
	if listErr == nil {
		for i := range secrets.Items {
			objs = append(objs, &metav1.PartialObjectMetadata{
				APIVersion: "v1", Kind: "Secret",
				ObjectMeta: secrets.Items[i].ObjectMeta,
			})
		}
	}
	return metadatafake.NewSimpleMetadataClient(scheme, objs...)
}