diff --git a/.github/ISSUE_TEMPLATE/---release.md b/.github/ISSUE_TEMPLATE/---release.md index 50e86ee3f..ab13bb822 100644 --- a/.github/ISSUE_TEMPLATE/---release.md +++ b/.github/ISSUE_TEMPLATE/---release.md @@ -65,7 +65,6 @@ These versions should be updated to match the new release. The example consts to - `DefaultDataPlaneTag` - `DefaultControlPlaneVersion` -- `WebhookCertificateConfigBaseImage` ## GitHub PAT diff --git a/.github/workflows/__release-workflow.yaml b/.github/workflows/__release-workflow.yaml index 34cbbb3f1..5a17606d9 100644 --- a/.github/workflows/__release-workflow.yaml +++ b/.github/workflows/__release-workflow.yaml @@ -124,13 +124,7 @@ jobs: test-integration-current-kubernetes: runs-on: ubuntu-latest - strategy: - fail-fast: true - matrix: - webhook-enabled: - - "true" - - "false" - name: "test-integration-current-kubernetes (WEBHOOK_ENABLED=${{ matrix.webhook-enabled }})" + name: "test-integration-current-kubernetes" steps: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -172,7 +166,6 @@ jobs: run: make test.integration env: KONG_LICENSE_DATA: ${{ steps.get-license.outputs.license || '' }} # The license is optional for OSS tests. - WEBHOOK_ENABLED: ${{ matrix.webhook-enabled }} KONG_TEST_KONNECT_ACCESS_TOKEN: ${{ secrets.konnect-pat }} KONG_TEST_KONNECT_SERVER_URL: us.api.konghq.tech @@ -180,7 +173,7 @@ jobs: if: always() uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: - name: diagnostics-integration-webhook-enabled-${{ matrix.webhook-enabled }} + name: diagnostics-integration path: /tmp/ktf-diag* if-no-files-found: ignore diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 1caab90b3..309a07055 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -315,13 +315,7 @@ jobs: integration-tests: runs-on: ubuntu-latest - strategy: - fail-fast: true - matrix: - webhook-enabled: - - "true" - - "false" - name: "integration-tests (WEBHOOK_ENABLED=${{ matrix.webhook-enabled }})" + name: integration-tests steps: - name: checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -340,9 +334,8 @@ jobs: env: KONG_TEST_DISABLE_CERTMANAGER: "true" KONG_PLUGIN_IMAGE_REGISTRY_CREDENTIALS: ${{ secrets.KONG_PLUGIN_IMAGE_REGISTRY_CREDENTIALS }} - WEBHOOK_ENABLED: ${{ matrix.webhook-enabled }} KONG_CONTROLLER_OUT: stdout - GOTESTSUM_JUNITFILE: integration-tests-webhook-enabled-${{ matrix.webhook-enabled }}.xml + GOTESTSUM_JUNITFILE: integration-tests.xml GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} KONG_TEST_KONNECT_ACCESS_TOKEN: ${{ secrets.KONG_TEST_KONNECT_ACCESS_TOKEN }} KONG_TEST_KONNECT_SERVER_URL: us.api.konghq.tech @@ -351,32 +344,26 @@ jobs: if: always() uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: - name: diagnostics-integration-webhook-enabled-${{ matrix.webhook-enabled }} + name: diagnostics-integration path: /tmp/ktf-diag* if-no-files-found: ignore - name: collect test coverage uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: - name: coverage-integration-webhook-enabled-${{ matrix.webhook-enabled }} + name: coverage-integration path: coverage.integration.out - name: collect test report if: ${{ always() }} uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: - name: tests-report-integration-webhook-enabled-${{ matrix.webhook-enabled }} - path: integration-tests-webhook-enabled-${{ matrix.webhook-enabled }}.xml + name: tests-report-integration + path: integration-tests.xml integration-tests-bluegreen: runs-on: ubuntu-latest - strategy: - fail-fast: true - matrix: - webhook-enabled: - - "true" - - "false" - name: "integration-tests-bluegreen (WEBHOOK_ENABLED=${{ matrix.webhook-enabled }})" + name: integration-tests-bluegreen steps: - name: checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -394,81 +381,30 @@ jobs: run: make test.integration_bluegreen env: KONG_TEST_DISABLE_CERTMANAGER: "true" - WEBHOOK_ENABLED: ${{ matrix.webhook-enabled }} KONG_CONTROLLER_OUT: stdout - GOTESTSUM_JUNITFILE: integration-tests-bluegreen-webhook-enabled-${{ matrix.webhook-enabled }}.xml + GOTESTSUM_JUNITFILE: integration-tests-bluegreen.xml GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: upload diagnostics if: always() uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: - name: diagnostics-integration-bluegreen-webhook-enabled-${{ matrix.webhook-enabled }} + name: diagnostics-integration-bluegreen path: /tmp/ktf-diag* if-no-files-found: ignore - name: collect test coverage uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: - name: coverage-integration-bluegreen-webhook-enabled-${{ matrix.webhook-enabled }} + name: coverage-integration-bluegreen path: coverage.integration-bluegreen.out - name: collect test report if: always() uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: - name: tests-report-integration-bluegreen-webhook-enabled-${{ matrix.webhook-enabled }} - path: integration-tests-bluegreen-webhook-enabled-${{ matrix.webhook-enabled }}.xml - - # Test reconciling Gateway with provisioning DataPlane failures. - # This test introduces a wrong gateway that will have errors on validation all `DataPlane`s, so it should run isolated. - integration-tests-provision-fail: - runs-on: ubuntu-latest - strategy: - fail-fast: true - name: integration-tests-provision-dataplane-fail - steps: - - name: checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: setup golang - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 - with: - go-version-file: go.mod - - - uses: jdx/mise-action@5083fe46898c414b2475087cc79da59e7da859e8 # v2.1.11 - with: - install: false - - - name: run integration tests - run: make test.integration_provision_dataplane_fail - env: - KONG_TEST_DISABLE_CERTMANAGER: "true" - KONG_CONTROLLER_OUT: stdout - KONG_PLUGIN_IMAGE_REGISTRY_CREDENTIALS: ${{ secrets.KONG_PLUGIN_IMAGE_REGISTRY_CREDENTIALS }} - GOTESTSUM_JUNITFILE: integration-tests-provision-dataplane-fail.xml - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: upload diagnostics - if: always() - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 - with: - name: diagnostics-integration-provision-fail - path: /tmp/ktf-diag* - if-no-files-found: ignore - - - name: collect test coverage - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 - with: - name: coverage-integration-tests-provision-fail - path: coverage.integration-provision-dataplane-fail.out - - - name: collect test report - if: always() - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 - with: - name: tests-report-integration-tests-provision-fail - path: integration-tests-provision-dataplane-fail.xml + name: tests-report-integration-bluegreen + path: integration-tests-bluegreen.xml e2e-tests: runs-on: ubuntu-latest @@ -498,7 +434,6 @@ jobs: env: KONG_TEST_DISABLE_CERTMANAGER: "true" KONG_TEST_GATEWAY_OPERATOR_IMAGE_LOAD: gateway-operator:e2e-${{ github.sha }} - WEBHOOK_ENABLED: "false" GOTESTSUM_JUNITFILE: "e2e-tests.xml" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Makefile b/Makefile index 610266742..bc90f8f0f 100644 --- a/Makefile +++ b/Makefile @@ -297,9 +297,8 @@ CONFIG_CRD_PATH = config/crd CONFIG_CRD_BASE_PATH = $(CONFIG_CRD_PATH)/bases .PHONY: manifests -manifests: controller-gen manifests.versions manifests.crds ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. +manifests: controller-gen manifests.versions manifests.crds ## Generate ClusterRole and CustomResourceDefinition objects. $(CONTROLLER_GEN) paths="$(CONTROLLER_GEN_PATHS)" rbac:roleName=manager-role output:rbac:dir=config/rbac/role - $(CONTROLLER_GEN) paths="$(CONTROLLER_GEN_PATHS)" webhook .PHONY: manifests.crds manifests.crds: controller-gen manifests.versions ## Generate CustomResourceDefinition objects. @@ -400,7 +399,7 @@ test.crds-validation.pretty: $(MAKE) _test.envtest GOTESTSUM_FORMAT=testname ENVTEST_TEST_PATHS=./test/crdsvalidation/... .PHONY: _test.integration -_test.integration: webhook-certs-dir gotestsum +_test.integration: gotestsum GOFLAGS=$(GOFLAGS) \ GOTESTSUM_FORMAT=$(GOTESTSUM_FORMAT) \ $(GOTESTSUM) -- $(GOTESTFLAGS) \ @@ -413,7 +412,7 @@ _test.integration: webhook-certs-dir gotestsum .PHONY: test.integration test.integration: @$(MAKE) _test.integration \ - GOTESTFLAGS="-skip='BlueGreen|TestGatewayProvisionDataPlaneFail' $(GOTESTFLAGS)" \ + GOTESTFLAGS="-skip='BlueGreen' $(GOTESTFLAGS)" \ COVERPROFILE="coverage.integration.out" .PHONY: test.integration_bluegreen @@ -423,13 +422,6 @@ test.integration_bluegreen: GOTESTFLAGS="-run='BlueGreen|TestDataPlane' $(GOTESTFLAGS)" \ COVERPROFILE="coverage.integration-bluegreen.out" \ -.PHONY: test.integration_provision_dataplane_fail -test.integration_provision_dataplane_fail: - @$(MAKE) _test.integration \ - WEBHOOK_ENABLED=true \ - GOTESTFLAGS="-run=TestGatewayProvisionDataPlaneFail $(GOTESTFLAGS)" \ - COVERPROFILE="coverage.integration.out" - .PHONY: _test.e2e _test.e2e: gotestsum GOTESTSUM_FORMAT=$(GOTESTSUM_FORMAT) \ @@ -521,22 +513,18 @@ ifndef ignore-not-found ignore-not-found = false endif -.PHONY: webhook-certs-dir -webhook-certs-dir: - @mkdir -p /tmp/k8s-webhook-server/serving-certs/ - .PHONY: _ensure-kong-system-namespace _ensure-kong-system-namespace: @kubectl create ns kong-system 2>/dev/null || true # Run a controller from your host. .PHONY: run -run: webhook-certs-dir manifests generate install.all _ensure-kong-system-namespace install.rbacs +run: manifests generate install.all _ensure-kong-system-namespace install.rbacs @$(MAKE) _run # Run a controller from your host and make it impersonate the controller-manager service account from kong-system namespace. .PHONY: run.with_impersonate -run.with_impersonate: webhook-certs-dir manifests generate install.all _ensure-kong-system-namespace install.rbacs +run.with_impersonate: manifests generate install.all _ensure-kong-system-namespace install.rbacs @$(MAKE) _run.with-impersonate KUBECONFIG ?= $(HOME)/.kube/config @@ -588,7 +576,7 @@ run.skaffold: $(MAKE) _skaffold .PHONY: debug -debug: webhook-certs-dir manifests generate install.all _ensure-kong-system-namespace +debug: manifests generate install.all _ensure-kong-system-namespace GATEWAY_OPERATOR_DEVELOPMENT_MODE=true dlv debug ./cmd/main.go -- \ --no-leader-election \ -cluster-ca-secret-namespace kong-system \ diff --git a/config/debug/manager_debug.yaml b/config/debug/manager_debug.yaml index f3ca12e4c..f3f219e7a 100644 --- a/config/debug/manager_debug.yaml +++ b/config/debug/manager_debug.yaml @@ -33,7 +33,6 @@ spec: - -zap-log-level=debug - -enable-controller-kongplugininstallation - -enable-controller-konnect - - -enable-validating-webhook name: manager env: - name: GATEWAY_OPERATOR_DEVELOPMENT_MODE diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index a30c30bb2..47b7321a0 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -11,4 +11,3 @@ resources: patches: - path: manager_metrics_access_filter_rbac_patch.yaml -- path: manager_webhook_certificates_patch.yaml diff --git a/config/default/manager_webhook_certificates_patch.yaml b/config/default/manager_webhook_certificates_patch.yaml deleted file mode 100644 index b8b20a5ec..000000000 --- a/config/default/manager_webhook_certificates_patch.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - volumes: - - name: webhook-certificates - emptyDir: {} - containers: - - name: manager - volumeMounts: - - name: webhook-certificates - mountPath: /tmp/k8s-webhook-server/serving-certs diff --git a/config/rbac/role/role.yaml b/config/rbac/role/role.yaml index 05072f738..ffad3d944 100644 --- a/config/rbac/role/role.yaml +++ b/config/rbac/role/role.yaml @@ -46,7 +46,6 @@ rules: resources: - secrets verbs: - - create - delete - get - list @@ -101,14 +100,6 @@ rules: - list - patch - watch -- apiGroups: - - batch - resources: - - jobs - verbs: - - create - - delete - - get - apiGroups: - configuration.konghq.com resources: @@ -462,12 +453,3 @@ rules: - patch - update - watch -- apiGroups: - - rbac.authorization.k8s.io - resources: - - rolebindings - - roles - verbs: - - create - - delete - - get diff --git a/controller/webhook_manager_rbac.go b/controller/webhook_manager_rbac.go deleted file mode 100644 index 485013e8b..000000000 --- a/controller/webhook_manager_rbac.go +++ /dev/null @@ -1,16 +0,0 @@ -package controller - -// ----------------------------------------------------------------------------- -// Webhook manager - RBAC Permissions -// ----------------------------------------------------------------------------- - -//+kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch -//+kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=get;create;delete -//+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;create;delete -//+kubebuilder:rbac:groups=core,resources=services,verbs=get;create;delete -//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles,verbs=get;create;delete -//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=rolebindings,verbs=get;create;delete -//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles,verbs=get;create;delete -//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=get;create;delete -//+kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=validatingwebhookconfigurations,verbs=get;create;update;patch;delete -//+kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;create;delete diff --git a/modules/cli/cli.go b/modules/cli/cli.go index 290a00bd0..d190588f3 100644 --- a/modules/cli/cli.go +++ b/modules/cli/cli.go @@ -62,9 +62,12 @@ func New(m metadata.Info) *CLI { flagSet.UintVar(&cfg.KonnectMaxConcurrentReconciles, "konnect-controller-max-concurrent-reconciles", consts.DefaultKonnectMaxConcurrentReconciles, "Maximum number of concurrent reconciles for Konnect entities.") // webhook and validation options - flagSet.BoolVar(&cfg.ValidatingWebhookEnabled, "enable-validating-webhook", false, "Enable the validating webhook.") - flagSet.StringVar(&cfg.WebhookCertificateConfigBaseImage, "webhook-certificate-config-base-image", consts.WebhookCertificateConfigBaseImage, "The base image for the certgen Jobs.") - flagSet.StringVar(&cfg.WebhookCertificateConfigShellImage, "webhook-certificate-config-shell-image", consts.WebhookCertificateConfigShellImage, "The shell image for the certgen Jobs.") + var validatingWebhookEnabled bool + flagSet.BoolVar(&validatingWebhookEnabled, "enable-validating-webhook", false, "Enable the validating webhook. DEPRECATED: This flag is no-op and will be removed in a future release.") + var validatingWebhookConfigBaseImage string + flagSet.StringVar(&validatingWebhookConfigBaseImage, "webhook-certificate-config-base-image", consts.WebhookCertificateConfigBaseImage, "The base image for the certgen Jobs. DEPRECATED: This flag is no-op and will be removed in a future release.") + var validatingWebhookConfigShellImage string + flagSet.StringVar(&validatingWebhookConfigShellImage, "webhook-certificate-config-shell-image", consts.WebhookCertificateConfigShellImage, "The shell image for the certgen Jobs. DEPRECATED: This flag is no-op and will be removed in a future release.") flagSet.BoolVar(&deferCfg.Version, "version", false, "Print version information.") @@ -150,11 +153,7 @@ func (c *CLI) Parse(arguments []string) manager.Config { developmentModeEnabled = true } - webhookCertDir := manager.DefaultConfig().WebhookCertDir // TODO: clean env handling https://github.com/Kong/gateway-operator-archive/issues/19 - if certDir := os.Getenv("WEBHOOK_CERT_DIR"); certDir != "" { - webhookCertDir = certDir - } // Flags take precedence over environment variables, // so we bind env vars first then parse aruments to override the values from flags. @@ -220,9 +219,7 @@ func (c *CLI) Parse(arguments []string) manager.Config { c.cfg.LeaderElection = leaderElection c.cfg.ControllerNamespace = controllerNamespace c.cfg.ClusterCASecretNamespace = clusterCASecretNamespace - c.cfg.WebhookCertDir = webhookCertDir c.cfg.LoggerOpts = logging.SetupLogEncoder(c.cfg.DevelopmentMode || c.loggerOpts.Development, c.loggerOpts) - c.cfg.WebhookPort = manager.DefaultConfig().WebhookPort c.cfg.LeaderElectionNamespace = controllerNamespace c.cfg.AnonymousReports = anonymousReportsEnabled diff --git a/modules/cli/cli_test.go b/modules/cli/cli_test.go index cfa39d42e..ed097183d 100644 --- a/modules/cli/cli_test.go +++ b/modules/cli/cli_test.go @@ -36,8 +36,6 @@ func TestParse(t *testing.T) { expectedCfg: func() manager.Config { cfg := expectedDefaultCfg() cfg.LeaderElection = false - cfg.ValidatingWebhookEnabled = false - cfg.WebhookCertDir = "/tmp/foo" return cfg }, }, @@ -55,7 +53,6 @@ func TestParse(t *testing.T) { cfg.ControllerNamespace = "test" // All the below config changes are the result of GATEWAY_OPERATOR_DEVELOPMENT_MODE=true. cfg.DevelopmentMode = true - cfg.ValidatingWebhookEnabled = false loggerOpts := manager.DefaultConfig().LoggerOpts loggerOpts.Development = true cfg.LoggerOpts = logging.SetupLogEncoder(true, loggerOpts) @@ -87,8 +84,6 @@ func TestParse(t *testing.T) { }, expectedCfg: func() manager.Config { cfg := expectedDefaultCfg() - cfg.WebhookCertificateConfigBaseImage = "mybaseimage:42" - cfg.WebhookCertificateConfigShellImage = "shellimg" return cfg }, }, @@ -172,8 +167,6 @@ func expectedDefaultCfg() manager.Config { MetricsAddr: ":8080", MetricsAccessFilter: "off", ProbeAddr: ":8081", - WebhookCertDir: "/tmp/k8s-webhook-server/serving-certs", - WebhookPort: 9443, LeaderElection: true, LeaderElectionNamespace: "kong-system", DevelopmentMode: false, @@ -193,9 +186,6 @@ func expectedDefaultCfg() manager.Config { KonnectControllersEnabled: false, KonnectSyncPeriod: consts.DefaultKonnectSyncPeriod, KongPluginInstallationControllerEnabled: false, - ValidatingWebhookEnabled: false, - WebhookCertificateConfigBaseImage: consts.WebhookCertificateConfigBaseImage, - WebhookCertificateConfigShellImage: consts.WebhookCertificateConfigShellImage, LoggerOpts: &zap.Options{}, KonnectMaxConcurrentReconciles: consts.DefaultKonnectMaxConcurrentReconciles, } diff --git a/modules/manager/run.go b/modules/manager/run.go index 8fde17e45..1975b6e3c 100644 --- a/modules/manager/run.go +++ b/modules/manager/run.go @@ -44,7 +44,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/metrics/filters" "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" "github.com/kong/gateway-operator/controller/pkg/secrets" "github.com/kong/gateway-operator/internal/telemetry" @@ -53,19 +52,11 @@ import ( "github.com/kong/gateway-operator/pkg/vars" ) -const ( - caCertFilename = "ca.crt" - tlsCertFilename = "tls.crt" - tlsKeyFilename = "tls.key" -) - // Config represents the configuration for the manager. type Config struct { MetricsAddr string MetricsAccessFilter MetricsAccessFilter ProbeAddr string - WebhookCertDir string - WebhookPort int LeaderElection bool LeaderElectionNamespace string DevelopmentMode bool @@ -97,11 +88,6 @@ type Config struct { // Controllers for Konnect APIs. KonnectControllersEnabled bool - - // webhook and validation options - ValidatingWebhookEnabled bool - WebhookCertificateConfigBaseImage string - WebhookCertificateConfigShellImage string } // DefaultConfig returns a default configuration for the manager. @@ -115,8 +101,6 @@ func DefaultConfig() Config { MetricsAddr: ":8080", MetricsAccessFilter: MetricsAccessFilterOff, ProbeAddr: ":8081", - WebhookCertDir: defaultWebhookCertDir, - WebhookPort: 9443, DevelopmentMode: false, LeaderElection: true, LeaderElectionNamespace: defaultLeaderElectionNamespace, @@ -197,11 +181,6 @@ func Run( } }(), }, - WebhookServer: webhook.NewServer( - webhook.Options{ - Port: cfg.WebhookPort, - }, - ), HealthProbeBindAddress: cfg.ProbeAddr, LeaderElection: cfg.LeaderElection, LeaderElectionNamespace: cfg.LeaderElectionNamespace, @@ -237,48 +216,22 @@ func Run( return err } - if cfg.ValidatingWebhookEnabled { - // if the validatingWebhook is enabled, we don't need to setup the Gateway API controllers - // here, as they will be set up by the webhook manager once all the webhook resources will be created - // and the webhook will be in place. - webhookMgr := &webhookManager{ - client: mgr.GetClient(), - mgr: mgr, - logger: ctrl.Log.WithName("webhook_manager"), - cfg: &cfg, - } - if err := webhookMgr.PrepareWebhookServerWithControllers(ctx, setupControllers, admissionRequestHandler); err != nil { - return fmt.Errorf("unable to create webhook server: %w", err) - } - - if err := mgr.Add(webhookMgr); err != nil { - return fmt.Errorf("unable to add webhook manager: %w", err) - } - - defer func() { - setupLog.Info("cleaning up webhook and certificateConfig resources") - if err := webhookMgr.cleanup(context.Background()); err != nil { - setupLog.Error(err, "error while performing cleanup") - } - }() - } else { - controllers, err := setupControllers(mgr, &cfg) - if err != nil { - setupLog.Error(err, "failed setting up controllers") - return err - } - for _, c := range controllers { - if err := c.MaybeSetupWithManager(ctx, mgr); err != nil { - return fmt.Errorf("unable to create controller %q: %w", c.Name(), err) - } + controllers, err := setupControllers(mgr, &cfg) + if err != nil { + setupLog.Error(err, "failed setting up controllers") + return err + } + for _, c := range controllers { + if err := c.MaybeSetupWithManager(ctx, mgr); err != nil { + return fmt.Errorf("unable to create controller %q: %w", c.Name(), err) } + } - // Add readyz check here only if the validating webhook is disabled. - // When the webhook is enabled we add a readyz check in PrepareWebhookServer - // to mark the controller ready only after the webhook has started. - if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - return fmt.Errorf("unable to set up ready check: %w", err) - } + // Add readyz check here only if the validating webhook is disabled. + // When the webhook is enabled we add a readyz check in PrepareWebhookServer + // to mark the controller ready only after the webhook has started. + if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + return fmt.Errorf("unable to set up ready check: %w", err) } //+kubebuilder:scaffold:builder diff --git a/modules/manager/webhook.go b/modules/manager/webhook.go index f23865bac..3c3011f75 100644 --- a/modules/manager/webhook.go +++ b/modules/manager/webhook.go @@ -17,398 +17,12 @@ limitations under the License. package manager import ( - "context" - "errors" - "fmt" - "os" - "path" - "sync" - "time" - "github.com/go-logr/logr" - corev1 "k8s.io/api/core/v1" - k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/webhook" "github.com/kong/gateway-operator/modules/admission" - "github.com/kong/gateway-operator/pkg/consts" - k8sutils "github.com/kong/gateway-operator/pkg/utils/kubernetes" - k8sresources "github.com/kong/gateway-operator/pkg/utils/kubernetes/resources" -) - -const ( - defaultWebhookCertDir = "/tmp/k8s-webhook-server/serving-certs" - - defaultsecretPollInterval = 2 * time.Second - defaultsecretPollTimeout = 60 * time.Second ) -type webhookManager struct { - client client.Client - mgr ctrl.Manager - logger logr.Logger - cfg *Config - server webhook.Server - - setupControllers SetupControllersFunc - admissionRequestHandler AdmissionRequestHandlerFunc -} - // AdmissionRequestHandlerFunc is a function that returns an implementation of admission.RequestHandler, // (validation webhook) it's passed to Run function and called later. type AdmissionRequestHandlerFunc func(c client.Client, l logr.Logger) *admission.RequestHandler - -// PrepareWebhookServerWithControllers creates a webhook server and adds it to the controller manager. -// Because the controller runtime 0.14.x doed not allow adding readiness probe after manager starts, -// We need to create webhook server and add it to manager before manager starts. -// https://github.com/Kong/gateway-operator/issues/611 -func (m *webhookManager) PrepareWebhookServerWithControllers( - ctx context.Context, - setupControllers SetupControllersFunc, - newAdmissionRequestHandler AdmissionRequestHandlerFunc, -) error { - if m.cfg.ControllerNamespace == "" { - return errors.New("controllerNamespace must be set") - } - if m.cfg.WebhookCertDir == "" { - return errors.New("webhookCertDir must be set") - } - if m.cfg.WebhookPort == 0 { - return errors.New("webhookPort must be set") - } - m.setupControllers = setupControllers - - // create and start a new webhook server - hookServer := webhook.NewServer(webhook.Options{ - CertDir: m.cfg.WebhookCertDir, - Port: m.cfg.WebhookPort, - }) - - // add readyz check for checking connection to webhook server - // to make the controller to be marked as ready after webhook started. - if err := m.mgr.AddReadyzCheck("readyz", hookServer.StartedChecker()); err != nil { - return fmt.Errorf("failed to add readiness probe for webhook: %w", err) - } - - m.server = hookServer - m.admissionRequestHandler = newAdmissionRequestHandler - - return nil -} - -// Start starts the webhook server and the controllers. -func (m *webhookManager) Start(ctx context.Context) error { - m.logger.Info("starting webhook manager") - - // create the webhook resources (if they already exist, it is no-op) - if err := m.createWebhookResources(ctx); err != nil { - return err - } - - certSecret := &corev1.Secret{} - // check if the certificate secret already exists - if err := m.client.Get(ctx, types.NamespacedName{Namespace: m.cfg.ControllerNamespace, Name: consts.WebhookCertificateConfigSecretName}, certSecret); err != nil { - if !k8serrors.IsNotFound(err) { - return err - } - // no certificate secret found, create all the resources needed to produce it (if they already exist, it is no-op) - if err := m.createCertificateConfigResources(ctx); err != nil { - return err - } - - // wait for the certificate to be created - certSecret, err = m.waitForWebhookCertificate(ctx, defaultsecretPollTimeout, defaultsecretPollInterval) - if err != nil { - return err - } - } - - // write the webhook certificate files on the filesystem - { - p := path.Join(m.cfg.WebhookCertDir, caCertFilename) - if err := os.WriteFile(p, certSecret.Data[consts.CAFieldSecret], os.ModePerm); err != nil { //nolint:gosec - return fmt.Errorf("failed writing CA to %s: %w", p, err) - } - } - { - p := path.Join(m.cfg.WebhookCertDir, tlsCertFilename) - if err := os.WriteFile(p, certSecret.Data[consts.CertFieldSecret], os.ModePerm); err != nil { //nolint:gosec - return fmt.Errorf("failed writing certificate to %s: %w", p, err) - } - } - { - p := path.Join(m.cfg.WebhookCertDir, tlsKeyFilename) - if err := os.WriteFile(p, certSecret.Data[consts.KeyFieldSecret], os.ModePerm); err != nil { //nolint:gosec - return fmt.Errorf("failed writing key to %s: %w", p, err) - } - } - - handler := m.admissionRequestHandler(m.mgr.GetClient(), m.logger) - m.server.Register("/validate", handler) - if err := m.mgr.Add(m.server); err != nil { - return err - } - - // load the Gateway API controllers and start them only after the webhook is in place - controllers, err := m.setupControllers(m.mgr, m.cfg) - if err != nil { - return err - } - - for _, c := range controllers { - if err := c.MaybeSetupWithManager(ctx, m.mgr); err != nil { - return fmt.Errorf("unable to create controller %q: %w", c.Name(), err) - } - } - - return nil -} - -// createCertificateConfigResources create all the resources needed by the CertificateConfig jobs -func (m *webhookManager) createCertificateConfigResources(ctx context.Context) error { - // create the certificateConfig ServiceAccount - serviceAccount := k8sresources.GenerateNewServiceAccountForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookCertificateConfigName, consts.WebhookCertificateConfigLabelvalue) - if err := m.client.Create(ctx, serviceAccount); err != nil { - if !k8serrors.IsAlreadyExists(err) { - return err - } - } - - // create the certificateConfig ClusterRole - clusterRole := k8sresources.GenerateNewClusterRoleForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookCertificateConfigName, consts.WebhookCertificateConfigLabelvalue) - if err := m.setNamespaceAsOwner(ctx, clusterRole); err != nil { - return err - } - if err := m.client.Create(ctx, clusterRole); err != nil { - if !k8serrors.IsAlreadyExists(err) { - return err - } - } - - // create the certificateConfig ClusterRoleBinding - clusterRoleBinding := k8sresources.GenerateNewClusterRoleBindingForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookCertificateConfigName, consts.WebhookCertificateConfigLabelvalue) - if err := m.setNamespaceAsOwner(ctx, clusterRoleBinding); err != nil { - return err - } - if err := m.client.Create(ctx, clusterRoleBinding); err != nil { - if !k8serrors.IsAlreadyExists(err) { - return err - } - } - - // create the certificateConfig Role - role := k8sresources.GenerateNewRoleForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookCertificateConfigName, consts.WebhookCertificateConfigLabelvalue) - if err := m.client.Create(ctx, role); err != nil { - if !k8serrors.IsAlreadyExists(err) { - return err - } - } - - // create the certificateConfig RoleBinding - roleBinding := k8sresources.GenerateNewRoleBindingForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookCertificateConfigName, consts.WebhookCertificateConfigLabelvalue) - if err := m.client.Create(ctx, roleBinding); err != nil { - if !k8serrors.IsAlreadyExists(err) { - return err - } - } - - // create the certificateConfig jobs - if err := m.createCertificateConfigJobs(ctx); err != nil { - return err - } - - return nil -} - -func (m *webhookManager) createWebhookResources(ctx context.Context) error { - // create the operator ValidatingWebhookConfiguration - validatingWebhookConfiguration := k8sresources. - NewValidatingWebhookConfigurationBuilder(consts.WebhookName). - WithClientConfigKubernetesService( - types.NamespacedName{ - Name: consts.WebhookServiceName, - Namespace: m.cfg.ControllerNamespace, - }, - ). - Build() - if err := m.setNamespaceAsOwner(ctx, validatingWebhookConfiguration); err != nil { - return err - } - if err := m.client.Create(ctx, validatingWebhookConfiguration); err != nil { - if !k8serrors.IsAlreadyExists(err) { - return err - } - } - - // create the Service needed to expose the operator Webhook - webhookService := k8sresources.GenerateNewServiceForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookServiceName) - if err := m.client.Create(ctx, webhookService); err != nil { - if !k8serrors.IsAlreadyExists(err) { - return err - } - } - - return nil -} - -func (m *webhookManager) createCertificateConfigJobs(ctx context.Context) error { - jobCertificateConfigBaseImage := m.cfg.WebhookCertificateConfigBaseImage - jobCertificateConfigShellImage := m.cfg.WebhookCertificateConfigShellImage - if relatedJobImage := os.Getenv("RELATED_IMAGE_CERTIFICATE_CONFIG"); relatedJobImage != "" { - // RELATED_IMAGE_CERTIFICATE_CONFIG is set by the operator-sdk when building the operator bundle. - // https://github.com/Kong/gateway-operator-archive/issues/261 - jobCertificateConfigBaseImage = relatedJobImage - } - job := k8sresources.GenerateNewWebhookCertificateConfigJob( - m.cfg.ControllerNamespace, - consts.WebhookCertificateConfigName, - jobCertificateConfigBaseImage, - jobCertificateConfigShellImage, - consts.WebhookCertificateConfigSecretName, - consts.WebhookName, - ) - - if err := m.client.Create(ctx, job); err != nil { - return err - } - - return nil -} - -func (m *webhookManager) cleanup(ctx context.Context) error { - m.logger.Info("cleaning up webhook resources") - - if err := m.cleanupCertificateConfigResources(ctx); err != nil { - return err - } - - return m.cleanupWebhookResources(ctx) -} - -func (m *webhookManager) cleanupWebhookResources(ctx context.Context) error { - // delete the operator ValidatingWebhookConfiguration - validatingWebhookConfiguration := k8sresources. - NewValidatingWebhookConfigurationBuilder(consts.WebhookName). - WithClientConfigKubernetesService( - types.NamespacedName{ - Name: consts.WebhookServiceName, - Namespace: m.cfg.ControllerNamespace, - }, - ). - Build() - if err := m.client.Delete(ctx, validatingWebhookConfiguration); client.IgnoreNotFound(err) != nil { - return err - } - - // delete the Service needed to expose the operator Webhook - webhookService := k8sresources.GenerateNewServiceForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookServiceName) - if err := m.client.Delete(ctx, webhookService); client.IgnoreNotFound(err) != nil { - return err - } - - certSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: consts.WebhookCertificateConfigSecretName, - Namespace: m.cfg.ControllerNamespace, - }, - } - if err := m.client.Delete(ctx, certSecret); client.IgnoreNotFound(err) != nil { - return err - } - - return nil -} - -func (m *webhookManager) cleanupCertificateConfigResources(ctx context.Context) error { - // delete the certificateConfig ServiceAccount - serviceAccount := k8sresources.GenerateNewServiceAccountForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookCertificateConfigName, consts.WebhookCertificateConfigLabelvalue) - if err := m.client.Delete(ctx, serviceAccount); client.IgnoreNotFound(err) != nil { - return err - } - - // delete the certificateConfig ClusterRole - clusterRole := k8sresources.GenerateNewClusterRoleForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookCertificateConfigName, consts.WebhookCertificateConfigLabelvalue) - if err := m.client.Delete(ctx, clusterRole); client.IgnoreNotFound(err) != nil { - return err - } - - // delete the certificateConfig ClusterRoleBinding - clusterRoleBinding := k8sresources.GenerateNewClusterRoleBindingForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookCertificateConfigName, consts.WebhookCertificateConfigLabelvalue) - if err := m.client.Delete(ctx, clusterRoleBinding); client.IgnoreNotFound(err) != nil { - return err - } - - // delete the certificateConfig Role - role := k8sresources.GenerateNewRoleForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookCertificateConfigName, consts.WebhookCertificateConfigLabelvalue) - if err := m.client.Delete(ctx, role); client.IgnoreNotFound(err) != nil { - return err - } - - // delete the certificateConfig RoleBinding - roleBinding := k8sresources.GenerateNewRoleBindingForCertificateConfig(m.cfg.ControllerNamespace, consts.WebhookCertificateConfigName, consts.WebhookCertificateConfigLabelvalue) - if err := m.client.Delete(ctx, roleBinding); client.IgnoreNotFound(err) != nil { - return err - } - - return nil -} - -// waitForWebhookCertificate polls the API server at a specific interval until the webhook certificate -// secret is created. If the timer expires, it returns an error. Otherwise, the Secret is returned. -func (m *webhookManager) waitForWebhookCertificate(ctx context.Context, pollTimeout time.Duration, pollInterval time.Duration) (*corev1.Secret, error) { - ticker := time.NewTicker(pollInterval) - quit := make(chan struct{}) - errChan := make(chan error, 1) - certificateSecret := &corev1.Secret{} - wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - for { - select { - case <-ticker.C: - err := m.client.Get(ctx, types.NamespacedName{Namespace: m.cfg.ControllerNamespace, Name: consts.WebhookCertificateConfigSecretName}, certificateSecret) - if err != nil { - if !k8serrors.IsNotFound(err) { - errChan <- err - return - } - continue - } - return - case <-quit: - ticker.Stop() - errChan <- fmt.Errorf("timeout for creating webhook certificate expired") - return - } - } - }() - time.AfterFunc(pollTimeout, func() { - close(quit) - }) - wg.Wait() - ticker.Stop() - select { - case err := <-errChan: - return nil, err - default: - return certificateSecret, nil - } -} - -// setNamespaceAsOwner sets the namespace as ownerReference for the given objects. -// This is needed by the operator-related cluster-wide resources that have to be -// collected when the namespace in which the operator lives is deleted -// (e.g., when 'kubectl kustomize config/default | kubectl delete -f -' is executed). -func (m *webhookManager) setNamespaceAsOwner(ctx context.Context, object client.Object) error { - namespace := &corev1.Namespace{} - if err := m.client.Get(ctx, types.NamespacedName{Name: m.cfg.ControllerNamespace}, namespace); err != nil { - return err - } - k8sutils.SetOwnerForObject(object, namespace) - return nil -} diff --git a/modules/manager/webhook_test.go b/modules/manager/webhook_test.go deleted file mode 100644 index 6aea04da0..000000000 --- a/modules/manager/webhook_test.go +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright 2022 Kong Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package manager - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - fakectrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "github.com/kong/gateway-operator/pkg/consts" -) - -func TestWaitForWebhookCertificate(t *testing.T) { - t.Parallel() - - testScheme := runtime.NewScheme() - require.NoError(t, clientgoscheme.AddToScheme(testScheme)) - - testCases := []struct { - name string - pollTimeout time.Duration - pollInterval time.Duration - createAfter time.Duration - namespace string - secret *corev1.Secret - err error - }{ - { - name: "secret created before the timer expires", - pollTimeout: 4 * time.Second, - pollInterval: 10 * time.Millisecond, - createAfter: 500 * time.Millisecond, - namespace: "test", - secret: &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: consts.WebhookCertificateConfigSecretName, - Namespace: "test", - }, - }, - err: nil, - }, - { - name: "secret not created before the timer expires", - pollTimeout: 500 * time.Millisecond, - pollInterval: 10 * time.Millisecond, - namespace: "test", - err: fmt.Errorf("timeout for creating webhook certificate expired"), - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - - ctx := context.Background() - - fakeClient := fakectrlruntimeclient. - NewClientBuilder(). - WithScheme(testScheme). - Build() - - webhookMgr := webhookManager{ - client: fakeClient, - cfg: &Config{ - ControllerNamespace: "test", - }, - } - - if tc.createAfter != 0 { - time.AfterFunc(tc.createAfter, func() { - require.NoError(t, fakeClient.Create(ctx, tc.secret)) - }) - } - _, err := webhookMgr.waitForWebhookCertificate(ctx, tc.pollTimeout, tc.pollInterval) - if tc.err != nil { - require.EqualError(t, err, tc.err.Error(), tc.name) - } else { - require.NoError(t, err, tc.name) - } - }) - } -} diff --git a/pkg/utils/kubernetes/resources/clusterrolebindings.go b/pkg/utils/kubernetes/resources/clusterrolebindings.go index d92e8e226..e67e4ba98 100644 --- a/pkg/utils/kubernetes/resources/clusterrolebindings.go +++ b/pkg/utils/kubernetes/resources/clusterrolebindings.go @@ -42,31 +42,6 @@ func GenerateNewClusterRoleBindingForControlPlane(namespace, controlplaneName, s return crb } -// GenerateNewClusterRoleBindingForCertificateConfig is a helper to generate a ClusterRoleBinding -// to be used by the certificateConfig jobs -func GenerateNewClusterRoleBindingForCertificateConfig(namespace, name, labelValue string) *rbacv1.ClusterRoleBinding { - return &rbacv1.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{ - "app": labelValue, - }, - }, - RoleRef: rbacv1.RoleRef{ - APIGroup: "rbac.authorization.k8s.io", - Kind: "ClusterRole", - Name: name, - }, - Subjects: []rbacv1.Subject{ - { - Kind: "ServiceAccount", - Name: name, - Namespace: namespace, - }, - }, - } -} - // CompareClusterRoleName compares RoleRef in ClusterRoleBinding with given cluster role name. // It returns true if the referenced role is the cluster role with the given name. func CompareClusterRoleName(existingClusterRoleBinding *rbacv1.ClusterRoleBinding, clusterRoleName string) bool { diff --git a/pkg/utils/kubernetes/resources/clusterroles.go b/pkg/utils/kubernetes/resources/clusterroles.go deleted file mode 100644 index 27e9400cc..000000000 --- a/pkg/utils/kubernetes/resources/clusterroles.go +++ /dev/null @@ -1,36 +0,0 @@ -package resources - -import ( - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// ----------------------------------------------------------------------------- -// ClusterRole generator helpers -// ----------------------------------------------------------------------------- - -// GenerateNewClusterRoleForCertificateConfig is a helper to generate a ClusterRole -// to be used by the certificateConfig jobs -func GenerateNewClusterRoleForCertificateConfig(namespace, name, labelValue string) *rbacv1.ClusterRole { - return &rbacv1.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{ - "app": labelValue, - }, - }, - Rules: []rbacv1.PolicyRule{ - { - APIGroups: []string{ - "admissionregistration.k8s.io", - }, - Resources: []string{ - "validatingwebhookconfigurations", - }, - Verbs: []string{ - "get", "update", - }, - }, - }, - } -} diff --git a/pkg/utils/kubernetes/resources/jobs.go b/pkg/utils/kubernetes/resources/jobs.go deleted file mode 100644 index 5fe817cd9..000000000 --- a/pkg/utils/kubernetes/resources/jobs.go +++ /dev/null @@ -1,95 +0,0 @@ -package resources - -import ( - "fmt" - - "github.com/samber/lo" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/kong/gateway-operator/pkg/consts" -) - -// ----------------------------------------------------------------------------- -// Jobs generators -// ----------------------------------------------------------------------------- - -// GenerateNewWebhookCertificateConfigJob generates the create and patch jobs for the certificateConfig -func GenerateNewWebhookCertificateConfigJob(namespace, - serviceAccountName, - baseImageName, - shellImageName, - secretName, - webhookName string, -) *batchv1.Job { - return newWebhookCertificateConfigJobCommon(namespace, serviceAccountName, func(j *batchv1.Job) { - j.GenerateName = fmt.Sprintf("%s-", consts.WebhookCertificateConfigName) - - // We rely on the order of execution for creating and patching the certificates - // hence we use the init containers for that purpose. - // The "done" container is only present for the purposes of not breaking - // the spec: Jobs require at least one container to be present in the spec. - - j.Spec.Template.Spec.InitContainers = []corev1.Container{ - { - Name: "create", - Args: []string{ - "create", - fmt.Sprintf("--host=gateway-operator-validating-webhook,gateway-operator-validating-webhook.%s.svc", namespace), - fmt.Sprintf("--namespace=%s", namespace), - fmt.Sprintf("--secret-name=%s", secretName), - }, - Image: baseImageName, - ImagePullPolicy: corev1.PullIfNotPresent, - }, - { - Name: "patch", - Args: []string{ - "patch", - fmt.Sprintf("--webhook-name=%s", webhookName), - fmt.Sprintf("--namespace=%s", namespace), - "--patch-mutating=false", - "--patch-validating=true", - fmt.Sprintf("--secret-name=%s", secretName), - "--patch-failure-policy=Fail", - }, - Image: baseImageName, - ImagePullPolicy: corev1.PullIfNotPresent, - }, - } - - j.Spec.Template.Spec.Containers = []corev1.Container{ - { - Name: "done", - Image: shellImageName, - Args: []string{"echo", "done"}, - ImagePullPolicy: corev1.PullIfNotPresent, - }, - } - }) -} - -func newWebhookCertificateConfigJobCommon(namespace, serviceAccountName string, options ...func(*batchv1.Job)) *batchv1.Job { - job := &batchv1.Job{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace, - }, - Spec: batchv1.JobSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyOnFailure, - ServiceAccountName: serviceAccountName, - SecurityContext: &corev1.PodSecurityContext{ - RunAsNonRoot: lo.ToPtr(true), - }, - }, - }, - }, - } - - for _, o := range options { - o(job) - } - return job -} diff --git a/pkg/utils/kubernetes/resources/rolebindings.go b/pkg/utils/kubernetes/resources/rolebindings.go deleted file mode 100644 index 1f65e39f5..000000000 --- a/pkg/utils/kubernetes/resources/rolebindings.go +++ /dev/null @@ -1,36 +0,0 @@ -package resources - -import ( - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// ----------------------------------------------------------------------------- -// ClusterRoleBinding generators -// ----------------------------------------------------------------------------- - -// GenerateNewRoleBindingForCertificateConfig is a helper to generate a RoleBinding -// to be used by the certificateConfig jobs -func GenerateNewRoleBindingForCertificateConfig(namespace, name, labelValue string) *rbacv1.RoleBinding { - return &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Labels: map[string]string{ - "app": labelValue, - }, - }, - RoleRef: rbacv1.RoleRef{ - APIGroup: "rbac.authorization.k8s.io", - Kind: "Role", - Name: name, - }, - Subjects: []rbacv1.Subject{ - { - Kind: "ServiceAccount", - Name: name, - Namespace: namespace, - }, - }, - } -} diff --git a/pkg/utils/kubernetes/resources/roles.go b/pkg/utils/kubernetes/resources/roles.go deleted file mode 100644 index 703f7fb51..000000000 --- a/pkg/utils/kubernetes/resources/roles.go +++ /dev/null @@ -1,37 +0,0 @@ -package resources - -import ( - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// ----------------------------------------------------------------------------- -// Role generator helpers -// ----------------------------------------------------------------------------- - -// GenerateNewRoleForCertificateConfig is a helper to generate a Role -// to be used by the certificateConfig jobs -func GenerateNewRoleForCertificateConfig(namespace, name, labelValue string) *rbacv1.Role { - return &rbacv1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Labels: map[string]string{ - "app": labelValue, - }, - }, - Rules: []rbacv1.PolicyRule{ - { - APIGroups: []string{ - "", - }, - Resources: []string{ - "secrets", - }, - Verbs: []string{ - "get", "create", - }, - }, - }, - } -} diff --git a/pkg/utils/kubernetes/resources/serviceaccounts.go b/pkg/utils/kubernetes/resources/serviceaccounts.go index a2a5b2fbc..aac53e04f 100644 --- a/pkg/utils/kubernetes/resources/serviceaccounts.go +++ b/pkg/utils/kubernetes/resources/serviceaccounts.go @@ -30,17 +30,3 @@ func GenerateNewServiceAccountForControlPlane(namespace, controlplaneName string return sa } - -// GenerateNewServiceAccountForCertificateConfig is a helper to generate a ServiceAccount -// to be used by the certificateConfig jobs -func GenerateNewServiceAccountForCertificateConfig(namespace, name, labelValue string) *corev1.ServiceAccount { - return &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Labels: map[string]string{ - "app": labelValue, - }, - }, - } -} diff --git a/pkg/utils/kubernetes/resources/services.go b/pkg/utils/kubernetes/resources/services.go index 247e82551..f1b1e7b75 100644 --- a/pkg/utils/kubernetes/resources/services.go +++ b/pkg/utils/kubernetes/resources/services.go @@ -21,30 +21,6 @@ import ( // Service generators // ----------------------------------------------------------------------------- -// GenerateNewServiceForCertificateConfig is a helper to generate a service -// to expose the operator webhook -func GenerateNewServiceForCertificateConfig(namespace, name string) *corev1.Service { - return &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "webhook", - Port: 443, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt(9443), - }, - }, - Selector: map[string]string{ - "control-plane": "controller-manager", - }, - }, - } -} - // GenerateNewIngressServiceForDataPlane is a helper to generate the dataplane ingress service func GenerateNewIngressServiceForDataPlane(dataplane *operatorv1beta1.DataPlane, opts ...ServiceOpt) (*corev1.Service, error) { svc := &corev1.Service{ diff --git a/pkg/utils/kubernetes/resources/validatingwebhookconfiguration.go b/pkg/utils/kubernetes/resources/validatingwebhookconfiguration.go deleted file mode 100644 index 89348335f..000000000 --- a/pkg/utils/kubernetes/resources/validatingwebhookconfiguration.go +++ /dev/null @@ -1,107 +0,0 @@ -package resources - -import ( - "github.com/samber/lo" - admissionregistrationv1 "k8s.io/api/admissionregistration/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - k8stypes "k8s.io/apimachinery/pkg/types" -) - -// ----------------------------------------------------------------------------- -// ValidatingWebhookConfiguration generators -// ----------------------------------------------------------------------------- - -// ValidatingWebhookConfigurationBuilder is a helper to generate a ValidatingWebhookConfiguration. -type ValidatingWebhookConfigurationBuilder struct { - vwc *admissionregistrationv1.ValidatingWebhookConfiguration -} - -// NewValidatingWebhookConfigurationBuilder returns builder for ValidatingWebhookConfiguration. -// Check method to learn more about the default values and available options. -func NewValidatingWebhookConfigurationBuilder(webhookName string) *ValidatingWebhookConfigurationBuilder { - namespacedScope := admissionregistrationv1.NamespacedScope - return &ValidatingWebhookConfigurationBuilder{ - vwc: &admissionregistrationv1.ValidatingWebhookConfiguration{ - ObjectMeta: metav1.ObjectMeta{ - Name: webhookName, - }, - Webhooks: []admissionregistrationv1.ValidatingWebhook{ - { - Name: webhookName, - Rules: []admissionregistrationv1.RuleWithOperations{ - { - Rule: admissionregistrationv1.Rule{ - APIGroups: []string{"gateway-operator.konghq.com"}, - APIVersions: []string{"v1beta1"}, - Resources: []string{"dataplanes"}, - Scope: &namespacedScope, - }, - Operations: []admissionregistrationv1.OperationType{ - admissionregistrationv1.Create, - admissionregistrationv1.Update, - }, - }, - { - Rule: admissionregistrationv1.Rule{ - APIGroups: []string{"gateway-operator.konghq.com"}, - APIVersions: []string{"v1beta1"}, - Resources: []string{"controlplanes"}, - Scope: &namespacedScope, - }, - Operations: []admissionregistrationv1.OperationType{ - admissionregistrationv1.Create, - admissionregistrationv1.Update, - }, - }, - }, - AdmissionReviewVersions: []string{"v1", "v1beta1"}, - SideEffects: lo.ToPtr(admissionregistrationv1.SideEffectClassNone), - TimeoutSeconds: lo.ToPtr(int32(5)), - }, - }, - }, - } -} - -// WithClientConfigKubernetesService sets the client config to use a Kubernetes service. -func (v *ValidatingWebhookConfigurationBuilder) WithClientConfigKubernetesService(svc k8stypes.NamespacedName) *ValidatingWebhookConfigurationBuilder { - for i := range v.vwc.Webhooks { - v.vwc.Webhooks[i].ClientConfig.Service = &admissionregistrationv1.ServiceReference{ - Namespace: svc.Namespace, - Name: svc.Name, - Path: lo.ToPtr("/validate"), - } - } - return v -} - -// WithClientConfigURL sets the client config to use a URL. -func (v *ValidatingWebhookConfigurationBuilder) WithClientConfigURL(url string) *ValidatingWebhookConfigurationBuilder { - for i := range v.vwc.Webhooks { - v.vwc.Webhooks[i].ClientConfig.URL = &url - } - return v -} - -// WithCABundle sets the CA bundle. -func (v *ValidatingWebhookConfigurationBuilder) WithCABundle(caBundle []byte) *ValidatingWebhookConfigurationBuilder { - for i := range v.vwc.Webhooks { - v.vwc.Webhooks[i].ClientConfig.CABundle = caBundle - } - return v -} - -// WithScopeAll sets the scope for all namespaces (default for the builder is namespace code). -func (v *ValidatingWebhookConfigurationBuilder) WithScopeAllNamespaces() *ValidatingWebhookConfigurationBuilder { - for i := range v.vwc.Webhooks { - for j := range v.vwc.Webhooks[i].Rules { - v.vwc.Webhooks[i].Rules[j].Scope = lo.ToPtr(admissionregistrationv1.AllScopes) - } - } - return v -} - -// Build returns the ValidatingWebhookConfiguration. -func (v *ValidatingWebhookConfigurationBuilder) Build() *admissionregistrationv1.ValidatingWebhookConfiguration { - return v.vwc -} diff --git a/test/conformance/suite_test.go b/test/conformance/suite_test.go index 684689af9..ba1d75dd0 100644 --- a/test/conformance/suite_test.go +++ b/test/conformance/suite_test.go @@ -171,7 +171,6 @@ func startControllerManager(metadata metadata.Info) <-chan struct{} { cfg.GatewayControllerEnabled = true cfg.ControlPlaneControllerEnabled = true cfg.DataPlaneControllerEnabled = true - cfg.ValidatingWebhookEnabled = false cfg.AnonymousReports = false cfg.ClusterCAKeyType = mgrconfig.ECDSA cfg.GatewayAPIExperimentalEnabled = true diff --git a/test/integration/suite.go b/test/integration/suite.go index efd17334d..68db16eb6 100644 --- a/test/integration/suite.go +++ b/test/integration/suite.go @@ -2,16 +2,12 @@ package integration import ( "context" - "crypto/tls" - "crypto/x509" "fmt" - "net/http" "os" "path" "runtime/debug" "strings" "testing" - "time" "github.com/kong/kubernetes-testing-framework/pkg/clusters" "github.com/kong/kubernetes-testing-framework/pkg/clusters/addons/certmanager" @@ -27,7 +23,6 @@ import ( testutils "github.com/kong/gateway-operator/pkg/utils/test" "github.com/kong/gateway-operator/test" "github.com/kong/gateway-operator/test/helpers" - "github.com/kong/gateway-operator/test/helpers/certificate" ) // ----------------------------------------------------------------------------- @@ -38,10 +33,7 @@ var ( existingCluster = os.Getenv("KONG_TEST_CLUSTER") controllerManagerOut = os.Getenv("KONG_CONTROLLER_OUT") skipClusterCleanup = strings.ToLower(os.Getenv("KONG_TEST_CLUSTER_PERSIST")) == "true" - webhookEnabled = strings.ToLower(os.Getenv("WEBHOOK_ENABLED")) == "true" - webhookServerIP = os.Getenv("GATEWAY_OPERATOR_WEBHOOK_IP") bluegreenController = strings.ToLower(os.Getenv("GATEWAY_OPERATOR_BLUEGREEN_CONTROLLER")) == "true" - webhookServerPort = 9443 ) // ----------------------------------------------------------------------------- @@ -161,12 +153,6 @@ func TestMain( fmt.Println("INFO: deploying CRDs to test cluster") exitOnErr(testutils.DeployCRDs(GetCtx(), path.Join(configPath, "/crd"), GetClients().OperatorClient, GetEnv().Cluster())) - var ca, cert, key []byte // Certificate generated for tests used by webhook. - if webhookEnabled { - ca, cert, key, err = prepareWebhook() - exitOnErr(err) - } - fmt.Println("INFO: starting the operator's controller manager") // Spawn the controller manager based on passed config in // a separate goroutine and report whether that succeeded. @@ -180,11 +166,6 @@ func TestMain( exitOnErr(err) exitOnErr(testutils.BuildMTLSCredentials(GetCtx(), GetClients().K8sClient, httpClient)) - // Wait for webhook server in controller to be ready after controller started. - if webhookEnabled { - exitOnErr(waitForWebhook(GetCtx(), webhookServerIP, webhookServerPort, ca, cert, key)) - } - fmt.Println("INFO: environment is ready, starting tests") code = m.Run() @@ -222,7 +203,6 @@ func DefaultControllerConfigForTests() manager.Config { cfg.DataPlaneBlueGreenControllerEnabled = bluegreenController cfg.KongPluginInstallationControllerEnabled = true cfg.AIGatewayControllerEnabled = true - cfg.ValidatingWebhookEnabled = webhookEnabled cfg.AnonymousReports = false cfg.KonnectControllersEnabled = true cfg.ClusterCAKeyType = mgrconfig.ECDSA @@ -238,67 +218,3 @@ func DefaultControllerConfigForTests() manager.Config { } return cfg } - -// prepareWebhook prepares for running webhook if we are going to run webhook tests. includes: -// - creating self-signed TLS certificates for webhook server -// - creating validating webhook resource in test cluster. -func prepareWebhook() (ca, cert, key []byte, err error) { - // Get IP for generating certificate and for clients to access. - if webhookServerIP == "" { - webhookServerIP = helpers.GetAdmissionWebhookListenHost() - } - // Generate certificates for webhooks. - // It must run before we start controller manager to start webhook server in controller. - cert, key = certificate.MustGenerateSelfSignedCertPEMFormat(certificate.WithIPAdresses(webhookServerIP)) - ca = cert // Self-signed certificate is its own CA. - - // Create webhook resources in k8s. - fmt.Println("INFO: creating a validating webhook and waiting for it to start") - if err = CreateValidatingWebhook( - GetCtx(), GetClients().K8sClient, - fmt.Sprintf("https://%s:%d/validate", webhookServerIP, webhookServerPort), - ca, cert, key, - ); err != nil { - return nil, nil, nil, err - } - return ca, cert, key, nil -} - -// waitForWebhook waits for webhook server being able to be accessed by HTTPS. -func waitForWebhook(ctx context.Context, ip string, port int, ca, cert, key []byte) error { - certFull, err := tls.X509KeyPair(cert, key) - if err != nil { - return err - } - // Setup HTTPS client. - caCertPool := x509.NewCertPool() - if ok := caCertPool.AppendCertsFromPEM(ca); !ok { - return fmt.Errorf("failed to append CA certificate to pool") - } - client := http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - MinVersion: tls.VersionTLS13, - Certificates: []tls.Certificate{certFull}, - RootCAs: caCertPool, - }, - }, - } - for ready := false; !ready; { - select { - case <-ctx.Done(): - return ctx.Err() - default: - // Any kind of response from /validate path is considered OK. - resp, err := client.Get(fmt.Sprintf("https://%s:%d/validate", ip, port)) - if err == nil { - _ = resp.Body.Close() - ready = true - } - } - if !ready { - time.Sleep(time.Second) - } - } - return nil -} diff --git a/test/integration/test_gateway.go b/test/integration/test_gateway.go index 9cb7c4550..b152a12d3 100644 --- a/test/integration/test_gateway.go +++ b/test/integration/test_gateway.go @@ -12,7 +12,6 @@ import ( "github.com/samber/lo" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - admissionregistrationv1 "k8s.io/api/admissionregistration/v1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" @@ -835,104 +834,6 @@ func TestGatewayDataPlaneNetworkPolicy(t *testing.T) { }) } -func TestGatewayProvisionDataPlaneFail(t *testing.T) { - t.Parallel() - if !webhookEnabled { - t.Skip("Skipping because webhook is not enabled") - } - - namespace, cleaner := helpers.SetupTestEnv(t, GetCtx(), GetEnv()) - - t.Logf("creating another service with no endpoints for wrong webhooks") - serviceClient := env.Cluster().Client().CoreV1().Services(namespace.Name) - service := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace.Name, - Name: "fake-webhook", - }, - Spec: corev1.ServiceSpec{ - Selector: map[string]string{ - "app": "fake", - }, - Ports: []corev1.ServicePort{ - {Port: int32(443), TargetPort: intstr.FromInt(8443)}, - }, - }, - } - _, err := serviceClient.Create(ctx, service, metav1.CreateOptions{}) - require.NoError(t, err) - cleaner.Add(service) - - t.Log("creating a wrong webhook for DataPlane with a Service having no endpoints") - webhookClient := env.Cluster().Client().AdmissionregistrationV1().ValidatingWebhookConfigurations() - wrongWebhook := &admissionregistrationv1.ValidatingWebhookConfiguration{ - ObjectMeta: metav1.ObjectMeta{ - Name: "gateway-operator-wrong-validators.test.konghq.com", - }, - Webhooks: []admissionregistrationv1.ValidatingWebhook{ - { - Name: "wrong-dataplane-webhook.test.konghq.com", - ClientConfig: admissionregistrationv1.WebhookClientConfig{ - Service: &admissionregistrationv1.ServiceReference{ - Namespace: namespace.Name, - Name: "fake-webhook", - }, - }, - Rules: []admissionregistrationv1.RuleWithOperations{ - { - Rule: admissionregistrationv1.Rule{ - APIGroups: []string{"gateway-operator.konghq.com"}, - APIVersions: []string{"v1beta1"}, - Resources: []string{"dataplanes"}, - Scope: lo.ToPtr(admissionregistrationv1.NamespacedScope), - }, - Operations: []admissionregistrationv1.OperationType{ - admissionregistrationv1.Create, - admissionregistrationv1.Update, - }, - }, - }, - AdmissionReviewVersions: []string{"v1", "v1beta1"}, - SideEffects: lo.ToPtr(admissionregistrationv1.SideEffectClassNone), - TimeoutSeconds: lo.ToPtr(int32(1)), - }, - }, - } - _, err = webhookClient.Create(ctx, wrongWebhook, metav1.CreateOptions{}) - require.NoError(t, err) - cleaner.Add(wrongWebhook) - - t.Log("creating a Gateway and verify that it does not get Programmed") - t.Log("deploying a GatewayClass resource") - gatewayClass := helpers.MustGenerateGatewayClass(t) - gatewayClass, err = GetClients().GatewayClient.GatewayV1().GatewayClasses().Create(GetCtx(), gatewayClass, metav1.CreateOptions{}) - require.NoError(t, err) - cleaner.Add(gatewayClass) - - t.Log("deploying Gateway resource") - gatewayNN := types.NamespacedName{ - Name: uuid.NewString(), - Namespace: namespace.Name, - } - gateway := helpers.GenerateGateway(gatewayNN, gatewayClass) - gateway, err = GetClients().GatewayClient.GatewayV1().Gateways(namespace.Name).Create(GetCtx(), gateway, metav1.CreateOptions{}) - require.NoError(t, err) - cleaner.Add(gateway) - - t.Log("verifying Gateway gets marked as Scheduled") - require.Eventually(t, testutils.GatewayIsAccepted(t, GetCtx(), gatewayNN, clients), testutils.GatewaySchedulingTimeLimit, time.Second) - - t.Log("verifying Gateway does not get marked as Programmed") - require.Never(t, testutils.GatewayIsProgrammed(t, GetCtx(), gatewayNN, clients), testutils.GatewayReadyTimeLimit, time.Second) - - t.Log("deleting the wrong webhook for dataplane") - err = webhookClient.Delete(ctx, wrongWebhook.Name, metav1.DeleteOptions{}) - require.NoError(t, err) - - t.Log("verifying Gateway gets marked as Programmed") - require.Eventually(t, testutils.GatewayIsProgrammed(t, GetCtx(), gatewayNN, clients), testutils.GatewayReadyTimeLimit, time.Second) -} - func setGatewayConfigurationEnvProxyPort(t *testing.T, gatewayConfiguration *operatorv1beta1.GatewayConfiguration, proxyPort int, proxySSLPort int) { t.Helper() diff --git a/test/integration/test_validating.go b/test/integration/test_validating.go index e60b27fa2..3641442b7 100644 --- a/test/integration/test_validating.go +++ b/test/integration/test_validating.go @@ -20,16 +20,10 @@ func TestDataPlaneValidation(t *testing.T) { t.Parallel() namespace, _ := helpers.SetupTestEnv(t, GetCtx(), GetEnv()) - if webhookEnabled { - t.Log("running tests for validation performed by admission webhook") - testDataPlaneValidatingWebhook(t, namespace) - } else { - t.Log("running tests for validation performed during reconciling") - testDataPlaneReconcileValidation(t, namespace) - } + t.Log("running tests for validation performed during reconciling") + testDataPlaneReconcileValidation(t, namespace) } -// could only run one of webhook validation or validation in reconciling. func testDataPlaneReconcileValidation(t *testing.T, namespace *corev1.Namespace) { testCases := []struct { name string @@ -135,54 +129,3 @@ func testDataPlaneReconcileValidation(t *testing.T, namespace *corev1.Namespace) }) } } - -func testDataPlaneValidatingWebhook(t *testing.T, namespace *corev1.Namespace) { - testCases := []struct { - name string - dataplane *operatorv1beta1.DataPlane - // empty if expect no error, - errMsg string - }{ - { - name: "webhook:validating_ok", - dataplane: &operatorv1beta1.DataPlane{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace.Name, - Name: uuid.NewString(), - }, - Spec: operatorv1beta1.DataPlaneSpec{ - DataPlaneOptions: operatorv1beta1.DataPlaneOptions{ - Deployment: operatorv1beta1.DataPlaneDeploymentOptions{ - DeploymentOptions: operatorv1beta1.DeploymentOptions{ - PodTemplateSpec: &corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: consts.DataPlaneProxyContainerName, - Image: helpers.GetDefaultDataPlaneImage(), - }, - }, - }, - }, - }, - }, - }, - }, - }, - errMsg: "", - }, - } - - dataplaneClient := GetClients().OperatorClient.ApisV1beta1().DataPlanes(namespace.Name) - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - _, err := dataplaneClient.Create(GetCtx(), tc.dataplane, metav1.CreateOptions{}) - if tc.errMsg == "" { - require.NoErrorf(t, err, "test case %s: should not return error", tc.name) - } else { - require.Containsf(t, err.Error(), tc.errMsg, - "test case %s: error message should contain expected content", tc.name) - } - }) - } -} diff --git a/test/integration/utils.go b/test/integration/utils.go index 26dc5f99c..d4b1b0482 100644 --- a/test/integration/utils.go +++ b/test/integration/utils.go @@ -14,10 +14,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - kubernetesclient "k8s.io/client-go/kubernetes" - "github.com/kong/gateway-operator/pkg/consts" - "github.com/kong/gateway-operator/pkg/utils/kubernetes/resources" "github.com/kong/gateway-operator/test/helpers" ) @@ -85,40 +82,6 @@ func URLForService(ctx context.Context, cluster clusters.Cluster, nsn types.Name return nil, fmt.Errorf("service %s has not yet been provisoned", service.Name) } -// CreateValidatingWebhook creates validating webhook for gateway operator. -func CreateValidatingWebhook(ctx context.Context, k8sClient *kubernetesclient.Clientset, webhookURL string, ca, cert, key []byte) error { - if _, err := k8sClient.CoreV1().Secrets("kong-system").Create( - ctx, - &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: consts.WebhookCertificateConfigSecretName, - }, - Data: map[string][]byte{ - consts.CAFieldSecret: ca, - consts.CertFieldSecret: cert, - consts.KeyFieldSecret: key, - }, - }, - metav1.CreateOptions{}, - ); err != nil { - return err - } - - validationWebhook := resources.NewValidatingWebhookConfigurationBuilder(consts.WebhookName). - WithScopeAllNamespaces(). - WithClientConfigURL(webhookURL). - WithCABundle(ca). - Build() - if _, err := k8sClient.AdmissionregistrationV1().ValidatingWebhookConfigurations().Create( - ctx, - validationWebhook, - metav1.CreateOptions{}, - ); err != nil { - return err - } - return nil -} - // GetEnvValueByName returns the corresponding value of LAST item with given name. // returns empty string if the name not appeared. func GetEnvValueByName(envs []corev1.EnvVar, name string) string { diff --git a/test/integration/zz_generated.registered_testcases.go b/test/integration/zz_generated.registered_testcases.go index 2267ba26b..1a505b197 100644 --- a/test/integration/zz_generated.registered_testcases.go +++ b/test/integration/zz_generated.registered_testcases.go @@ -24,7 +24,6 @@ func init() { TestGatewayDataPlaneNetworkPolicy, TestGatewayEssentials, TestGatewayMultiple, - TestGatewayProvisionDataPlaneFail, TestGatewayWithMultipleListeners, TestHTTPRoute, TestHTTPRouteWithTLS,