From 850bdd0923529993509593e9d24455a8da46ece6 Mon Sep 17 00:00:00 2001 From: Erik Hollensbe Date: Tue, 2 Jun 2015 21:51:10 -0700 Subject: [PATCH] Expose the remote driver API structs publicly. --- libnetwork/drivers/remote/api/api.go | 144 +++++++++++++++++++++ libnetwork/drivers/remote/driver.go | 104 ++++++++++++--- libnetwork/drivers/remote/messages.go | 178 -------------------------- 3 files changed, 229 insertions(+), 197 deletions(-) create mode 100644 libnetwork/drivers/remote/api/api.go delete mode 100644 libnetwork/drivers/remote/messages.go diff --git a/libnetwork/drivers/remote/api/api.go b/libnetwork/drivers/remote/api/api.go new file mode 100644 index 0000000000..ec703235c6 --- /dev/null +++ b/libnetwork/drivers/remote/api/api.go @@ -0,0 +1,144 @@ +/* +Package api represents all requests and responses suitable for conversation +with a remote driver. +*/ +package api + +import "net" + +// Response is the basic response structure used in all responses. +type Response struct { + Err string +} + +// GetError returns the error from the response, if any. +func (r *Response) GetError() string { + return r.Err +} + +// CreateNetworkRequest requests a new network. +type CreateNetworkRequest struct { + // A network ID that remote plugins are expected to store for future + // reference. + NetworkID string + + // A free form map->object interface for communication of options. + Options map[string]interface{} +} + +// CreateNetworkResponse is the response to the CreateNetworkRequest. +type CreateNetworkResponse struct { + Response +} + +// DeleteNetworkRequest is the request to delete an existing network. +type DeleteNetworkRequest struct { + // The ID of the network to delete. + NetworkID string +} + +// DeleteNetworkResponse is the response to a request for deleting a network. +type DeleteNetworkResponse struct { + Response +} + +// CreateEndpointRequest is the request to create an endpoint within a network. +type CreateEndpointRequest struct { + // Provided at create time, this will be the network id referenced. + NetworkID string + // The ID of the endpoint for later reference. + EndpointID string + Interfaces []*EndpointInterface + Options map[string]interface{} +} + +// EndpointInterface represents an interface endpoint. +type EndpointInterface struct { + ID int + Address string + AddressIPv6 string + MacAddress string +} + +// CreateEndpointResponse is the response to the CreateEndpoint action. +type CreateEndpointResponse struct { + Response + Interfaces []*EndpointInterface +} + +// Interface is the representation of a linux interface. +type Interface struct { + ID int + Address *net.IPNet + AddressIPv6 *net.IPNet + MacAddress net.HardwareAddr +} + +// DeleteEndpointRequest describes the API for deleting an endpoint. +type DeleteEndpointRequest struct { + NetworkID string + EndpointID string +} + +// DeleteEndpointResponse is the response to the DeleteEndpoint action. +type DeleteEndpointResponse struct { + Response +} + +// EndpointInfoRequest retrieves information about the endpoint from the network driver. +type EndpointInfoRequest struct { + NetworkID string + EndpointID string +} + +// EndpointInfoResponse is the response to an EndpointInfoRequest. +type EndpointInfoResponse struct { + Response + Value map[string]interface{} +} + +// JoinRequest describes the API for joining an endpoint to a sandbox. +type JoinRequest struct { + NetworkID string + EndpointID string + SandboxKey string + Options map[string]interface{} +} + +// InterfaceName is the struct represetation of a pair of devices with source +// and destination, for the purposes of putting an endpoint into a container. +type InterfaceName struct { + SrcName string + DstName string + DstPrefix string +} + +// StaticRoute is the plain JSON representation of a static route. +type StaticRoute struct { + Destination string + RouteType int + NextHop string + InterfaceID int +} + +// JoinResponse is the response to a JoinRequest. +type JoinResponse struct { + Response + InterfaceNames []*InterfaceName + Gateway string + GatewayIPv6 string + HostsPath string + ResolvConfPath string + StaticRoutes []StaticRoute +} + +// LeaveRequest describes the API for detaching an endpoint from a sandbox. +type LeaveRequest struct { + NetworkID string + EndpointID string +} + +// LeaveResponse is the answer to LeaveRequest. +type LeaveResponse struct { + Response +} diff --git a/libnetwork/drivers/remote/driver.go b/libnetwork/drivers/remote/driver.go index 1395933a17..8cfbe51aa2 100644 --- a/libnetwork/drivers/remote/driver.go +++ b/libnetwork/drivers/remote/driver.go @@ -7,6 +7,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/docker/docker/pkg/plugins" "github.com/docker/libnetwork/driverapi" + "github.com/docker/libnetwork/drivers/remote/api" "github.com/docker/libnetwork/types" ) @@ -15,6 +16,10 @@ type driver struct { networkType string } +type maybeError interface { + GetError() string +} + func newDriver(name string, client *plugins.Client) driverapi.Driver { return &driver{networkType: name, endpoint: client} } @@ -46,23 +51,23 @@ func (d *driver) call(methodName string, arg interface{}, retVal maybeError) err if err != nil { return err } - if e := retVal.getError(); e != "" { + if e := retVal.GetError(); e != "" { return fmt.Errorf("remote: %s", e) } return nil } func (d *driver) CreateNetwork(id types.UUID, options map[string]interface{}) error { - create := &createNetworkRequest{ + create := &api.CreateNetworkRequest{ NetworkID: string(id), Options: options, } - return d.call("CreateNetwork", create, &createNetworkResponse{}) + return d.call("CreateNetwork", create, &api.CreateNetworkResponse{}) } func (d *driver) DeleteNetwork(nid types.UUID) error { - delete := &deleteNetworkRequest{NetworkID: string(nid)} - return d.call("DeleteNetwork", delete, &deleteNetworkResponse{}) + delete := &api.DeleteNetworkRequest{NetworkID: string(nid)} + return d.call("DeleteNetwork", delete, &api.DeleteNetworkResponse{}) } func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointInfo, epOptions map[string]interface{}) error { @@ -70,29 +75,29 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn return fmt.Errorf("must not be called with nil EndpointInfo") } - reqIfaces := make([]*endpointInterface, len(epInfo.Interfaces())) + reqIfaces := make([]*api.EndpointInterface, len(epInfo.Interfaces())) for i, iface := range epInfo.Interfaces() { addr4 := iface.Address() addr6 := iface.AddressIPv6() - reqIfaces[i] = &endpointInterface{ + reqIfaces[i] = &api.EndpointInterface{ ID: iface.ID(), Address: addr4.String(), AddressIPv6: addr6.String(), MacAddress: iface.MacAddress().String(), } } - create := &createEndpointRequest{ + create := &api.CreateEndpointRequest{ NetworkID: string(nid), EndpointID: string(eid), Interfaces: reqIfaces, Options: epOptions, } - var res createEndpointResponse + var res api.CreateEndpointResponse if err := d.call("CreateEndpoint", create, &res); err != nil { return err } - ifaces, err := res.parseInterfaces() + ifaces, err := parseInterfaces(res) if err != nil { return err } @@ -125,19 +130,19 @@ func errorWithRollback(msg string, err error) error { } func (d *driver) DeleteEndpoint(nid, eid types.UUID) error { - delete := &deleteEndpointRequest{ + delete := &api.DeleteEndpointRequest{ NetworkID: string(nid), EndpointID: string(eid), } - return d.call("DeleteEndpoint", delete, &deleteEndpointResponse{}) + return d.call("DeleteEndpoint", delete, &api.DeleteEndpointResponse{}) } func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{}, error) { - info := &endpointInfoRequest{ + info := &api.EndpointInfoRequest{ NetworkID: string(nid), EndpointID: string(eid), } - var res endpointInfoResponse + var res api.EndpointInfoResponse if err := d.call("EndpointOperInfo", info, &res); err != nil { return nil, err } @@ -146,14 +151,14 @@ func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{}, // Join method is invoked when a Sandbox is attached to an endpoint. func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { - join := &joinRequest{ + join := &api.JoinRequest{ NetworkID: string(nid), EndpointID: string(eid), SandboxKey: sboxKey, Options: options, } var ( - res joinResponse + res api.JoinResponse err error ) if err = d.call("Join", join, &res); err != nil { @@ -194,7 +199,7 @@ func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinI } } if len(res.StaticRoutes) > 0 { - routes, err := res.parseStaticRoutes() + routes, err := parseStaticRoutes(res) if err != nil { return err } @@ -215,13 +220,74 @@ func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinI // Leave method is invoked when a Sandbox detaches from an endpoint. func (d *driver) Leave(nid, eid types.UUID) error { - leave := &leaveRequest{ + leave := &api.LeaveRequest{ NetworkID: string(nid), EndpointID: string(eid), } - return d.call("Leave", leave, &leaveResponse{}) + return d.call("Leave", leave, &api.LeaveResponse{}) } func (d *driver) Type() string { return d.networkType } + +func parseStaticRoutes(r api.JoinResponse) ([]*types.StaticRoute, error) { + var routes = make([]*types.StaticRoute, len(r.StaticRoutes)) + for i, inRoute := range r.StaticRoutes { + var err error + outRoute := &types.StaticRoute{InterfaceID: inRoute.InterfaceID, RouteType: inRoute.RouteType} + + if inRoute.Destination != "" { + if outRoute.Destination, err = toAddr(inRoute.Destination); err != nil { + return nil, err + } + } + + if inRoute.NextHop != "" { + outRoute.NextHop = net.ParseIP(inRoute.NextHop) + if outRoute.NextHop == nil { + return nil, fmt.Errorf("failed to parse nexthop IP %s", inRoute.NextHop) + } + } + + routes[i] = outRoute + } + return routes, nil +} + +// parseInterfaces validates all the parameters of an Interface and returns them. +func parseInterfaces(r api.CreateEndpointResponse) ([]*api.Interface, error) { + var ( + Interfaces = make([]*api.Interface, len(r.Interfaces)) + ) + for i, inIf := range r.Interfaces { + var err error + outIf := &api.Interface{ID: inIf.ID} + if inIf.Address != "" { + if outIf.Address, err = toAddr(inIf.Address); err != nil { + return nil, err + } + } + if inIf.AddressIPv6 != "" { + if outIf.AddressIPv6, err = toAddr(inIf.AddressIPv6); err != nil { + return nil, err + } + } + if inIf.MacAddress != "" { + if outIf.MacAddress, err = net.ParseMAC(inIf.MacAddress); err != nil { + return nil, err + } + } + Interfaces[i] = outIf + } + return Interfaces, nil +} + +func toAddr(ipAddr string) (*net.IPNet, error) { + ip, ipnet, err := net.ParseCIDR(ipAddr) + if err != nil { + return nil, err + } + ipnet.IP = ip + return ipnet, nil +} diff --git a/libnetwork/drivers/remote/messages.go b/libnetwork/drivers/remote/messages.go deleted file mode 100644 index d9c9e1534e..0000000000 --- a/libnetwork/drivers/remote/messages.go +++ /dev/null @@ -1,178 +0,0 @@ -package remote - -import ( - "fmt" - "net" - - "github.com/docker/libnetwork/types" -) - -type response struct { - Err string -} - -type maybeError interface { - getError() string -} - -func (r *response) getError() string { - return r.Err -} - -type createNetworkRequest struct { - NetworkID string - Options map[string]interface{} -} - -type createNetworkResponse struct { - response -} - -type deleteNetworkRequest struct { - NetworkID string -} - -type deleteNetworkResponse struct { - response -} - -type createEndpointRequest struct { - NetworkID string - EndpointID string - Interfaces []*endpointInterface - Options map[string]interface{} -} - -type endpointInterface struct { - ID int - Address string - AddressIPv6 string - MacAddress string -} - -type staticRoute struct { - Destination string - RouteType int - NextHop string - InterfaceID int -} - -type createEndpointResponse struct { - response - Interfaces []*endpointInterface -} - -func toAddr(ipAddr string) (*net.IPNet, error) { - ip, ipnet, err := net.ParseCIDR(ipAddr) - if err != nil { - return nil, err - } - ipnet.IP = ip - return ipnet, nil -} - -type iface struct { - ID int - Address *net.IPNet - AddressIPv6 *net.IPNet - MacAddress net.HardwareAddr -} - -func (r *createEndpointResponse) parseInterfaces() ([]*iface, error) { - var ifaces = make([]*iface, len(r.Interfaces)) - for i, inIf := range r.Interfaces { - var err error - outIf := &iface{ID: inIf.ID} - if inIf.Address != "" { - if outIf.Address, err = toAddr(inIf.Address); err != nil { - return nil, err - } - } - if inIf.AddressIPv6 != "" { - if outIf.AddressIPv6, err = toAddr(inIf.AddressIPv6); err != nil { - return nil, err - } - } - if inIf.MacAddress != "" { - if outIf.MacAddress, err = net.ParseMAC(inIf.MacAddress); err != nil { - return nil, err - } - } - ifaces[i] = outIf - } - return ifaces, nil -} - -func (r *joinResponse) parseStaticRoutes() ([]*types.StaticRoute, error) { - var routes = make([]*types.StaticRoute, len(r.StaticRoutes)) - for i, inRoute := range r.StaticRoutes { - var err error - outRoute := &types.StaticRoute{InterfaceID: inRoute.InterfaceID, RouteType: inRoute.RouteType} - - if inRoute.Destination != "" { - if outRoute.Destination, err = toAddr(inRoute.Destination); err != nil { - return nil, err - } - } - - if inRoute.NextHop != "" { - outRoute.NextHop = net.ParseIP(inRoute.NextHop) - if outRoute.NextHop == nil { - return nil, fmt.Errorf("failed to parse nexthop IP %s", inRoute.NextHop) - } - } - - routes[i] = outRoute - } - return routes, nil -} - -type deleteEndpointRequest struct { - NetworkID string - EndpointID string -} - -type deleteEndpointResponse struct { - response -} - -type endpointInfoRequest struct { - NetworkID string - EndpointID string -} - -type endpointInfoResponse struct { - response - Value map[string]interface{} -} - -type joinRequest struct { - NetworkID string - EndpointID string - SandboxKey string - Options map[string]interface{} -} - -type ifaceName struct { - SrcName string - DstPrefix string -} - -type joinResponse struct { - response - InterfaceNames []*ifaceName - Gateway string - GatewayIPv6 string - StaticRoutes []*staticRoute - HostsPath string - ResolvConfPath string -} - -type leaveRequest struct { - NetworkID string - EndpointID string -} - -type leaveResponse struct { - response -}