Skip to content
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
2 changes: 1 addition & 1 deletion test/e2e/config/operator-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ intervals:
default/wait-controllers: ["3m", "10s"]

variables:
CERTMANAGER_URL: https://github.com/cert-manager/cert-manager/releases/download/${E2E_CERT_MANAGER_VERSION}/cert-manager.yaml
CERTMANAGER_VERSION: ${E2E_CERT_MANAGER_VERSION}
79 changes: 36 additions & 43 deletions test/e2e/e2e_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,10 @@ package e2e
import (
"flag"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"testing"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand All @@ -39,7 +36,7 @@ import (
"k8s.io/klog/v2"
operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha1"

operatorframework "sigs.k8s.io/cluster-api-operator/test/framework"
. "sigs.k8s.io/cluster-api-operator/test/framework"
"sigs.k8s.io/cluster-api/test/framework"
"sigs.k8s.io/cluster-api/test/framework/bootstrap"
"sigs.k8s.io/cluster-api/test/framework/clusterctl"
Expand All @@ -48,12 +45,9 @@ import (
)

const (
certManagerURL = "CERTMANAGER_URL"
certManagerNamespace = "cert-manager"
certManagerDeployment = "cert-manager"
certManagerCAInjectorDeployment = "cert-manager-cainjector"
certManagerWebhookDeployment = "cert-manager-webhook"
capiOperatorManagerDeployment = "capi-operator-controller-manager"
certManagerVersion = "CERTMANAGER_VERSION"
certManagerNamespace = "cert-manager"
capiOperatorManagerDeployment = "capi-operator-controller-manager"
)

// Test suite flags.
Expand Down Expand Up @@ -116,7 +110,7 @@ var (
usePRArtifacts bool

// helmChart is the helm chart helper to be used for the e2e tests.
helmChart *operatorframework.HelmChart
helmChart *HelmChart
)

func init() {
Expand Down Expand Up @@ -302,51 +296,50 @@ func initHelmCluster(clusterProxy framework.ClusterProxy, config *clusterctl.E2E

func ensureCertManager(clusterProxy framework.ClusterProxy, config *clusterctl.E2EConfig) {
By("Deploying cert-manager")
Expect(config.Variables).To(HaveKey(certManagerURL), "Missing %s variable in the config", certManagerURL)
certManagerComponentsUrl := config.GetVariable(certManagerURL)

var netClient = &http.Client{
Timeout: time.Second * 10,
addCertChart := &HelmChart{
BinaryPath: helmBinaryPath,
Name: "jetstack",
Path: "https://charts.jetstack.io/",
Kubeconfig: clusterProxy.GetKubeconfigPath(),
Commands: Commands(Repo, Add),
AdditionalFlags: Flags("--force-update"),
}
_, err := addCertChart.Run(nil)
Expect(err).ToNot(HaveOccurred())

certManagerResponse, err := netClient.Get(certManagerComponentsUrl)
Expect(err).ToNot(HaveOccurred(), "Failed to download cert-manager components from %s", certManagerComponentsUrl)
defer certManagerResponse.Body.Close()

rawCertManagerResponse, err := io.ReadAll(certManagerResponse.Body)
Expect(err).ToNot(HaveOccurred(), "Failed to read the cert-manager components file")

Expect(clusterProxy.Apply(ctx, rawCertManagerResponse)).To(Succeed(), "Failed to apply cert-manager components to the cluster")

By("Waiting for cert manager to be available")
certManagerDeployments := []*appsv1.Deployment{
{
ObjectMeta: metav1.ObjectMeta{Name: certManagerDeployment, Namespace: certManagerNamespace},
},
{
ObjectMeta: metav1.ObjectMeta{Name: certManagerCAInjectorDeployment, Namespace: certManagerNamespace},
},
{
ObjectMeta: metav1.ObjectMeta{Name: certManagerWebhookDeployment, Namespace: certManagerNamespace},
},
repoUpdate := &HelmChart{
BinaryPath: helmBinaryPath,
Kubeconfig: clusterProxy.GetKubeconfigPath(),
Commands: Commands(Repo, Update),
}
_, err = repoUpdate.Run(nil)
Expect(err).ToNot(HaveOccurred())

for _, deployment := range certManagerDeployments {
framework.WaitForDeploymentsAvailable(ctx, framework.WaitForDeploymentsAvailableInput{
Getter: clusterProxy.GetClient(),
Deployment: deployment,
}, config.GetIntervals(clusterProxy.GetName(), "wait-controllers")...)
certChart := &HelmChart{
BinaryPath: helmBinaryPath,
Path: "jetstack/cert-manager",
Name: "cert-manager",
Kubeconfig: clusterProxy.GetKubeconfigPath(),
Wait: true,
AdditionalFlags: Flags(
"--create-namespace",
"-n", certManagerNamespace,
"--version", config.GetVariable(certManagerVersion),
),
}
_, err = certChart.Run(map[string]string{
"installCRDs": "true",
})
}

func initHelmChart() {
helmChart = &operatorframework.HelmChart{
helmChart = &HelmChart{
BinaryPath: helmBinaryPath,
Path: chartPath,
Name: "capi-operator",
Kubeconfig: helmClusterProxy.GetKubeconfigPath(),
DryRun: true,
Output: operatorframework.Hooks,
Output: Hooks,
}
}

Expand Down
26 changes: 13 additions & 13 deletions test/e2e/helm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,29 @@ import (

var _ = Describe("Create a proper set of manifests when using helm charts", func() {
It("should deploy default manifest set for quick-start process", func() {
fullInstallChart := &HelmChart{
fullRun := &HelmChart{
BinaryPath: helmChart.BinaryPath,
Path: helmChart.Path,
Name: helmChart.Name,
Kubeconfig: helmChart.Kubeconfig,
DryRun: helmChart.DryRun,
Output: Manifests,
}
fullInstallChart.Output = Manifests
manifests, err := fullInstallChart.InstallChart(nil)
fullRun.Output = Manifests
manifests, err := fullRun.Run(nil)
Expect(err).ToNot(HaveOccurred())
fullChartInstall, err := os.ReadFile(filepath.Join(customManifestsFolder, "full-chart-install.yaml"))
Expect(manifests).To(Equal(string(fullChartInstall)))
})

It("should not deploy providers when none specified", func() {
manifests, err := helmChart.InstallChart(nil)
manifests, err := helmChart.Run(nil)
Expect(err).ToNot(HaveOccurred())
Expect(manifests).To(BeEmpty())
})

It("should deploy all providers with custom namespace and versions", func() {
manifests, err := helmChart.InstallChart(map[string]string{
manifests, err := helmChart.Run(map[string]string{
"secretName": "test-secret-name",
"secretNamespace": "test-secret-namespace",
"core": "capi-custom-ns:cluster-api:v1.4.2",
Expand All @@ -68,7 +68,7 @@ var _ = Describe("Create a proper set of manifests when using helm charts", func
})

It("should deploy all providers with custom versions", func() {
manifests, err := helmChart.InstallChart(map[string]string{
manifests, err := helmChart.Run(map[string]string{
"secretName": "test-secret-name",
"secretNamespace": "test-secret-namespace",
"core": "cluster-api:v1.4.2",
Expand All @@ -84,7 +84,7 @@ var _ = Describe("Create a proper set of manifests when using helm charts", func
})

It("should deploy all providers with latest version", func() {
manifests, err := helmChart.InstallChart(map[string]string{
manifests, err := helmChart.Run(map[string]string{
"secretName": "test-secret-name",
"secretNamespace": "test-secret-namespace",
"core": "cluster-api",
Expand All @@ -100,7 +100,7 @@ var _ = Describe("Create a proper set of manifests when using helm charts", func
})

It("should deploy core, bootstrap, control plane when only infra is specified", func() {
manifests, err := helmChart.InstallChart(map[string]string{
manifests, err := helmChart.Run(map[string]string{
"secretName": "test-secret-name",
"secretNamespace": "test-secret-namespace",
"infrastructure": "docker",
Expand All @@ -113,7 +113,7 @@ var _ = Describe("Create a proper set of manifests when using helm charts", func
})

It("should deploy core when only bootstrap is specified", func() {
manifests, err := helmChart.InstallChart(map[string]string{
manifests, err := helmChart.Run(map[string]string{
"secretName": "test-secret-name",
"secretNamespace": "test-secret-namespace",
"bootstrap": "kubeadm",
Expand All @@ -126,7 +126,7 @@ var _ = Describe("Create a proper set of manifests when using helm charts", func
})

It("should deploy core when only control plane is specified", func() {
manifests, err := helmChart.InstallChart(map[string]string{
manifests, err := helmChart.Run(map[string]string{
"secretName": "test-secret-name",
"secretNamespace": "test-secret-namespace",
"controlPlane": "kubeadm",
Expand All @@ -139,7 +139,7 @@ var _ = Describe("Create a proper set of manifests when using helm charts", func
})

It("should deploy multiple infra providers with custom namespace and versions", func() {
manifests, err := helmChart.InstallChart(map[string]string{
manifests, err := helmChart.Run(map[string]string{
"secretName": "test-secret-name",
"secretNamespace": "test-secret-namespace",
"infrastructure": "capd-custom-ns:docker:v1.4.2;capz-custom-ns:azure:v1.10.0",
Expand All @@ -152,7 +152,7 @@ var _ = Describe("Create a proper set of manifests when using helm charts", func
})

It("should deploy multiple control plane providers with custom namespace and versions", func() {
manifests, err := helmChart.InstallChart(map[string]string{
manifests, err := helmChart.Run(map[string]string{
"secretName": "test-secret-name",
"secretNamespace": "test-secret-namespace",
"controlPlane": "kubeadm-control-plane-custom-ns:kubeadm:v1.4.2;rke2-control-plane-custom-ns:rke2:v0.3.0",
Expand All @@ -165,7 +165,7 @@ var _ = Describe("Create a proper set of manifests when using helm charts", func
})

It("should deploy multiple bootstrap providers with custom namespace and versions", func() {
manifests, err := helmChart.InstallChart(map[string]string{
manifests, err := helmChart.Run(map[string]string{
"secretName": "test-secret-name",
"secretNamespace": "test-secret-namespace",
"bootstrap": "kubeadm-bootstrap-custom-ns:kubeadm:v1.4.2;rke2-bootstrap-custom-ns:rke2:v0.3.0",
Expand Down
98 changes: 77 additions & 21 deletions test/framework/all_type_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,47 +113,103 @@ func WaitFor(ctx context.Context, input ConditionalInterface, intervals ...inter
type HelmOutput int

const (
Manifests HelmOutput = iota
Full HelmOutput = iota
Manifests
Hooks
Full
)

//go:generate go run golang.org/x/tools/cmd/stringer -type=HelmCommand all_type_helpers.go
type HelmCommand int
type HelmCommands []HelmCommand

const (
Install HelmCommand = iota
Uninstall
Repo
Template
Add
Update
Remove
)

func (c HelmCommands) Strings() []string {
commands := []string{}
for _, command := range c {
commands = append(commands, strings.ToLower(command.String()))
}
return commands
}

// Commands generate a valid list of helm commands from input or defaults to install
func Commands(commands ...HelmCommand) HelmCommands {
return commands
}

type HelmFlags []string

// Flags returns a list of additional flags for helm chart
func Flags(flags ...string) HelmFlags {
f := HelmFlags{}
return *f.Flags(flags...)
}

// Flags extends existing list with additional flags for helm chart
func (h *HelmFlags) Flags(flags ...string) *HelmFlags {
if flags == nil {
return h
}
for _, flag := range flags {
if flag != "" {
*h = append(*h, flag)
}
}
return h
}

func (h *HelmFlags) Set(set bool, flag string) *HelmFlags {
if set {
h.Flags(flag)
}
return h
}

type HelmChart struct {
BinaryPath string
Commands HelmCommands
Path string
Name string
Kubeconfig string
DryRun bool
Wait bool
AdditionalFlags []string
AdditionalFlags HelmFlags
Output HelmOutput
}

// InstallChart performs an install of the helm chart. Install returns the rendered manifest
// with some additional data that can't be parsed as yaml. This function processes the output and returns only the optional resources,
// Run performs an execution of the helm command. Run returns the output
// with some additional data that can't be parsed as yaml.
// This function processes the output and returns only the optional resources,
// marked as post install hooks.
func (h *HelmChart) InstallChart(values map[string]string) (string, error) {
args := []string{"install", "--kubeconfig", h.Kubeconfig, h.Name, h.Path}
if h.DryRun {
args = append(args, "--dry-run")
}
if h.Wait {
args = append(args, "--wait")
func (h *HelmChart) Run(values map[string]string) (string, error) {
args := Flags()
if h.Commands == nil {
h.Commands = Commands(Install)
}
args.Flags(h.Commands.Strings()...)
args.Flags("--kubeconfig", h.Kubeconfig, h.Name, h.Path)
args.Set(h.DryRun, "--dry-run")
args.Set(h.Wait, "--wait")
for key, value := range values {
args = append(args, "--set")
args = append(args, fmt.Sprintf("%s=%s", key, value))
args.Flags("--set", fmt.Sprintf("%s=%s", key, value))
}
if h.AdditionalFlags != nil {
args = append(args, h.AdditionalFlags...)
args.Flags(h.AdditionalFlags...)
if h.BinaryPath == "" {
h.BinaryPath = "helm"
}

fullCommand := append([]string{h.BinaryPath}, args...)
klog.Infof("Executing: %s", fullCommand, " ")
cmd := exec.Command(h.BinaryPath, args...)
out, err := cmd.CombinedOutput()
klog.Infof("Executing: %s", fullCommand)
out, err := exec.Command(h.BinaryPath, args...).CombinedOutput()
if err != nil {
return "", fmt.Errorf("failed to run helm install: %w, output: %s", err, string(out))
return "", fmt.Errorf("failed to run helm %s: %w, output: %s", strings.Join(h.Commands.Strings(), " "), err, string(out))
}

outString := string(out)
Expand Down
29 changes: 29 additions & 0 deletions test/framework/helmcommand_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading