Expose the remote driver API structs publicly.

This commit is contained in:
Erik Hollensbe 2015-06-02 21:51:10 -07:00
parent 90de4b4f3f
commit 850bdd0923
3 changed files with 229 additions and 197 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}