github.com/looshlee/cilium@v1.6.12/plugins/cilium-docker/driver/ipam.go (about) 1 // Copyright 2016-2017 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package driver 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "net/http" 21 22 "github.com/cilium/cilium/pkg/client" 23 "github.com/cilium/cilium/pkg/logging/logfields" 24 25 "github.com/docker/libnetwork/ipams/remote/api" 26 ) 27 28 const ( 29 PoolIPv4 = "CiliumPoolv4" 30 PoolIPv6 = "CiliumPoolv6" 31 ) 32 33 func (driver *driver) ipamCapabilities(w http.ResponseWriter, r *http.Request) { 34 err := json.NewEncoder(w).Encode(&api.GetCapabilityResponse{}) 35 if err != nil { 36 log.WithError(err).Fatal("capabilities encode") 37 sendError(w, "encode error", http.StatusInternalServerError) 38 return 39 } 40 log.Debug("IPAM capabilities exchange complete") 41 } 42 43 func (driver *driver) getDefaultAddressSpaces(w http.ResponseWriter, r *http.Request) { 44 log.Debug("GetDefaultAddressSpaces Called") 45 46 resp := &api.GetAddressSpacesResponse{ 47 LocalDefaultAddressSpace: "CiliumLocal", 48 GlobalDefaultAddressSpace: "CiliumGlobal", 49 } 50 51 log.WithField(logfields.Response, logfields.Repr(resp)).Debug("Get Default Address Spaces response") 52 objectResponse(w, resp) 53 } 54 55 func (driver *driver) getPoolResponse(req *api.RequestPoolRequest) *api.RequestPoolResponse { 56 addr := driver.conf.Addressing 57 if req.V6 == false { 58 return &api.RequestPoolResponse{ 59 PoolID: PoolIPv4, 60 Pool: "0.0.0.0/0", 61 Data: map[string]string{ 62 "com.docker.network.gateway": addr.IPV4.IP + "/32", 63 }, 64 } 65 } 66 67 return &api.RequestPoolResponse{ 68 PoolID: PoolIPv6, 69 Pool: addr.IPV6.AllocRange, 70 Data: map[string]string{ 71 "com.docker.network.gateway": addr.IPV6.IP + "/128", 72 }, 73 } 74 } 75 76 func (driver *driver) requestPool(w http.ResponseWriter, r *http.Request) { 77 var req api.RequestPoolRequest 78 79 if err := json.NewDecoder(r.Body).Decode(&req); err != nil { 80 sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest) 81 return 82 } 83 84 log.WithField(logfields.Request, logfields.Repr(&req)).Debug("Request Pool request") 85 resp := driver.getPoolResponse(&req) 86 log.WithField(logfields.Response, logfields.Repr(resp)).Debug("Request Pool response") 87 objectResponse(w, resp) 88 } 89 90 func (driver *driver) releasePool(w http.ResponseWriter, r *http.Request) { 91 var release api.ReleasePoolRequest 92 if err := json.NewDecoder(r.Body).Decode(&release); err != nil { 93 sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest) 94 return 95 } 96 97 log.WithField(logfields.Request, logfields.Repr(&release)).Debug("Release Pool request") 98 99 emptyResponse(w) 100 } 101 102 func (driver *driver) requestAddress(w http.ResponseWriter, r *http.Request) { 103 var request api.RequestAddressRequest 104 if err := json.NewDecoder(r.Body).Decode(&request); err != nil { 105 sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest) 106 return 107 } 108 109 log.WithField(logfields.Request, logfields.Repr(&request)).Debug("Request Address request") 110 111 family := client.AddressFamilyIPv6 // Default 112 switch request.PoolID { 113 case PoolIPv4: 114 family = client.AddressFamilyIPv4 115 case PoolIPv6: 116 family = client.AddressFamilyIPv6 117 } 118 119 ipam, err := driver.client.IPAMAllocate(family, "docker-ipam", false) 120 if err != nil { 121 sendError(w, fmt.Sprintf("Could not allocate IP address: %s", err), http.StatusBadRequest) 122 return 123 } 124 125 // The host addressing may have changed due to a daemon restart, update it 126 driver.updateRoutes(ipam.HostAddressing) 127 128 addr := ipam.Address 129 if addr == nil { 130 sendError(w, "No IP addressing provided", http.StatusBadRequest) 131 return 132 } 133 134 resp := &api.RequestAddressResponse{} 135 if addr.IPV6 != "" { 136 if family != client.AddressFamilyIPv6 { 137 sendError(w, "Requested IPv4, received IPv6 address", http.StatusInternalServerError) 138 } 139 resp.Address = addr.IPV6 + "/128" 140 } else if addr.IPV4 != "" { 141 if family != client.AddressFamilyIPv4 { 142 sendError(w, "Requested IPv6, received IPv4 address", http.StatusInternalServerError) 143 } 144 resp.Address = addr.IPV4 + "/32" 145 } 146 147 log.WithField(logfields.Response, logfields.Repr(resp)).Debug("Request Address response") 148 objectResponse(w, resp) 149 } 150 151 func (driver *driver) releaseAddress(w http.ResponseWriter, r *http.Request) { 152 var release api.ReleaseAddressRequest 153 if err := json.NewDecoder(r.Body).Decode(&release); err != nil { 154 sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest) 155 return 156 } 157 158 log.WithField(logfields.Request, logfields.Repr(&release)).Debug("Release Address request") 159 if err := driver.client.IPAMReleaseIP(release.Address); err != nil { 160 sendError(w, fmt.Sprintf("Could not release IP address: %s", err), http.StatusBadRequest) 161 return 162 } 163 164 emptyResponse(w) 165 }