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 }