Skip to content

Commit 4ff7922

Browse files
committed
Add first cut at networking API
1 parent 714179e commit 4ff7922

File tree

1 file changed

+168
-57
lines changed

1 file changed

+168
-57
lines changed

api.go

Lines changed: 168 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,96 @@ import (
99
)
1010

1111
const (
12-
// DefaultDockerRootDirectory is the default directory where volumes will be created.
13-
DefaultDockerRootDirectory = "/var/lib/docker-volumes"
14-
1512
defaultContentTypeV1_1 = "application/vnd.docker.plugins.v1.1+json"
16-
defaultImplementationManifest = `{"Implements": ["VolumeDriver"]}`
17-
18-
activatePath = "/Plugin.Activate"
19-
createPath = "/VolumeDriver.Create"
20-
remotePath = "/VolumeDriver.Remove"
21-
hostVirtualPath = "/VolumeDriver.Path"
22-
mountPath = "/VolumeDriver.Mount"
23-
unmountPath = "/VolumeDriver.Unmount"
13+
defaultImplementationManifest = `{"Implements": ["NetworkDriver"]}`
14+
defaultScope = `{"Scope":"Local"]`
15+
16+
activatePath = "/Plugin.Activate"
17+
capabilitiesPath = "/NetworkDriver.GetCapabilities"
18+
createNetworkPath = "/NetworkDriver.CreateNetwork"
19+
deleteNetworkPath = "/NetworkDriver.DeleteNetwork"
20+
createEndpointPath = "/NetworkDriver.CreateEndpoint"
21+
//infoEndpointPath = "/NetworkDriver.EndpointOperInfo"
22+
deleteEndpointPath = "/NetworkDriver.DeleteEndpoint"
23+
joinPath = "/NetworkDriver.Join"
24+
leavePath = "/NetworkDriver.Leave"
25+
//discoverNewPath = "/NetworkDriver.DiscoverNew"
26+
//discoverDeletePath = "/NetworkDriver.DiscoverDelete"
2427
)
2528

26-
// Request is the structure that docker's requests are deserialized to.
27-
type Request struct {
28-
Name string
29-
Options map[string]string `json:"Opts,omitempty"`
29+
// Driver represent the interface a driver must fulfill.
30+
type Driver interface {
31+
CreateNetwork(CreateNetworkRequest) error
32+
DeleteNetwork(DeleteNetworkRequest) error
33+
CreateEndpoint(CreateEndpointRequest) error
34+
DeleteEndpoint(DeleteEndpointRequest) error
35+
Join(JoinRequest) (JoinResponse, error)
36+
Leave(LeaveRequest) error
3037
}
3138

32-
// Response is the strucutre that the plugin's responses are serialized to.
33-
type Response struct {
34-
Mountpoint string
35-
Err string
39+
type NetworkCreateRequest struct {
40+
NetworkID string
41+
Options map[string]interface{}
42+
IpV4Data []driverapi.IPAMData
43+
ipV6Data []driverapi.IPAMData
3644
}
3745

38-
// Driver represent the interface a driver must fulfill.
39-
type Driver interface {
40-
Create(Request) Response
41-
Remove(Request) Response
42-
Path(Request) Response
43-
Mount(Request) Response
44-
Unmount(Request) Response
46+
type NetworkDeleteRequest struct {
47+
NetworkID string
48+
}
49+
50+
type EndpointCreateRequest struct {
51+
NetworkID string
52+
EndpointID string
53+
Interface *EndpointInterface
54+
Options map[string]interface{}
55+
}
56+
57+
type EndpointInterface struct {
58+
Address string
59+
AddressIPv6 string
60+
MacAddress string
61+
}
62+
63+
type InterfaceName struct {
64+
SrcName string
65+
DstPrefix string
66+
}
67+
68+
/* Not supported in this library right now
69+
type EndpointOperInfoRequest struct {
70+
NetworkID string
71+
EnpointID string
72+
}
73+
74+
type EndpointOperInfoResponse struct {
75+
Value map[string]string
76+
}
77+
*/
78+
79+
type JoinRequest struct {
80+
NetworkID string
81+
EndpointID string
82+
SandboxKey string
83+
Options map[string]interface{}
84+
}
85+
86+
type StaticRoute struct {
87+
Destination string
88+
RouteType int
89+
NextHop string
90+
}
91+
92+
type JoinResponse struct {
93+
Gateway string
94+
InterfaceName InterfaceName
95+
StaticRoutes []*staticRoute
96+
}
97+
98+
type LeaveRequest struct {
99+
NetworkID string
100+
EndpointID string
101+
Options map[string]interface{}
45102
}
46103

47104
// Handler forwards requests and responses between the docker daemon and the plugin.
@@ -50,8 +107,6 @@ type Handler struct {
50107
mux *http.ServeMux
51108
}
52109

53-
type actionHandler func(Request) Response
54-
55110
// NewHandler initializes the request handler with a driver implementation.
56111
func NewHandler(driver Driver) *Handler {
57112
h := &Handler{driver, http.NewServeMux()}
@@ -65,38 +120,84 @@ func (h *Handler) initMux() {
65120
fmt.Fprintln(w, defaultImplementationManifest)
66121
})
67122

68-
h.handle(createPath, func(req Request) Response {
69-
return h.driver.Create(req)
123+
h.mux.HandleFunc(capabilitiesPath, func(w http.ResponseWriter, r *http.Request) {
124+
w.Header().Set("Content-Type", defaultContentTypeV1_1)
125+
fmt.Fprintln(w, defaultScope)
70126
})
71127

72-
h.handle(remotePath, func(req Request) Response {
73-
return h.driver.Remove(req)
128+
h.mux.HandleFunc(createNetworkPath, func(w http.ResponseWriter, r *http.Request) {
129+
req = &NetworkCreateRequest{}
130+
err := decodeRequest(w, r, req)
131+
if err != nil {
132+
return
133+
}
134+
err = h.Driver.CreateNetwork(req)
135+
if err != nil {
136+
errorResponse(w, err)
137+
}
138+
successResponse(w)
74139
})
75-
76-
h.handle(hostVirtualPath, func(req Request) Response {
77-
return h.driver.Path(req)
140+
h.mux.HandleFunc(createDeletePath, func(w http.ResponseWriter, r *http.Request) {
141+
req = &NetworkDeleteRequest{}
142+
err := decodeRequest(w, r, req)
143+
if err != nil {
144+
return
145+
}
146+
err = h.Driver.DeleteNetwork(req)
147+
if err != nil {
148+
errorResponse(w, err)
149+
}
150+
successResponse(w)
78151
})
79-
80-
h.handle(mountPath, func(req Request) Response {
81-
return h.driver.Mount(req)
152+
h.mux.HandleFunc(endpointCreatePath, func(w http.ResponseWriter, r *http.Request) {
153+
req = &EndpointCreateRequest{}
154+
err := decodeRequest(w, r, req)
155+
if err != nil {
156+
return
157+
}
158+
err = h.Driver.CreateEndpoint(req)
159+
if err != nil {
160+
errorResponse(w, err)
161+
}
162+
successResponse(w)
82163
})
83-
84-
h.handle(unmountPath, func(req Request) Response {
85-
return h.driver.Unmount(req)
164+
h.mux.HandleFunc(endpointDeletePath, func(w http.ResponseWriter, r *http.Request) {
165+
req = &EndpointDeleteRequest{}
166+
err := decodeRequest(w, r, req)
167+
if err != nil {
168+
return
169+
}
170+
err = h.Driver.DeleteEndpoint(req)
171+
if err != nil {
172+
errorResponse(w, err)
173+
}
174+
successResponse(w)
86175
})
87-
}
88-
89-
func (h *Handler) handle(name string, actionCall actionHandler) {
90-
h.mux.HandleFunc(name, func(w http.ResponseWriter, r *http.Request) {
91-
req, err := decodeRequest(w, r)
176+
h.mux.HandleFunc(joinPath, func(w http.ResponseWriter, r *http.Request) {
177+
req = &JoinRequest{}
178+
err := decodeRequest(w, r, req)
92179
if err != nil {
93180
return
94181
}
95-
96-
res := actionCall(req)
97-
98-
encodeResponse(w, res)
182+
res, err := h.Driver.Join(req)
183+
if err != nil {
184+
errorResponse(w, err)
185+
}
186+
objectResponse(w, res)
99187
})
188+
h.mux.HandleFunc(leavePath, func(w http.ResponseWriter, r *http.Request) {
189+
req = &LeaveRequest{}
190+
err := decodeRequest(w, r, req)
191+
if err != nil {
192+
return
193+
}
194+
err = h.Driver.Leave(req)
195+
if err != nil {
196+
errorResponse(w, err)
197+
}
198+
successResponse(w)
199+
})
200+
100201
}
101202

102203
// ServeTCP makes the handler to listen for request in a given TCP address.
@@ -142,17 +243,27 @@ func (h *Handler) listenAndServe(proto, addr, group string) error {
142243
return server.Serve(l)
143244
}
144245

145-
func decodeRequest(w http.ResponseWriter, r *http.Request) (req Request, err error) {
146-
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
246+
func decodeResponse(w http.ResponseWriter, r http.Request, req *interface{}) error {
247+
if err = json.NewDecoder(r.Body).Decode(req); err != nil {
147248
http.Error(w, err.Error(), http.StatusBadRequest)
148249
}
149250
return
150251
}
151252

152-
func encodeResponse(w http.ResponseWriter, res Response) {
253+
func errorResponse(w http.ResponseWriter, err error) {
153254
w.Header().Set("Content-Type", defaultContentTypeV1_1)
154-
if res.Err != "" {
155-
w.WriteHeader(http.StatusInternalServerError)
156-
}
157-
json.NewEncoder(w).Encode(res)
255+
json.NewEncoder(w).Encode(map[string]string{
256+
"Err": err.Error(),
257+
})
258+
w.WriteHeader(http.StatusInternalServerError)
259+
}
260+
261+
func objectResponse(w http.ResponseWriter, obj interface{}) {
262+
w.Header().Set("Content-Type", defaultContentTypeV1_1)
263+
json.NewEncoder(w).Encode(obj)
264+
}
265+
266+
func successResponse(w http.ResponseWriter) {
267+
w.Header().Set("Content-Type", defaultContentTypeV1_1)
268+
w.WriteHeader(http.OK)
158269
}

0 commit comments

Comments
 (0)