Skip to content

Commit

Permalink
Merge branch 'flux-agent-unit-tests' of github.com:defenseunicorns/za…
Browse files Browse the repository at this point in the history
…rf into flux-agent-unit-tests
  • Loading branch information
AustinAbro321 committed May 22, 2024
2 parents d68265d + e6bb0cc commit 637096f
Show file tree
Hide file tree
Showing 6 changed files with 332 additions and 120 deletions.
13 changes: 13 additions & 0 deletions site/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ export default defineConfig({
integrations: [
starlight({
title: "Zarf",
head: [
{
tag: "script",
content: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','G-N1XZ8ZXCWL');`,
},
],
components: {
SkipLink: "./src/components/SkipLink.astro",
},
social: {
github: "https://github.com/defenseunicorns/zarf",
slack: "https://kubernetes.slack.com/archives/C03B6BJAUJ3",
Expand Down
18 changes: 18 additions & 0 deletions site/src/components/SkipLink.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
import type { Props } from '@astrojs/starlight/props'
import Default from '@astrojs/starlight/components/SkipLink.astro'
---

<!-- Add the noscript tag for Google Tag Manager. -->
<noscript>
<iframe
src="https://www.googletagmanager.com/gtag/js?id=G-N1XZ8ZXCWL"
height="0"
width="0"
style="display:none;visibility:hidden"
>
</iframe>
</noscript>

<!-- Render the default <SkipLink/> component. -->
<Default {...Astro.props}><slot /></Default>
101 changes: 101 additions & 0 deletions src/pkg/cluster/distro.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors

// Package cluster contains Zarf-specific cluster management functions.
package cluster

import (
"regexp"

corev1 "k8s.io/api/core/v1"
)

// List of supported distros via distro detection.
const (
DistroIsUnknown = "unknown"
DistroIsK3s = "k3s"
DistroIsK3d = "k3d"
DistroIsKind = "kind"
DistroIsMicroK8s = "microk8s"
DistroIsEKS = "eks"
DistroIsEKSAnywhere = "eksanywhere"
DistroIsDockerDesktop = "dockerdesktop"
DistroIsGKE = "gke"
DistroIsAKS = "aks"
DistroIsRKE2 = "rke2"
DistroIsTKG = "tkg"
)

// DetectDistro returns the matching distro or unknown if not found.
func detectDistro(node corev1.Node, namespaces []corev1.Namespace) string {
kindNodeRegex := regexp.MustCompile(`^kind://`)
k3dNodeRegex := regexp.MustCompile(`^k3s://k3d-`)
eksNodeRegex := regexp.MustCompile(`^aws:///`)
gkeNodeRegex := regexp.MustCompile(`^gce://`)
aksNodeRegex := regexp.MustCompile(`^azure:///subscriptions`)
rke2Regex := regexp.MustCompile(`^rancher/rancher-agent:v2`)
tkgRegex := regexp.MustCompile(`^projects\.registry\.vmware\.com/tkg/tanzu_core/`)

// Regex explanation: https://regex101.com/r/TIUQVe/1
// https://github.com/rancher/k3d/blob/v5.2.2/cmd/node/nodeCreate.go#L187
if k3dNodeRegex.MatchString(node.Spec.ProviderID) {
return DistroIsK3d
}

// Regex explanation: https://regex101.com/r/le7PRB/1
// https://github.com/kubernetes-sigs/kind/pull/1805
if kindNodeRegex.MatchString(node.Spec.ProviderID) {
return DistroIsKind
}

// https://github.com/kubernetes/cloud-provider-aws/blob/454ed784c33b974c873c7d762f9d30e7c4caf935/pkg/providers/v2/instances.go#L234
if eksNodeRegex.MatchString(node.Spec.ProviderID) {
return DistroIsEKS
}

if gkeNodeRegex.MatchString(node.Spec.ProviderID) {
return DistroIsGKE
}

// https://github.com/kubernetes/kubernetes/blob/v1.23.4/staging/src/k8s.io/legacy-cloud-providers/azure/azure_wrap.go#L46
if aksNodeRegex.MatchString(node.Spec.ProviderID) {
return DistroIsAKS
}

labels := node.GetLabels()
for k, v := range labels {
// kubectl get nodes --selector node.kubernetes.io/instance-type=k3s for K3s
if k == "node.kubernetes.io/instance-type" && v == "k3s" {
return DistroIsK3s
}
// kubectl get nodes --selector microk8s.io/cluster=true for MicroK8s
if k == "microk8s.io/cluster" && v == "true" {
return DistroIsMicroK8s
}
}

if node.GetName() == "docker-desktop" {
return DistroIsDockerDesktop
}

// TODO: Find a new detection method, by default the amount of images in the node status is limited.
for _, images := range node.Status.Images {
for _, image := range images.Names {
if rke2Regex.MatchString(image) {
return DistroIsRKE2
}
if tkgRegex.MatchString(image) {
return DistroIsTKG
}
}
}

// kubectl get ns eksa-system for EKS Anywhere
for _, namespace := range namespaces {
if namespace.Name == "eksa-system" {
return DistroIsEKSAnywhere
}
}

return DistroIsUnknown
}
181 changes: 181 additions & 0 deletions src/pkg/cluster/distro_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors

// Package cluster contains Zarf-specific cluster management functions.
package cluster

import (
"testing"

"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestDetectDistro(t *testing.T) {
t.Parallel()

tests := []struct {
distro string
node corev1.Node
namespaces []corev1.Namespace
}{
{
distro: DistroIsUnknown,
node: corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"foo": "bar",
},
},
Spec: corev1.NodeSpec{
ProviderID: "hello world",
},
},
namespaces: []corev1.Namespace{
{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
},
},
},
},
{
distro: DistroIsK3s,
node: corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"node.kubernetes.io/instance-type": "k3s",
},
},
},
},
{
distro: DistroIsK3d,
node: corev1.Node{
Spec: corev1.NodeSpec{
ProviderID: "k3s://k3d-k3s-default-server-0",
},
},
},
{
distro: DistroIsKind,
node: corev1.Node{
Spec: corev1.NodeSpec{
ProviderID: "kind://docker/kind/kind-control-plane",
},
},
},
{
distro: DistroIsMicroK8s,
node: corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"microk8s.io/cluster": "true",
},
},
},
},
{
distro: DistroIsEKS,
node: corev1.Node{
Spec: corev1.NodeSpec{
ProviderID: "aws:////i-112bac41a19da1819",
},
},
},
{
distro: DistroIsEKSAnywhere,
namespaces: []corev1.Namespace{
{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "eksa-system",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "baz",
},
},
},
},
{
distro: DistroIsDockerDesktop,
node: corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "docker-desktop",
},
},
},
{
distro: DistroIsGKE,
node: corev1.Node{
Spec: corev1.NodeSpec{
ProviderID: "gce://kthw-239419/us-central1-f/gk3-autopilot-cluster-1-pool-2-e87e560a-7gvw",
},
},
},
{
distro: DistroIsAKS,
node: corev1.Node{
Spec: corev1.NodeSpec{
ProviderID: "azure:///subscriptions/9107f2fb-e486-a434-a948-52e2929b6f18/resourceGroups/MC_rg_capz-managed-aks_eastus/providers/Microsoft.Compute/virtualMachineScaleSets/aks-agentpool0-10226072-vmss/virtualMachines/0",
},
},
},
{
distro: DistroIsRKE2,
node: corev1.Node{
Status: corev1.NodeStatus{
Images: []corev1.ContainerImage{
{
Names: []string{"docker.io/library/ubuntu:latest"},
},
{
Names: []string{"rancher/rancher-agent:v2"},
},
},
},
},
},
{
distro: DistroIsTKG,
node: corev1.Node{
Status: corev1.NodeStatus{
Images: []corev1.ContainerImage{
{
Names: []string{"docker.io/library/ubuntu:latest"},
},
{
Names: []string{"projects.registry.vmware.com/tkg/tanzu_core/"},
},
},
},
},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.distro, func(t *testing.T) {
t.Parallel()

distro := detectDistro(tt.node, tt.namespaces)
require.Equal(t, tt.distro, distro)
})
}
}
35 changes: 19 additions & 16 deletions src/pkg/cluster/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,20 @@ import (
"context"
"encoding/json"
"fmt"
"time"

"slices"
"time"

"github.com/defenseunicorns/zarf/src/config"
"github.com/defenseunicorns/zarf/src/config/lang"
"github.com/defenseunicorns/zarf/src/types"
"github.com/fatih/color"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/defenseunicorns/pkg/helpers"
"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"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/defenseunicorns/zarf/src/types"
)

// Zarf Cluster Constants.
Expand Down Expand Up @@ -54,20 +53,24 @@ func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitO
state = &types.ZarfState{}
spinner.Updatef("New cluster, no prior Zarf deployments found")

// If the K3s component is being deployed, skip distro detection.
if initOptions.ApplianceMode {
distro = k8s.DistroIsK3s
// If the K3s component is being deployed, skip distro detection.
distro = DistroIsK3s
state.ZarfAppliance = true
} else {
// Otherwise, trying to detect the K8s distro type.
distro, err = c.DetectDistro(ctx)
nodeList, err := c.Clientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
if err != nil {
return err
}
namespaceList, err := c.Clientset.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
if err != nil {
// This is a basic failure right now but likely could be polished to provide user guidance to resolve.
return fmt.Errorf("unable to connect to the cluster to verify the distro: %w", err)
return err
}
distro = detectDistro(nodeList.Items[0], namespaceList.Items)
}

if distro != k8s.DistroIsUnknown {
if distro != DistroIsUnknown {
spinner.Updatef("Detected K8s distro %s", distro)
}

Expand Down Expand Up @@ -144,13 +147,13 @@ func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitO
}

switch state.Distro {
case k8s.DistroIsK3s, k8s.DistroIsK3d:
case DistroIsK3s, DistroIsK3d:
state.StorageClass = "local-path"

case k8s.DistroIsKind, k8s.DistroIsGKE:
case DistroIsKind, DistroIsGKE:
state.StorageClass = "standard"

case k8s.DistroIsDockerDesktop:
case DistroIsDockerDesktop:
state.StorageClass = "hostpath"
}

Expand Down
Loading

0 comments on commit 637096f

Please sign in to comment.