diff --git a/api/v1/chyt_webhook.go b/api/v1/chyt_webhook.go index df3d5b5d..3b9941bf 100644 --- a/api/v1/chyt_webhook.go +++ b/api/v1/chyt_webhook.go @@ -33,19 +33,6 @@ func (r *Chyt) SetupWebhookWithManager(mgr ctrl.Manager) error { Complete() } -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -//+kubebuilder:webhook:path=/mutate-cluster-ytsaurus-tech-v1-chyt,mutating=true,failurePolicy=fail,sideEffects=None,groups=cluster.ytsaurus.tech,resources=chyts,verbs=create;update,versions=v1,name=mchyt.kb.io,admissionReviewVersions=v1 - -var _ webhook.Defaulter = &Chyt{} - -// Default implements webhook.Defaulter so a webhook will be registered for the type -func (r *Chyt) Default() { - chytlog.Info("default", "name", r.Name) - - // TODO(user): fill in your defaulting logic. -} - // TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. //+kubebuilder:webhook:path=/validate-cluster-ytsaurus-tech-v1-chyt,mutating=false,failurePolicy=fail,sideEffects=None,groups=cluster.ytsaurus.tech,resources=chyts,verbs=create;update,versions=v1,name=vchyt.kb.io,admissionReviewVersions=v1 diff --git a/api/v1/spyt_webhook.go b/api/v1/spyt_webhook.go index 520b455d..203fd225 100644 --- a/api/v1/spyt_webhook.go +++ b/api/v1/spyt_webhook.go @@ -33,19 +33,6 @@ func (r *Spyt) SetupWebhookWithManager(mgr ctrl.Manager) error { Complete() } -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -//+kubebuilder:webhook:path=/mutate-cluster-ytsaurus-tech-v1-spyt,mutating=true,failurePolicy=fail,sideEffects=None,groups=cluster.ytsaurus.tech,resources=spyts,verbs=create;update,versions=v1,name=mspyt.kb.io,admissionReviewVersions=v1 - -var _ webhook.Defaulter = &Spyt{} - -// Default implements webhook.Defaulter so a webhook will be registered for the type -func (r *Spyt) Default() { - spytlog.Info("default", "name", r.Name) - - // TODO(user): fill in your defaulting logic. -} - // TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. //+kubebuilder:webhook:path=/validate-cluster-ytsaurus-tech-v1-spyt,mutating=false,failurePolicy=fail,sideEffects=None,groups=cluster.ytsaurus.tech,resources=spyts,verbs=create;update,versions=v1,name=vspyt.kb.io,admissionReviewVersions=v1 diff --git a/api/v1/ytsaurus_webhook.go b/api/v1/ytsaurus_webhook.go index 1fb608bd..145d2145 100644 --- a/api/v1/ytsaurus_webhook.go +++ b/api/v1/ytsaurus_webhook.go @@ -22,14 +22,16 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/yaml" + ptr "k8s.io/utils/pointer" ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -45,36 +47,6 @@ func (r *Ytsaurus) SetupWebhookWithManager(mgr ctrl.Manager) error { Complete() } -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -//+kubebuilder:webhook:path=/mutate-cluster-ytsaurus-tech-v1-ytsaurus,mutating=true,failurePolicy=fail,sideEffects=None,groups=cluster.ytsaurus.tech,resources=ytsaurus,verbs=create;update,versions=v1,name=mytsaurus.kb.io,admissionReviewVersions=v1 - -var _ webhook.Defaulter = &Ytsaurus{} - -// Default implements webhook.Defaulter so a webhook will be registered for the type -func (r *Ytsaurus) Default() { - ytsauruslog.Info("default", "name", r.Name) - - // Set anti affinity for masters - if r.Spec.PrimaryMasters.Affinity == nil { - r.Spec.PrimaryMasters.Affinity = &corev1.Affinity{} - } - if r.Spec.PrimaryMasters.Affinity.PodAntiAffinity == nil { - r.Spec.PrimaryMasters.Affinity.PodAntiAffinity = &corev1.PodAntiAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - consts.YTComponentLabelName: fmt.Sprintf("%s-%s", r.Name, "yt-master"), - }, - }, - TopologyKey: "kubernetes.io/hostname", - }, - }, - } - } -} - // TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. //+kubebuilder:webhook:path=/validate-cluster-ytsaurus-tech-v1-ytsaurus,mutating=false,failurePolicy=fail,sideEffects=None,groups=cluster.ytsaurus.tech,resources=ytsaurus,verbs=create;update,versions=v1,name=vytsaurus.kb.io,admissionReviewVersions=v1 @@ -109,6 +81,13 @@ func (r *Ytsaurus) validatePrimaryMasters(old *Ytsaurus) field.ErrorList { allErrors = append(allErrors, field.Invalid(path.Child("cellTag"), r.Spec.PrimaryMasters.CellTag, "Could not be changed")) } + if old.Spec.PrimaryMasters.InstanceCount > 1 && !old.Spec.EphemeralCluster { + affinity := old.Spec.PrimaryMasters.Affinity + if affinity == nil || affinity.PodAntiAffinity == nil { + allErrors = append(allErrors, field.Required(path.Child("affinity").Child("podAntiAffinity"), "masters must be placed on different nodes")) + } + } + return allErrors } diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml index c8ee5b86..75151df4 100644 --- a/config/default/webhookcainjection_patch.yaml +++ b/config/default/webhookcainjection_patch.yaml @@ -1,20 +1,6 @@ # This patch add annotation to admission webhook config and # the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - labels: - app.kubernetes.io/name: mutatingwebhookconfiguration - app.kubernetes.io/instance: mutating-webhook-configuration - app.kubernetes.io/component: webhook - app.kubernetes.io/created-by: yt-k8s-operator - app.kubernetes.io/part-of: yt-k8s-operator - app.kubernetes.io/managed-by: kustomize - name: mutating-webhook-configuration - annotations: - cert-manager.io/inject-ca-from: $(WEBHOOK_CERTIFICATE_NAMESPACE)/$(WEBHOOK_CERTIFICATE_NAME) ---- -apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: labels: diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 9ff3f70e..2920726e 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -1,71 +1,5 @@ --- apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-cluster-ytsaurus-tech-v1-chyt - failurePolicy: Fail - name: mchyt.kb.io - rules: - - apiGroups: - - cluster.ytsaurus.tech - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - chyts - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-cluster-ytsaurus-tech-v1-spyt - failurePolicy: Fail - name: mspyt.kb.io - rules: - - apiGroups: - - cluster.ytsaurus.tech - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - spyts - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-cluster-ytsaurus-tech-v1-ytsaurus - failurePolicy: Fail - name: mytsaurus.kb.io - rules: - - apiGroups: - - cluster.ytsaurus.tech - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - ytsaurus - sideEffects: None ---- -apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: validating-webhook-configuration diff --git a/pkg/apiproxy/ytsaurus.go b/pkg/apiproxy/ytsaurus.go index 7c769828..48b8e844 100644 --- a/pkg/apiproxy/ytsaurus.go +++ b/pkg/apiproxy/ytsaurus.go @@ -140,10 +140,10 @@ func (c *Ytsaurus) IsStatusConditionFalse(conditionType string) bool { func sortConditions(conditions []metav1.Condition) { slices.SortStableFunc(conditions, func(a, b metav1.Condition) int { - statusOrder := []metav1.ConditionStatus{metav1.ConditionTrue, metav1.ConditionFalse, metav1.ConditionUnknown} - if diff := cmp.Compare(slices.Index(statusOrder, a.Status), slices.Index(statusOrder, b.Status)); diff != 0 { - return diff - } - return a.LastTransitionTime.Compare(b.LastTransitionTime.Time) + statusOrder := []metav1.ConditionStatus{metav1.ConditionTrue, metav1.ConditionFalse, metav1.ConditionUnknown} + if diff := cmp.Compare(slices.Index(statusOrder, a.Status), slices.Index(statusOrder, b.Status)); diff != 0 { + return diff + } + return a.LastTransitionTime.Compare(b.LastTransitionTime.Time) }) }