Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove k8s package #2627

Merged
merged 5 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/internal/agent/hooks/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)

Expand Down
118 changes: 118 additions & 0 deletions src/pkg/cluster/cluster.go
Original file line number Diff line number Diff line change
@@ -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()

Check warning on line 40 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L38-L40

Added lines #L38 - L40 were not covered by tests

c, err := NewCluster()
if err != nil {
return nil, err

Check warning on line 44 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L42-L44

Added lines #L42 - L44 were not covered by tests
}
err = waitForHealthyCluster(ctx, c.Clientset)
if err != nil {
return nil, err

Check warning on line 48 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L46-L48

Added lines #L46 - L48 were not covered by tests
}

spinner.Success()

Check warning on line 51 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L51

Added line #L51 was not covered by tests

return c, nil

Check warning on line 53 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L53

Added line #L53 was not covered by tests
}

// 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

Check warning on line 60 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L57-L60

Added lines #L57 - L60 were not covered by tests
}
watcher, err := pkgkubernetes.WatcherForConfig(config)
if err != nil {
return nil, err

Check warning on line 64 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L62-L64

Added lines #L62 - L64 were not covered by tests
}
c := &Cluster{
Clientset: clientset,
RestConfig: config,
Watcher: watcher,

Check warning on line 69 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L66-L69

Added lines #L66 - L69 were not covered by tests
}
// 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

Check warning on line 74 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L72-L74

Added lines #L72 - L74 were not covered by tests
}
return c, nil

Check warning on line 76 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L76

Added line #L76 was not covered by tests
}

// 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

Check warning on line 81 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L80-L81

Added lines #L80 - L81 were not covered by tests

timer := time.NewTimer(0)
defer timer.Stop()

Check warning on line 84 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L83-L84

Added lines #L83 - L84 were not covered by tests

for {
select {
case <-ctx.Done():
return fmt.Errorf("error waiting for cluster to report healthy: %w", ctx.Err())
case <-timer.C:

Check warning on line 90 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L86-L90

Added lines #L86 - L90 were not covered by tests
// 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

Check warning on line 96 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L92-L96

Added lines #L92 - L96 were not covered by tests
}

// 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 warning on line 104 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L100-L104

Added lines #L100 - L104 were not covered by tests
}

// 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

Check warning on line 110 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L108-L110

Added lines #L108 - L110 were not covered by tests
}
}

message.Debug("No pods reported 'succeeded' or 'running' state yet.")
timer.Reset(waitDuration)

Check warning on line 115 in src/pkg/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/cluster.go#L114-L115

Added lines #L114 - L115 were not covered by tests
}
}
}
65 changes: 0 additions & 65 deletions src/pkg/cluster/common.go

This file was deleted.

23 changes: 12 additions & 11 deletions src/pkg/cluster/injector.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@
"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"
Expand All @@ -30,6 +22,15 @@
"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.
Expand Down Expand Up @@ -380,8 +381,8 @@
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{
Expand Down Expand Up @@ -544,7 +545,7 @@
return result, nil
}

c.Log("No images found on any node. Retrying...")
message.Debug("No images found on any node. Retrying...")

Check warning on line 548 in src/pkg/cluster/injector.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/injector.go#L548

Added line #L548 was not covered by tests
timer.Reset(2 * time.Second)
}
}
Expand Down
15 changes: 3 additions & 12 deletions src/pkg/cluster/injector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -32,9 +30,7 @@ func TestCreateInjectorConfigMap(t *testing.T) {

cs := fake.NewSimpleClientset()
c := &Cluster{
&k8s.K8s{
Clientset: cs,
},
Clientset: cs,
}

ctx := context.Background()
Expand All @@ -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")
Expand Down Expand Up @@ -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{
Expand Down
6 changes: 3 additions & 3 deletions src/pkg/cluster/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}
9 changes: 4 additions & 5 deletions src/pkg/cluster/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
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"
)
Expand Down Expand Up @@ -119,8 +118,8 @@
}

// 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") {

Check warning on line 122 in src/pkg/cluster/secrets.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/secrets.go#L121-L122

Added lines #L121 - L122 were not covered by tests
spinner.Updatef("Updating existing Zarf-managed image secret for namespace: '%s'", namespace.Name)

newRegistrySecret := c.GenerateRegistryPullCreds(namespace.Name, config.ZarfImagePullSecretName, state.RegistryInfo)
Expand Down Expand Up @@ -154,8 +153,8 @@
}

// 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") {

Check warning on line 157 in src/pkg/cluster/secrets.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/cluster/secrets.go#L156-L157

Added lines #L156 - L157 were not covered by tests
spinner.Updatef("Updating existing Zarf-managed git secret for namespace: '%s'", namespace.Name)

// Create the secret
Expand Down
5 changes: 2 additions & 3 deletions src/pkg/cluster/secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Loading
Loading