Skip to content

Commit

Permalink
add delete valid
Browse files Browse the repository at this point in the history
  • Loading branch information
pengbinbin1 committed Aug 18, 2023
1 parent 5ac3cc2 commit 4e526fb
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ go.sum
/cmd/ipamwrapper/test.go
/cmd/ipamwrapper-ds/*.exe
/cmd/ipamwrapper-ds/ipamwrapper-ds
/cmd/controller/*.exe
/cmd/controller/*.exe
/cmd/controller/controller
6 changes: 6 additions & 0 deletions pkg/constant/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,9 @@ const (
AnnoNSDefautlV6Pool = Pre + "/default-ipv6-ippool"
AnnoNSDefautlPool = Pre + "/default-ippool"
)

const (
APIGroup = "inspuripam.inspur.com"
APIVersion = "v1"
IPPOOL = "ippool"
)
12 changes: 12 additions & 0 deletions pkg/controller/ippool/ippool_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/Inspur-Data/ipamwrapper/pkg/constant"
ipamip "github.com/Inspur-Data/ipamwrapper/pkg/ip"
"github.com/Inspur-Data/ipamwrapper/pkg/logging"
"github.com/Inspur-Data/ipamwrapper/pkg/utils/convert"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

Expand Down Expand Up @@ -100,6 +101,17 @@ func (r *IPPoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
logging.Debugf("set ippool '%s' status AllocatedIPCount to 0", req.NamespacedName.String())
}

allocatedIPs, err := convert.UnmarshalIPPoolAllocatedIPs(ippool.Status.AllocatedIPs)
if nil != err {

}

if int64(len(allocatedIPs)) != *ippool.Status.AllocatedIPCount {
needUpdate = true
ippool.Status.AllocatedIPCount = pointer.Int64(int64(len(allocatedIPs)))
logging.Debugf("allocateIPCount unequal to length of the allocatedIPs, set ippool '%s' status AllocatedIPCount to %d", req.NamespacedName, len(allocatedIPs))
}

totalIPs, err := ipamip.AssembleTotalIPs(*ippool.Spec.IPVersion, ippool.Spec.IPs, ippool.Spec.ExcludeIPs)
if nil != err {
logging.Errorf("calculate total ip failed: %v", err)
Expand Down
100 changes: 99 additions & 1 deletion pkg/k8s/api/v1/ippool_validate.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
package v1

import (
"context"
"fmt"
"github.com/Inspur-Data/ipamwrapper/pkg/constant"
ipamwrapperip "github.com/Inspur-Data/ipamwrapper/pkg/ip"
"k8s.io/apimachinery/pkg/util/validation/field"
"strconv"
)

var (
ipVersionField *field.Path = field.NewPath("spec").Child("ipVersion")
subnetField *field.Path = field.NewPath("spec").Child("subnet")
cidrField *field.Path = field.NewPath("spec").Child("cidr")
ipsField *field.Path = field.NewPath("spec").Child("ips")
excludeIPsField *field.Path = field.NewPath("spec").Child("excludeIPs")
allocateIPField *field.Path = field.NewPath("status").Child("allocatedIPCount")
)

func (r *IPPool) validCreate() field.ErrorList {
//check ipversion
if err := r.validIPversion(); err != nil {
return field.ErrorList{err}
}

//check CIDR
ctx := context.Background()
if err := r.validCIDR(ctx); err != nil {
return field.ErrorList{err}
}

//check available ip
if err := r.validAvailableIPs(ctx); err != nil {
return field.ErrorList{err}
}

return nil
}

// validIPversion check the ippool's IP version
func (r *IPPool) validIPversion() *field.Error {
//check ipversion
version := r.Spec.IPVersion
Expand All @@ -36,3 +61,76 @@ func (r *IPPool) validIPversion() *field.Error {

return nil
}

// validCIDR check the ippool's CIDR
func (r *IPPool) validCIDR(ctx context.Context) *field.Error {
//checkout CIDR
if err := ipamwrapperip.IsCIDR(*r.Spec.IPVersion, r.Spec.CIDR); err != nil {
return field.Invalid(
cidrField,
r.Spec.CIDR,
err.Error(),
)
}

var poollist IPPoolList
if err := ippoolClient.List(ctx, &poollist); err != nil {
return field.InternalError(cidrField, fmt.Errorf("failed to list IPPools: %v", err))
}

for _, pool := range poollist.Items {
if *pool.Spec.IPVersion == *r.Spec.IPVersion {
if pool.Name == r.Name {
return field.InternalError(cidrField, fmt.Errorf("IPPool %s already exists", r.Name))
}

if pool.Spec.CIDR == r.Spec.CIDR {
continue
}

overlap, err := ipamwrapperip.IsCIDROverlap(*r.Spec.IPVersion, r.Spec.CIDR, pool.Spec.CIDR)
if err != nil {
return field.InternalError(cidrField, fmt.Errorf("failed to judge whether 'spec.CIDR' overlaped: %v", err))
}

if overlap {
return field.Invalid(
cidrField,
r.Spec.CIDR,
fmt.Sprintf("cidr is overlaped with IPPool %s which 'spec.CIDR' is %s", pool.Name, pool.Spec.CIDR),
)
}
}
}

return nil
}

// validAvailableIPs check the ippool's available ips
func (r *IPPool) validAvailableIPs(ctx context.Context) *field.Error {
//validate exclude ips
for _, excludeIP := range r.Spec.ExcludeIPs {
valid, err := ipamwrapperip.ContainsIP(*r.Spec.IPVersion, r.Spec.CIDR, excludeIP)
if err != nil {
return field.InternalError(excludeIPsField, fmt.Errorf("check contains failed %v", err))
}

if !valid {
return field.Invalid(
excludeIPsField,
excludeIP,
fmt.Sprintf("not pertains to the 'spec.cidr' %s of IPPool", r.Name),
)
}
}

return nil
}

func (r *IPPool) validDelete() field.ErrorList {
if *r.Status.AllocatedIPCount != 0 {
err := field.InternalError(allocateIPField, fmt.Errorf("ippool:%s still has allocated IPs", r.Name))
return field.ErrorList{err}
}
return nil
}
15 changes: 13 additions & 2 deletions pkg/k8s/api/v1/ippool_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ import (
"github.com/Inspur-Data/ipamwrapper/pkg/constant"
ipamip "github.com/Inspur-Data/ipamwrapper/pkg/ip"
"github.com/Inspur-Data/ipamwrapper/pkg/types"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
Expand All @@ -31,8 +34,10 @@ import (

// log is for logging in this package.
var ippoollog = logf.Log.WithName("ippool-resource")
var ippoolClient client.Client

func (r *IPPool) SetupWebhookWithManager(mgr ctrl.Manager) error {
ippoolClient = mgr.GetClient()
return ctrl.NewWebhookManagedBy(mgr).
For(r).
Complete()
Expand Down Expand Up @@ -61,7 +66,10 @@ var _ webhook.Validator = &IPPool{}
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (r *IPPool) ValidateCreate() (warnings admission.Warnings, err error) {
ippoollog.Info("validate create", "name", r.Name)

errlist := r.validCreate()
if len(errlist) != 0 {
return nil, apierrors.NewInvalid(schema.GroupKind{Group: constant.APIGroup, Kind: constant.IPPOOL}, r.Name, errlist)
}
// TODO(user): fill in your validation logic upon object creation.
return nil, nil
}
Expand All @@ -77,7 +85,10 @@ func (r *IPPool) ValidateUpdate(old runtime.Object) (warnings admission.Warnings
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (r *IPPool) ValidateDelete() (warnings admission.Warnings, err error) {
ippoollog.Info("validate delete", "name", r.Name)

errList := r.validDelete()
if len(errList) != 0 {
return nil, apierrors.NewInvalid(schema.GroupKind{Group: constant.APIGroup, Kind: constant.IPPOOL}, r.Name, errList)
}
// TODO(user): fill in your validation logic upon object deletion.
return nil, nil
}
Expand Down
1 change: 1 addition & 0 deletions pkg/manager/ippoolmanager/ippool_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ func (im *ipPoolManager) ReleaseIP(ctx context.Context, poolName string, ipAndUI
delete(allocatedRecords, iu.IP)
*ipPool.Status.AllocatedIPCount--
release = true
logging.Debugf("release ip:%s,pod :%s", iu.IP, record.NamespacedName)
}
}
}
Expand Down

0 comments on commit 4e526fb

Please sign in to comment.