Expand listener skeleton to support IPAM driver
This commit is contained in:
1 parent
9f86e2ba43
commit
c1d2c159f0
3 files changed
+111
-22
No files matched your search
@@ -3,12 +3,9 @@ package api
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
. "github.com/weaveworks/weave/common"
|
||||
)
|
||||
|
||||
func (client *Client) ipamOp(ID string, op string) (*net.IPNet, error) {
|
||||
Log.Debugf("IPAM operation %s for %s", op, ID)
|
||||
ip, err := httpVerb(op, fmt.Sprintf("%s/ip/%s", client.baseUrl, ID), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+110
-18
@@ -9,10 +9,13 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/docker/libnetwork/drivers/remote/api"
|
||||
"github.com/docker/libnetwork/ipamapi"
|
||||
iapi "github.com/docker/libnetwork/ipams/remote/api"
|
||||
)
|
||||
|
||||
const (
|
||||
MethodReceiver = "NetworkDriver"
|
||||
networkReceiver = "NetworkDriver"
|
||||
ipamReceiver = ipamapi.PluginEndpointType
|
||||
)
|
||||
|
||||
type Driver interface {
|
||||
@@ -30,42 +33,67 @@ type Driver interface {
|
||||
|
||||
type listener struct {
|
||||
d Driver
|
||||
i ipamapi.Ipam
|
||||
}
|
||||
|
||||
func Listen(socket net.Listener, driver Driver) error {
|
||||
func Listen(socket net.Listener, driver Driver, ipamDriver ipamapi.Ipam) error {
|
||||
router := mux.NewRouter()
|
||||
router.NotFoundHandler = http.HandlerFunc(notFound)
|
||||
|
||||
router.Methods("POST").Path("/Plugin.Activate").HandlerFunc(handshake)
|
||||
listener := &listener{driver, ipamDriver}
|
||||
|
||||
handleMethod := func(method string, h http.HandlerFunc) {
|
||||
router.Methods("POST").Path(fmt.Sprintf("/%s.%s", MethodReceiver, method)).HandlerFunc(h)
|
||||
router.Methods("POST").Path("/Plugin.Activate").HandlerFunc(listener.handshake)
|
||||
|
||||
handleMethod := func(receiver, method string, h http.HandlerFunc) {
|
||||
router.Methods("POST").Path(fmt.Sprintf("/%s.%s", receiver, method)).HandlerFunc(h)
|
||||
}
|
||||
|
||||
listener := &listener{driver}
|
||||
handleMethod(networkReceiver, "GetCapabilities", listener.getCapabilities)
|
||||
|
||||
handleMethod("GetCapabilities", listener.getCapabilities)
|
||||
handleMethod("CreateNetwork", listener.createNetwork)
|
||||
handleMethod("DeleteNetwork", listener.deleteNetwork)
|
||||
handleMethod("CreateEndpoint", listener.createEndpoint)
|
||||
handleMethod("DeleteEndpoint", listener.deleteEndpoint)
|
||||
handleMethod("EndpointOperInfo", listener.infoEndpoint)
|
||||
handleMethod("Join", listener.joinEndpoint)
|
||||
handleMethod("Leave", listener.leaveEndpoint)
|
||||
if driver != nil {
|
||||
handleMethod(networkReceiver, "CreateNetwork", listener.createNetwork)
|
||||
handleMethod(networkReceiver, "DeleteNetwork", listener.deleteNetwork)
|
||||
handleMethod(networkReceiver, "CreateEndpoint", listener.createEndpoint)
|
||||
handleMethod(networkReceiver, "DeleteEndpoint", listener.deleteEndpoint)
|
||||
handleMethod(networkReceiver, "EndpointOperInfo", listener.infoEndpoint)
|
||||
handleMethod(networkReceiver, "Join", listener.joinEndpoint)
|
||||
handleMethod(networkReceiver, "Leave", listener.leaveEndpoint)
|
||||
}
|
||||
|
||||
if ipamDriver != nil {
|
||||
handleMethod(ipamReceiver, "GetDefaultAddressSpaces", listener.getDefaultAddressSpaces)
|
||||
handleMethod(ipamReceiver, "RequestPool", listener.requestPool)
|
||||
handleMethod(ipamReceiver, "ReleasePool", listener.releasePool)
|
||||
handleMethod(ipamReceiver, "RequestAddress", listener.requestAddress)
|
||||
handleMethod(ipamReceiver, "ReleaseAddress", listener.releaseAddress)
|
||||
}
|
||||
|
||||
return http.Serve(socket, router)
|
||||
}
|
||||
|
||||
func decode(w http.ResponseWriter, r *http.Request, v interface{}) error {
|
||||
err := json.NewDecoder(r.Body).Decode(v)
|
||||
if err != nil {
|
||||
sendError(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// === protocol handlers
|
||||
|
||||
type handshakeResp struct {
|
||||
Implements []string
|
||||
}
|
||||
|
||||
func handshake(w http.ResponseWriter, r *http.Request) {
|
||||
err := json.NewEncoder(w).Encode(&handshakeResp{
|
||||
[]string{"NetworkDriver"},
|
||||
})
|
||||
func (listener *listener) handshake(w http.ResponseWriter, r *http.Request) {
|
||||
var resp handshakeResp
|
||||
if listener.d != nil {
|
||||
resp.Implements = append(resp.Implements, "NetworkDriver")
|
||||
}
|
||||
if listener.i != nil {
|
||||
resp.Implements = append(resp.Implements, "IpamDriver")
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(&resp)
|
||||
if err != nil {
|
||||
sendError(w, "encode error", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -164,6 +192,70 @@ func (listener *listener) discoverDelete(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
// ===
|
||||
|
||||
func (listener *listener) getDefaultAddressSpaces(w http.ResponseWriter, r *http.Request) {
|
||||
local, global, err := listener.i.GetDefaultAddressSpaces()
|
||||
response := &iapi.GetAddressSpacesResponse{
|
||||
LocalDefaultAddressSpace: local,
|
||||
GlobalDefaultAddressSpace: global,
|
||||
}
|
||||
objectOrErrorResponse(w, response, err)
|
||||
}
|
||||
|
||||
func (listener *listener) requestPool(w http.ResponseWriter, r *http.Request) {
|
||||
var rq iapi.RequestPoolRequest
|
||||
if err := decode(w, r, &rq); err != nil {
|
||||
return
|
||||
}
|
||||
poolID, pool, data, err := listener.i.RequestPool(rq.AddressSpace, rq.Pool, rq.SubPool, rq.Options, rq.V6)
|
||||
if err != nil {
|
||||
errorResponse(w, err.Error())
|
||||
return
|
||||
}
|
||||
response := &iapi.RequestPoolResponse{
|
||||
PoolID: poolID,
|
||||
Pool: pool.String(),
|
||||
Data: data,
|
||||
}
|
||||
objectResponse(w, response)
|
||||
}
|
||||
|
||||
func (listener *listener) releasePool(w http.ResponseWriter, r *http.Request) {
|
||||
var rq iapi.ReleasePoolRequest
|
||||
if err := decode(w, r, &rq); err != nil {
|
||||
return
|
||||
}
|
||||
err := listener.i.ReleasePool(rq.PoolID)
|
||||
emptyOrErrorResponse(w, err)
|
||||
}
|
||||
|
||||
func (listener *listener) requestAddress(w http.ResponseWriter, r *http.Request) {
|
||||
var rq iapi.RequestAddressRequest
|
||||
if err := decode(w, r, &rq); err != nil {
|
||||
return
|
||||
}
|
||||
address, data, err := listener.i.RequestAddress(rq.PoolID, net.ParseIP(rq.Address), rq.Options)
|
||||
if err != nil {
|
||||
errorResponse(w, err.Error())
|
||||
return
|
||||
}
|
||||
response := &iapi.RequestAddressResponse{
|
||||
Address: address.String(),
|
||||
Data: data,
|
||||
}
|
||||
objectResponse(w, response)
|
||||
}
|
||||
|
||||
func (listener *listener) releaseAddress(w http.ResponseWriter, r *http.Request) {
|
||||
var rq iapi.ReleaseAddressRequest
|
||||
if err := decode(w, r, &rq); err != nil {
|
||||
return
|
||||
}
|
||||
err := listener.i.ReleaseAddress(rq.PoolID, net.ParseIP(rq.Address))
|
||||
emptyOrErrorResponse(w, err)
|
||||
}
|
||||
|
||||
// ===
|
||||
|
||||
func notFound(w http.ResponseWriter, r *http.Request) {
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ func main() {
|
||||
|
||||
endChan := make(chan error, 1)
|
||||
go func() {
|
||||
endChan <- skel.Listen(listener, d)
|
||||
endChan <- skel.Listen(listener, d, nil)
|
||||
}()
|
||||
|
||||
select {
|
||||
|
||||
Reference in new issue
Block a user