-
Notifications
You must be signed in to change notification settings - Fork 137
Expand file tree
/
Copy pathapi.go
More file actions
173 lines (155 loc) · 4.66 KB
/
api.go
File metadata and controls
173 lines (155 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package ipam
import (
"net/http"
"github.com/docker/go-plugins-helpers/sdk"
)
const (
manifest = `{"Implements": ["IpamDriver"]}`
capabilitiesPath = "/IpamDriver.GetCapabilities"
addressSpacesPath = "/IpamDriver.GetDefaultAddressSpaces"
requestPoolPath = "/IpamDriver.RequestPool"
releasePoolPath = "/IpamDriver.ReleasePool"
requestAddressPath = "/IpamDriver.RequestAddress"
releaseAddressPath = "/IpamDriver.ReleaseAddress"
)
// Ipam represent the interface a driver must fulfill.
type Ipam interface {
GetCapabilities() (*CapabilitiesResponse, error)
GetDefaultAddressSpaces() (*AddressSpacesResponse, error)
RequestPool(*RequestPoolRequest) (*RequestPoolResponse, error)
ReleasePool(*ReleasePoolRequest) error
RequestAddress(*RequestAddressRequest) (*RequestAddressResponse, error)
ReleaseAddress(*ReleaseAddressRequest) error
}
// CapabilitiesResponse returns whether or not this IPAM required pre-made MAC
type CapabilitiesResponse struct {
RequiresMACAddress bool
}
// AddressSpacesResponse returns the default local and global address space names for this IPAM
type AddressSpacesResponse struct {
LocalDefaultAddressSpace string
GlobalDefaultAddressSpace string
}
// RequestPoolRequest is sent by the daemon when a pool needs to be created
type RequestPoolRequest struct {
AddressSpace string
Pool string
SubPool string
Options map[string]string
V6 bool
}
// RequestPoolResponse returns a registered address pool with the IPAM driver
type RequestPoolResponse struct {
PoolID string
Pool string
Data map[string]string
}
// ReleasePoolRequest is sent when releasing a previously registered address pool
type ReleasePoolRequest struct {
PoolID string
}
// RequestAddressRequest is sent when requesting an address from IPAM
type RequestAddressRequest struct {
PoolID string
Address string
Options map[string]string
}
// RequestAddressResponse is formed with allocated address by IPAM
type RequestAddressResponse struct {
Address string
Data map[string]string
}
// ReleaseAddressRequest is sent in order to release an address from the pool
type ReleaseAddressRequest struct {
PoolID string
Address string
}
// ErrorResponse is a formatted error message that libnetwork can understand
type ErrorResponse struct {
Err string
}
// NewErrorResponse creates an ErrorResponse with the provided message
func NewErrorResponse(msg string) *ErrorResponse {
return &ErrorResponse{Err: msg}
}
// Handler forwards requests and responses between the docker daemon and the plugin.
type Handler struct {
ipam Ipam
sdk.Handler
}
// NewHandler initializes the request handler with a driver implementation.
func NewHandler(ipam Ipam) *Handler {
h := &Handler{ipam, sdk.NewHandler(manifest)}
h.initMux()
return h
}
func (h *Handler) initMux() {
h.HandleFunc(capabilitiesPath, func(w http.ResponseWriter, r *http.Request) {
res, err := h.ipam.GetCapabilities()
if err != nil {
sdk.EncodeResponse(w, NewErrorResponse(err.Error()), true)
return
}
sdk.EncodeResponse(w, res, false)
})
h.HandleFunc(addressSpacesPath, func(w http.ResponseWriter, r *http.Request) {
res, err := h.ipam.GetDefaultAddressSpaces()
if err != nil {
sdk.EncodeResponse(w, NewErrorResponse(err.Error()), true)
return
}
sdk.EncodeResponse(w, res, false)
})
h.HandleFunc(requestPoolPath, func(w http.ResponseWriter, r *http.Request) {
req := &RequestPoolRequest{}
err := sdk.DecodeRequest(w, r, req)
if err != nil {
return
}
res, err := h.ipam.RequestPool(req)
if err != nil {
sdk.EncodeResponse(w, NewErrorResponse(err.Error()), true)
return
}
sdk.EncodeResponse(w, res, false)
})
h.HandleFunc(releasePoolPath, func(w http.ResponseWriter, r *http.Request) {
req := &ReleasePoolRequest{}
err := sdk.DecodeRequest(w, r, req)
if err != nil {
return
}
err = h.ipam.ReleasePool(req)
if err != nil {
sdk.EncodeResponse(w, NewErrorResponse(err.Error()), true)
return
}
sdk.EncodeResponse(w, struct{}{}, false)
})
h.HandleFunc(requestAddressPath, func(w http.ResponseWriter, r *http.Request) {
req := &RequestAddressRequest{}
err := sdk.DecodeRequest(w, r, req)
if err != nil {
return
}
res, err := h.ipam.RequestAddress(req)
if err != nil {
sdk.EncodeResponse(w, NewErrorResponse(err.Error()), true)
return
}
sdk.EncodeResponse(w, res, false)
})
h.HandleFunc(releaseAddressPath, func(w http.ResponseWriter, r *http.Request) {
req := &ReleaseAddressRequest{}
err := sdk.DecodeRequest(w, r, req)
if err != nil {
return
}
err = h.ipam.ReleaseAddress(req)
if err != nil {
sdk.EncodeResponse(w, NewErrorResponse(err.Error()), true)
return
}
sdk.EncodeResponse(w, struct{}{}, false)
})
}