Skip to content

Commit

Permalink
Update ClusterSet and ClusterClaim webhooks
Browse files Browse the repository at this point in the history
1. Add a ClusterSet webhook to make Leader's ClusterID immutable, and
   allow only one ClusterSet in mc-controller's  Namespace.
2. Update ClusterClaim webhook to make `Value` field
   (ClusterID/ClusterSetID) immutable
3. Remove unused mutate webhook of ClusterClaim

Signed-off-by: Lan Luo <[email protected]>
  • Loading branch information
luolanzone committed Jul 21, 2022
1 parent 2a092ab commit 5b0a69e
Show file tree
Hide file tree
Showing 9 changed files with 363 additions and 57 deletions.
16 changes: 9 additions & 7 deletions multicluster/apis/multicluster/v1alpha2/clusterclaim_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ func (r *ClusterClaim) SetupWebhookWithManager(mgr ctrl.Manager) error {
Complete()
}

//+kubebuilder:webhook:path=/mutate-multicluster-crd-antrea-io-v1alpha2-clusterclaim,mutating=true,failurePolicy=fail,sideEffects=None,groups=multicluster.crd.antrea.io,resources=clusterclaims,verbs=create;update,versions=v1alpha2,name=mclusterclaim.kb.io,admissionReviewVersions={v1,v1beta1}

var _ webhook.Defaulter = &ClusterClaim{}

// Default implements webhook.Defaulter so a webhook will be registered for the type
Expand All @@ -49,9 +47,9 @@ var _ webhook.Validator = &ClusterClaim{}

// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (r *ClusterClaim) ValidateCreate() error {
klog.InfoS("validate create", "name", r.Name)
klog.InfoS("Validate create", "name", r.Name)
if r.Name != WellKnownClusterClaimClusterSet && r.Name != WellKnownClusterClaimID {
err := fmt.Errorf("The name %s is not valid, only 'id.k8s.io' and 'clusterset.k8s.io' are valid names for ClusterClaim", r.Name)
err := fmt.Errorf("the name %s is not valid, only 'id.k8s.io' and 'clusterset.k8s.io' are valid names for ClusterClaim", r.Name)
return err
}

Expand All @@ -60,15 +58,19 @@ func (r *ClusterClaim) ValidateCreate() error {

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (r *ClusterClaim) ValidateUpdate(old runtime.Object) error {
klog.InfoS("validate update", "name", r.Name)
klog.InfoS("Validate update", "name", r.Name)

// TODO(user): fill in your validation logic upon object update.
oldClusterClaim := old.(*ClusterClaim)
if r.Value != oldClusterClaim.Value {
err := fmt.Errorf("the field 'value' is immutable")
return err
}
return nil
}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (r *ClusterClaim) ValidateDelete() error {
klog.InfoS("validate delete", "name", r.Name)
klog.InfoS("Validate delete", "name", r.Name)

// TODO(user): fill in your validation logic upon object deletion.
return nil
Expand Down
30 changes: 15 additions & 15 deletions multicluster/build/yamls/antrea-multicluster-leader-namespaced.yml
Original file line number Diff line number Diff line change
Expand Up @@ -441,16 +441,25 @@ webhooks:
resources:
- resourceexports
sideEffects: None
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
creationTimestamp: null
labels:
app: antrea
name: antrea-multicluster-antrea-mc-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: antrea-mc-webhook-service
namespace: antrea-multicluster
path: /mutate-multicluster-crd-antrea-io-v1alpha2-clusterclaim
path: /validate-multicluster-crd-antrea-io-v1alpha2-clusterclaim
failurePolicy: Fail
name: mclusterclaim.kb.io
name: vclusterclaim.kb.io
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: antrea-multicluster
Expand All @@ -465,38 +474,29 @@ webhooks:
resources:
- clusterclaims
sideEffects: None
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
creationTimestamp: null
labels:
app: antrea
name: antrea-multicluster-antrea-mc-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: antrea-mc-webhook-service
namespace: antrea-multicluster
path: /validate-multicluster-crd-antrea-io-v1alpha2-clusterclaim
path: /validate-multicluster-crd-antrea-io-v1alpha1-clusterset
failurePolicy: Fail
name: vclusterclaim.kb.io
name: vclusterset.kb.io
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: antrea-multicluster
rules:
- apiGroups:
- multicluster.crd.antrea.io
apiVersions:
- v1alpha2
- v1alpha1
operations:
- CREATE
- UPDATE
resources:
- clusterclaims
- clustersets
sideEffects: None
- admissionReviewVersions:
- v1
Expand Down
28 changes: 14 additions & 14 deletions multicluster/build/yamls/antrea-multicluster-member.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,14 @@ metadata:
labels:
app: antrea
name: antrea-mc-mutating-webhook-configuration
webhooks: []
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
labels:
app: antrea
name: antrea-mc-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
Expand All @@ -1049,9 +1057,9 @@ webhooks:
service:
name: antrea-mc-webhook-service
namespace: kube-system
path: /mutate-multicluster-crd-antrea-io-v1alpha2-clusterclaim
path: /validate-multicluster-crd-antrea-io-v1alpha2-clusterclaim
failurePolicy: Fail
name: mclusterclaim.kb.io
name: vclusterclaim.kb.io
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
Expand All @@ -1066,35 +1074,27 @@ webhooks:
resources:
- clusterclaims
sideEffects: None
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
labels:
app: antrea
name: antrea-mc-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: antrea-mc-webhook-service
namespace: kube-system
path: /validate-multicluster-crd-antrea-io-v1alpha2-clusterclaim
path: /validate-multicluster-crd-antrea-io-v1alpha1-clusterset
failurePolicy: Fail
name: vclusterclaim.kb.io
name: vclusterset.kb.io
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
rules:
- apiGroups:
- multicluster.crd.antrea.io
apiVersions:
- v1alpha2
- v1alpha1
operations:
- CREATE
- UPDATE
resources:
- clusterclaims
- clustersets
sideEffects: None
83 changes: 83 additions & 0 deletions multicluster/cmd/multicluster-controller/clusterset_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
Copyright 2022 Antrea Authors.
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 main

import (
"context"
"fmt"
"net/http"

apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

mcv1alpha1 "antrea.io/antrea/multicluster/apis/multicluster/v1alpha1"
)

//+kubebuilder:webhook:path=/validate-multicluster-crd-antrea-io-v1alpha1-clusterset,mutating=false,failurePolicy=fail,sideEffects=None,groups=multicluster.crd.antrea.io,resources=clustersets,verbs=create;update,versions=v1alpha1,name=vclusterset.kb.io,admissionReviewVersions={v1,v1beta1}

// ClusterSet validator
type clusterSetValidator struct {
Client client.Client
decoder *admission.Decoder
namespace string
}

// Handle handles admission requests.
func (v *clusterSetValidator) Handle(ctx context.Context, req admission.Request) admission.Response {
clusterSet := &mcv1alpha1.ClusterSet{}
err := v.decoder.Decode(req, clusterSet)
if err != nil {
klog.ErrorS(err, "Error while decoding")
return admission.Errored(http.StatusBadRequest, err)
}

oldClusterSet := &mcv1alpha1.ClusterSet{}
err = v.Client.Get(ctx, types.NamespacedName{Namespace: v.namespace, Name: clusterSet.GetName()}, oldClusterSet)
if err != nil && !apierrors.IsNotFound(err) {
return admission.Errored(http.StatusPreconditionFailed,
fmt.Errorf("failed to get existing ClusterSet %s", clusterSet.GetName()))
}

// Check if there is any existing ClusterSet.
clusterSetList := &mcv1alpha1.ClusterSetList{}
if err := v.Client.List(context.TODO(), clusterSetList, client.InNamespace(v.namespace)); err != nil {
klog.ErrorS(err, "Error reading ClusterSet", "namespace", v.namespace)
return admission.Errored(http.StatusPreconditionFailed, err)
}

if apierrors.IsNotFound(err) {
if len(clusterSetList.Items) > 0 {
return admission.Errored(http.StatusPreconditionFailed,
fmt.Errorf("multiple ClusterSets in the Namespace %s are not allowed, please contact your administrator", v.namespace))
}
return admission.Allowed("")
}

if oldClusterSet.Spec.Leaders[0].ClusterID != clusterSet.Spec.Leaders[0].ClusterID {
return admission.Denied("the field 'clusterID' is immutable")
}

return admission.Allowed("")
}

func (v *clusterSetValidator) InjectDecoder(d *admission.Decoder) error {
v.decoder = d
return nil
}
Loading

0 comments on commit 5b0a69e

Please sign in to comment.