Remove multiple interface in an endpoint

Currently the endpoint data model consists of multiple
interfaces per-endpoint. This seems to be an overkill
since there is no real use case for it. Removing it
to remove unnecessary complexity from the code.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
This commit is contained in:
Jana Radhakrishnan
2015-09-11 09:19:01 -07:00
parent 614f396bee
commit a3db98ec00
20 changed files with 229 additions and 340 deletions
+6 -9
View File
@@ -48,13 +48,12 @@ type CreateEndpointRequest struct {
NetworkID string
// The ID of the endpoint for later reference.
EndpointID string
Interfaces []*EndpointInterface
Interface *EndpointInterface
Options map[string]interface{}
}
// EndpointInterface represents an interface endpoint.
type EndpointInterface struct {
ID int
Address string
AddressIPv6 string
MacAddress string
@@ -63,12 +62,11 @@ type EndpointInterface struct {
// CreateEndpointResponse is the response to the CreateEndpoint action.
type CreateEndpointResponse struct {
Response
Interfaces []*EndpointInterface
Interface *EndpointInterface
}
// Interface is the representation of a linux interface.
type Interface struct {
ID int
Address *net.IPNet
AddressIPv6 *net.IPNet
MacAddress net.HardwareAddr
@@ -118,16 +116,15 @@ 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
StaticRoutes []StaticRoute
InterfaceName *InterfaceName
Gateway string
GatewayIPv6 string
StaticRoutes []StaticRoute
}
// LeaveRequest describes the API for detaching an endpoint from a sandbox.
+36 -39
View File
@@ -71,16 +71,17 @@ func (d *driver) DeleteNetwork(nid string) error {
}
func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo, epOptions map[string]interface{}) error {
var reqIface *api.EndpointInterface
if epInfo == nil {
return fmt.Errorf("must not be called with nil EndpointInfo")
}
reqIfaces := make([]*api.EndpointInterface, len(epInfo.Interfaces()))
for i, iface := range epInfo.Interfaces() {
iface := epInfo.Interface()
if iface != nil {
addr4 := iface.Address()
addr6 := iface.AddressIPv6()
reqIfaces[i] = &api.EndpointInterface{
ID: iface.ID(),
reqIface = &api.EndpointInterface{
Address: addr4.String(),
AddressIPv6: addr6.String(),
MacAddress: iface.MacAddress().String(),
@@ -89,7 +90,7 @@ func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo,
create := &api.CreateEndpointRequest{
NetworkID: nid,
EndpointID: eid,
Interfaces: reqIfaces,
Interface: reqIface,
Options: epOptions,
}
var res api.CreateEndpointResponse
@@ -97,25 +98,26 @@ func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo,
return err
}
ifaces, err := parseInterfaces(res)
inIface, err := parseInterface(res)
if err != nil {
return err
}
if len(reqIfaces) > 0 && len(ifaces) > 0 {
// We're not supposed to add interfaces if there already are
// some. Attempt to roll back
return errorWithRollback("driver attempted to add more interfaces", d.DeleteEndpoint(nid, eid))
if reqIface != nil && inIface != nil {
// We're not supposed to add interface if there is already
// one. Attempt to roll back
return errorWithRollback("driver attempted to add interface ignoring the one provided", d.DeleteEndpoint(nid, eid))
}
for _, iface := range ifaces {
if inIface != nil {
var addr4, addr6 net.IPNet
if iface.Address != nil {
addr4 = *(iface.Address)
if inIface.Address != nil {
addr4 = *(inIface.Address)
}
if iface.AddressIPv6 != nil {
addr6 = *(iface.AddressIPv6)
if inIface.AddressIPv6 != nil {
addr6 = *(inIface.AddressIPv6)
}
if err := epInfo.AddInterface(iface.ID, iface.MacAddress, addr4, addr6); err != nil {
return errorWithRollback(fmt.Sprintf("failed to AddInterface %v: %s", iface, err), d.DeleteEndpoint(nid, eid))
if err := epInfo.AddInterface(inIface.MacAddress, addr4, addr6); err != nil {
return errorWithRollback(fmt.Sprintf("failed to AddInterface %v: %s", inIface, err), d.DeleteEndpoint(nid, eid))
}
}
return nil
@@ -165,18 +167,13 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
return err
}
// Expect each interface ID given by CreateEndpoint to have an
// entry at that index in the names supplied here. In other words,
// if you supply 0..n interfaces with IDs 0..n above, you should
// supply the names in the same order.
ifaceNames := res.InterfaceNames
for _, iface := range jinfo.InterfaceNames() {
i := iface.ID()
if i >= len(ifaceNames) || i < 0 {
return fmt.Errorf("no correlating interface %d in supplied interface names", i)
}
supplied := ifaceNames[i]
if err := iface.SetNames(supplied.SrcName, supplied.DstPrefix); err != nil {
ifaceName := res.InterfaceName
if ifaceName == nil {
return fmt.Errorf("no interface name information received")
}
if iface := jinfo.InterfaceName(); iface != nil {
if err := iface.SetNames(ifaceName.SrcName, ifaceName.DstPrefix); err != nil {
return errorWithRollback(fmt.Sprintf("failed to set interface name: %s", err), d.Leave(nid, eid))
}
}
@@ -204,7 +201,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
return err
}
for _, route := range routes {
if jinfo.AddStaticRoute(route.Destination, route.RouteType, route.NextHop, route.InterfaceID) != nil {
if jinfo.AddStaticRoute(route.Destination, route.RouteType, route.NextHop) != nil {
return errorWithRollback(fmt.Sprintf("failed to set static route: %v", route), d.Leave(nid, eid))
}
}
@@ -229,7 +226,7 @@ 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}
outRoute := &types.StaticRoute{RouteType: inRoute.RouteType}
if inRoute.Destination != "" {
if outRoute.Destination, err = toAddr(inRoute.Destination); err != nil {
@@ -250,13 +247,13 @@ func parseStaticRoutes(r api.JoinResponse) ([]*types.StaticRoute, error) {
}
// 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 {
func parseInterface(r api.CreateEndpointResponse) (*api.Interface, error) {
var outIf *api.Interface
inIf := r.Interface
if inIf != nil {
var err error
outIf := &api.Interface{ID: inIf.ID}
outIf = &api.Interface{}
if inIf.Address != "" {
if outIf.Address, err = toAddr(inIf.Address); err != nil {
return nil, err
@@ -272,9 +269,9 @@ func parseInterfaces(r api.CreateEndpointResponse) ([]*api.Interface, error) {
return nil, err
}
}
Interfaces[i] = outIf
}
return Interfaces, nil
return outIf, nil
}
func toAddr(ipAddr string) (*net.IPNet, error) {
+15 -36
View File
@@ -59,7 +59,6 @@ func setupPlugin(t *testing.T, name string, mux *http.ServeMux) func() {
type testEndpoint struct {
t *testing.T
id int
src string
dst string
address string
@@ -74,16 +73,11 @@ type testEndpoint struct {
routeType int
}
func (test *testEndpoint) Interfaces() []driverapi.InterfaceInfo {
// return an empty one so we don't trip the check for existing
// interfaces; we don't care about this after that
return []driverapi.InterfaceInfo{}
func (test *testEndpoint) Interface() driverapi.InterfaceInfo {
return nil
}
func (test *testEndpoint) AddInterface(ID int, mac net.HardwareAddr, ipv4 net.IPNet, ipv6 net.IPNet) error {
if ID != test.id {
test.t.Fatalf("Wrong ID passed to AddInterface: %d", ID)
}
func (test *testEndpoint) AddInterface(mac net.HardwareAddr, ipv4 net.IPNet, ipv6 net.IPNet) error {
ip4, net4, _ := net.ParseCIDR(test.address)
ip6, net6, _ := net.ParseCIDR(test.addressIPv6)
if ip4 != nil {
@@ -104,8 +98,8 @@ func (test *testEndpoint) AddInterface(ID int, mac net.HardwareAddr, ipv4 net.IP
return nil
}
func (test *testEndpoint) InterfaceNames() []driverapi.InterfaceNameInfo {
return []driverapi.InterfaceNameInfo{test}
func (test *testEndpoint) InterfaceName() driverapi.InterfaceNameInfo {
return test
}
func compareIPs(t *testing.T, kind string, shouldBe string, supplied net.IP) {
@@ -148,7 +142,7 @@ func (test *testEndpoint) SetNames(src string, dst string) error {
return nil
}
func (test *testEndpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP, interfaceID int) error {
func (test *testEndpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
compareIPNets(test.t, "Destination", test.destination, *destination)
compareIPs(test.t, "NextHop", test.nextHop, nextHop)
@@ -156,17 +150,9 @@ func (test *testEndpoint) AddStaticRoute(destination *net.IPNet, routeType int,
test.t.Fatalf(`Wrong RouteType; expected "%d", got "%d"`, test.routeType, routeType)
}
if test.id != interfaceID {
test.t.Fatalf(`Wrong InterfaceID; expected "%d", got "%d"`, test.id, interfaceID)
}
return nil
}
func (test *testEndpoint) ID() int {
return test.id
}
func TestRemoteDriver(t *testing.T) {
var plugin = "test-net-driver"
@@ -207,13 +193,12 @@ func TestRemoteDriver(t *testing.T) {
})
handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
iface := map[string]interface{}{
"ID": ep.id,
"Address": ep.address,
"AddressIPv6": ep.addressIPv6,
"MacAddress": ep.macAddress,
}
return map[string]interface{}{
"Interfaces": []interface{}{iface},
"Interface": iface,
}
})
handle(t, mux, "Join", func(msg map[string]interface{}) interface{} {
@@ -227,17 +212,14 @@ func TestRemoteDriver(t *testing.T) {
"GatewayIPv6": ep.gatewayIPv6,
"HostsPath": ep.hostsPath,
"ResolvConfPath": ep.resolvConfPath,
"InterfaceNames": []map[string]interface{}{
map[string]interface{}{
"SrcName": ep.src,
"DstPrefix": ep.dst,
},
"InterfaceName": map[string]interface{}{
"SrcName": ep.src,
"DstPrefix": ep.dst,
},
"StaticRoutes": []map[string]interface{}{
map[string]interface{}{
"Destination": ep.destination,
"RouteType": ep.routeType,
"InterfaceID": ep.id,
"NextHop": ep.nextHop,
},
},
@@ -343,13 +325,11 @@ func TestMissingValues(t *testing.T) {
defer setupPlugin(t, plugin, mux)()
ep := &testEndpoint{
t: t,
id: 0,
t: t,
}
handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
iface := map[string]interface{}{
"ID": ep.id,
"Address": ep.address,
"AddressIPv6": ep.addressIPv6,
"MacAddress": ep.macAddress,
@@ -373,11 +353,11 @@ func TestMissingValues(t *testing.T) {
type rollbackEndpoint struct {
}
func (r *rollbackEndpoint) Interfaces() []driverapi.InterfaceInfo {
return []driverapi.InterfaceInfo{}
func (r *rollbackEndpoint) Interface() driverapi.InterfaceInfo {
return nil
}
func (r *rollbackEndpoint) AddInterface(_ int, _ net.HardwareAddr, _ net.IPNet, _ net.IPNet) error {
func (r *rollbackEndpoint) AddInterface(_ net.HardwareAddr, _ net.IPNet, _ net.IPNet) error {
return fmt.Errorf("fail this to trigger a rollback")
}
@@ -391,13 +371,12 @@ func TestRollback(t *testing.T) {
handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
iface := map[string]interface{}{
"ID": 0,
"Address": "192.168.4.5/16",
"AddressIPv6": "",
"MacAddress": "7a:12:34:56:78:90",
}
return map[string]interface{}{
"Interfaces": []interface{}{iface},
"Interface": interface{}(iface),
}
})
handle(t, mux, "DeleteEndpoint", func(msg map[string]interface{}) interface{} {