From b62d9f9ae45b8947cb3fbce1ddfa7c7280d6cb01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Fri, 20 Oct 2023 19:26:52 +0200 Subject: [PATCH] feat(kong): allow multiple kong addons to be deployed in cluster (#845) --- CHANGELOG.md | 8 ++++ pkg/clusters/addons/kong/addon.go | 16 +++---- pkg/clusters/addons/kong/builder.go | 45 ++++++++++++++++---- test/integration/kongaddon_test.go | 65 +++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cd41342..60cc8455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## v0.41.0 + +- Allow deploying multiple kong addons to the cluster and identifying them by + their name. + [#845](https://github.com/Kong/kubernetes-testing-framework/pull/845) +- Allow setting kong addon admin API and proxy NodePorts. + [#844](https://github.com/Kong/kubernetes-testing-framework/pull/844) + ## v0.40.0 - Metallb addon now has a builder. The builder can disable IPAddressPool diff --git a/pkg/clusters/addons/kong/addon.go b/pkg/clusters/addons/kong/addon.go index bddf1abd..a6c63e7a 100644 --- a/pkg/clusters/addons/kong/addon.go +++ b/pkg/clusters/addons/kong/addon.go @@ -73,11 +73,13 @@ const ( type Addon struct { logger *logrus.Logger + name string + // kubernetes and helm chart related configuration options - namespace string - name string - deployArgs []string - chartVersion string + namespace string + helmReleaseName string + deployArgs []string + chartVersion string // ingress controller configuration options ingressControllerDisabled bool @@ -179,7 +181,7 @@ func (a *Addon) ProxyUDPURL(ctx context.Context, cluster clusters.Cluster) (*url // ----------------------------------------------------------------------------- func (a *Addon) Name() clusters.AddonName { - return AddonName + return clusters.AddonName(a.name) } func (a *Addon) Dependencies(_ context.Context, cluster clusters.Cluster) []clusters.AddonName { @@ -259,7 +261,7 @@ func (a *Addon) Deploy(ctx context.Context, cluster clusters.Cluster) error { } // if the dbmode is postgres, set several related values - args := []string{"--kubeconfig", kubeconfig.Name(), "upgrade", "--install", DefaultDeploymentName, "kong/kong"} + args := []string{"--kubeconfig", kubeconfig.Name(), "upgrade", "--install", a.helmReleaseName, "kong/kong"} if a.proxyDBMode == PostgreSQL { a.deployArgs = append(a.deployArgs, "--set", "env.database=postgres", @@ -409,7 +411,7 @@ func (a *Addon) Delete(ctx context.Context, cluster clusters.Cluster) error { // delete the chart release from the cluster stderr := new(bytes.Buffer) - cmd := exec.CommandContext(ctx, "helm", "--kubeconfig", kubeconfig.Name(), "uninstall", DefaultDeploymentName, "--namespace", a.namespace) //nolint:gosec + cmd := exec.CommandContext(ctx, "helm", "--kubeconfig", kubeconfig.Name(), "uninstall", a.helmReleaseName, "--namespace", a.namespace) //nolint:gosec cmd.Stdout = io.Discard cmd.Stderr = stderr if err := cmd.Run(); err != nil { diff --git a/pkg/clusters/addons/kong/builder.go b/pkg/clusters/addons/kong/builder.go index aade7054..4ec4bd7c 100644 --- a/pkg/clusters/addons/kong/builder.go +++ b/pkg/clusters/addons/kong/builder.go @@ -7,6 +7,10 @@ import ( corev1 "k8s.io/api/core/v1" ) +const ( + DefaultKongAddonName = "kong" +) + // ----------------------------------------------------------------------------- // Kong Addon - Builder // ----------------------------------------------------------------------------- @@ -15,11 +19,13 @@ import ( type Builder struct { logger *logrus.Logger + name string + // kubernetes and helm chart related configuration options - namespace string - name string - deployArgs []string - chartVersion string + namespace string + helmReleaseName string + deployArgs []string + chartVersion string // ingress controller configuration options ingressControllerDisabled bool @@ -54,8 +60,9 @@ type Builder struct { // Kong Addon objects which can be deployed to cluster.Clusters func NewBuilder() *Builder { builder := &Builder{ + name: DefaultKongAddonName, namespace: DefaultNamespace, - name: DefaultDeploymentName, + helmReleaseName: DefaultDeploymentName, deployArgs: []string{}, proxyEnvVars: make(map[string]string), additionalValues: make(map[string]string), @@ -91,11 +98,12 @@ func (b *Builder) Build() *Addon { return &Addon{ logger: b.logger, + name: b.name, - namespace: b.namespace, - name: b.name, - deployArgs: b.deployArgs, - chartVersion: b.chartVersion, + namespace: b.namespace, + helmReleaseName: b.helmReleaseName, + deployArgs: b.deployArgs, + chartVersion: b.chartVersion, ingressControllerDisabled: b.ingressControllerDisabled, ingressControllerImage: b.ingressControllerImage, @@ -264,3 +272,22 @@ func (b *Builder) WithAdminNodePort(port int) *Builder { b.adminNodePort = port return b } + +// WithHelmReleaseName sets the helm release name. +func (b *Builder) WithHelmReleaseName(name string) *Builder { + b.helmReleaseName = name + return b +} + +// WithName sets the addon name. +// +// Note: if you want to deploy more than 1 addon of this type in a cluster, then +// you need to specify the name here. +// Without this, environment builder will silently overwrite the first addon +// of the same type (using the same, default name). +// +// TODO: https://github.com/Kong/kubernetes-testing-framework/issues/846 +func (b *Builder) WithName(name string) *Builder { + b.name = name + return b +} diff --git a/test/integration/kongaddon_test.go b/test/integration/kongaddon_test.go index 5ec28ef7..cb375c94 100644 --- a/test/integration/kongaddon_test.go +++ b/test/integration/kongaddon_test.go @@ -333,3 +333,68 @@ func TestKongUDPProxy(t *testing.T) { return false }, time.Minute*3, time.Second) } + +func TestKongAddonMultiplePerCluster(t *testing.T) { + testNS1 := "kong-test-1" + kong1 := kongaddon.NewBuilder(). + // Have to specify the relelase name: https://github.com/Kong/charts/issues/910 + WithHelmReleaseName("ingress-controller1"). + WithNamespace(testNS1). + // We need to specify different names for addons due to this limitation: + // https://github.com/Kong/kubernetes-testing-framework/issues/846 + // Without this environment builder will silently overwrite the first addon + // of the same type (using the same, default name). + WithName("kong1"). + WithProxyServiceType(corev1.ServiceTypeClusterIP). + WithLogLevel("debug"). + Build() + + testNS2 := "kong-test-2" + kong2 := kongaddon.NewBuilder(). + // Have to specify the relelase name: https://github.com/Kong/charts/issues/910 + WithHelmReleaseName("ingress-controller2"). + WithNamespace(testNS2). + // We need to specify different names for addons due to this limitation: + // https://github.com/Kong/kubernetes-testing-framework/issues/846 + // Without this environment builder will silently overwrite the first addon + // of the same type (using the same, default name). + WithName("kong2"). + WithProxyServiceType(corev1.ServiceTypeClusterIP). + WithLogLevel("debug"). + Build() + + t.Log("configuring the testing environment") + builder := environment.NewBuilder().WithAddons(kong1, kong2) + + t.Log("building the testing environment and Kubernetes cluster") + env, err := builder.Build(ctx) + require.NoError(t, err) + + t.Cleanup(func() { + assert.NoError(t, env.Cluster().DeleteAddon(ctx, kong1)) + assert.NoError(t, env.Cluster().DeleteAddon(ctx, kong2)) + }) + + err = <-env.WaitForReady(ctx) + require.NoError(t, err) + + t.Log("verifying that kong addon have been loaded into the environment") + require.Len(t, env.Cluster().ListAddons(), 2) + + apps := env.Cluster().Client().AppsV1() + t.Log("verifying that kong deployments are deployed in their namespaces") + { + deployments := apps.Deployments(testNS1) + kongDeployment, err := deployments.Get(ctx, "ingress-controller1-kong", metav1.GetOptions{}) + require.NoError(t, err) + require.Greater(t, int(kongDeployment.Status.ReadyReplicas), 0, "should have at least one ready replicas") + require.Equal(t, kongDeployment.Status.Replicas, kongDeployment.Status.ReadyReplicas, "replicas should be all ready") + } + { + deployments := apps.Deployments(testNS2) + kongDeployment, err := deployments.Get(ctx, "ingress-controller2-kong", metav1.GetOptions{}) + require.NoError(t, err) + require.Greater(t, int(kongDeployment.Status.ReadyReplicas), 0, "should have at least one ready replicas") + require.Equal(t, kongDeployment.Status.Replicas, kongDeployment.Status.ReadyReplicas, "replicas should be all ready") + } +}