From 21024745d41ee0bbda8c15fd1854779e557328cf Mon Sep 17 00:00:00 2001 From: Philip Laine Date: Mon, 17 Jun 2024 08:07:10 +0200 Subject: [PATCH] remove: k8s package --- src/internal/agent/hooks/utils_test.go | 3 +- src/pkg/cluster/cluster.go | 118 +++++++++++++++++++++++ src/pkg/cluster/common.go | 65 ------------- src/pkg/cluster/injector.go | 23 ++--- src/pkg/cluster/injector_test.go | 15 +-- src/pkg/cluster/namespace.go | 6 +- src/pkg/cluster/secrets.go | 9 +- src/pkg/cluster/secrets_test.go | 5 +- src/pkg/cluster/state.go | 7 +- src/pkg/cluster/state_test.go | 8 +- src/pkg/cluster/zarf.go | 7 +- src/pkg/cluster/zarf_test.go | 9 +- src/pkg/k8s/common.go | 128 ------------------------- src/pkg/k8s/types.go | 29 ------ src/pkg/packager/common_test.go | 16 ++-- src/pkg/pki/pki.go | 6 +- src/types/k8s.go | 18 ++-- 17 files changed, 176 insertions(+), 296 deletions(-) create mode 100644 src/pkg/cluster/cluster.go delete mode 100644 src/pkg/cluster/common.go delete mode 100644 src/pkg/k8s/common.go delete mode 100644 src/pkg/k8s/types.go diff --git a/src/internal/agent/hooks/utils_test.go b/src/internal/agent/hooks/utils_test.go index 7cc1c912a6..716a5b5245 100644 --- a/src/internal/agent/hooks/utils_test.go +++ b/src/internal/agent/hooks/utils_test.go @@ -13,7 +13,6 @@ import ( "github.com/defenseunicorns/zarf/src/internal/agent/operations" "github.com/defenseunicorns/zarf/src/pkg/cluster" - "github.com/defenseunicorns/zarf/src/pkg/k8s" "github.com/defenseunicorns/zarf/src/types" "github.com/stretchr/testify/require" v1 "k8s.io/api/admission/v1" @@ -32,7 +31,7 @@ type admissionTest struct { func createTestClientWithZarfState(ctx context.Context, t *testing.T, state *types.ZarfState) *cluster.Cluster { t.Helper() - c := &cluster.Cluster{K8s: &k8s.K8s{Clientset: fake.NewSimpleClientset()}} + c := &cluster.Cluster{Clientset: fake.NewSimpleClientset()} stateData, err := json.Marshal(state) require.NoError(t, err) diff --git a/src/pkg/cluster/cluster.go b/src/pkg/cluster/cluster.go new file mode 100644 index 0000000000..0aad1ad848 --- /dev/null +++ b/src/pkg/cluster/cluster.go @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2021-Present The Zarf Authors + +// Package cluster contains Zarf-specific cluster management functions. +package cluster + +import ( + "context" + "fmt" + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "sigs.k8s.io/cli-utils/pkg/kstatus/watcher" + + pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" + + "github.com/defenseunicorns/zarf/src/pkg/message" +) + +const ( + // DefaultTimeout is the default time to wait for a cluster to be ready. + DefaultTimeout = 30 * time.Second + // AgentLabel is used to give instructions to the Zarf agent + AgentLabel = "zarf.dev/agent" +) + +// Cluster Zarf specific cluster management functions. +type Cluster struct { + Clientset kubernetes.Interface + RestConfig *rest.Config + Watcher watcher.StatusWatcher +} + +// NewClusterWithWait creates a new Cluster instance and waits for the given timeout for the cluster to be ready. +func NewClusterWithWait(ctx context.Context) (*Cluster, error) { + spinner := message.NewProgressSpinner("Waiting for cluster connection") + defer spinner.Stop() + + c, err := NewCluster() + if err != nil { + return nil, err + } + err = waitForHealthyCluster(ctx, c.Clientset) + if err != nil { + return nil, err + } + + spinner.Success() + + return c, nil +} + +// NewCluster creates a new Cluster instance and validates connection to the cluster by fetching the Kubernetes version. +func NewCluster() (*Cluster, error) { + clientset, config, err := pkgkubernetes.ClientAndConfig() + if err != nil { + return nil, err + } + watcher, err := pkgkubernetes.WatcherForConfig(config) + if err != nil { + return nil, err + } + c := &Cluster{ + Clientset: clientset, + RestConfig: config, + Watcher: watcher, + } + // Dogsled the version output. We just want to ensure no errors were returned to validate cluster connection. + _, err = c.Clientset.Discovery().ServerVersion() + if err != nil { + return nil, err + } + return c, nil +} + +// WaitForHealthyCluster checks for an available K8s cluster every second until timeout. +func waitForHealthyCluster(ctx context.Context, client kubernetes.Interface) error { + const waitDuration = 1 * time.Second + + timer := time.NewTimer(0) + defer timer.Stop() + + for { + select { + case <-ctx.Done(): + return fmt.Errorf("error waiting for cluster to report healthy: %w", ctx.Err()) + case <-timer.C: + // Make sure there is at least one running Node + nodeList, err := client.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) + if err != nil || len(nodeList.Items) < 1 { + message.Debug("No nodes reporting healthy yet: %v\n", err) + timer.Reset(waitDuration) + continue + } + + // Get the cluster pod list + pods, err := client.CoreV1().Pods(corev1.NamespaceAll).List(ctx, metav1.ListOptions{}) + if err != nil { + message.Debug("Could not get the pod list: %w", err) + timer.Reset(waitDuration) + continue + } + + // Check that at least one pod is in the 'succeeded' or 'running' state + for _, pod := range pods.Items { + if pod.Status.Phase == corev1.PodSucceeded || pod.Status.Phase == corev1.PodRunning { + return nil + } + } + + message.Debug("No pods reported 'succeeded' or 'running' state yet.") + timer.Reset(waitDuration) + } + } +} diff --git a/src/pkg/cluster/common.go b/src/pkg/cluster/common.go deleted file mode 100644 index 02b6f1da78..0000000000 --- a/src/pkg/cluster/common.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2021-Present The Zarf Authors - -// Package cluster contains Zarf-specific cluster management functions. -package cluster - -import ( - "context" - "time" - - "github.com/defenseunicorns/zarf/src/pkg/k8s" - "github.com/defenseunicorns/zarf/src/pkg/message" -) - -// Cluster is a wrapper for the k8s package that provides Zarf-specific cluster management functions. -type Cluster struct { - *k8s.K8s -} - -const ( - // DefaultTimeout is the default time to wait for a cluster to be ready. - DefaultTimeout = 30 * time.Second -) - -// NewClusterWithWait creates a new Cluster instance and waits for the given timeout for the cluster to be ready. -func NewClusterWithWait(ctx context.Context) (*Cluster, error) { - spinner := message.NewProgressSpinner("Waiting for cluster connection") - defer spinner.Stop() - - c := &Cluster{} - var err error - - c.K8s, err = k8s.New(message.Debugf) - if err != nil { - return nil, err - } - - err = c.WaitForHealthyCluster(ctx) - if err != nil { - return nil, err - } - - spinner.Success() - - return c, nil -} - -// NewCluster creates a new Cluster instance and validates connection to the cluster by fetching the Kubernetes version. -func NewCluster() (*Cluster, error) { - c := &Cluster{} - var err error - - c.K8s, err = k8s.New(message.Debugf) - if err != nil { - return nil, err - } - - // Dogsled the version output. We just want to ensure no errors were returned to validate cluster connection. - _, err = c.Clientset.Discovery().ServerVersion() - if err != nil { - return nil, err - } - - return c, nil -} diff --git a/src/pkg/cluster/injector.go b/src/pkg/cluster/injector.go index 04cd80a580..10b2778d7a 100644 --- a/src/pkg/cluster/injector.go +++ b/src/pkg/cluster/injector.go @@ -12,14 +12,6 @@ import ( "regexp" "time" - "github.com/defenseunicorns/pkg/helpers/v2" - pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" - "github.com/defenseunicorns/zarf/src/config" - "github.com/defenseunicorns/zarf/src/pkg/k8s" - "github.com/defenseunicorns/zarf/src/pkg/layout" - "github.com/defenseunicorns/zarf/src/pkg/message" - "github.com/defenseunicorns/zarf/src/pkg/transform" - "github.com/defenseunicorns/zarf/src/pkg/utils" "github.com/google/go-containerregistry/pkg/crane" "github.com/google/uuid" "github.com/mholt/archiver/v3" @@ -30,6 +22,15 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/cli-utils/pkg/object" + + "github.com/defenseunicorns/pkg/helpers/v2" + pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" + + "github.com/defenseunicorns/zarf/src/config" + "github.com/defenseunicorns/zarf/src/pkg/layout" + "github.com/defenseunicorns/zarf/src/pkg/message" + "github.com/defenseunicorns/zarf/src/pkg/transform" + "github.com/defenseunicorns/zarf/src/pkg/utils" ) // The chunk size for the tarball chunks. @@ -380,8 +381,8 @@ func (c *Cluster) buildInjectionPod(node, image string, payloadConfigmaps []stri Name: fmt.Sprintf("injector-%s", uuid), Namespace: ZarfNamespaceName, Labels: map[string]string{ - "app": "zarf-injector", - k8s.AgentLabel: "ignore", + "app": "zarf-injector", + AgentLabel: "ignore", }, }, Spec: corev1.PodSpec{ @@ -544,7 +545,7 @@ func (c *Cluster) getImagesAndNodesForInjection(ctx context.Context) (imageNodeM return result, nil } - c.Log("No images found on any node. Retrying...") + message.Debug("No images found on any node. Retrying...") timer.Reset(2 * time.Second) } } diff --git a/src/pkg/cluster/injector_test.go b/src/pkg/cluster/injector_test.go index 16005126f0..291eb092ef 100644 --- a/src/pkg/cluster/injector_test.go +++ b/src/pkg/cluster/injector_test.go @@ -18,8 +18,6 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - - "github.com/defenseunicorns/zarf/src/pkg/k8s" ) func TestCreateInjectorConfigMap(t *testing.T) { @@ -32,9 +30,7 @@ func TestCreateInjectorConfigMap(t *testing.T) { cs := fake.NewSimpleClientset() c := &Cluster{ - &k8s.K8s{ - Clientset: cs, - }, + Clientset: cs, } ctx := context.Background() @@ -52,9 +48,7 @@ func TestCreateService(t *testing.T) { cs := fake.NewSimpleClientset() c := &Cluster{ - &k8s.K8s{ - Clientset: cs, - }, + Clientset: cs, } expected, err := os.ReadFile("./testdata/expected-injection-service.json") @@ -94,10 +88,7 @@ func TestImagesAndNodesForInjection(t *testing.T) { cs := fake.NewSimpleClientset() c := &Cluster{ - &k8s.K8s{ - Clientset: cs, - Log: func(string, ...any) {}, - }, + Clientset: cs, } nodes := []corev1.Node{ diff --git a/src/pkg/cluster/namespace.go b/src/pkg/cluster/namespace.go index 6a35ee6a56..c65c968d0e 100644 --- a/src/pkg/cluster/namespace.go +++ b/src/pkg/cluster/namespace.go @@ -8,11 +8,11 @@ import ( "context" "time" - "github.com/defenseunicorns/zarf/src/pkg/k8s" - "github.com/defenseunicorns/zarf/src/pkg/message" corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/defenseunicorns/zarf/src/pkg/message" ) // DeleteZarfNamespace deletes the Zarf namespace from the connected cluster. @@ -66,6 +66,6 @@ func AdoptZarfManagedLabels(labels map[string]string) map[string]string { if labels == nil { labels = make(map[string]string) } - labels[k8s.ZarfManagedByLabel] = "zarf" + labels[ZarfManagedByLabel] = "zarf" return labels } diff --git a/src/pkg/cluster/secrets.go b/src/pkg/cluster/secrets.go index cfbb90953e..55c2cd950e 100644 --- a/src/pkg/cluster/secrets.go +++ b/src/pkg/cluster/secrets.go @@ -14,7 +14,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/defenseunicorns/zarf/src/config" - "github.com/defenseunicorns/zarf/src/pkg/k8s" "github.com/defenseunicorns/zarf/src/pkg/message" "github.com/defenseunicorns/zarf/src/types" ) @@ -118,8 +117,8 @@ func (c *Cluster) UpdateZarfManagedImageSecrets(ctx context.Context, state *type } // Check if this is a Zarf managed secret or is in a namespace the Zarf agent will take action in - if currentRegistrySecret.Labels[k8s.ZarfManagedByLabel] == "zarf" || - (namespace.Labels[k8s.AgentLabel] != "skip" && namespace.Labels[k8s.AgentLabel] != "ignore") { + if currentRegistrySecret.Labels[ZarfManagedByLabel] == "zarf" || + (namespace.Labels[AgentLabel] != "skip" && namespace.Labels[AgentLabel] != "ignore") { spinner.Updatef("Updating existing Zarf-managed image secret for namespace: '%s'", namespace.Name) newRegistrySecret := c.GenerateRegistryPullCreds(namespace.Name, config.ZarfImagePullSecretName, state.RegistryInfo) @@ -153,8 +152,8 @@ func (c *Cluster) UpdateZarfManagedGitSecrets(ctx context.Context, state *types. } // Check if this is a Zarf managed secret or is in a namespace the Zarf agent will take action in - if currentGitSecret.Labels[k8s.ZarfManagedByLabel] == "zarf" || - (namespace.Labels[k8s.AgentLabel] != "skip" && namespace.Labels[k8s.AgentLabel] != "ignore") { + if currentGitSecret.Labels[ZarfManagedByLabel] == "zarf" || + (namespace.Labels[AgentLabel] != "skip" && namespace.Labels[AgentLabel] != "ignore") { spinner.Updatef("Updating existing Zarf-managed git secret for namespace: '%s'", namespace.Name) // Create the secret diff --git a/src/pkg/cluster/secrets_test.go b/src/pkg/cluster/secrets_test.go index a3c4a3a35a..dc9f6c9e22 100644 --- a/src/pkg/cluster/secrets_test.go +++ b/src/pkg/cluster/secrets_test.go @@ -10,7 +10,6 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/defenseunicorns/zarf/src/pkg/k8s" "github.com/defenseunicorns/zarf/src/types" ) @@ -33,7 +32,7 @@ func TestGenerateRegistryPullCreds(t *testing.T) { Name: "bar", Namespace: "foo", Labels: map[string]string{ - k8s.ZarfManagedByLabel: "zarf", + ZarfManagedByLabel: "zarf", }, }, Type: corev1.SecretTypeDockerConfigJson, @@ -62,7 +61,7 @@ func TestGenerateGitPullCreds(t *testing.T) { Name: "bar", Namespace: "foo", Labels: map[string]string{ - k8s.ZarfManagedByLabel: "zarf", + ZarfManagedByLabel: "zarf", }, }, Type: corev1.SecretTypeOpaque, diff --git a/src/pkg/cluster/state.go b/src/pkg/cluster/state.go index 64b8162c21..03194efd2d 100644 --- a/src/pkg/cluster/state.go +++ b/src/pkg/cluster/state.go @@ -19,7 +19,6 @@ import ( "github.com/defenseunicorns/pkg/helpers/v2" "github.com/defenseunicorns/zarf/src/config" "github.com/defenseunicorns/zarf/src/config/lang" - "github.com/defenseunicorns/zarf/src/pkg/k8s" "github.com/defenseunicorns/zarf/src/pkg/message" "github.com/defenseunicorns/zarf/src/pkg/pki" "github.com/defenseunicorns/zarf/src/types" @@ -100,7 +99,7 @@ func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitO namespace.Labels = make(map[string]string) } // This label will tell the Zarf Agent to ignore this namespace. - namespace.Labels[k8s.AgentLabel] = "ignore" + namespace.Labels[AgentLabel] = "ignore" namespaceCopy := namespace _, err := c.Clientset.CoreV1().Namespaces().Update(ctx, &namespaceCopy, metav1.UpdateOptions{}) if err != nil { @@ -148,7 +147,7 @@ func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitO return err } if kerrors.IsNotFound(err) { - c.Log("Service account %s/%s not found, retrying...", ns, name) + message.Debug("Service account %s/%s not found, retrying...", ns, name) timer.Reset(1 * time.Second) continue } @@ -281,7 +280,7 @@ func (c *Cluster) SaveZarfState(ctx context.Context, state *types.ZarfState) err Name: ZarfStateSecretName, Namespace: ZarfNamespaceName, Labels: map[string]string{ - k8s.ZarfManagedByLabel: "zarf", + ZarfManagedByLabel: "zarf", }, }, Type: corev1.SecretTypeOpaque, diff --git a/src/pkg/cluster/state_test.go b/src/pkg/cluster/state_test.go index e8c42983b3..19301432f1 100644 --- a/src/pkg/cluster/state_test.go +++ b/src/pkg/cluster/state_test.go @@ -17,7 +17,6 @@ import ( "github.com/defenseunicorns/pkg/helpers/v2" - "github.com/defenseunicorns/zarf/src/pkg/k8s" "github.com/defenseunicorns/zarf/src/pkg/message" "github.com/defenseunicorns/zarf/src/pkg/pki" "github.com/defenseunicorns/zarf/src/types" @@ -130,10 +129,7 @@ func TestInitZarfState(t *testing.T) { require.NoError(t, err) } c := &Cluster{ - &k8s.K8s{ - Clientset: cs, - Log: func(string, ...any) {}, - }, + Clientset: cs, } // Create default service account in Zarf namespace @@ -173,7 +169,7 @@ func TestInitZarfState(t *testing.T) { } ns, err := cs.CoreV1().Namespaces().Get(ctx, ns.Name, metav1.GetOptions{}) require.NoError(t, err) - require.Equal(t, map[string]string{k8s.AgentLabel: "ignore"}, ns.Labels) + require.Equal(t, map[string]string{AgentLabel: "ignore"}, ns.Labels) } }) } diff --git a/src/pkg/cluster/zarf.go b/src/pkg/cluster/zarf.go index 787852b761..93d8406ced 100644 --- a/src/pkg/cluster/zarf.go +++ b/src/pkg/cluster/zarf.go @@ -18,7 +18,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/defenseunicorns/zarf/src/config" - "github.com/defenseunicorns/zarf/src/pkg/k8s" "github.com/defenseunicorns/zarf/src/pkg/message" "github.com/defenseunicorns/zarf/src/types" ) @@ -72,7 +71,7 @@ func (c *Cluster) StripZarfLabelsAndSecretsFromNamespaces(ctx context.Context) { deleteOptions := metav1.DeleteOptions{} listOptions := metav1.ListOptions{ - LabelSelector: k8s.ZarfManagedByLabel + "=zarf", + LabelSelector: ZarfManagedByLabel + "=zarf", } namespaceList, err := c.Clientset.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) @@ -80,9 +79,9 @@ func (c *Cluster) StripZarfLabelsAndSecretsFromNamespaces(ctx context.Context) { spinner.Errorf(err, "Unable to get k8s namespaces") } else { for _, namespace := range namespaceList.Items { - if _, ok := namespace.Labels[k8s.AgentLabel]; ok { + if _, ok := namespace.Labels[AgentLabel]; ok { spinner.Updatef("Removing Zarf Agent label for namespace %s", namespace.Name) - delete(namespace.Labels, k8s.AgentLabel) + delete(namespace.Labels, AgentLabel) namespaceCopy := namespace _, err := c.Clientset.CoreV1().Namespaces().Update(ctx, &namespaceCopy, metav1.UpdateOptions{}) if err != nil { diff --git a/src/pkg/cluster/zarf_test.go b/src/pkg/cluster/zarf_test.go index 6c400bb97b..4abfb81e8f 100644 --- a/src/pkg/cluster/zarf_test.go +++ b/src/pkg/cluster/zarf_test.go @@ -17,7 +17,6 @@ import ( "k8s.io/client-go/kubernetes/fake" "github.com/defenseunicorns/zarf/src/config" - "github.com/defenseunicorns/zarf/src/pkg/k8s" "github.com/defenseunicorns/zarf/src/types" ) @@ -205,7 +204,9 @@ func TestPackageSecretNeedsWait(t *testing.T) { func TestGetDeployedPackage(t *testing.T) { t.Parallel() ctx := context.Background() - c := &Cluster{&k8s.K8s{Clientset: fake.NewSimpleClientset()}} + c := &Cluster{ + Clientset: fake.NewSimpleClientset(), + } packages := []types.DeployedPackage{ {Name: "package1"}, @@ -268,9 +269,7 @@ func TestRegistryHPA(t *testing.T) { _, err := cs.AutoscalingV2().HorizontalPodAutoscalers(hpa.Namespace).Create(ctx, &hpa, metav1.CreateOptions{}) require.NoError(t, err) c := &Cluster{ - &k8s.K8s{ - Clientset: cs, - }, + Clientset: cs, } err = c.EnableRegHPAScaleDown(ctx) diff --git a/src/pkg/k8s/common.go b/src/pkg/k8s/common.go deleted file mode 100644 index 2d24f6d66c..0000000000 --- a/src/pkg/k8s/common.go +++ /dev/null @@ -1,128 +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" - "fmt" - "time" - - "github.com/go-logr/logr/funcr" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/klog/v2" - - // Include the cloud auth plugins - _ "k8s.io/client-go/plugin/pkg/client/auth" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - - pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" -) - -const ( - // ZarfManagedByLabel is used to denote Zarf manages the lifecycle of a resource - ZarfManagedByLabel = "app.kubernetes.io/managed-by" - // AgentLabel is used to give instructions to the Zarf agent - AgentLabel = "zarf.dev/agent" -) - -// New creates a new K8s client. -func New(logger Log) (*K8s, error) { - klog.SetLogger(funcr.New(func(_, args string) { - logger(args) - }, funcr.Options{})) - - config, clientset, err := connect() - if err != nil { - return nil, fmt.Errorf("failed to connect to k8s cluster: %w", err) - } - watcher, err := pkgkubernetes.WatcherForConfig(config) - if err != nil { - return nil, err - } - - return &K8s{ - RestConfig: config, - Clientset: clientset, - Watcher: watcher, - Log: logger, - }, nil -} - -// WaitForHealthyCluster checks for an available K8s cluster every second until timeout. -func (k *K8s) WaitForHealthyCluster(ctx context.Context) error { - const waitDuration = 1 * time.Second - - timer := time.NewTimer(0) - defer timer.Stop() - - for { - select { - case <-ctx.Done(): - return fmt.Errorf("error waiting for cluster to report healthy: %w", ctx.Err()) - case <-timer.C: - if k.RestConfig == nil || k.Clientset == nil { - config, clientset, err := connect() - if err != nil { - k.Log("Cluster connection not available yet: %w", err) - timer.Reset(waitDuration) - continue - } - - k.RestConfig = config - k.Clientset = clientset - } - - // Make sure there is at least one running Node - nodeList, err := k.Clientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) - if err != nil || len(nodeList.Items) < 1 { - k.Log("No nodes reporting healthy yet: %v\n", err) - timer.Reset(waitDuration) - continue - } - - // Get the cluster pod list - pods, err := k.Clientset.CoreV1().Pods(corev1.NamespaceAll).List(ctx, metav1.ListOptions{}) - if err != nil { - k.Log("Could not get the pod list: %w", err) - timer.Reset(waitDuration) - continue - } - - // Check that at least one pod is in the 'succeeded' or 'running' state - for _, pod := range pods.Items { - if pod.Status.Phase == corev1.PodSucceeded || pod.Status.Phase == corev1.PodRunning { - return nil - } - } - - k.Log("No pods reported 'succeeded' or 'running' state yet.") - timer.Reset(waitDuration) - } - } -} - -// Use the K8s "client-go" library to get the currently active kube context, in the same way that -// "kubectl" gets it if no extra config flags like "--kubeconfig" are passed. -func connect() (config *rest.Config, clientset *kubernetes.Clientset, err error) { - // Build the config from the currently active kube context in the default way that the k8s client-go gets it, which - // is to look at the KUBECONFIG env var - config, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig( - clientcmd.NewDefaultClientConfigLoadingRules(), - &clientcmd.ConfigOverrides{}).ClientConfig() - - if err != nil { - return nil, nil, err - } - - clientset, err = kubernetes.NewForConfig(config) - if err != nil { - return nil, nil, err - } - - return config, clientset, nil -} diff --git a/src/pkg/k8s/types.go b/src/pkg/k8s/types.go deleted file mode 100644 index 409aa2fe96..0000000000 --- a/src/pkg/k8s/types.go +++ /dev/null @@ -1,29 +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 ( - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - "sigs.k8s.io/cli-utils/pkg/kstatus/watcher" -) - -// Log is a function that logs a message. -type Log func(string, ...any) - -// K8s is a client for interacting with a Kubernetes cluster. -type K8s struct { - Clientset kubernetes.Interface - RestConfig *rest.Config - Watcher watcher.StatusWatcher - Log Log -} - -// GeneratedPKI is a struct for storing generated PKI data. -type GeneratedPKI struct { - CA []byte `json:"ca"` - Cert []byte `json:"cert"` - Key []byte `json:"key"` -} diff --git a/src/pkg/packager/common_test.go b/src/pkg/packager/common_test.go index e60b030ffc..b298a1d0de 100644 --- a/src/pkg/packager/common_test.go +++ b/src/pkg/packager/common_test.go @@ -8,15 +8,15 @@ import ( "fmt" "testing" - "github.com/defenseunicorns/zarf/src/config" - "github.com/defenseunicorns/zarf/src/config/lang" - "github.com/defenseunicorns/zarf/src/pkg/cluster" - "github.com/defenseunicorns/zarf/src/pkg/k8s" - "github.com/defenseunicorns/zarf/src/types" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" + + "github.com/defenseunicorns/zarf/src/config" + "github.com/defenseunicorns/zarf/src/config/lang" + "github.com/defenseunicorns/zarf/src/pkg/cluster" + "github.com/defenseunicorns/zarf/src/types" ) func TestValidatePackageArchitecture(t *testing.T) { @@ -78,14 +78,10 @@ func TestValidatePackageArchitecture(t *testing.T) { t.Parallel() cs := fake.NewSimpleClientset() - logger := func(string, ...interface{}) {} p := &Packager{ cluster: &cluster.Cluster{ - K8s: &k8s.K8s{ - Clientset: cs, - Log: logger, - }, + Clientset: cs, }, cfg: &types.PackagerConfig{ Pkg: types.ZarfPackage{ diff --git a/src/pkg/pki/pki.go b/src/pkg/pki/pki.go index f732b2e1cb..00d1e212a6 100644 --- a/src/pkg/pki/pki.go +++ b/src/pkg/pki/pki.go @@ -15,8 +15,8 @@ import ( "time" "github.com/defenseunicorns/pkg/helpers/v2" - "github.com/defenseunicorns/zarf/src/pkg/k8s" "github.com/defenseunicorns/zarf/src/pkg/message" + "github.com/defenseunicorns/zarf/src/types" ) // Based off of https://github.com/dmcgowan/quicktls/blob/master/main.go @@ -29,8 +29,8 @@ const org = "Zarf Cluster" const validFor = time.Hour * 24 * 375 // GeneratePKI create a CA and signed server keypair. -func GeneratePKI(host string, dnsNames ...string) k8s.GeneratedPKI { - results := k8s.GeneratedPKI{} +func GeneratePKI(host string, dnsNames ...string) types.GeneratedPKI { + results := types.GeneratedPKI{} ca, caKey, err := generateCA(validFor) if err != nil { diff --git a/src/types/k8s.go b/src/types/k8s.go index 183125c72b..2bf0900cf9 100644 --- a/src/types/k8s.go +++ b/src/types/k8s.go @@ -10,7 +10,6 @@ import ( "github.com/defenseunicorns/pkg/helpers/v2" "github.com/defenseunicorns/zarf/src/config/lang" - "github.com/defenseunicorns/zarf/src/pkg/k8s" ) // WebhookStatus defines the status of a Component Webhook operating on a Zarf package secret. @@ -50,13 +49,20 @@ const ( ZarfInClusterArtifactServiceURL = ZarfInClusterGitServiceURL + "/api/packages/" + ZarfGitPushUser ) +// GeneratedPKI is a struct for storing generated PKI data. +type GeneratedPKI struct { + CA []byte `json:"ca"` + Cert []byte `json:"cert"` + Key []byte `json:"key"` +} + // ZarfState is maintained as a secret in the Zarf namespace to track Zarf init data. type ZarfState struct { - ZarfAppliance bool `json:"zarfAppliance" jsonschema:"description=Indicates if Zarf was initialized while deploying its own k8s cluster"` - Distro string `json:"distro" jsonschema:"description=K8s distribution of the cluster Zarf was deployed to"` - Architecture string `json:"architecture" jsonschema:"description=Machine architecture of the k8s node(s)"` - StorageClass string `json:"storageClass" jsonschema:"Default StorageClass value Zarf uses for variable templating"` - AgentTLS k8s.GeneratedPKI `json:"agentTLS" jsonschema:"PKI certificate information for the agent pods Zarf manages"` + ZarfAppliance bool `json:"zarfAppliance" jsonschema:"description=Indicates if Zarf was initialized while deploying its own k8s cluster"` + Distro string `json:"distro" jsonschema:"description=K8s distribution of the cluster Zarf was deployed to"` + Architecture string `json:"architecture" jsonschema:"description=Machine architecture of the k8s node(s)"` + StorageClass string `json:"storageClass" jsonschema:"Default StorageClass value Zarf uses for variable templating"` + AgentTLS GeneratedPKI `json:"agentTLS" jsonschema:"PKI certificate information for the agent pods Zarf manages"` GitServer GitServerInfo `json:"gitServer" jsonschema:"description=Information about the repository Zarf is configured to use"` RegistryInfo RegistryInfo `json:"registryInfo" jsonschema:"description=Information about the container registry Zarf is configured to use"`