diff --git a/pkg/admission/webhook/subnet.go b/pkg/admission/webhook/subnet.go index c9297a6..27ec797 100644 --- a/pkg/admission/webhook/subnet.go +++ b/pkg/admission/webhook/subnet.go @@ -3,14 +3,14 @@ package webhook import ( "encoding/json" "fmt" + "time" "github.com/sirupsen/logrus" admissionv1 "k8s.io/api/admission/v1" - "k8s.io/apimachinery/pkg/labels" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" flv1 "github.com/cnrancher/rancher-flat-network/pkg/apis/flatnetwork.pandaria.io/v1" "github.com/cnrancher/rancher-flat-network/pkg/common" - "github.com/cnrancher/rancher-flat-network/pkg/utils" ) const ( @@ -18,6 +18,9 @@ const ( labelVlan = "vlan" labelMode = "mode" labelFlatMode = "flatMode" + + listInterval = time.Microsecond * 100 + listLimit = 100 ) func deserializeFlatNetworkSubnet(ar *admissionv1.AdmissionReview) (*flv1.FlatNetworkSubnet, error) { @@ -33,15 +36,29 @@ func (h *Handler) validateFlatNetworkSubnet(ar *admissionv1.AdmissionReview) (bo return false, err } - set := map[string]string{ - labelMaster: subnet.Spec.Master, - labelVlan: fmt.Sprintf("%v", subnet.Spec.VLAN), + var subnets = make([]*flv1.FlatNetworkSubnet, 0) + options := v1.ListOptions{ + LabelSelector: fmt.Sprintf("%v=%v,%v=%v", + labelMaster, subnet.Spec.Master, labelVlan, subnet.Spec.VLAN), + Limit: listLimit, + Continue: "", } - subnets, err := h.subnetCache.List(flv1.SubnetNamespace, labels.SelectorFromSet(set)) - if err != nil { - return false, fmt.Errorf("failed to list subnet by selector %q: %w", - utils.Print(set), err) + for { + subnetList, err := h.subnetClient.List(flv1.SubnetNamespace, options) + if err != nil { + return false, fmt.Errorf("failed to list subnet by selector %q: %w", + options.LabelSelector, err) + } + for i := range subnetList.Items { + subnets = append(subnets, subnetList.Items[i].DeepCopy()) + } + if subnetList.Continue == "" { + break + } + options.Continue = subnetList.Continue + time.Sleep(listInterval) } + // Validate subnet spec (CIDR, gw, ranges, routes) if err := common.ValidateSubnet(subnet); err != nil { return false, err diff --git a/pkg/admission/webhook/webhook.go b/pkg/admission/webhook/webhook.go index 3d27013..7fdd6c2 100644 --- a/pkg/admission/webhook/webhook.go +++ b/pkg/admission/webhook/webhook.go @@ -21,28 +21,26 @@ import ( ) type Handler struct { - ipCache flcontroller.FlatNetworkIPCache - subnetCache flcontroller.FlatNetworkSubnetCache - podCache corecontroller.PodCache - deploymentCache appscontroller.DeploymentCache - daemonSetCache appscontroller.DaemonSetCache - replicaSetCache appscontroller.ReplicaSetCache - statefulSetCache appscontroller.StatefulSetCache - cronJobCache batchcontroller.CronJobCache - jobCache batchcontroller.JobCache + ipClient flcontroller.FlatNetworkIPClient + subnetClient flcontroller.FlatNetworkSubnetClient + podClient corecontroller.PodClient + deploymentClient appscontroller.DeploymentClient + daemonSetClient appscontroller.DaemonSetClient + statefulSetClient appscontroller.StatefulSetClient + cronJobClient batchcontroller.CronJobClient + jobClient batchcontroller.JobClient } func NewWebhookHandler(wctx *wrangler.Context) *Handler { return &Handler{ - ipCache: wctx.FlatNetwork.FlatNetworkIP().Cache(), - subnetCache: wctx.FlatNetwork.FlatNetworkSubnet().Cache(), - podCache: wctx.Core.Pod().Cache(), - deploymentCache: wctx.Apps.Deployment().Cache(), - daemonSetCache: wctx.Apps.DaemonSet().Cache(), - replicaSetCache: wctx.Apps.ReplicaSet().Cache(), - statefulSetCache: wctx.Apps.StatefulSet().Cache(), - cronJobCache: wctx.Batch.CronJob().Cache(), - jobCache: wctx.Batch.Job().Cache(), + ipClient: wctx.FlatNetwork.FlatNetworkIP(), + subnetClient: wctx.FlatNetwork.FlatNetworkSubnet(), + podClient: wctx.Core.Pod(), + deploymentClient: wctx.Apps.Deployment(), + daemonSetClient: wctx.Apps.DaemonSet(), + statefulSetClient: wctx.Apps.StatefulSet(), + cronJobClient: wctx.Batch.CronJob(), + jobClient: wctx.Batch.Job(), } } diff --git a/pkg/admission/webhook/workload.go b/pkg/admission/webhook/workload.go index d03f31d..218cba0 100644 --- a/pkg/admission/webhook/workload.go +++ b/pkg/admission/webhook/workload.go @@ -121,7 +121,8 @@ func (h *Handler) validateAnnotationIP(workload *WorkloadReview) error { return err } // Check the ip is available in subnet CIDR and not gateway - subnet, err := h.subnetCache.Get(flv1.SubnetNamespace, workload.PodTemplateAnnotations(flv1.AnnotationSubnet)) + subnet, err := h.subnetClient.Get( + flv1.SubnetNamespace, workload.PodTemplateAnnotations(flv1.AnnotationSubnet), metav1.GetOptions{}) if err != nil { return err } @@ -217,7 +218,7 @@ func (h *Handler) isUpdatingWorkloadSubnetLabel(workload *WorkloadReview) bool { name, namespace := workload.ObjectMeta.Name, workload.ObjectMeta.Namespace switch workload.AdmissionReview.Request.Kind.Kind { case kindDeployment: - old, err := h.deploymentCache.Get(namespace, name) + old, err := h.deploymentClient.Get(namespace, name, metav1.GetOptions{}) if err != nil { return false } @@ -226,7 +227,7 @@ func (h *Handler) isUpdatingWorkloadSubnetLabel(workload *WorkloadReview) bool { return true } case kindDaemonSet: - old, err := h.daemonSetCache.Get(namespace, name) + old, err := h.daemonSetClient.Get(namespace, name, metav1.GetOptions{}) if err != nil { return false } @@ -235,7 +236,7 @@ func (h *Handler) isUpdatingWorkloadSubnetLabel(workload *WorkloadReview) bool { return true } case kindStatefulSet: - old, err := h.statefulSetCache.Get(namespace, name) + old, err := h.statefulSetClient.Get(namespace, name, metav1.GetOptions{}) if err != nil { return false } @@ -244,7 +245,7 @@ func (h *Handler) isUpdatingWorkloadSubnetLabel(workload *WorkloadReview) bool { return true } case kindCronJob: - old, err := h.cronJobCache.Get(namespace, name) + old, err := h.cronJobClient.Get(namespace, name, metav1.GetOptions{}) if err != nil { return false } @@ -253,7 +254,7 @@ func (h *Handler) isUpdatingWorkloadSubnetLabel(workload *WorkloadReview) bool { return true } case kindJob: - old, err := h.jobCache.Get(namespace, name) + old, err := h.jobClient.Get(namespace, name, metav1.GetOptions{}) if err != nil { return false }