func TestGetCapabilities(t *testing.T) { var plugin = "test-ipam-driver-capabilities" mux := http.NewServeMux() defer setupPlugin(t, plugin, mux)() handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} { return map[string]interface{}{ "RequiresMACAddress": true, } }) p, err := plugins.Get(plugin, ipamapi.PluginEndpointType) if err != nil { t.Fatal(err) } d := newAllocator(plugin, p.Client) caps, err := d.(*allocator).getCapabilities() if err != nil { t.Fatal(err) } if !caps.RequiresMACAddress || caps.RequiresRequestReplay { t.Fatalf("Unexpected capability: %v", caps) } }
func initPlugin() { volPlugin, err = plugins.Get(volumeDriver, "VolumeDriver") volProxy = volumeDriverProxy{volPlugin.Client} if err != nil { log.WithField("volumeDriver", volumeDriver).Info(err) } }
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) } d := newDriver(plugin, p.Client) 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") } }
func lookupPlugin(name, home string, opts []string) (Driver, error) { pl, err := plugins.Get(name, "GraphDriver") if err != nil { return nil, fmt.Errorf("Error looking up graphdriver plugin %s: %v", name, err) } return newPluginDriver(name, home, opts, pl.Client) }
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 TestMissingValues(t *testing.T) { var plugin = "test-net-driver-missing" mux := http.NewServeMux() defer setupPlugin(t, plugin, mux)() ep := &testEndpoint{ t: t, } 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{}{ "Interface": iface, } }) p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType) if err != nil { t.Fatal(err) } driver := newDriver(plugin, p.Client) if err := driver.CreateEndpoint("dummy", "dummy", ep, map[string]interface{}{}); err != nil { t.Fatal(err) } }
// LookupWithCapability returns a plugin matching the given name and capability. func LookupWithCapability(name, capability string) (Plugin, error) { var ( p *plugin err error ) handleLegacy := true if manager != nil { p, err = manager.get(name) if err != nil { if _, ok := err.(ErrNotFound); !ok { return nil, err } handleLegacy = manager.handleLegacy } else { handleLegacy = false } } if handleLegacy { p, err := plugins.Get(name, capability) if err != nil { return nil, fmt.Errorf("legacy plugin: %v", err) } return p, nil } else if err != nil { return nil, err } capability = strings.ToLower(capability) for _, typ := range p.p.Manifest.Interface.Types { if typ.Capability == capability && typ.Prefix == "docker" { return p, nil } } return nil, ErrInadequateCapability{name, 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{}{ "Scope": "local", "foo": "bar", } }) p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType) if err != nil { t.Fatal(err) } d := newDriver(plugin, p.Client) if d.Type() != plugin { t.Fatal("Driver type does not match that given") } c, err := d.(*driver).getCapabilities() if err != nil { t.Fatal(err) } else if c.DataScope != datastore.LocalScope { t.Fatalf("get capability '%s', expecting 'local'", c.DataScope) } }
// Get returns an enabled plugin matching the given name and capability. func (ps *Store) Get(name, capability string, mode int) (plugingetter.CompatPlugin, error) { var ( p *v2.Plugin err error ) // Lookup using new model. if ps != nil { p, err = ps.GetV2Plugin(name) if err == nil { p.AddRefCount(mode) if p.IsEnabled() { return p.FilterByCap(capability) } // Plugin was found but it is disabled, so we should not fall back to legacy plugins // but we should error out right away return nil, ErrNotFound(name) } if _, ok := errors.Cause(err).(ErrNotFound); !ok { return nil, err } } // Lookup using legacy model. if allowV1PluginsFallback { p, err := plugins.Get(name, capability) if err != nil { return nil, fmt.Errorf("legacy plugin: %v", err) } return p, nil } return nil, err }
// Lookup returns the driver associated with the given name. If a // driver with the given name has not been registered it checks if // there is a VolumeDriver plugin available with the given name. func Lookup(name string) (volume.Driver, error) { drivers.driverLock.Lock(name) defer drivers.driverLock.Unlock(name) drivers.Lock() ext, ok := drivers.extensions[name] drivers.Unlock() if ok { return ext, nil } pl, err := plugins.Get(name, extName) if err != nil { return nil, fmt.Errorf("Error looking up volume plugin %s: %v", name, err) } drivers.Lock() defer drivers.Unlock() if ext, ok := drivers.extensions[name]; ok { return ext, nil } d := NewVolumeDriver(name, pl.Client) drivers.extensions[name] = d return d, nil }
// initPlugin initializes the authorization plugin if needed func (a *authorizationPlugin) initPlugin() error { // Lazy loading of plugins var err error a.once.Do(func() { if a.plugin == nil { a.plugin, err = plugins.Get(a.name, AuthZApiImplements) } }) return err }
func (c *controller) loadIPAMDriver(name string) error { if _, err := plugins.Get(name, ipamapi.PluginEndpointType); err != nil { if err == plugins.ErrNotFound { return types.NotFoundErrorf(err.Error()) } return err } return nil }
// initPlugin initializes the authorization plugin if needed func (a *authorizationPlugin) initPlugin() error { // Lazy loading of plugins if a.plugin == nil { var err error a.plugin, err = plugins.Get(a.name, AuthZApiImplements) if err != nil { return err } } return nil }
func (c *controller) loadDriver(networkType string) error { // Plugins pkg performs lazy loading of plugins that acts as remote drivers. // As per the design, this Get call will result in remote driver discovery if there is a corresponding plugin available. _, err := plugins.Get(networkType, driverapi.NetworkPluginEndpointType) if err != nil { if err == plugins.ErrNotFound { return types.NotFoundErrorf(err.Error()) } return err } return nil }
func (c *controller) loadIpamDriver(name string) (*ipamData, error) { if _, err := plugins.Get(name, ipamapi.PluginEndpointType); err != nil { if err == plugins.ErrNotFound { return nil, types.NotFoundErrorf(err.Error()) } return nil, err } c.Lock() id, ok := c.ipamDrivers[name] c.Unlock() if !ok { return nil, ErrInvalidNetworkDriver(name) } return id, nil }
func (c *controller) loadDriver(networkType string) (driverapi.Driver, error) { // Plugins pkg performs lazy loading of plugins that acts as remote drivers. // As per the design, this Get call will result in remote driver discovery if there is a corresponding plugin available. _, err := plugins.Get(networkType, driverapi.NetworkPluginEndpointType) if err != nil { return nil, err } c.Lock() defer c.Unlock() d, ok := c.drivers[networkType] if !ok { return nil, ErrInvalidNetworkDriver } return d, nil }
// initPlugin initializes the authorization plugin if needed func (a *authorizationPlugin) initPlugin() error { // Lazy loading of plugins var err error a.once.Do(func() { if a.plugin == nil { plugin, e := plugins.Get(a.name, AuthZApiImplements) if e != nil { err = e return } a.plugin = plugin.Client() } }) return err }
// Get returns an enabled plugin matching the given name and capability. func (ps *Store) Get(name, capability string, mode int) (plugingetter.CompatPlugin, error) { var ( p *v2.Plugin err error ) // Lookup using new model. if ps != nil { fullName := name if named, err := reference.ParseNamed(fullName); err == nil { // FIXME: validate if reference.IsNameOnly(named) { named = reference.WithDefaultTag(named) } ref, ok := named.(reference.NamedTagged) if !ok { return nil, fmt.Errorf("invalid name: %s", named.String()) } fullName = ref.String() } p, err = ps.GetByName(fullName) if err == nil { p.Lock() p.RefCount += mode p.Unlock() if p.IsEnabled() { return p.FilterByCap(capability) } // Plugin was found but it is disabled, so we should not fall back to legacy plugins // but we should error out right away return nil, ErrNotFound(fullName) } if _, ok := err.(ErrNotFound); !ok { return nil, err } } // Lookup using legacy model. if allowV1PluginsFallback { p, err := plugins.Get(name, capability) if err != nil { return nil, fmt.Errorf("legacy plugin: %v", err) } return p, nil } return nil, err }
func TestGetCapabilitiesFromLegacyDriver(t *testing.T) { var plugin = "test-ipam-legacy-driver" mux := http.NewServeMux() defer setupPlugin(t, plugin, mux)() p, err := plugins.Get(plugin, ipamapi.PluginEndpointType) if err != nil { t.Fatal(err) } d := newAllocator(plugin, p.Client) if _, err := d.(*allocator).getCapabilities(); err == nil { t.Fatalf("Expected error, but got Success %v", err) } }
// LookupWithCapability returns a plugin matching the given name and capability. func LookupWithCapability(name, capability string) (Plugin, error) { var ( p *plugin err error ) handleLegacy := true if manager != nil { fullName := name if named, err := reference.ParseNamed(fullName); err == nil { // FIXME: validate if reference.IsNameOnly(named) { named = reference.WithDefaultTag(named) } ref, ok := named.(reference.NamedTagged) if !ok { return nil, fmt.Errorf("invalid name: %s", named.String()) } fullName = ref.String() } p, err = manager.get(fullName) if err != nil { if _, ok := err.(ErrNotFound); !ok { return nil, err } handleLegacy = manager.handleLegacy } else { handleLegacy = false } } if handleLegacy { p, err := plugins.Get(name, capability) if err != nil { return nil, fmt.Errorf("legacy plugin: %v", err) } return p, nil } else if err != nil { return nil, err } capability = strings.ToLower(capability) for _, typ := range p.PluginObj.Manifest.Interface.Types { if typ.Capability == capability && typ.Prefix == "docker" { return p, nil } } return nil, ErrInadequateCapability{name, capability} }
func (c *controller) loadDriver(networkType string) error { var err error if pg := c.GetPluginGetter(); pg != nil { _, err = pg.Get(networkType, driverapi.NetworkPluginEndpointType, plugingetter.Lookup) } else { _, err = plugins.Get(networkType, driverapi.NetworkPluginEndpointType) } if err != nil { if err == plugins.ErrNotFound { return types.NotFoundErrorf(err.Error()) } return err } return nil }
func (c *controller) loadIPAMDriver(name string) error { var err error if pg := c.GetPluginGetter(); pg != nil { _, err = pg.Get(name, ipamapi.PluginEndpointType, plugingetter.LOOKUP) } else { _, err = plugins.Get(name, ipamapi.PluginEndpointType) } if err != nil { if err == plugins.ErrNotFound { return types.NotFoundErrorf(err.Error()) } return err } return nil }
// LookupWithCapability returns a plugin matching the given name and capability. func LookupWithCapability(name, capability string) (CompatPlugin, error) { var ( p *v2.Plugin err error ) // Lookup using new model. if store != nil { fullName := name if named, err := reference.ParseNamed(fullName); err == nil { // FIXME: validate if reference.IsNameOnly(named) { named = reference.WithDefaultTag(named) } ref, ok := named.(reference.NamedTagged) if !ok { return nil, fmt.Errorf("invalid name: %s", named.String()) } fullName = ref.String() } p, err = store.GetByName(fullName) if err == nil { return p.FilterByCap(capability) } if _, ok := err.(ErrNotFound); !ok { return nil, err } } // Lookup using legacy model. if allowV1PluginsFallback { p, err := plugins.Get(name, capability) if err != nil { return nil, fmt.Errorf("legacy plugin: %v", err) } return p, nil } return nil, err }
// initPlugin initializes the authorization plugin if needed func (a *authorizationPlugin) initPlugin() error { // Lazy loading of plugins var err error a.once.Do(func() { if a.plugin == nil { var plugin plugingetter.CompatPlugin var e error if pg := GetPluginGetter(); pg != nil { plugin, e = pg.Get(a.name, AuthZApiImplements, plugingetter.Lookup) } else { plugin, e = plugins.Get(a.name, AuthZApiImplements) } if e != nil { err = e return } a.plugin = plugin.Client() } }) return err }
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{}{ "Interface": interface{}(iface), } }) 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) } driver := newDriver(plugin, p.Client) ep := &rollbackEndpoint{} if err := driver.CreateEndpoint("dummy", "dummy", ep.Interface(), map[string]interface{}{}); err == nil { t.Fatalf("Expected error from driver") } if !rolledback { t.Fatalf("Expected to have had DeleteEndpoint called") } }
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) } driver := newDriver(plugin, p.Client) if err := driver.CreateEndpoint("dummy", "dummy", &testEndpoint{t: t}, map[string]interface{}{}); err == nil { t.Fatalf("Expected error from driver") } }
// LookupWithCapability returns a plugin matching the given name and capability. func LookupWithCapability(name, capability string, _ int) (CompatPlugin, error) { return plugins.Get(name, capability) }
func (na *NetworkAllocator) loadDriver(name string) error { _, err := plugins.Get(name, driverapi.NetworkPluginEndpointType) return err }
// LookupWithCapability returns a plugin matching the given name and capability. func LookupWithCapability(name, capability string) (Plugin, error) { return plugins.Get(name, capability) }
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", macAddress: "ab:cd:ef:ee:ee:ee", gateway: "192.168.0.1", gatewayIPv6: "2001:DB8::1", hostsPath: "/here/comes/the/host/path", resolvConfPath: "/there/goes/the/resolv/conf", destination: "10.0.0.0/8", nextHop: "10.0.0.1", routeType: 1, } mux := http.NewServeMux() defer setupPlugin(t, plugin, mux)() var networkID string handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} { return map[string]interface{}{ "Scope": "global", } }) 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{}{ "MacAddress": ep.macAddress, "Address": ep.address, "AddressIPv6": ep.addressIPv6, } return map[string]interface{}{ "Interface": iface, } }) 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, "InterfaceName": map[string]interface{}{ "SrcName": ep.src, "DstPrefix": ep.dst, }, "StaticRoutes": []map[string]interface{}{ { "Destination": ep.destination, "RouteType": ep.routeType, "NextHop": ep.nextHop, }, }, } }) 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?", }, } }) 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{}{} }) p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType) if err != nil { t.Fatal(err) } d := newDriver(plugin, p.Client) if d.Type() != plugin { t.Fatal("Driver type does not match that given") } c, err := d.(*driver).getCapabilities() if err != nil { t.Fatal(err) } else if c.DataScope != datastore.GlobalScope { t.Fatalf("get capability '%s', expecting 'global'", c.DataScope) } netID := "dummy-network" err = d.CreateNetwork(netID, map[string]interface{}{}, nil, nil, nil) if err != nil { t.Fatal(err) } endID := "dummy-endpoint" ifInfo := &testEndpoint{} err = d.CreateEndpoint(netID, endID, ifInfo, map[string]interface{}{}) if err != nil { t.Fatal(err) } 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()) } joinOpts := map[string]interface{}{"foo": "fooValue"} err = d.Join(netID, endID, "sandbox-key", ep, joinOpts) if err != nil { t.Fatal(err) } if _, err = d.EndpointOperInfo(netID, endID); err != nil { t.Fatal(err) } if err = d.Leave(netID, endID); err != nil { t.Fatal(err) } if err = d.DeleteEndpoint(netID, endID); err != nil { t.Fatal(err) } if err = d.DeleteNetwork(netID); err != nil { t.Fatal(err) } data := discoverapi.NodeDiscoveryData{ Address: "192.168.1.1", } if err = d.DiscoverNew(discoverapi.NodeDiscovery, data); err != nil { t.Fatal(err) } if err = d.DiscoverDelete(discoverapi.NodeDiscovery, data); err != nil { t.Fatal(err) } }