Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
package remote
|
|
|
|
|
|
|
|
import (
|
2015-10-29 03:04:08 -04:00
|
|
|
"bytes"
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
"encoding/json"
|
2016-11-21 20:29:53 -05:00
|
|
|
"errors"
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
"fmt"
|
2015-12-23 18:07:33 -05:00
|
|
|
"io"
|
2015-09-30 11:16:58 -04:00
|
|
|
"io/ioutil"
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
"net"
|
|
|
|
"net/http"
|
2015-09-30 11:16:58 -04:00
|
|
|
"net/http/httptest"
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
"os"
|
2021-04-27 18:40:39 -04:00
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
"testing"
|
|
|
|
|
2021-04-05 20:24:47 -04:00
|
|
|
"github.com/docker/docker/libnetwork/datastore"
|
|
|
|
"github.com/docker/docker/libnetwork/discoverapi"
|
|
|
|
"github.com/docker/docker/libnetwork/driverapi"
|
|
|
|
"github.com/docker/docker/libnetwork/types"
|
2021-04-27 18:40:39 -04:00
|
|
|
"github.com/docker/docker/pkg/plugins"
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
func decodeToMap(r *http.Request) (res map[string]interface{}, err error) {
|
|
|
|
err = json.NewDecoder(r.Body).Decode(&res)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func handle(t *testing.T, mux *http.ServeMux, method string, h func(map[string]interface{}) interface{}) {
|
|
|
|
mux.HandleFunc(fmt.Sprintf("/%s.%s", driverapi.NetworkPluginEndpointType, method), func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ask, err := decodeToMap(r)
|
2015-12-23 18:07:33 -05:00
|
|
|
if err != nil && err != io.EOF {
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
answer := h(ask)
|
|
|
|
err = json.NewEncoder(w).Encode(&answer)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func setupPlugin(t *testing.T, name string, mux *http.ServeMux) func() {
|
2021-04-27 18:40:39 -04:00
|
|
|
specPath := "/etc/docker/plugins"
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
specPath = filepath.Join(os.Getenv("programdata"), "docker", "plugins")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := os.MkdirAll(specPath, 0755); err != nil {
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2021-04-27 18:40:39 -04:00
|
|
|
defer func() {
|
|
|
|
if t.Failed() {
|
|
|
|
os.RemoveAll(specPath)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2015-09-30 11:16:58 -04:00
|
|
|
server := httptest.NewServer(mux)
|
|
|
|
if server == nil {
|
2016-06-02 01:37:39 -04:00
|
|
|
t.Fatal("Failed to start an HTTP Server")
|
2015-09-30 11:16:58 -04:00
|
|
|
}
|
|
|
|
|
2021-04-27 18:40:39 -04:00
|
|
|
if err := ioutil.WriteFile(filepath.Join(specPath, name+".spec"), []byte(server.URL), 0644); err != nil {
|
2015-09-30 11:16:58 -04:00
|
|
|
t.Fatal(err)
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
|
2015-09-30 11:16:58 -04:00
|
|
|
w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
fmt.Fprintf(w, `{"Implements": ["%s"]}`, driverapi.NetworkPluginEndpointType)
|
|
|
|
})
|
|
|
|
|
|
|
|
return func() {
|
2021-04-27 18:40:39 -04:00
|
|
|
if err := os.RemoveAll(specPath); err != nil {
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-30 11:16:58 -04:00
|
|
|
server.Close()
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type testEndpoint struct {
|
2015-12-02 21:07:44 -05:00
|
|
|
t *testing.T
|
|
|
|
src string
|
|
|
|
dst string
|
|
|
|
address string
|
|
|
|
addressIPv6 string
|
|
|
|
macAddress string
|
|
|
|
gateway string
|
|
|
|
gatewayIPv6 string
|
|
|
|
resolvConfPath string
|
|
|
|
hostsPath string
|
|
|
|
nextHop string
|
|
|
|
destination string
|
|
|
|
routeType int
|
|
|
|
disableGatewayService bool
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
2015-09-09 19:06:35 -04:00
|
|
|
func (test *testEndpoint) Interface() driverapi.InterfaceInfo {
|
2015-10-03 19:11:50 -04:00
|
|
|
return test
|
|
|
|
}
|
|
|
|
|
|
|
|
func (test *testEndpoint) Address() *net.IPNet {
|
|
|
|
if test.address == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
nw, _ := types.ParseCIDR(test.address)
|
|
|
|
return nw
|
|
|
|
}
|
|
|
|
|
|
|
|
func (test *testEndpoint) AddressIPv6() *net.IPNet {
|
|
|
|
if test.addressIPv6 == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
nw, _ := types.ParseCIDR(test.addressIPv6)
|
|
|
|
return nw
|
|
|
|
}
|
|
|
|
|
|
|
|
func (test *testEndpoint) MacAddress() net.HardwareAddr {
|
|
|
|
if test.macAddress == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
mac, _ := net.ParseMAC(test.macAddress)
|
|
|
|
return mac
|
|
|
|
}
|
|
|
|
|
|
|
|
func (test *testEndpoint) SetMacAddress(mac net.HardwareAddr) error {
|
|
|
|
if test.macAddress != "" {
|
|
|
|
return types.ForbiddenErrorf("endpoint interface MAC address present (%s). Cannot be modified with %s.", test.macAddress, mac)
|
|
|
|
}
|
|
|
|
if mac == nil {
|
|
|
|
return types.BadRequestErrorf("tried to set nil MAC address to endpoint interface")
|
|
|
|
}
|
|
|
|
test.macAddress = mac.String()
|
2015-09-09 19:06:35 -04:00
|
|
|
return nil
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
2015-10-03 19:11:50 -04:00
|
|
|
func (test *testEndpoint) SetIPAddress(address *net.IPNet) error {
|
|
|
|
if address.IP == nil {
|
|
|
|
return types.BadRequestErrorf("tried to set nil IP address to endpoint interface")
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
2015-10-03 19:11:50 -04:00
|
|
|
if address.IP.To4() == nil {
|
|
|
|
return setAddress(&test.addressIPv6, address)
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
2015-10-03 19:11:50 -04:00
|
|
|
return setAddress(&test.address, address)
|
|
|
|
}
|
|
|
|
|
|
|
|
func setAddress(ifaceAddr *string, address *net.IPNet) error {
|
|
|
|
if *ifaceAddr != "" {
|
|
|
|
return types.ForbiddenErrorf("endpoint interface IP present (%s). Cannot be modified with (%s).", *ifaceAddr, address)
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
2015-10-03 19:11:50 -04:00
|
|
|
*ifaceAddr = address.String()
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-09-09 19:06:35 -04:00
|
|
|
func (test *testEndpoint) InterfaceName() driverapi.InterfaceNameInfo {
|
|
|
|
return test
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func compareIPs(t *testing.T, kind string, shouldBe string, supplied net.IP) {
|
|
|
|
ip := net.ParseIP(shouldBe)
|
|
|
|
if ip == nil {
|
|
|
|
t.Fatalf(`Invalid IP to test against: "%s"`, shouldBe)
|
|
|
|
}
|
|
|
|
if !ip.Equal(supplied) {
|
|
|
|
t.Fatalf(`%s IPs are not equal: expected "%s", got %v`, kind, shouldBe, supplied)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-27 21:39:46 -04:00
|
|
|
func compareIPNets(t *testing.T, kind string, shouldBe string, supplied net.IPNet) {
|
|
|
|
_, net, _ := net.ParseCIDR(shouldBe)
|
|
|
|
if net == nil {
|
|
|
|
t.Fatalf(`Invalid IP network to test against: "%s"`, shouldBe)
|
|
|
|
}
|
|
|
|
if !types.CompareIPNet(net, &supplied) {
|
|
|
|
t.Fatalf(`%s IP networks are not equal: expected "%s", got %v`, kind, shouldBe, supplied)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
func (test *testEndpoint) SetGateway(ipv4 net.IP) error {
|
|
|
|
compareIPs(test.t, "Gateway", test.gateway, ipv4)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (test *testEndpoint) SetGatewayIPv6(ipv6 net.IP) error {
|
|
|
|
compareIPs(test.t, "GatewayIPv6", test.gatewayIPv6, ipv6)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (test *testEndpoint) SetNames(src string, dst string) error {
|
|
|
|
if test.src != src {
|
|
|
|
test.t.Fatalf(`Wrong SrcName; expected "%s", got "%s"`, test.src, src)
|
|
|
|
}
|
|
|
|
if test.dst != dst {
|
2015-06-01 18:35:57 -04:00
|
|
|
test.t.Fatalf(`Wrong DstPrefix; expected "%s", got "%s"`, test.dst, dst)
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-09-09 19:06:35 -04:00
|
|
|
func (test *testEndpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
|
2015-05-27 21:39:46 -04:00
|
|
|
compareIPNets(test.t, "Destination", test.destination, *destination)
|
|
|
|
compareIPs(test.t, "NextHop", test.nextHop, nextHop)
|
|
|
|
|
|
|
|
if test.routeType != routeType {
|
|
|
|
test.t.Fatalf(`Wrong RouteType; expected "%d", got "%d"`, test.routeType, routeType)
|
|
|
|
}
|
|
|
|
|
2015-05-19 20:08:56 -04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-12-02 21:07:44 -05:00
|
|
|
func (test *testEndpoint) DisableGatewayService() {
|
|
|
|
test.disableGatewayService = true
|
|
|
|
}
|
|
|
|
|
2016-04-18 22:55:39 -04:00
|
|
|
func (test *testEndpoint) AddTableEntry(tableName string, key string, value []byte) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-09-13 08:00:05 -04:00
|
|
|
func TestGetEmptyCapabilities(t *testing.T) {
|
|
|
|
var plugin = "test-net-driver-empty-cap"
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
defer setupPlugin(t, plugin, mux)()
|
|
|
|
|
|
|
|
handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} {
|
|
|
|
return map[string]interface{}{}
|
|
|
|
})
|
|
|
|
|
|
|
|
p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-05-31 12:36:58 -04:00
|
|
|
client, err := getPluginClient(p)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
d := newDriver(plugin, client)
|
2015-09-13 08:00:05 -04:00
|
|
|
if d.Type() != plugin {
|
|
|
|
t.Fatal("Driver type does not match that given")
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = d.(*driver).getCapabilities()
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("There should be error reported when get empty capability")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetExtraCapabilities(t *testing.T) {
|
|
|
|
var plugin = "test-net-driver-extra-cap"
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
defer setupPlugin(t, plugin, mux)()
|
|
|
|
|
|
|
|
handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} {
|
|
|
|
return map[string]interface{}{
|
2017-04-07 16:31:44 -04:00
|
|
|
"Scope": "local",
|
|
|
|
"foo": "bar",
|
|
|
|
"ConnectivityScope": "global",
|
2015-09-13 08:00:05 -04:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-05-31 12:36:58 -04:00
|
|
|
client, err := getPluginClient(p)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
d := newDriver(plugin, client)
|
2015-09-13 08:00:05 -04:00
|
|
|
if d.Type() != plugin {
|
|
|
|
t.Fatal("Driver type does not match that given")
|
|
|
|
}
|
|
|
|
|
|
|
|
c, err := d.(*driver).getCapabilities()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
2015-09-16 07:42:35 -04:00
|
|
|
} else if c.DataScope != datastore.LocalScope {
|
|
|
|
t.Fatalf("get capability '%s', expecting 'local'", c.DataScope)
|
2017-04-07 16:31:44 -04:00
|
|
|
} else if c.ConnectivityScope != datastore.GlobalScope {
|
|
|
|
t.Fatalf("get capability '%s', expecting %q", c.ConnectivityScope, datastore.GlobalScope)
|
2015-09-13 08:00:05 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetInvalidCapabilities(t *testing.T) {
|
|
|
|
var plugin = "test-net-driver-invalid-cap"
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
defer setupPlugin(t, plugin, mux)()
|
|
|
|
|
|
|
|
handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} {
|
|
|
|
return map[string]interface{}{
|
|
|
|
"Scope": "fake",
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-05-31 12:36:58 -04:00
|
|
|
client, err := getPluginClient(p)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
d := newDriver(plugin, client)
|
2015-09-13 08:00:05 -04:00
|
|
|
if d.Type() != plugin {
|
|
|
|
t.Fatal("Driver type does not match that given")
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = d.(*driver).getCapabilities()
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("There should be error reported when get invalid capability")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
func TestRemoteDriver(t *testing.T) {
|
|
|
|
var plugin = "test-net-driver"
|
|
|
|
|
|
|
|
ep := &testEndpoint{
|
|
|
|
t: t,
|
|
|
|
src: "vethsrc",
|
|
|
|
dst: "vethdst",
|
|
|
|
address: "192.168.5.7/16",
|
|
|
|
addressIPv6: "2001:DB8::5:7/48",
|
2015-10-29 03:04:08 -04:00
|
|
|
macAddress: "ab:cd:ef:ee:ee:ee",
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
gateway: "192.168.0.1",
|
|
|
|
gatewayIPv6: "2001:DB8::1",
|
|
|
|
hostsPath: "/here/comes/the/host/path",
|
|
|
|
resolvConfPath: "/there/goes/the/resolv/conf",
|
2015-05-27 21:39:46 -04:00
|
|
|
destination: "10.0.0.0/8",
|
|
|
|
nextHop: "10.0.0.1",
|
|
|
|
routeType: 1,
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
defer setupPlugin(t, plugin, mux)()
|
|
|
|
|
|
|
|
var networkID string
|
|
|
|
|
2015-09-13 08:00:05 -04:00
|
|
|
handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} {
|
|
|
|
return map[string]interface{}{
|
|
|
|
"Scope": "global",
|
|
|
|
}
|
|
|
|
})
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
handle(t, mux, "CreateNetwork", func(msg map[string]interface{}) interface{} {
|
|
|
|
nid := msg["NetworkID"]
|
|
|
|
var ok bool
|
|
|
|
if networkID, ok = nid.(string); !ok {
|
|
|
|
t.Fatal("RPC did not include network ID string")
|
|
|
|
}
|
|
|
|
return map[string]interface{}{}
|
|
|
|
})
|
|
|
|
handle(t, mux, "DeleteNetwork", func(msg map[string]interface{}) interface{} {
|
|
|
|
if nid, ok := msg["NetworkID"]; !ok || nid != networkID {
|
|
|
|
t.Fatal("Network ID missing or does not match that created")
|
|
|
|
}
|
|
|
|
return map[string]interface{}{}
|
|
|
|
})
|
|
|
|
handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
|
|
|
|
iface := map[string]interface{}{
|
2015-10-29 03:04:08 -04:00
|
|
|
"MacAddress": ep.macAddress,
|
|
|
|
"Address": ep.address,
|
|
|
|
"AddressIPv6": ep.addressIPv6,
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
return map[string]interface{}{
|
2015-09-09 19:06:35 -04:00
|
|
|
"Interface": iface,
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
})
|
|
|
|
handle(t, mux, "Join", func(msg map[string]interface{}) interface{} {
|
|
|
|
options := msg["Options"].(map[string]interface{})
|
|
|
|
foo, ok := options["foo"].(string)
|
|
|
|
if !ok || foo != "fooValue" {
|
|
|
|
t.Fatalf("Did not receive expected foo string in request options: %+v", msg)
|
|
|
|
}
|
|
|
|
return map[string]interface{}{
|
|
|
|
"Gateway": ep.gateway,
|
|
|
|
"GatewayIPv6": ep.gatewayIPv6,
|
|
|
|
"HostsPath": ep.hostsPath,
|
|
|
|
"ResolvConfPath": ep.resolvConfPath,
|
2015-09-09 19:06:35 -04:00
|
|
|
"InterfaceName": map[string]interface{}{
|
|
|
|
"SrcName": ep.src,
|
|
|
|
"DstPrefix": ep.dst,
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
},
|
2015-05-27 21:39:46 -04:00
|
|
|
"StaticRoutes": []map[string]interface{}{
|
2015-12-02 21:07:44 -05:00
|
|
|
{
|
2015-05-27 21:39:46 -04:00
|
|
|
"Destination": ep.destination,
|
|
|
|
"RouteType": ep.routeType,
|
|
|
|
"NextHop": ep.nextHop,
|
|
|
|
},
|
|
|
|
},
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
})
|
|
|
|
handle(t, mux, "Leave", func(msg map[string]interface{}) interface{} {
|
|
|
|
return map[string]string{}
|
|
|
|
})
|
|
|
|
handle(t, mux, "DeleteEndpoint", func(msg map[string]interface{}) interface{} {
|
|
|
|
return map[string]interface{}{}
|
|
|
|
})
|
|
|
|
handle(t, mux, "EndpointOperInfo", func(msg map[string]interface{}) interface{} {
|
|
|
|
return map[string]interface{}{
|
|
|
|
"Value": map[string]string{
|
|
|
|
"Arbitrary": "key",
|
|
|
|
"Value": "pairs?",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
})
|
2015-09-18 15:54:08 -04:00
|
|
|
handle(t, mux, "DiscoverNew", func(msg map[string]interface{}) interface{} {
|
|
|
|
return map[string]string{}
|
|
|
|
})
|
|
|
|
handle(t, mux, "DiscoverDelete", func(msg map[string]interface{}) interface{} {
|
|
|
|
return map[string]interface{}{}
|
|
|
|
})
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
|
|
|
|
p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-05-31 12:36:58 -04:00
|
|
|
client, err := getPluginClient(p)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
d := newDriver(plugin, client)
|
2015-09-13 08:00:05 -04:00
|
|
|
if d.Type() != plugin {
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
t.Fatal("Driver type does not match that given")
|
|
|
|
}
|
|
|
|
|
2015-09-13 08:00:05 -04:00
|
|
|
c, err := d.(*driver).getCapabilities()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
2015-09-16 07:42:35 -04:00
|
|
|
} else if c.DataScope != datastore.GlobalScope {
|
|
|
|
t.Fatalf("get capability '%s', expecting 'global'", c.DataScope)
|
2015-09-13 08:00:05 -04:00
|
|
|
}
|
|
|
|
|
2015-07-02 01:00:48 -04:00
|
|
|
netID := "dummy-network"
|
2016-04-18 22:55:39 -04:00
|
|
|
err = d.CreateNetwork(netID, map[string]interface{}{}, nil, nil, nil)
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2015-07-02 01:00:48 -04:00
|
|
|
endID := "dummy-endpoint"
|
2015-10-29 03:04:08 -04:00
|
|
|
ifInfo := &testEndpoint{}
|
|
|
|
err = d.CreateEndpoint(netID, endID, ifInfo, map[string]interface{}{})
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2015-10-29 03:04:08 -04:00
|
|
|
if !bytes.Equal(ep.MacAddress(), ifInfo.MacAddress()) || !types.CompareIPNet(ep.Address(), ifInfo.Address()) ||
|
|
|
|
!types.CompareIPNet(ep.AddressIPv6(), ifInfo.AddressIPv6()) {
|
|
|
|
t.Fatalf("Unexpected InterfaceInfo data. Expected (%s, %s, %s). Got (%v, %v, %v)",
|
|
|
|
ep.MacAddress(), ep.Address(), ep.AddressIPv6(),
|
|
|
|
ifInfo.MacAddress(), ifInfo.Address(), ifInfo.AddressIPv6())
|
|
|
|
}
|
|
|
|
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
joinOpts := map[string]interface{}{"foo": "fooValue"}
|
2015-09-13 08:00:05 -04:00
|
|
|
err = d.Join(netID, endID, "sandbox-key", ep, joinOpts)
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-13 08:00:05 -04:00
|
|
|
if _, err = d.EndpointOperInfo(netID, endID); err != nil {
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-13 08:00:05 -04:00
|
|
|
if err = d.Leave(netID, endID); err != nil {
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-13 08:00:05 -04:00
|
|
|
if err = d.DeleteEndpoint(netID, endID); err != nil {
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-13 08:00:05 -04:00
|
|
|
if err = d.DeleteNetwork(netID); err != nil {
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-18 15:54:08 -04:00
|
|
|
|
2016-01-28 14:54:03 -05:00
|
|
|
data := discoverapi.NodeDiscoveryData{
|
2015-09-18 15:54:08 -04:00
|
|
|
Address: "192.168.1.1",
|
|
|
|
}
|
2016-01-28 14:54:03 -05:00
|
|
|
if err = d.DiscoverNew(discoverapi.NodeDiscovery, data); err != nil {
|
2015-09-18 15:54:08 -04:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2016-01-28 14:54:03 -05:00
|
|
|
if err = d.DiscoverDelete(discoverapi.NodeDiscovery, data); err != nil {
|
2015-09-18 15:54:08 -04:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestDriverError(t *testing.T) {
|
|
|
|
var plugin = "test-net-driver-error"
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
defer setupPlugin(t, plugin, mux)()
|
|
|
|
|
|
|
|
handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
|
|
|
|
return map[string]interface{}{
|
|
|
|
"Err": "this should get raised as an error",
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-05-31 12:36:58 -04:00
|
|
|
client, err := getPluginClient(p)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
driver := newDriver(plugin, client)
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
|
2015-07-02 01:00:48 -04:00
|
|
|
if err := driver.CreateEndpoint("dummy", "dummy", &testEndpoint{t: t}, map[string]interface{}{}); err == nil {
|
2016-11-21 20:29:53 -05:00
|
|
|
t.Fatal("Expected error from driver")
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMissingValues(t *testing.T) {
|
|
|
|
var plugin = "test-net-driver-missing"
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
defer setupPlugin(t, plugin, mux)()
|
|
|
|
|
|
|
|
ep := &testEndpoint{
|
2015-09-09 19:06:35 -04:00
|
|
|
t: t,
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
|
|
|
|
iface := map[string]interface{}{
|
|
|
|
"Address": ep.address,
|
|
|
|
"AddressIPv6": ep.addressIPv6,
|
|
|
|
"MacAddress": ep.macAddress,
|
|
|
|
}
|
|
|
|
return map[string]interface{}{
|
2015-10-03 19:11:50 -04:00
|
|
|
"Interface": iface,
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2018-05-31 12:36:58 -04:00
|
|
|
|
|
|
|
client, err := getPluginClient(p)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
driver := newDriver(plugin, client)
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
|
2015-07-02 01:00:48 -04:00
|
|
|
if err := driver.CreateEndpoint("dummy", "dummy", ep, map[string]interface{}{}); err != nil {
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type rollbackEndpoint struct {
|
|
|
|
}
|
|
|
|
|
2015-09-09 19:06:35 -04:00
|
|
|
func (r *rollbackEndpoint) Interface() driverapi.InterfaceInfo {
|
2015-10-03 19:11:50 -04:00
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *rollbackEndpoint) MacAddress() net.HardwareAddr {
|
2015-09-09 19:06:35 -04:00
|
|
|
return nil
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
2015-10-03 19:11:50 -04:00
|
|
|
func (r *rollbackEndpoint) Address() *net.IPNet {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *rollbackEndpoint) AddressIPv6() *net.IPNet {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *rollbackEndpoint) SetMacAddress(mac net.HardwareAddr) error {
|
2016-11-21 20:29:53 -05:00
|
|
|
return errors.New("invalid mac")
|
2015-10-03 19:11:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (r *rollbackEndpoint) SetIPAddress(ip *net.IPNet) error {
|
2016-11-21 20:29:53 -05:00
|
|
|
return errors.New("invalid ip")
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestRollback(t *testing.T) {
|
|
|
|
var plugin = "test-net-driver-rollback"
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
defer setupPlugin(t, plugin, mux)()
|
|
|
|
|
|
|
|
rolledback := false
|
|
|
|
|
|
|
|
handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
|
|
|
|
iface := map[string]interface{}{
|
|
|
|
"Address": "192.168.4.5/16",
|
|
|
|
"AddressIPv6": "",
|
|
|
|
"MacAddress": "7a:12:34:56:78:90",
|
|
|
|
}
|
|
|
|
return map[string]interface{}{
|
2015-09-09 19:06:35 -04:00
|
|
|
"Interface": interface{}(iface),
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
})
|
|
|
|
handle(t, mux, "DeleteEndpoint", func(msg map[string]interface{}) interface{} {
|
|
|
|
rolledback = true
|
|
|
|
return map[string]interface{}{}
|
|
|
|
})
|
|
|
|
|
|
|
|
p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2018-05-31 12:36:58 -04:00
|
|
|
|
|
|
|
client, err := getPluginClient(p)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
driver := newDriver(plugin, client)
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
|
|
|
|
ep := &rollbackEndpoint{}
|
|
|
|
|
2015-10-03 19:11:50 -04:00
|
|
|
if err := driver.CreateEndpoint("dummy", "dummy", ep.Interface(), map[string]interface{}{}); err == nil {
|
2016-11-21 20:29:53 -05:00
|
|
|
t.Fatal("Expected error from driver")
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
if !rolledback {
|
2016-11-21 20:29:53 -05:00
|
|
|
t.Fatal("Expected to have had DeleteEndpoint called")
|
Remote driver implementation
In essense, this just involves marshalling structs back and forth to a
remote process, via the plugin client. There are a couple of types
that don't JSONify well, notably `net.IPNet`, so there is some
translation to be done.
To conform to the driverapi interface, we must give the list of
endpoint interfaces to the remote process, and let it puzzle out what
it's supposed to do; including the possibility of returning an error.
The constraints on EndpointInfo are enforced by the remote driver
implementation; namely:
* It can't be nil
* If it's got non-empty Interfaces(), the remote process can't put
more in
In the latter case, or if we fail to add an interface for some
(future) reason, we try to roll the endpoint creation back. Likewise
for join -- if we fail to set the fields of the JoinInfo, we roll the
join back by leaving.
Signed-off-by: Michael Bridgen <mikeb@squaremobius.net>
2015-05-16 12:27:21 -04:00
|
|
|
}
|
|
|
|
}
|