diff --git a/pkg/ipam/ipam.go b/pkg/ipam/ipam.go index a7eb1d719d..7341f20a06 100644 --- a/pkg/ipam/ipam.go +++ b/pkg/ipam/ipam.go @@ -72,26 +72,75 @@ func New(ctx context.Context, cl client.Client, opts *ServerOptions) (*LiqoIPAM, } // IPAcquire acquires a free IP from a given CIDR. -func (lipam *LiqoIPAM) IPAcquire(_ context.Context, _ *IPAcquireRequest) (*IPAcquireResponse, error) { - panic("implement me") +func (lipam *LiqoIPAM) IPAcquire(_ context.Context, req *IPAcquireRequest) (*IPAcquireResponse, error) { + remappedIP, err := lipam.acquireIP(req.GetCidr()) + if err != nil { + return &IPAcquireResponse{ + Result: &ResponseResult{ + Success: false, + Error: err.Error(), + }, + }, err + } + + return &IPAcquireResponse{ + Ip: remappedIP, + Result: &ResponseResult{ + Success: true, + }, + }, nil } // IPRelease releases an IP from a given CIDR. -func (lipam *LiqoIPAM) IPRelease(_ context.Context, _ *IPReleaseRequest) (*IPReleaseResponse, error) { - panic("implement me") +func (lipam *LiqoIPAM) IPRelease(_ context.Context, req *IPReleaseRequest) (*IPReleaseResponse, error) { + lipam.freeIP(ipCidr{ip: req.GetIp(), cidr: req.GetCidr()}) + + return &IPReleaseResponse{ + Result: &ResponseResult{ + Success: true, + }, + }, nil } // NetworkAcquire acquires a network. If it is already reserved, it allocates and reserves a new free one with the same prefix length. -func (lipam *LiqoIPAM) NetworkAcquire(_ context.Context, _ *NetworkAcquireRequest) (*NetworkAcquireResponse, error) { - panic("implement me") +func (lipam *LiqoIPAM) NetworkAcquire(_ context.Context, req *NetworkAcquireRequest) (*NetworkAcquireResponse, error) { + remappedCidr, err := lipam.acquireNetwork(req.GetCidr(), req.GetImmutable()) + if err != nil { + return &NetworkAcquireResponse{ + Result: &ResponseResult{ + Success: false, + Error: err.Error(), + }, + }, err + } + + return &NetworkAcquireResponse{ + Cidr: remappedCidr, + Result: &ResponseResult{ + Success: true, + }, + }, nil } // NetworkRelease releases a network. -func (lipam *LiqoIPAM) NetworkRelease(_ context.Context, _ *NetworkReleaseRequest) (*NetworkReleaseResponse, error) { - panic("implement me") +func (lipam *LiqoIPAM) NetworkRelease(_ context.Context, req *NetworkReleaseRequest) (*NetworkReleaseResponse, error) { + lipam.freeNetwork(req.GetCidr()) + + return &NetworkReleaseResponse{ + Result: &ResponseResult{ + Success: true, + }, + }, nil } // NetworkIsAvailable checks if a network is available. -func (lipam *LiqoIPAM) NetworkIsAvailable(_ context.Context, _ *NetworkAvailableRequest) (*NetworkAvailableResponse, error) { - panic("implement me") +func (lipam *LiqoIPAM) NetworkIsAvailable(_ context.Context, req *NetworkAvailableRequest) (*NetworkAvailableResponse, error) { + available := lipam.isNetworkAvailable(req.GetCidr()) + + return &NetworkAvailableResponse{ + Available: available, + Result: &ResponseResult{ + Success: true, + }, + }, nil } diff --git a/pkg/ipam/ips.go b/pkg/ipam/ips.go index 2ae7eed0ab..0a9117985c 100644 --- a/pkg/ipam/ips.go +++ b/pkg/ipam/ips.go @@ -43,17 +43,38 @@ func (lipam *LiqoIPAM) reserveIP(ip ipCidr) error { lipam.mutex.Lock() defer lipam.mutex.Unlock() - ipI := ipInfo{ + if lipam.cacheIPs == nil { + lipam.cacheIPs = make(map[string]ipInfo) + } + lipam.cacheIPs[ip.String()] = ipInfo{ ipCidr: ip, creationTimestamp: time.Now(), } + + klog.Infof("Reserved IP %q (network %q)", ip.ip, ip.cidr) + return nil +} + +// acquireIP acquires an IP, eventually remapped if conflicts are found. +func (lipam *LiqoIPAM) acquireIP(cidr string) (string, error) { + lipam.mutex.Lock() + defer lipam.mutex.Unlock() + + // TODO: implement real IP acquire logic if lipam.cacheIPs == nil { lipam.cacheIPs = make(map[string]ipInfo) } - lipam.cacheIPs[ip.String()] = ipI + ip := ipCidr{ + ip: "", + cidr: cidr, + } + lipam.cacheIPs[ip.String()] = ipInfo{ + ipCidr: ip, + creationTimestamp: time.Now(), + } - klog.Infof("Reserved IP %q (network %q)", ip.ip, ip.cidr) - return nil + klog.Infof("Acquired IP %q (network %q)", ip.ip, ip.cidr) + return ip.ip, nil } // freeIP frees an IP, removing it from the cache. diff --git a/pkg/ipam/networks.go b/pkg/ipam/networks.go index 29c0682404..d0c785d3c8 100644 --- a/pkg/ipam/networks.go +++ b/pkg/ipam/networks.go @@ -34,17 +34,35 @@ func (lipam *LiqoIPAM) reserveNetwork(cidr string) error { lipam.mutex.Lock() defer lipam.mutex.Unlock() - nwI := networkInfo{ + if lipam.cacheNetworks == nil { + lipam.cacheNetworks = make(map[string]networkInfo) + } + lipam.cacheNetworks[cidr] = networkInfo{ cidr: cidr, creationTimestamp: time.Now(), } + + klog.Infof("Reserved network %q", cidr) + return nil +} + +// acquireNetwork acquires a network, eventually remapped if conflicts are found. +func (lipam *LiqoIPAM) acquireNetwork(cidr string, immutable bool) (string, error) { + lipam.mutex.Lock() + defer lipam.mutex.Unlock() + + // TODO: implement real network acquire logic + _ = immutable if lipam.cacheNetworks == nil { lipam.cacheNetworks = make(map[string]networkInfo) } - lipam.cacheNetworks[cidr] = nwI + lipam.cacheNetworks[cidr] = networkInfo{ + cidr: cidr, + creationTimestamp: time.Now(), + } - klog.Infof("Reserved network %q", cidr) - return nil + klog.Infof("Acquired network %q", cidr) + return cidr, nil } // freeNetwork frees a network, removing it from the cache. @@ -56,6 +74,19 @@ func (lipam *LiqoIPAM) freeNetwork(cidr string) { klog.Infof("Freed network %q", cidr) } +// isNetworkAvailable checks if a network is available. +func (lipam *LiqoIPAM) isNetworkAvailable(cidr string) bool { + lipam.mutex.Lock() + defer lipam.mutex.Unlock() + + if lipam.cacheNetworks == nil { + return true + } + _, ok := lipam.cacheNetworks[cidr] + + return ok +} + func listNetworksOnCluster(ctx context.Context, cl client.Client) ([]string, error) { var nets []string var networks ipamv1alpha1.NetworkList