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:
committed by
hongming
parent
9f6f781a39
commit
834c393cf0
@@ -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{}))
|
||||
}
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
68
pkg/controller/application/apprelease_webhook.go
Normal file
68
pkg/controller/application/apprelease_webhook.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user