@@ -25,9 +25,11 @@ import (
2525 configurationv1 "github.com/kong/kubernetes-configuration/v2/api/configuration/v1"
2626 "github.com/kong/kubernetes-configuration/v2/pkg/clientset"
2727
28+ "github.com/kong/kong-operator/ingress-controller/internal/adminapi"
2829 "github.com/kong/kong-operator/ingress-controller/internal/annotations"
2930 "github.com/kong/kong-operator/ingress-controller/internal/gatewayapi"
3031 "github.com/kong/kong-operator/ingress-controller/internal/labels"
32+ managercfg "github.com/kong/kong-operator/ingress-controller/pkg/manager/config"
3133 "github.com/kong/kong-operator/ingress-controller/test"
3234 "github.com/kong/kong-operator/ingress-controller/test/consts"
3335 "github.com/kong/kong-operator/ingress-controller/test/internal/helpers"
@@ -716,3 +718,99 @@ func TestPluginCrossNamespaceReference(t *testing.T) {
716718 assert .True (c , resp .StatusCode == http .StatusTeapot )
717719 }, ingressWait , waitTick )
718720}
721+
722+ func TestPluginNullInConfig (t * testing.T ) {
723+ ctx := t .Context ()
724+
725+ t .Parallel ()
726+ ns , cleaner := helpers .Setup (ctx , t , env )
727+
728+ t .Log ("deploying a minimal HTTP container deployment to test Ingress routes" )
729+ container := generators .NewContainer ("httpbin" , test .HTTPBinImage , test .HTTPBinPort )
730+ deployment := generators .NewDeploymentForContainer (container )
731+ deployment , err := env .Cluster ().Client ().AppsV1 ().Deployments (ns .Name ).Create (ctx , deployment , metav1.CreateOptions {})
732+ require .NoError (t , err )
733+ cleaner .Add (deployment )
734+
735+ t .Logf ("exposing deployment %s via service" , deployment .Name )
736+ service := generators .NewServiceForDeployment (deployment , corev1 .ServiceTypeLoadBalancer )
737+ service , err = env .Cluster ().Client ().CoreV1 ().Services (ns .Name ).Create (ctx , service , metav1.CreateOptions {})
738+ require .NoError (t , err )
739+ cleaner .Add (service )
740+
741+ t .Logf ("creating an ingress for service %s with ingress.class %s" , service .Name , consts .IngressClass )
742+ ingress := generators .NewIngressForService ("/test_plugin_essentials" , map [string ]string {
743+ "konghq.com/strip-path" : "true" ,
744+ }, service )
745+ ingress .Spec .IngressClassName = kong .String (consts .IngressClass )
746+ ingress , err = env .Cluster ().Client ().NetworkingV1 ().Ingresses (ns .Name ).Create (ctx , ingress , metav1.CreateOptions {})
747+ require .NoError (t , err )
748+ cleaner .Add (ingress )
749+
750+ t .Log ("waiting for routes from Ingress to be operational" )
751+ assert .Eventually (t , func () bool {
752+ resp , err := helpers .DefaultHTTPClient ().Get (fmt .Sprintf ("%s/test_plugin_essentials" , proxyHTTPURL ))
753+ if err != nil {
754+ t .Logf ("WARNING: error while waiting for %s: %v" , proxyHTTPURL , err )
755+ return false
756+ }
757+ defer resp .Body .Close ()
758+ if resp .StatusCode == http .StatusOK {
759+ // now that the ingress backend is routable, make sure the contents we're getting back are what we expect
760+ // Expected: "<title>httpbin.org</title>"
761+ b := new (bytes.Buffer )
762+ n , err := b .ReadFrom (resp .Body )
763+ require .NoError (t , err )
764+ require .True (t , n > 0 )
765+ return strings .Contains (b .String (), "<title>httpbin.org</title>" )
766+ }
767+ return false
768+ }, ingressWait , waitTick )
769+
770+ t .Log ("Creating a plugin with `null` in its configuration" )
771+
772+ kongplugin := & configurationv1.KongPlugin {
773+ ObjectMeta : metav1.ObjectMeta {
774+ Namespace : ns .Name ,
775+ Name : "plugin-datadog" ,
776+ },
777+ InstanceName : "plugin-with-null" ,
778+ PluginName : "datadog" ,
779+ Config : apiextensionsv1.JSON {
780+ Raw : []byte (`{"host":"localhost","port":8125,"prefix":null}` ),
781+ },
782+ }
783+ c , err := clientset .NewForConfig (env .Cluster ().Config ())
784+ require .NoError (t , err )
785+ kongplugin , err = c .ConfigurationV1 ().KongPlugins (ns .Name ).Create (ctx , kongplugin , metav1.CreateOptions {})
786+ require .NoError (t , err )
787+ cleaner .Add (kongplugin )
788+
789+ t .Logf ("Updating Ingress to use plugin %s" , kongplugin .Name )
790+ require .Eventually (t , func () bool {
791+ ingress , err := env .Cluster ().Client ().NetworkingV1 ().Ingresses (ns .Name ).Get (ctx , ingress .Name , metav1.GetOptions {})
792+ if err != nil {
793+ return false
794+ }
795+ ingress .Annotations [annotations .AnnotationPrefix + annotations .PluginsKey ] = kongplugin .Name
796+ _ , err = env .Cluster ().Client ().NetworkingV1 ().Ingresses (ns .Name ).Update (ctx , ingress , metav1.UpdateOptions {})
797+ return err == nil
798+ }, ingressWait , waitTick )
799+
800+ t .Logf ("Checking the configuration of the plugin %s in Kong" , kongplugin .Name )
801+ require .Eventually (t , func () bool {
802+ kc , err := adminapi .NewKongAPIClient (proxyAdminURL .String (), managercfg.AdminAPIClientConfig {}, consts .KongTestPassword )
803+ require .NoError (t , err , "failed to create Kong client" )
804+ plugins , err := kc .Plugins .ListAll (ctx )
805+ require .NoError (t , err , "failed to list plugins" )
806+ if len (plugins ) != 1 {
807+ return false
808+ }
809+ plugin := plugins [0 ]
810+ if plugin .Name == nil || * plugin .Name != "datadog" {
811+ return false
812+ }
813+ configPrefix , ok := plugin .Config ["prefix" ]
814+ return ok && configPrefix == nil
815+ }, ingressWait , waitTick , "failed to find 'datadog' plugin with null in config.prefix in Kong" )
816+ }
0 commit comments