123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- package remote
- import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "net"
- "net/http"
- "net/http/httptest"
- "os"
- "testing"
- "github.com/docker/docker/pkg/plugins"
- "github.com/docker/libnetwork/ipamapi"
- _ "github.com/docker/libnetwork/testutils"
- )
- 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", ipamapi.PluginEndpointType, method), func(w http.ResponseWriter, r *http.Request) {
- ask, err := decodeToMap(r)
- if err != nil {
- 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() {
- if err := os.MkdirAll("/etc/docker/plugins", 0755); err != nil {
- t.Fatal(err)
- }
- server := httptest.NewServer(mux)
- if server == nil {
- t.Fatal("Failed to start a HTTP Server")
- }
- if err := ioutil.WriteFile(fmt.Sprintf("/etc/docker/plugins/%s.spec", name), []byte(server.URL), 0644); err != nil {
- t.Fatal(err)
- }
- mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
- fmt.Fprintf(w, `{"Implements": ["%s"]}`, ipamapi.PluginEndpointType)
- })
- return func() {
- if err := os.RemoveAll("/etc/docker/plugins"); err != nil {
- t.Fatal(err)
- }
- server.Close()
- }
- }
- func TestGetDefaultAddressSpaces(t *testing.T) {
- var plugin = "test-ipam-driver-addr-spaces"
- mux := http.NewServeMux()
- defer setupPlugin(t, plugin, mux)()
- handle(t, mux, "GetDefaultAddressSpaces", func(msg map[string]interface{}) interface{} {
- return map[string]interface{}{
- "LocalDefaultAddressSpace": "white",
- "GlobalDefaultAddressSpace": "blue",
- }
- })
- p, err := plugins.Get(plugin, ipamapi.PluginEndpointType)
- if err != nil {
- t.Fatal(err)
- }
- d := newAllocator(plugin, p.Client)
- l, g, err := d.(*allocator).GetDefaultAddressSpaces()
- if err != nil {
- t.Fatal(err)
- }
- if l != "white" || g != "blue" {
- t.Fatalf("Unexpected default local and global address spaces: %s, %s", l, g)
- }
- }
- func TestRemoteDriver(t *testing.T) {
- var plugin = "test-ipam-driver"
- mux := http.NewServeMux()
- defer setupPlugin(t, plugin, mux)()
- handle(t, mux, "GetDefaultAddressSpaces", func(msg map[string]interface{}) interface{} {
- return map[string]interface{}{
- "LocalDefaultAddressSpace": "white",
- "GlobalDefaultAddressSpace": "blue",
- }
- })
- handle(t, mux, "RequestPool", func(msg map[string]interface{}) interface{} {
- as := "white"
- if v, ok := msg["AddressSpace"]; ok && v.(string) != "" {
- as = v.(string)
- }
- pl := "172.18.0.0/16"
- sp := ""
- if v, ok := msg["Pool"]; ok && v.(string) != "" {
- pl = v.(string)
- }
- if v, ok := msg["SubPool"]; ok && v.(string) != "" {
- sp = v.(string)
- }
- pid := fmt.Sprintf("%s/%s", as, pl)
- if sp != "" {
- pid = fmt.Sprintf("%s/%s", pid, sp)
- }
- return map[string]interface{}{
- "PoolID": pid,
- "Pool": pl,
- "Data": map[string]string{"DNS": "8.8.8.8"},
- }
- })
- handle(t, mux, "ReleasePool", func(msg map[string]interface{}) interface{} {
- if _, ok := msg["PoolID"]; !ok {
- t.Fatalf("Missing PoolID in Release request")
- }
- return map[string]interface{}{}
- })
- handle(t, mux, "RequestAddress", func(msg map[string]interface{}) interface{} {
- if _, ok := msg["PoolID"]; !ok {
- t.Fatalf("Missing PoolID in address request")
- }
- prefAddr := ""
- if v, ok := msg["Address"]; ok {
- prefAddr = v.(string)
- }
- ip := prefAddr
- if ip == "" {
- ip = "172.20.0.34"
- }
- ip = fmt.Sprintf("%s/16", ip)
- return map[string]interface{}{
- "Address": ip,
- }
- })
- handle(t, mux, "ReleaseAddress", func(msg map[string]interface{}) interface{} {
- if _, ok := msg["PoolID"]; !ok {
- t.Fatalf("Missing PoolID in address request")
- }
- if _, ok := msg["Address"]; !ok {
- t.Fatalf("Missing Address in release address request")
- }
- return map[string]interface{}{}
- })
- p, err := plugins.Get(plugin, ipamapi.PluginEndpointType)
- if err != nil {
- t.Fatal(err)
- }
- d := newAllocator(plugin, p.Client)
- l, g, err := d.(*allocator).GetDefaultAddressSpaces()
- if err != nil {
- t.Fatal(err)
- }
- if l != "white" || g != "blue" {
- t.Fatalf("Unexpected default local/global address spaces: %s, %s", l, g)
- }
- // Request any pool
- poolID, pool, _, err := d.RequestPool("white", "", "", nil, false)
- if err != nil {
- t.Fatal(err)
- }
- if poolID != "white/172.18.0.0/16" {
- t.Fatalf("Unexpected pool id: %s", poolID)
- }
- if pool == nil || pool.String() != "172.18.0.0/16" {
- t.Fatalf("Unexpected pool: %s", pool)
- }
- // Request specific pool
- poolID2, pool2, ops, err := d.RequestPool("white", "172.20.0.0/16", "", nil, false)
- if err != nil {
- t.Fatal(err)
- }
- if poolID2 != "white/172.20.0.0/16" {
- t.Fatalf("Unexpected pool id: %s", poolID2)
- }
- if pool2 == nil || pool2.String() != "172.20.0.0/16" {
- t.Fatalf("Unexpected pool: %s", pool2)
- }
- if dns, ok := ops["DNS"]; !ok || dns != "8.8.8.8" {
- t.Fatalf("Missing options")
- }
- // Request specific pool and subpool
- poolID3, pool3, _, err := d.RequestPool("white", "172.20.0.0/16", "172.20.3.0/24" /*nil*/, map[string]string{"culo": "yes"}, false)
- if err != nil {
- t.Fatal(err)
- }
- if poolID3 != "white/172.20.0.0/16/172.20.3.0/24" {
- t.Fatalf("Unexpected pool id: %s", poolID3)
- }
- if pool3 == nil || pool3.String() != "172.20.0.0/16" {
- t.Fatalf("Unexpected pool: %s", pool3)
- }
- // Request any address
- addr, _, err := d.RequestAddress(poolID2, nil, nil)
- if err != nil {
- t.Fatal(err)
- }
- if addr == nil || addr.String() != "172.20.0.34/16" {
- t.Fatalf("Unexpected address: %s", addr)
- }
- // Request specific address
- addr2, _, err := d.RequestAddress(poolID2, net.ParseIP("172.20.1.45"), nil)
- if err != nil {
- t.Fatal(err)
- }
- if addr2 == nil || addr2.String() != "172.20.1.45/16" {
- t.Fatalf("Unexpected address: %s", addr2)
- }
- // Release address
- err = d.ReleaseAddress(poolID, net.ParseIP("172.18.1.45"))
- if err != nil {
- t.Fatal(err)
- }
- }
|