cilium
154 строки · 4.5 Кб
1// SPDX-License-Identifier: Apache-2.0
2// Copyright Authors of Cilium
3
4package driver
5
6import (
7"encoding/json"
8"fmt"
9"net/http"
10
11"github.com/docker/libnetwork/ipams/remote/api"
12
13"github.com/cilium/cilium/pkg/client"
14"github.com/cilium/cilium/pkg/logging/logfields"
15)
16
17const (
18PoolIPv4 = "CiliumPoolv4"
19PoolIPv6 = "CiliumPoolv6"
20)
21
22func (driver *driver) ipamCapabilities(w http.ResponseWriter, r *http.Request) {
23err := json.NewEncoder(w).Encode(&api.GetCapabilityResponse{})
24if err != nil {
25log.WithError(err).Fatal("capabilities encode")
26sendError(w, "encode error", http.StatusInternalServerError)
27return
28}
29log.Debug("IPAM capabilities exchange complete")
30}
31
32func (driver *driver) getDefaultAddressSpaces(w http.ResponseWriter, r *http.Request) {
33log.Debug("GetDefaultAddressSpaces Called")
34
35resp := &api.GetAddressSpacesResponse{
36LocalDefaultAddressSpace: "CiliumLocal",
37GlobalDefaultAddressSpace: "CiliumGlobal",
38}
39
40log.WithField(logfields.Response, logfields.Repr(resp)).Debug("Get Default Address Spaces response")
41objectResponse(w, resp)
42}
43
44func (driver *driver) getPoolResponse(req *api.RequestPoolRequest) *api.RequestPoolResponse {
45addr := driver.conf.Addressing
46if !req.V6 {
47return &api.RequestPoolResponse{
48PoolID: PoolIPv4,
49Pool: "0.0.0.0/0",
50Data: map[string]string{
51"com.docker.network.gateway": addr.IPV4.IP + "/32",
52},
53}
54}
55
56return &api.RequestPoolResponse{
57PoolID: PoolIPv6,
58Pool: addr.IPV6.AllocRange,
59Data: map[string]string{
60"com.docker.network.gateway": addr.IPV6.IP + "/128",
61},
62}
63}
64
65func (driver *driver) requestPool(w http.ResponseWriter, r *http.Request) {
66var req api.RequestPoolRequest
67
68if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
69sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest)
70return
71}
72
73log.WithField(logfields.Request, logfields.Repr(&req)).Debug("Request Pool request")
74resp := driver.getPoolResponse(&req)
75log.WithField(logfields.Response, logfields.Repr(resp)).Debug("Request Pool response")
76objectResponse(w, resp)
77}
78
79func (driver *driver) releasePool(w http.ResponseWriter, r *http.Request) {
80var release api.ReleasePoolRequest
81if err := json.NewDecoder(r.Body).Decode(&release); err != nil {
82sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest)
83return
84}
85
86log.WithField(logfields.Request, logfields.Repr(&release)).Debug("Release Pool request")
87
88emptyResponse(w)
89}
90
91func (driver *driver) requestAddress(w http.ResponseWriter, r *http.Request) {
92var request api.RequestAddressRequest
93if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
94sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest)
95return
96}
97
98log.WithField(logfields.Request, logfields.Repr(&request)).Debug("Request Address request")
99
100family := client.AddressFamilyIPv6 // Default
101switch request.PoolID {
102case PoolIPv4:
103family = client.AddressFamilyIPv4
104case PoolIPv6:
105family = client.AddressFamilyIPv6
106}
107
108ipam, err := driver.client.IPAMAllocate(family, "docker-ipam", "", false)
109if err != nil {
110sendError(w, fmt.Sprintf("Could not allocate IP address: %s", err), http.StatusBadRequest)
111return
112}
113
114// The host addressing may have changed due to a daemon restart, update it
115driver.updateRoutes(ipam.HostAddressing)
116
117addr := ipam.Address
118if addr == nil {
119sendError(w, "No IP addressing provided", http.StatusBadRequest)
120return
121}
122
123resp := &api.RequestAddressResponse{}
124if addr.IPV6 != "" {
125if family != client.AddressFamilyIPv6 {
126sendError(w, "Requested IPv4, received IPv6 address", http.StatusInternalServerError)
127}
128resp.Address = addr.IPV6 + "/128"
129} else if addr.IPV4 != "" {
130if family != client.AddressFamilyIPv4 {
131sendError(w, "Requested IPv6, received IPv4 address", http.StatusInternalServerError)
132}
133resp.Address = addr.IPV4 + "/32"
134}
135
136log.WithField(logfields.Response, logfields.Repr(resp)).Debug("Request Address response")
137objectResponse(w, resp)
138}
139
140func (driver *driver) releaseAddress(w http.ResponseWriter, r *http.Request) {
141var release api.ReleaseAddressRequest
142if err := json.NewDecoder(r.Body).Decode(&release); err != nil {
143sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest)
144return
145}
146
147log.WithField(logfields.Request, logfields.Repr(&release)).Debug("Release Address request")
148if err := driver.client.IPAMReleaseIP(release.Address, ""); err != nil {
149sendError(w, fmt.Sprintf("Could not release IP address: %s", err), http.StatusBadRequest)
150return
151}
152
153emptyResponse(w)
154}
155