aboutsummaryrefslogtreecommitdiff
path: root/plugin/forwardcrd/plugin_map_test.go
diff options
context:
space:
mode:
authorGravatar Christian Ang <christian.ang@outlook.com> 2021-11-12 08:22:34 -0800
committerGravatar GitHub <noreply@github.com> 2021-11-12 11:22:34 -0500
commit2e6953c7dbd1d6b359911e1ce92e2567df07ca8c (patch)
treed91514ca867bb5b000bec3ea219e6a2ab0a0c244 /plugin/forwardcrd/plugin_map_test.go
parent6953ab2b4f23f916a08b68ba51b9a26e41e9a748 (diff)
downloadcoredns-2e6953c7dbd1d6b359911e1ce92e2567df07ca8c.tar.gz
coredns-2e6953c7dbd1d6b359911e1ce92e2567df07ca8c.tar.zst
coredns-2e6953c7dbd1d6b359911e1ce92e2567df07ca8c.zip
Initial implementation of ForwardCRD plugin (#4512)
* 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>
Diffstat (limited to 'plugin/forwardcrd/plugin_map_test.go')
-rw-r--r--plugin/forwardcrd/plugin_map_test.go89
1 files changed, 89 insertions, 0 deletions
diff --git a/plugin/forwardcrd/plugin_map_test.go b/plugin/forwardcrd/plugin_map_test.go
new file mode 100644
index 000000000..eef0caf7d
--- /dev/null
+++ b/plugin/forwardcrd/plugin_map_test.go
@@ -0,0 +1,89 @@
+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)
+ }
+}