From 5c181fd796dd27816e1dd410a49315589c651755 Mon Sep 17 00:00:00 2001 From: Philip Laine Date: Thu, 30 May 2024 11:17:10 +0200 Subject: [PATCH] refactor: remove use of k8s dynamic --- src/internal/packager/git/gitea.go | 40 +++++++---- src/internal/packager/helm/post-render.go | 56 ++++++++++++--- src/pkg/k8s/dynamic.go | 83 ----------------------- 3 files changed, 74 insertions(+), 105 deletions(-) delete mode 100644 src/pkg/k8s/dynamic.go diff --git a/src/internal/packager/git/gitea.go b/src/internal/packager/git/gitea.go index d243337d3c..c6644c6b1a 100644 --- a/src/internal/packager/git/gitea.go +++ b/src/internal/packager/git/gitea.go @@ -10,17 +10,17 @@ import ( "encoding/json" "fmt" "io" + netHttp "net/http" "os" "time" - netHttp "net/http" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/defenseunicorns/zarf/src/config" "github.com/defenseunicorns/zarf/src/pkg/cluster" "github.com/defenseunicorns/zarf/src/pkg/k8s" "github.com/defenseunicorns/zarf/src/pkg/message" "github.com/defenseunicorns/zarf/src/types" - "k8s.io/apimachinery/pkg/runtime/schema" ) // CreateTokenResponse is the response given from creating a token in Gitea @@ -253,24 +253,38 @@ func UpdateGiteaPVC(ctx context.Context, shouldRollBack bool) (string, error) { } pvcName := os.Getenv("ZARF_VAR_GIT_SERVER_EXISTING_PVC") - groupKind := schema.GroupKind{ - Group: "", - Kind: "PersistentVolumeClaim", - } - labels := map[string]string{"app.kubernetes.io/managed-by": "Helm"} - annotations := map[string]string{"meta.helm.sh/release-name": "zarf-gitea", "meta.helm.sh/release-namespace": "zarf"} if shouldRollBack { - err = c.K8s.RemoveLabelsAndAnnotations(ctx, cluster.ZarfNamespaceName, pvcName, groupKind, labels, annotations) - return "false", err + pvc, err := c.Clientset.CoreV1().PersistentVolumeClaims(cluster.ZarfNamespaceName).Get(ctx, pvcName, metav1.GetOptions{}) + if err != nil { + return "false", err + } + delete(pvc.Labels, "app.kubernetes.io/managed-by") + delete(pvc.Annotations, "meta.helm.sh/release-name") + delete(pvc.Annotations, "meta.helm.sh/release-namespace") + _, err = c.Clientset.CoreV1().PersistentVolumeClaims(cluster.ZarfNamespaceName).Update(ctx, pvc, metav1.UpdateOptions{}) + if err != nil { + return "false", err + } + return "false", nil } if pvcName == "data-zarf-gitea-0" { - err = c.K8s.AddLabelsAndAnnotations(ctx, cluster.ZarfNamespaceName, pvcName, groupKind, labels, annotations) - return "true", err + pvc, err := c.Clientset.CoreV1().PersistentVolumeClaims(cluster.ZarfNamespaceName).Get(ctx, pvcName, metav1.GetOptions{}) + if err != nil { + return "true", err + } + pvc.Labels["app.kubernetes.io/managed-by"] = "Helm" + pvc.Annotations["meta.helm.sh/release-name"] = "zarf-gitea" + pvc.Annotations["meta.helm.sh/release-namespace"] = "zarf" + _, err = c.Clientset.CoreV1().PersistentVolumeClaims(cluster.ZarfNamespaceName).Update(ctx, pvc, metav1.UpdateOptions{}) + if err != nil { + return "true", err + } + return "true", nil } - return "false", err + return "false", nil } // DoHTTPThings adds http request boilerplate and perform the request, checking for a successful response. diff --git a/src/internal/packager/helm/post-render.go b/src/internal/packager/helm/post-render.go index 4be00a1b11..da71335201 100644 --- a/src/internal/packager/helm/post-render.go +++ b/src/internal/packager/helm/post-render.go @@ -20,6 +20,8 @@ import ( "github.com/defenseunicorns/zarf/src/types" "helm.sh/helm/v3/pkg/releaseutil" corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/restmapper" "sigs.k8s.io/yaml" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -174,6 +176,16 @@ func (r *renderer) adoptAndUpdateNamespaces(ctx context.Context) error { } func (r *renderer) editHelmResources(ctx context.Context, resources []releaseutil.Manifest, finalManifestsOutput *bytes.Buffer) error { + dc, err := dynamic.NewForConfig(r.cluster.RestConfig) + if err != nil { + return err + } + groupResources, err := restmapper.GetAPIGroupResources(r.cluster.Clientset.Discovery()) + if err != nil { + return err + } + mapper := restmapper.NewDiscoveryRESTMapper(groupResources) + for _, resource := range resources { // parse to unstructured to have access to more data than just the name rawData := &unstructured.Unstructured{} @@ -199,8 +211,13 @@ func (r *renderer) editHelmResources(ctx context.Context, resources []releaseuti case "Service": // Check service resources for the zarf-connect label labels := rawData.GetLabels() + if labels == nil { + labels = map[string]string{} + } annotations := rawData.GetAnnotations() - + if annotations == nil { + annotations = map[string]string{} + } if key, keyExists := labels[config.ZarfConnectLabelName]; keyExists { // If there is a zarf-connect label message.Debugf("Match helm service %s for zarf connection %s", rawData.GetName(), key) @@ -226,14 +243,35 @@ func (r *renderer) editHelmResources(ctx context.Context, resources []releaseuti deployedNamespace = r.chart.Namespace } - helmLabels := map[string]string{"app.kubernetes.io/managed-by": "Helm"} - helmAnnotations := map[string]string{ - "meta.helm.sh/release-name": r.chart.ReleaseName, - "meta.helm.sh/release-namespace": r.chart.Namespace, - } - - if err := r.cluster.AddLabelsAndAnnotations(ctx, deployedNamespace, rawData.GetName(), rawData.GroupVersionKind().GroupKind(), helmLabels, helmAnnotations); err != nil { - // Print a debug message since this could just be because the resource doesn't exist + err := func() error { + mapping, err := mapper.RESTMapping(rawData.GroupVersionKind().GroupKind()) + if err != nil { + return err + } + resource, err := dc.Resource(mapping.Resource).Namespace(deployedNamespace).Get(ctx, rawData.GetName(), metav1.GetOptions{}) + if err != nil { + return err + } + labels := resource.GetLabels() + if labels == nil { + labels = map[string]string{} + } + labels["app.kubernetes.io/managed-by"] = "Helm" + resource.SetLabels(labels) + annotations := resource.GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + } + annotations["meta.helm.sh/release-name"] = r.chart.ReleaseName + annotations["meta.helm.sh/release-namespace"] = r.chart.Namespace + resource.SetAnnotations(annotations) + _, err = dc.Resource(mapping.Resource).Namespace(deployedNamespace).Update(ctx, resource, metav1.UpdateOptions{}) + if err != nil { + return err + } + return nil + }() + if err != nil { message.Debugf("Unable to adopt resource %s: %s", rawData.GetName(), err.Error()) } } diff --git a/src/pkg/k8s/dynamic.go b/src/pkg/k8s/dynamic.go deleted file mode 100644 index 59f295f26b..0000000000 --- a/src/pkg/k8s/dynamic.go +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2021-Present The Zarf Authors - -// Package k8s provides a client for interacting with a Kubernetes cluster. -package k8s - -import ( - "context" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/discovery" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/restmapper" -) - -// AddLabelsAndAnnotations adds the provided labels and annotations to the specified K8s resource -func (k *K8s) AddLabelsAndAnnotations(ctx context.Context, resourceNamespace, resourceName string, groupKind schema.GroupKind, labels, annotations map[string]string) error { - return k.updateLabelsAndAnnotations(ctx, resourceNamespace, resourceName, groupKind, labels, annotations, false) -} - -// RemoveLabelsAndAnnotations removes the provided labels and annotations to the specified K8s resource -func (k *K8s) RemoveLabelsAndAnnotations(ctx context.Context, resourceNamespace, resourceName string, groupKind schema.GroupKind, labels, annotations map[string]string) error { - return k.updateLabelsAndAnnotations(ctx, resourceNamespace, resourceName, groupKind, labels, annotations, true) -} - -// updateLabelsAndAnnotations updates the provided labels and annotations to the specified K8s resource -func (k *K8s) updateLabelsAndAnnotations(ctx context.Context, resourceNamespace, resourceName string, groupKind schema.GroupKind, labels, annotations map[string]string, isRemove bool) error { - dynamicClient := dynamic.NewForConfigOrDie(k.RestConfig) - - discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(k.RestConfig) - - groupResources, err := restmapper.GetAPIGroupResources(discoveryClient) - if err != nil { - return err - } - mapper := restmapper.NewDiscoveryRESTMapper(groupResources) - - mapping, err := mapper.RESTMapping(groupKind) - if err != nil { - return err - } - - deployedResource, err := dynamicClient.Resource(mapping.Resource).Namespace(resourceNamespace).Get(ctx, resourceName, metav1.GetOptions{}) - if err != nil { - return err - } - - // Pull the existing labels from the rendered resource - deployedLabels := deployedResource.GetLabels() - if deployedLabels == nil { - // Ensure label map exists to avoid nil panic - deployedLabels = make(map[string]string) - } - for key, value := range labels { - if isRemove { - delete(deployedLabels, key) - } else { - deployedLabels[key] = value - } - } - - deployedResource.SetLabels(deployedLabels) - - // Pull the existing annotations from the rendered resource - deployedAnnotations := deployedResource.GetAnnotations() - if deployedAnnotations == nil { - // Ensure label map exists to avoid nil panic - deployedAnnotations = make(map[string]string) - } - for key, value := range annotations { - if isRemove { - delete(deployedAnnotations, key) - } else { - deployedAnnotations[key] = value - } - } - - deployedResource.SetAnnotations(deployedAnnotations) - - _, err = dynamicClient.Resource(mapping.Resource).Namespace(resourceNamespace).Update(ctx, deployedResource, metav1.UpdateOptions{}) - return err -}