github.com/cilium/cilium@v1.16.2/pkg/ipam/api/ipam_api_handler.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package ipamapi
     5  
     6  import (
     7  	"fmt"
     8  	"net"
     9  	"strings"
    10  
    11  	"github.com/go-openapi/runtime/middleware"
    12  	"github.com/go-openapi/swag"
    13  
    14  	"github.com/cilium/cilium/api/v1/models"
    15  	ipamapi "github.com/cilium/cilium/api/v1/server/restapi/ipam"
    16  	"github.com/cilium/cilium/pkg/api"
    17  	"github.com/cilium/cilium/pkg/defaults"
    18  	"github.com/cilium/cilium/pkg/endpointmanager"
    19  	"github.com/cilium/cilium/pkg/ipam"
    20  	"github.com/cilium/cilium/pkg/node"
    21  	"github.com/cilium/cilium/pkg/time"
    22  )
    23  
    24  type IpamDeleteIpamIPHandler struct {
    25  	IPAM            *ipam.IPAM
    26  	EndpointManager endpointmanager.EndpointManager
    27  }
    28  
    29  type IpamPostIpamHandler struct {
    30  	IPAM *ipam.IPAM
    31  }
    32  
    33  type IpamPostIpamIPHandler struct {
    34  	IPAM *ipam.IPAM
    35  }
    36  
    37  func (r *IpamPostIpamHandler) Handle(params ipamapi.PostIpamParams) middleware.Responder {
    38  	family := strings.ToLower(swag.StringValue(params.Family))
    39  	owner := swag.StringValue(params.Owner)
    40  	pool := ipam.Pool(swag.StringValue(params.Pool))
    41  	var expirationTimeout time.Duration
    42  	if swag.BoolValue(params.Expiration) {
    43  		expirationTimeout = defaults.IPAMExpiration
    44  	}
    45  	ipv4Result, ipv6Result, err := r.IPAM.AllocateNextWithExpiration(family, owner, pool, expirationTimeout)
    46  	if err != nil {
    47  		return api.Error(ipamapi.PostIpamFailureCode, err)
    48  	}
    49  
    50  	resp := &models.IPAMResponse{
    51  		HostAddressing: node.GetNodeAddressing(),
    52  		Address:        &models.AddressPair{},
    53  	}
    54  
    55  	if ipv4Result != nil {
    56  		resp.Address.IPV4 = ipv4Result.IP.String()
    57  		resp.Address.IPV4PoolName = ipv4Result.IPPoolName.String()
    58  		resp.IPV4 = &models.IPAMAddressResponse{
    59  			Cidrs:           ipv4Result.CIDRs,
    60  			IP:              ipv4Result.IP.String(),
    61  			MasterMac:       ipv4Result.PrimaryMAC,
    62  			Gateway:         ipv4Result.GatewayIP,
    63  			ExpirationUUID:  ipv4Result.ExpirationUUID,
    64  			InterfaceNumber: ipv4Result.InterfaceNumber,
    65  		}
    66  	}
    67  
    68  	if ipv6Result != nil {
    69  		resp.Address.IPV6 = ipv6Result.IP.String()
    70  		resp.Address.IPV6PoolName = ipv6Result.IPPoolName.String()
    71  		resp.IPV6 = &models.IPAMAddressResponse{
    72  			Cidrs:           ipv6Result.CIDRs,
    73  			IP:              ipv6Result.IP.String(),
    74  			MasterMac:       ipv6Result.PrimaryMAC,
    75  			Gateway:         ipv6Result.GatewayIP,
    76  			ExpirationUUID:  ipv6Result.ExpirationUUID,
    77  			InterfaceNumber: ipv6Result.InterfaceNumber,
    78  		}
    79  	}
    80  
    81  	return ipamapi.NewPostIpamCreated().WithPayload(resp)
    82  }
    83  
    84  // Handle incoming requests address allocation requests for the daemon.
    85  func (r *IpamPostIpamIPHandler) Handle(params ipamapi.PostIpamIPParams) middleware.Responder {
    86  	owner := swag.StringValue(params.Owner)
    87  	pool := ipam.Pool(swag.StringValue(params.Pool))
    88  	if err := r.IPAM.AllocateIPString(params.IP, owner, pool); err != nil {
    89  		return api.Error(ipamapi.PostIpamIPFailureCode, err)
    90  	}
    91  
    92  	return ipamapi.NewPostIpamIPOK()
    93  }
    94  
    95  func (r *IpamDeleteIpamIPHandler) Handle(params ipamapi.DeleteIpamIPParams) middleware.Responder {
    96  	// Release of an IP that is in use is not allowed
    97  	if ep := r.EndpointManager.LookupIPv4(params.IP); ep != nil {
    98  		return api.Error(ipamapi.DeleteIpamIPFailureCode, fmt.Errorf("IP is in use by endpoint %d", ep.ID))
    99  	}
   100  	if ep := r.EndpointManager.LookupIPv6(params.IP); ep != nil {
   101  		return api.Error(ipamapi.DeleteIpamIPFailureCode, fmt.Errorf("IP is in use by endpoint %d", ep.ID))
   102  	}
   103  
   104  	ip := net.ParseIP(params.IP)
   105  	if ip == nil {
   106  		return api.Error(ipamapi.DeleteIpamIPInvalidCode, fmt.Errorf("Invalid IP address: %s", params.IP))
   107  	}
   108  
   109  	pool := ipam.Pool(swag.StringValue(params.Pool))
   110  	if err := r.IPAM.ReleaseIP(ip, pool); err != nil {
   111  		return api.Error(ipamapi.DeleteIpamIPFailureCode, err)
   112  	}
   113  
   114  	return ipamapi.NewDeleteIpamIPOK()
   115  }