diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ef3d173..6583471a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## v0.34.0 + +- Fix KTF to properly deploy Kong Gateway Enterprise in DBLess mode + [#757](https://github.com/Kong/kubernetes-testing-framework/pull/757) + ## v0.33.0 - Make `KustomizeDeployForCluster` and `KustomizeDeleteForCluster` always diff --git a/pkg/clusters/addons/kong/addon.go b/pkg/clusters/addons/kong/addon.go index d0d87469..383b0abc 100644 --- a/pkg/clusters/addons/kong/addon.go +++ b/pkg/clusters/addons/kong/addon.go @@ -299,39 +299,39 @@ func (a *Addon) Deploy(ctx context.Context, cluster clusters.Cluster) error { a.deployArgs = append(a.deployArgs, "--set", fmt.Sprintf("env.log_level=%s", a.proxyLogLevel)) } - // deploy licenses and other configurations for enterprise mode + // Deploy licenses and other configurations for enterprise mode. if a.proxyEnterpriseEnabled { - // deploy the license as a Kubernetes secret to enable enterprise features for the proxy + // Set the enterprise defaults helm installation values. + a.deployArgs = append(a.deployArgs, enterpriseDefaults()...) + // Deploy the license as a Kubernetes secret to enable enterprise features for the proxy. if err := deployKongEnterpriseLicenseSecret(ctx, cluster, a.namespace, DefaultEnterpriseLicenseSecretName, a.proxyEnterpriseLicenseJSON); err != nil { return err } - - // deploy the superadmin password as a Kubernetes secret adjacent to the proxy pod and configure - // the chart to use that secret to configure controller auth to the admin API. - a.proxyEnterpriseSuperAdminPassword, err = deployEnterpriseSuperAdminPasswordSecret(ctx, cluster, a.namespace, a.proxyEnterpriseSuperAdminPassword) - if err != nil { - return err - } - if !a.ingressControllerDisabled { - a.deployArgs = append(a.deployArgs, - "--set", fmt.Sprintf("ingressController.env.kong_admin_token.valueFrom.secretKeyRef.name=%s", DefaultEnterpriseAdminPasswordSecretName), - ) - a.deployArgs = append(a.deployArgs, - "--set", "ingressController.env.kong_admin_token.valueFrom.secretKeyRef.key=password", - ) + // For DB-less mode, admin password can't be configured because there is nowhere for it to be stored. + if a.proxyDBMode != DBLESS { + // Deploy the superadmin password as a Kubernetes secret adjacent to the proxy pod and configure + // the chart to use that secret to configure controller auth to the admin API. + a.proxyEnterpriseSuperAdminPassword, err = deployEnterpriseSuperAdminPasswordSecret(ctx, cluster, a.namespace, a.proxyEnterpriseSuperAdminPassword) + if err != nil { + return err + } + a.deployArgs = append(a.deployArgs, "--set", fmt.Sprintf("env.password.valueFrom.secretKeyRef.name=%s", DefaultEnterpriseAdminPasswordSecretName)) + a.deployArgs = append(a.deployArgs, "--set", "env.password.valueFrom.secretKeyRef.key=password") + a.deployArgs = append(a.deployArgs, "--set", "enterprise.rbac.enabled=true", "--set", "env.enforce_rbac=on") + if !a.ingressControllerDisabled { + a.deployArgs = append( + a.deployArgs, + "--set", fmt.Sprintf("ingressController.env.kong_admin_token.valueFrom.secretKeyRef.name=%s", DefaultEnterpriseAdminPasswordSecretName), + ) + a.deployArgs = append(a.deployArgs, "--set", "ingressController.env.kong_admin_token.valueFrom.secretKeyRef.key=password") + } } - a.deployArgs = append(a.deployArgs, - "--set", fmt.Sprintf("env.password.valueFrom.secretKeyRef.name=%s", DefaultEnterpriseAdminPasswordSecretName), - ) - a.deployArgs = append(a.deployArgs, "--set", "env.password.valueFrom.secretKeyRef.key=password") - // deploy the admin session configuration needed for enterprise enabled mode + // Deploy the admin session configuration needed for enterprise enabled mode. if err := deployKongEnterpriseAdminGUISessionConf(ctx, cluster, a.namespace); err != nil { return err } - // set the enterprise defaults helm installation values - a.deployArgs = append(a.deployArgs, enterpriseDefaults()...) } for name, value := range a.proxyEnvVars { @@ -557,8 +557,6 @@ func defaults() []string { func enterpriseDefaults() []string { return []string{ "--set", "enterprise.enabled=true", - "--set", "enterprise.rbac.enabled=true", - "--set", "env.enforce_rbac=on", "--set", "admin.annotations.konghq.com/protocol=http", "--set", fmt.Sprintf("enterprise.license_secret=%s", DefaultEnterpriseLicenseSecretName), } diff --git a/test/integration/enterprise_test.go b/test/integration/enterprise_test.go index 98d70561..94b047ed 100644 --- a/test/integration/enterprise_test.go +++ b/test/integration/enterprise_test.go @@ -22,7 +22,6 @@ import ( func TestKongEnterprisePostgres(t *testing.T) { SkipEnterpriseTestIfNoEnv(t) - t.Parallel() licenseJSON := prepareKongEnterpriseLicense(t) @@ -40,6 +39,20 @@ func TestKongEnterprisePostgres(t *testing.T) { deployAndTestKongEnterprise(t, kongAddon, adminPassword) } +func TestKongEnterpriseDBLess(t *testing.T) { + SkipEnterpriseTestIfNoEnv(t) + + licenseJSON := prepareKongEnterpriseLicense(t) + + t.Log("configuring the testing environment") + kongAddon := kongaddon.NewBuilder(). + WithProxyAdminServiceTypeLoadBalancer(). + WithProxyEnterpriseEnabled(licenseJSON). + Build() + + deployAndTestKongEnterprise(t, kongAddon, "") +} + // deployAndTestKongEnterprise deploys a Kong Enterprise cluster and tests it for basic functionality. // It works for both DB-less and DB-mode deployments (configuration of kongAddon). For DB-less set adminPassword to "". // It verifies that workspace (enterprise feature) can be successfully created. @@ -97,26 +110,29 @@ func deployAndTestKongEnterprise(t *testing.T, kongAddon *kongaddon.Addon, admin t, httpClient, req, test.WithStatusCode(http.StatusOK), test.WithBodyContains("httpbin.org"), ) - const workspaceToCreate = "test-workspace" + const consumerGroupToCreate = "test-consumer-group" if adminPassword != "" { - t.Log("verifying enterprise workspace API functionality using /workspaces (works only for dbmode)") + t.Log("verifying enterprise consumer groups API functionality using /consumer_groups (works only for dbmode)") req, err = http.NewRequestWithContext( - ctx, http.MethodPost, adminURL.JoinPath("/workspaces").String(), - strings.NewReader(fmt.Sprintf(`{"name": "%s"}`, workspaceToCreate)), + ctx, http.MethodPost, adminURL.JoinPath("/consumer_groups").String(), + strings.NewReader(fmt.Sprintf(`{"name": "%s"}`, consumerGroupToCreate)), ) require.NoError(t, err) decorateRequestWithAdminPassword(t, req, adminPassword) } else { - t.Log("verifying enterprise workspace API functionality using /config (works only for dblessmode)") - t.Fatal("not implemented yet") + t.Log("verifying enterprise consumer groups API functionality using /config (works only for dblessmode)") + req, err = http.NewRequestWithContext( + ctx, http.MethodPost, adminURL.JoinPath("/config").String(), + strings.NewReader(fmt.Sprintf(`{"_format_version": "3.0", "consumer_groups": [{"name": "%s"}]}`, consumerGroupToCreate)), + ) } req.Header.Set("Content-Type", "application/json") test.EventuallyExpectResponse(t, httpClient, req, test.WithStatusCode(http.StatusCreated)) - t.Log("verifying that the workspace was indeed created") + t.Log("verifying that the consumer group was indeed created") req, err = http.NewRequestWithContext( ctx, http.MethodGet, - adminURL.JoinPath("/workspaces/").JoinPath(workspaceToCreate).String(), + adminURL.JoinPath("/consumer_groups/").JoinPath(consumerGroupToCreate).String(), nil, ) require.NoError(t, err)