* Add forwardcrd plugin README.md Co-authored-by: Aidan Obley <aobley@vmware.com> Signed-off-by: Christian Ang <angc@vmware.com> * Create forwardcrd plugin - Place forwardcrd before forward plugin in plugin list. This will avoid forward from preventing the forwardcrd plugin from handling any queries in the case of having a default upstream forwarder in a server block (as is the case in the default kubernetes Corefile). Co-authored-by: Aidan Obley <aobley@vmware.com> Signed-off-by: Christian Ang <angc@vmware.com> * Add Forward CRD Signed-off-by: Christian Ang <angc@vmware.com> * Add NewWithConfig to forward plugin - allows external packages to instanciate forward plugins Co-authored-by: Aidan Obley <aobley@vmware.com> Signed-off-by: Christian Ang <angc@vmware.com> * ForwardCRD plugin handles requests for Forward CRs - add a Kubernetes controller that can read Forward CRs - instances of the forward plugin are created based on Forward CRs from the Kubernetes controller - DNS requests are handled by calling matching Forward plugin instances based on zone name - Defaults to the kube-system namespace to align with Corefile RBAC Signed-off-by: Christian Ang <angc@vmware.com> Use klog v2 in forwardcrd plugin * Refactor forward setup to use NewWithConfig Co-authored-by: Christian Ang <angc@vmware.com> Signed-off-by: Edwin Xie <exie@vmware.com> * Use ParseInt instead of Atoi - to ensure that the bitsize is 32 for later casting to uint32 Signed-off-by: Christian Ang <angc@vmware.com> * Add @christianang to CODEOWNERS for forwardcrd Signed-off-by: Christian Ang <angc@vmware.com> Co-authored-by: Edwin Xie <exie@vmware.com>
89 lines
2.9 KiB
Go
89 lines
2.9 KiB
Go
package forwardcrd
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/coredns/coredns/plugin/forward"
|
|
)
|
|
|
|
func TestPluginMap(t *testing.T) {
|
|
pluginInstanceMap := NewPluginInstanceMap()
|
|
|
|
zone1ForwardPlugin := forward.New()
|
|
zone2ForwardPlugin := forward.New()
|
|
|
|
// Testing concurrency to ensure map is thread-safe
|
|
// i.e should run with `go test -race`
|
|
wg := sync.WaitGroup{}
|
|
wg.Add(1)
|
|
go func() {
|
|
pluginInstanceMap.Upsert("default/some-dns-zone", "zone-1.test", zone1ForwardPlugin)
|
|
wg.Done()
|
|
}()
|
|
wg.Add(1)
|
|
go func() {
|
|
pluginInstanceMap.Upsert("default/another-dns-zone", "zone-2.test", zone2ForwardPlugin)
|
|
wg.Done()
|
|
}()
|
|
wg.Wait()
|
|
|
|
if plugin, exists := pluginInstanceMap.Get("zone-1.test."); exists && plugin != zone1ForwardPlugin {
|
|
t.Fatalf("Expected plugin instance map to get plugin with address: %p but was: %p", zone1ForwardPlugin, plugin)
|
|
}
|
|
|
|
if plugin, exists := pluginInstanceMap.Get("zone-2.test"); exists && plugin != zone2ForwardPlugin {
|
|
t.Fatalf("Expected plugin instance map to get plugin with address: %p but was: %p", zone2ForwardPlugin, plugin)
|
|
}
|
|
|
|
if _, exists := pluginInstanceMap.Get("non-existant-zone.test"); exists {
|
|
t.Fatal("Expected plugin instance map to not return a plugin")
|
|
}
|
|
|
|
// list
|
|
|
|
plugins := pluginInstanceMap.List()
|
|
if len(plugins) != 2 {
|
|
t.Fatalf("Expected plugin instance map to have len %d, got: %d", 2, len(plugins))
|
|
}
|
|
|
|
if plugins[0] != zone1ForwardPlugin && plugins[0] != zone2ForwardPlugin {
|
|
t.Fatalf("Expected plugin instance map to list plugin[0] with address: %p or %p but was: %p", zone1ForwardPlugin, zone2ForwardPlugin, plugins[0])
|
|
}
|
|
|
|
if plugins[1] != zone1ForwardPlugin && plugins[1] != zone2ForwardPlugin {
|
|
t.Fatalf("Expected plugin instance map to list plugin[1] with address: %p or %p but was: %p", zone1ForwardPlugin, zone2ForwardPlugin, plugins[1])
|
|
}
|
|
|
|
// update record with the same key
|
|
|
|
oldPlugin, update := pluginInstanceMap.Upsert("default/some-dns-zone", "new-zone-1.test", zone1ForwardPlugin)
|
|
|
|
if !update {
|
|
t.Fatalf("Expected Upsert to be an update")
|
|
}
|
|
|
|
if oldPlugin != zone1ForwardPlugin {
|
|
t.Fatalf("Expected Upsert to return the old plugin %#v, got: %#v", zone1ForwardPlugin, oldPlugin)
|
|
}
|
|
|
|
if plugin, exists := pluginInstanceMap.Get("new-zone-1.test"); exists && plugin != zone1ForwardPlugin {
|
|
t.Fatalf("Expected plugin instance map to get plugin with address: %p but was: %p", zone1ForwardPlugin, plugin)
|
|
|
|
}
|
|
if _, exists := pluginInstanceMap.Get("zone-1.test"); exists {
|
|
t.Fatalf("Expected plugin instance map to not get plugin with zone: %s", "zone-1.test")
|
|
}
|
|
|
|
// delete record by key
|
|
|
|
deletedPlugin := pluginInstanceMap.Delete("default/some-dns-zone")
|
|
|
|
if _, exists := pluginInstanceMap.Get("new-zone-1.test"); exists {
|
|
t.Fatalf("Expected plugin instance map to not get plugin with zone: %s", "new-zone-1.test")
|
|
}
|
|
|
|
if deletedPlugin == nil || deletedPlugin != zone1ForwardPlugin {
|
|
t.Fatalf("Expected Delete to return the deleted plugin %#v, got: %#v", zone1ForwardPlugin, deletedPlugin)
|
|
}
|
|
}
|