diff --git a/cmd/main.go b/cmd/main.go index 587653c1..375c3127 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,7 +1,6 @@ package main import ( - "context" "crypto/tls" "flag" "os" @@ -101,8 +100,6 @@ func main() { v := buildInfo.Get() - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - // if the enable-http2 flag is false (the default), http/2 should be disabled // due to its vulnerabilities. More specifically, disabling http/2 will // prevent from being vulnerable to the HTTP/2 Stream Cancellation and @@ -287,7 +284,7 @@ func main() { } if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = webhook.RegisterValidationWebHook(context.Background(), mgr, ns); err != nil { + if err = webhook.RegisterValidationWebHook(mgr); err != nil { setupLog.Error(err, "failed to create webhook", "webhook", "Codebase") os.Exit(1) } diff --git a/deploy-templates/README.md b/deploy-templates/README.md index 838583bf..dde05163 100644 --- a/deploy-templates/README.md +++ b/deploy-templates/README.md @@ -23,6 +23,7 @@ A Helm chart for KubeRocketCI Codebase Operator |-----|------|---------|-------------| | affinity | object | `{}` | | | annotations | object | `{}` | | +| enableWebhooks | bool | `true` | Enable webhook and cert-manager certificate resources. Webhooks require cert-manager to be installed in the cluster. | | envs[0].name | string | `"RECONCILATION_PERIOD"` | | | envs[0].value | string | `"360"` | | | envs[1] | object | `{"name":"CODEBASE_BRANCH_MAX_CONCURRENT_RECONCILES","value":"3"}` | Maximum number of parallel reconciliation codebasebranches | diff --git a/deploy-templates/templates/cert_secret.yaml b/deploy-templates/templates/cert_secret.yaml deleted file mode 100644 index b6b7d411..00000000 --- a/deploy-templates/templates/cert_secret.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: edp-codebase-operator-webhook-certs - labels: - {{- include "codebase-operator.labels" . | nindent 4 }} \ No newline at end of file diff --git a/deploy-templates/templates/clusterrole_kubernetes.yaml b/deploy-templates/templates/clusterrole_kubernetes.yaml deleted file mode 100644 index 10c86075..00000000 --- a/deploy-templates/templates/clusterrole_kubernetes.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if eq .Values.global.platform "kubernetes" -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "codebase-operator.labels" . | nindent 4 }} - name: edp-{{ .Values.name }}-{{ .Release.Namespace }} -rules: -- apiGroups: - - admissionregistration.k8s.io - resources: - - validatingwebhookconfigurations - verbs: - - get - - update - - patch -{{- end -}} diff --git a/deploy-templates/templates/clusterrole_openshift.yaml b/deploy-templates/templates/clusterrole_openshift.yaml deleted file mode 100644 index 766670b5..00000000 --- a/deploy-templates/templates/clusterrole_openshift.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if eq .Values.global.platform "openshift" -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "codebase-operator.labels" . | nindent 4 }} - name: edp-{{ .Values.name }}-{{ .Release.Namespace }} -rules: -- apiGroups: - - admissionregistration.k8s.io - resources: - - validatingwebhookconfigurations - verbs: - - get - - update - - patch -{{- end -}} diff --git a/deploy-templates/templates/clusterrolebinding_kubernetes.yaml b/deploy-templates/templates/clusterrolebinding_kubernetes.yaml deleted file mode 100644 index 0bb143ca..00000000 --- a/deploy-templates/templates/clusterrolebinding_kubernetes.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if eq .Values.global.platform "kubernetes" -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "codebase-operator.labels" . | nindent 4 }} - name: edp-{{ .Values.name }}-{{ .Release.Namespace }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: edp-{{ .Values.name }}-{{ .Release.Namespace }} -subjects: - - kind: ServiceAccount - name: edp-{{ .Values.name }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/deploy-templates/templates/clusterrolebinding_openshift.yaml b/deploy-templates/templates/clusterrolebinding_openshift.yaml deleted file mode 100644 index b084408c..00000000 --- a/deploy-templates/templates/clusterrolebinding_openshift.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if eq .Values.global.platform "openshift" -}} -apiVersion: rbac.authorization.k8s.io/v1 -groupNames: null -kind: ClusterRoleBinding -metadata: - labels: - {{- include "codebase-operator.labels" . | nindent 4 }} - name: edp-{{ .Values.name }}-{{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: edp-{{ .Values.name }}-{{ .Release.Namespace }} -subjects: - - kind: ServiceAccount - name: edp-{{ .Values.name }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/deploy-templates/templates/deployment.yaml b/deploy-templates/templates/deployment.yaml index f18ba523..f5d3d834 100644 --- a/deploy-templates/templates/deployment.yaml +++ b/deploy-templates/templates/deployment.yaml @@ -34,6 +34,9 @@ spec: containers: - name: {{ .Values.name }} image: {{ if .Values.image.registry }}{{ .Values.image.registry }}/{{ end }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }} + {{- if .Values.enableWebhooks }} + args: + - --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs ports: - containerPort: 9443 name: webhook-server @@ -42,6 +45,7 @@ spec: - mountPath: /tmp/k8s-webhook-server/serving-certs name: cert readOnly: true + {{- end }} imagePullPolicy: "{{ .Values.imagePullPolicy }}" {{- if .Values.securityContext }} securityContext: {{ toYaml .Values.securityContext | nindent 12 }} @@ -61,6 +65,8 @@ spec: value: "{{ .Values.global.platform }}" - name: TELEMETRY_ENABLED value: "{{ .Values.telemetryEnabled }}" + - name: ENABLE_WEBHOOKS + value: {{ .Values.enableWebhooks | quote }} {{ toYaml .Values.envs | indent 12 }} resources: {{ toYaml .Values.resources | indent 12 }} @@ -76,8 +82,10 @@ spec: tolerations: {{- toYaml . | nindent 8 }} {{- end }} + {{- if .Values.enableWebhooks }} volumes: - name: cert secret: defaultMode: 420 - secretName: edp-codebase-operator-webhook-certs + secretName: {{ .Values.name }}-webhook-certs + {{- end }} diff --git a/deploy-templates/templates/role_kubernetes.yaml b/deploy-templates/templates/role_kubernetes.yaml index aaaa1f81..d8072860 100644 --- a/deploy-templates/templates/role_kubernetes.yaml +++ b/deploy-templates/templates/role_kubernetes.yaml @@ -87,7 +87,6 @@ rules: - list - patch - update - - create resources: - secrets - apiGroups: diff --git a/deploy-templates/templates/service.yaml b/deploy-templates/templates/service.yaml index bdcdb2e4..d5be5abc 100644 --- a/deploy-templates/templates/service.yaml +++ b/deploy-templates/templates/service.yaml @@ -1,3 +1,4 @@ +{{- if .Values.enableWebhooks }} apiVersion: v1 kind: Service metadata: @@ -10,4 +11,5 @@ spec: protocol: TCP targetPort: 9443 selector: - name: {{ .Values.name }} \ No newline at end of file + name: {{ .Values.name }} +{{- end }} \ No newline at end of file diff --git a/deploy-templates/templates/validation_webhook.yaml b/deploy-templates/templates/validation_webhook.yaml index de1b7a29..6ef38100 100644 --- a/deploy-templates/templates/validation_webhook.yaml +++ b/deploy-templates/templates/validation_webhook.yaml @@ -1,8 +1,11 @@ +{{- if .Values.enableWebhooks }} apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: labels: {{- include "codebase-operator.labels" . | nindent 4 }} + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ .Values.name }}-serving-cert name: edp-codebase-operator-validating-webhook-configuration-{{ .Release.Namespace }} webhooks: - admissionReviewVersions: @@ -115,3 +118,4 @@ webhooks: - codebases scope: Namespaced sideEffects: None +{{- end }} diff --git a/deploy-templates/templates/validation_webhook_rbac.yaml b/deploy-templates/templates/validation_webhook_rbac.yaml new file mode 100644 index 00000000..5f30a66c --- /dev/null +++ b/deploy-templates/templates/validation_webhook_rbac.yaml @@ -0,0 +1,34 @@ +{{- if .Values.enableWebhooks }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "codebase-operator.labels" . | nindent 4 }} + name: edp-{{ .Values.name }}-{{ .Release.Namespace }}-validation-webhook +rules: +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "codebase-operator.labels" . | nindent 4 }} + name: edp-{{ .Values.name }}-{{ .Release.Namespace }}-validation-webhook +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: edp-{{ .Values.name }}-{{ .Release.Namespace }}-validation-webhook +subjects: + - kind: ServiceAccount + name: edp-{{ .Values.name }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/deploy-templates/templates/webhook/certmanager.yaml b/deploy-templates/templates/webhook/certmanager.yaml new file mode 100644 index 00000000..8ad47db1 --- /dev/null +++ b/deploy-templates/templates/webhook/certmanager.yaml @@ -0,0 +1,25 @@ +{{- if .Values.enableWebhooks }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + {{- include "codebase-operator.labels" . | nindent 4 }} + name: {{ .Values.name }}-selfsigned-issuer +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + {{- include "codebase-operator.labels" . | nindent 4 }} + name: {{ .Values.name }}-serving-cert +spec: + dnsNames: + - edp-{{ .Values.name }}-webhook-service.{{ .Release.Namespace }}.svc + - edp-{{ .Values.name }}-webhook-service.{{ .Release.Namespace }}.svc.cluster.local + issuerRef: + kind: Issuer + name: {{ .Values.name }}-selfsigned-issuer + secretName: {{ .Values.name }}-webhook-certs +{{- end }} diff --git a/deploy-templates/values.yaml b/deploy-templates/values.yaml index 2a0a396a..1d8372e7 100644 --- a/deploy-templates/values.yaml +++ b/deploy-templates/values.yaml @@ -70,3 +70,7 @@ jira: # Read more about KubeRocketCI telemetry here: https://docs.kuberocketci.io/docs/developer-guide/telemetry # -- Flag to enable/disable telemetry telemetryEnabled: true + +# -- Enable webhook and cert-manager certificate resources. +# Webhooks require cert-manager to be installed in the cluster. +enableWebhooks: true diff --git a/go.mod b/go.mod index 6dff7b3a..38839118 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,6 @@ require ( k8s.io/apimachinery v0.33.7 k8s.io/client-go v0.33.7 k8s.io/utils v0.0.0-20241210054802-24370beab758 - knative.dev/pkg v0.0.0-20250415155312-ed3e2158b883 sigs.k8s.io/controller-runtime v0.21.0 ) @@ -146,6 +145,7 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect knative.dev/eventing v0.30.3 // indirect + knative.dev/pkg v0.0.0-20250415155312-ed3e2158b883 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/pkg/webhook/cert.go b/pkg/webhook/cert.go deleted file mode 100644 index d5421c35..00000000 --- a/pkg/webhook/cert.go +++ /dev/null @@ -1,158 +0,0 @@ -package webhook - -import ( - "context" - "fmt" - "time" - - admissionregistrationv1 "k8s.io/api/admissionregistration/v1" - corev1 "k8s.io/api/core/v1" - k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - certresources "knative.dev/pkg/webhook/certificates/resources" - ctrlClient "sigs.k8s.io/controller-runtime/pkg/client" -) - -const ( - // secretCertsName is name of secret where ca.crt, tls.crt, tls.key will be stored after generation. - secretCertsName = "edp-codebase-operator-webhook-certs" - // secretTLSKey is the name of the key associated with the secret's private key. - secretTLSKey = "tls.key" - // secretCACert is the name of the key associated with the certificate of the CA for the keypair. - secretCACert = "ca.crt" - // secretTLSCert is the name of the key associated with the secret's certificate. - secretTLSCert = "tls.crt" - century = 100 * 365 * 24 * time.Hour - // serviceName is the name of the service used to serve the webhook. - serviceName = "edp-codebase-operator-webhook-service" - // validatingWebHookName is the name of the ValidatingWebhookConfiguration resource used for webhook configuration. - validatingWebHookName = "edp-codebase-operator-validating-webhook-configuration" -) - -// CertData is a struct that contains certificates data. -type CertData struct { - ServerKey []byte - ServerCert []byte - CaCert []byte -} - -// NewCertData creates a new CertData struct. -func NewCertData(serverKey, serverCert, caCert []byte) *CertData { - return &CertData{ServerKey: serverKey, ServerCert: serverCert, CaCert: caCert} -} - -// CertService is a service that provides certificates for webhook. -type CertService struct { - clientReader ctrlClient.Reader - clientWriter ctrlClient.Writer -} - -// NewCertService creates a new CertService service. -func NewCertService(clientReader ctrlClient.Reader, clientWriter ctrlClient.Writer) *CertService { - return &CertService{ - clientReader: clientReader, - clientWriter: clientWriter, - } -} - -// PopulateCertificates populates certificates for webhook. -func (s *CertService) PopulateCertificates(ctx context.Context, namespace string) error { - cert, err := s.createCertsSecret(ctx, namespace, serviceName) - if err != nil { - return fmt.Errorf("failed to create certificates: %w", err) - } - - return s.updateWebHookCABundle(ctx, getValidationWebHookName(namespace), cert.CaCert) -} - -// createCertsSecret creates and returns a CertData with CA certificate, server certificate and key. -// serverKey and serverCert are used by the server to establish trust for clients, CA certificate is used by the -// client to verify the server authentication chain. Certificates are based on kubernetes service spec and namespace. -// After generation all certificates are stored in secret: secretCertsName. -func (s *CertService) createCertsSecret( - ctx context.Context, - namespace, - serviceName string, -) (*CertData, error) { - serKey, serCert, caCert, err := certresources.CreateCerts( - ctx, - serviceName, - namespace, - time.Now().Add(century), - ) - if err != nil { - return nil, fmt.Errorf("failed to create certs: %w", err) - } - - certData := NewCertData(serKey, serCert, caCert) - - secret := &corev1.Secret{} - - err = s.clientReader.Get(ctx, ctrlClient.ObjectKey{Namespace: namespace, Name: secretCertsName}, secret) - if err != nil { - if k8serrors.IsNotFound(err) { - secret.ObjectMeta = metav1.ObjectMeta{ - Namespace: namespace, - Name: secretCertsName, - } - secret.Data = map[string][]byte{ - secretTLSKey: serKey, - secretTLSCert: serCert, - secretCACert: caCert, - } - secret.Type = corev1.SecretTypeOpaque - - if err = s.clientWriter.Create(ctx, secret); err != nil { - return nil, fmt.Errorf("failed to create secret: %w", err) - } - - return certData, nil - } - - return nil, fmt.Errorf("failed to get secret: %w", err) - } - - secret.Data = map[string][]byte{ - secretTLSKey: serKey, - secretTLSCert: serCert, - secretCACert: caCert, - } - if err = s.clientWriter.Update(ctx, secret); err != nil { - return nil, fmt.Errorf("failed to update secret: %w", err) - } - - return certData, nil -} - -// updateWebHookCABundle updates ValidatingWebhookConfiguration CaBundle spec with CA certificate. -func (s *CertService) updateWebHookCABundle( - ctx context.Context, - webHookName string, - caBundle []byte, -) error { - webHook := &admissionregistrationv1.ValidatingWebhookConfiguration{} - - err := s.clientReader.Get(ctx, ctrlClient.ObjectKey{Name: webHookName}, webHook) - if err != nil { - return fmt.Errorf("failed to get validation webHook: %w", err) - } - - if len(webHook.Webhooks) == 0 { - return nil - } - - for i := range webHook.Webhooks { - webHook.Webhooks[i].ClientConfig.CABundle = caBundle - } - - if err = s.clientWriter.Update(ctx, webHook); err != nil { - return fmt.Errorf("failed to update validation webHook caBundle: %w", err) - } - - return nil -} - -// getValidationWebHookName returns name of ValidatingWebhookConfiguration resource. -func getValidationWebHookName(namespace string) string { - return fmt.Sprintf("%s-%s", validatingWebHookName, namespace) -} diff --git a/pkg/webhook/cert_test.go b/pkg/webhook/cert_test.go deleted file mode 100644 index 5072f883..00000000 --- a/pkg/webhook/cert_test.go +++ /dev/null @@ -1,219 +0,0 @@ -package webhook - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - admissionregistrationv1 "k8s.io/api/admissionregistration/v1" - corev1 "k8s.io/api/core/v1" - metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - codebaseApi "github.com/epam/edp-codebase-operator/v2/api/v1" -) - -func TestCertService_PopulateCertificates(t *testing.T) { - t.Parallel() - - scheme := runtime.NewScheme() - defaultNs := "default" - - require.NoError(t, codebaseApi.AddToScheme(scheme)) - require.NoError(t, corev1.AddToScheme(scheme)) - require.NoError(t, admissionregistrationv1.AddToScheme(scheme)) - - tests := []struct { - name string - objects []client.Object - wantErr require.ErrorAssertionFunc - wantCheck func(t *testing.T, c client.Client) - }{ - { - name: "should create secret and update webhook CaBundle successfully", - objects: []client.Object{ - &admissionregistrationv1.ValidatingWebhookConfiguration{ - ObjectMeta: metaV1.ObjectMeta{ - Name: getValidationWebHookName(defaultNs), - }, - Webhooks: []admissionregistrationv1.ValidatingWebhook{ - { - Name: "validate-codebase", - }, - }, - }, - &corev1.Service{ - ObjectMeta: metaV1.ObjectMeta{ - Name: serviceName, - Namespace: defaultNs, - }, - }, - }, - wantErr: require.NoError, - wantCheck: func(t *testing.T, c client.Client) { - secret := &corev1.Secret{} - err := c.Get( - context.Background(), - client.ObjectKey{ - Namespace: defaultNs, - Name: secretCertsName, - }, - secret, - ) - - require.NoError(t, err) - require.NotEmpty(t, secret.Data[secretTLSKey]) - require.NotEmpty(t, secret.Data[secretCACert]) - require.NotEmpty(t, secret.Data[secretTLSCert]) - - webhook := &admissionregistrationv1.ValidatingWebhookConfiguration{} - err = c.Get( - context.Background(), - client.ObjectKey{ - Name: getValidationWebHookName(defaultNs), - }, - webhook, - ) - - require.NoError(t, err) - require.NotEmpty(t, webhook.Webhooks) - require.NotEmpty(t, webhook.Webhooks[0].ClientConfig.CABundle) - }, - }, - { - name: "should update secret and update webhook CaBundle successfully", - objects: []client.Object{ - &admissionregistrationv1.ValidatingWebhookConfiguration{ - ObjectMeta: metaV1.ObjectMeta{ - Name: getValidationWebHookName(defaultNs), - }, - Webhooks: []admissionregistrationv1.ValidatingWebhook{ - { - Name: "validate-codebase", - }, - }, - }, - &corev1.Service{ - ObjectMeta: metaV1.ObjectMeta{ - Name: serviceName, - Namespace: defaultNs, - }, - }, - &corev1.Secret{ - ObjectMeta: metaV1.ObjectMeta{ - Name: secretCertsName, - Namespace: defaultNs, - }, - }, - }, - wantErr: require.NoError, - wantCheck: func(t *testing.T, c client.Client) { - secret := &corev1.Secret{} - err := c.Get( - context.Background(), - client.ObjectKey{ - Namespace: defaultNs, - Name: secretCertsName, - }, - secret, - ) - - require.NoError(t, err) - require.NotEmpty(t, secret.Data[secretTLSKey]) - require.NotEmpty(t, secret.Data[secretCACert]) - require.NotEmpty(t, secret.Data[secretTLSCert]) - - webhook := &admissionregistrationv1.ValidatingWebhookConfiguration{} - err = c.Get( - context.Background(), - client.ObjectKey{ - Name: getValidationWebHookName(defaultNs), - }, - webhook, - ) - - require.NoError(t, err) - require.NotEmpty(t, webhook.Webhooks) - require.NotEmpty(t, webhook.Webhooks[0].ClientConfig.CABundle) - }, - }, - { - name: "empty webhook", - objects: []client.Object{ - &admissionregistrationv1.ValidatingWebhookConfiguration{ - ObjectMeta: metaV1.ObjectMeta{ - Name: getValidationWebHookName(defaultNs), - }, - }, - &corev1.Service{ - ObjectMeta: metaV1.ObjectMeta{ - Name: serviceName, - Namespace: defaultNs, - }, - }, - }, - wantErr: require.NoError, - wantCheck: func(t *testing.T, c client.Client) { - secret := &corev1.Secret{} - err := c.Get( - context.Background(), - client.ObjectKey{ - Namespace: defaultNs, - Name: secretCertsName, - }, - secret, - ) - - require.NoError(t, err) - require.NotEmpty(t, secret.Data[secretTLSKey]) - require.NotEmpty(t, secret.Data[secretCACert]) - require.NotEmpty(t, secret.Data[secretTLSCert]) - - webhook := &admissionregistrationv1.ValidatingWebhookConfiguration{} - err = c.Get( - context.Background(), - client.ObjectKey{ - Name: getValidationWebHookName(defaultNs), - }, - webhook, - ) - - require.NoError(t, err) - require.Empty(t, webhook.Webhooks) - }, - }, - { - name: "validatingWebhookConfiguration resource not found", - objects: []client.Object{ - &corev1.Service{ - ObjectMeta: metaV1.ObjectMeta{ - Name: serviceName, - Namespace: defaultNs, - }, - }, - }, - wantErr: func(t require.TestingT, err error, i ...interface{}) { - require.Error(t, err) - require.Contains(t, err.Error(), "failed to get validation webHook") - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - - k8sClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(tt.objects...).Build() - - s := NewCertService(k8sClient, k8sClient) - err := s.PopulateCertificates(context.Background(), defaultNs) - - tt.wantErr(t, err) - - if tt.wantCheck != nil { - tt.wantCheck(t, k8sClient) - } - }) - } -} diff --git a/pkg/webhook/webhook.go b/pkg/webhook/webhook.go index 9d5e72b0..71f6a3e3 100644 --- a/pkg/webhook/webhook.go +++ b/pkg/webhook/webhook.go @@ -1,22 +1,13 @@ package webhook import ( - "context" - "fmt" - ctrl "sigs.k8s.io/controller-runtime" codebaseApi "github.com/epam/edp-codebase-operator/v2/api/v1" ) // RegisterValidationWebHook registers a new webhook for validating CRD. -func RegisterValidationWebHook(ctx context.Context, mgr ctrl.Manager, namespace string) error { - // mgr.GetAPIReader() is used to read objects before cache is started. - certService := NewCertService(mgr.GetAPIReader(), mgr.GetClient()) - if err := certService.PopulateCertificates(ctx, namespace); err != nil { - return fmt.Errorf("failed to populate certificates: %w", err) - } - +func RegisterValidationWebHook(mgr ctrl.Manager) error { if err := NewCodebaseValidationWebhook( mgr.GetClient(), ctrl.Log.WithName("codebase-webhook"), diff --git a/pkg/webhook/webhook_test.go b/pkg/webhook/webhook_test.go index 3e00bd34..75464d8f 100644 --- a/pkg/webhook/webhook_test.go +++ b/pkg/webhook/webhook_test.go @@ -4,79 +4,40 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - admissionregistrationv1 "k8s.io/api/admissionregistration/v1" "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" - ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" ) var _ = Describe("webhooks registration", func() { - When("ValidatingWebhookConfiguration exists", func() { - BeforeEach(func() { - By("creating ValidatingWebhookConfiguration") - webhook := &admissionregistrationv1.ValidatingWebhookConfiguration{ - ObjectMeta: ctrl.ObjectMeta{ - Name: getValidationWebHookName("default"), - }, - } - Expect(k8sClient.Create(ctx, webhook)).ToNot(HaveOccurred()) - }) - AfterEach(func() { - webhook := &admissionregistrationv1.ValidatingWebhookConfiguration{ - ObjectMeta: ctrl.ObjectMeta{ - Name: getValidationWebHookName("default"), - }, - } - err := ctrlclient.IgnoreNotFound(k8sClient.Delete(ctx, webhook)) - Expect(err).ToNot(HaveOccurred()) + It("should register validation webhooks", func() { + By("creating manager") + k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: k8sClient.Scheme(), + Metrics: metricsserver.Options{ + BindAddress: "0", + }, }) + Expect(err).ToNot(HaveOccurred()) - It("should register validation webhooks", func() { - By("creating manager") - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: k8sClient.Scheme(), - Metrics: metricsserver.Options{ - BindAddress: "0", - }, - }) - Expect(err).ToNot(HaveOccurred()) - - By("registering validation webhooks") - err = RegisterValidationWebHook(ctx, k8sManager, "default") - Expect(err).ToNot(HaveOccurred()) - }) - - When("scheme doesn't contain cdpipeline types", func() { - It("should return error", func() { - By("creating manager") - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - Metrics: metricsserver.Options{ - BindAddress: "0", - }, - }) - Expect(err).ToNot(HaveOccurred()) - - By("registering validation webhooks") - err = RegisterValidationWebHook(ctx, k8sManager, "default") - Expect(err).To(HaveOccurred()) - }) - }) + By("registering validation webhooks") + err = RegisterValidationWebHook(k8sManager) + Expect(err).ToNot(HaveOccurred()) }) - When("MutatingWebhookConfiguration doesn't exist", func() { + + When("scheme doesn't contain cdpipeline types", func() { It("should return error", func() { By("creating manager") k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: k8sClient.Scheme(), + Scheme: scheme.Scheme, Metrics: metricsserver.Options{ BindAddress: "0", }, }) Expect(err).ToNot(HaveOccurred()) - By("registering mutation webhooks") - err = RegisterValidationWebHook(ctx, k8sManager, "default") + By("registering validation webhooks") + err = RegisterValidationWebHook(k8sManager) Expect(err).To(HaveOccurred()) }) })