add application release validatingWebhook (#2170)

* add application release validatingWebhook

Signed-off-by: wenhaozhou <wenhaozhou@yunify.com>

* enable at host cluster

Signed-off-by: wenhaozhou <wenhaozhou@yunify.com>

---------

Signed-off-by: wenhaozhou <wenhaozhou@yunify.com>
Co-authored-by: wenhaozhou <wenhaozhou@yunify.com>
Signed-off-by: hongming <coder.scala@gmail.com>
This commit is contained in:
KubeSphere CI Bot
2025-01-07 17:08:20 +08:00
committed by hongming
parent 9f6f781a39
commit 834c393cf0
3 changed files with 105 additions and 0 deletions

View File

@@ -115,6 +115,7 @@ func init() {
runtime.Must(controller.Register(&application.AppVersionReconciler{}))
// k8s application
runtime.Must(controller.Register(&k8sapplication.Reconciler{}))
runtime.Must(controller.Register(&application.ReleaseWebhook{}))
// kubectl
runtime.Must(controller.Register(&kubectl.Reconciler{}))
}

View File

@@ -427,3 +427,39 @@ webhooks:
scope: '*'
sideEffects: None
timeoutSeconds: 30
---
{{- if eq (include "multicluster.role" .) "host" }}
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: applications.kubesphere.io
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
caBundle: {{ b64enc $ca.Cert | quote }}
service:
name: ks-controller-manager
namespace: {{ .Release.Namespace }}
path: /validate-application-kubesphere-io-v2-applicationrelease
port: 443
failurePolicy: Fail
matchPolicy: Exact
name: applicationrelease.extensions.kubesphere.io
namespaceSelector: {}
objectSelector: {}
rules:
- apiGroups:
- application.kubesphere.io
apiVersions:
- v2
operations:
- CREATE
- UPDATE
resources:
- applicationreleases
scope: '*'
sideEffects: None
timeoutSeconds: 30
{{- end }}

View File

@@ -0,0 +1,68 @@
package application
import (
"context"
"fmt"
"strings"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
kscontroller "kubesphere.io/kubesphere/pkg/controller"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
appv2 "kubesphere.io/api/application/v2"
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)
var _ admission.CustomValidator = &ReleaseWebhook{}
var _ kscontroller.ClusterSelector = &ReleaseWebhook{}
var _ kscontroller.Controller = &ReleaseWebhook{}
type ReleaseWebhook struct {
cache.Cache
}
func (a *ReleaseWebhook) Name() string {
return "applicationrelease-webhook"
}
func (a *ReleaseWebhook) SetupWithManager(mgr *kscontroller.Manager) error {
a.Cache = mgr.GetCache()
return ctrl.NewWebhookManagedBy(mgr).WithValidator(a).For(&appv2.ApplicationRelease{}).Complete()
}
func (a *ReleaseWebhook) Enabled(clusterRole string) bool {
return strings.EqualFold(clusterRole, string(clusterv1alpha1.ClusterRoleHost))
}
func (a *ReleaseWebhook) ValidateCreate(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) {
return a.validateAppVersionState(ctx, obj.(*appv2.ApplicationRelease))
}
func (a *ReleaseWebhook) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) {
return a.validateAppVersionState(ctx, newObj.(*appv2.ApplicationRelease))
}
func (a *ReleaseWebhook) ValidateDelete(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) {
return nil, nil
}
func (a *ReleaseWebhook) validateAppVersionState(ctx context.Context, release *appv2.ApplicationRelease) (warnings admission.Warnings, err error) {
versionID := release.Spec.AppVersionID
appVersion := &appv2.ApplicationVersion{}
err = a.Get(ctx, types.NamespacedName{Name: versionID}, appVersion)
if err != nil {
return nil, err
}
if appVersion.Status.State != appv2.ReviewStatusActive && release.Status.State != appv2.ReviewStatusPassed {
return nil, fmt.Errorf("invalid application version: %s, state: %s, for release: %s",
versionID, appVersion.Status.State, release.Name)
}
return nil, nil
}