@@ -9,39 +9,96 @@ import (
99)
1010
1111const (
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.
56111func 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