diff --git a/.github/workflows/build_controller_on_pr.yaml b/.github/workflows/build_controller_on_pr.yaml index 4d8f3d2..9c52286 100644 --- a/.github/workflows/build_controller_on_pr.yaml +++ b/.github/workflows/build_controller_on_pr.yaml @@ -21,5 +21,8 @@ jobs: - name: Install dependencies run: go mod download + - name: Test + run: go test -v ./controllers/... + - name: Build run: go build -v ./... \ No newline at end of file diff --git a/controllers/auto_register_spark_ui_controller.go b/controllers/auto_register_spark_ui_controller.go index c17805f..a812e95 100644 --- a/controllers/auto_register_spark_ui_controller.go +++ b/controllers/auto_register_spark_ui_controller.go @@ -12,6 +12,7 @@ import ( errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" logger "k8s.io/klog/v2" ) @@ -20,7 +21,8 @@ import ( // It takes the ingress path, either creates a new ingress object or patch the existing one func createOrUpdateSparkUIIngressObject( ctx context.Context, - clientset *kubernetes.Clientset, + clientset kubernetes.Interface, + dynamicClient dynamic.Interface, service *v1.Service, ingressPath networkingv1.HTTPIngressPath, ingressName string, @@ -38,7 +40,7 @@ func createOrUpdateSparkUIIngressObject( if ingressType == "traefik" { // Create the Traefik middleware - err := ManageTraefikMiddleware(service.Namespace, "create", &authenticationSecret) + err := ManageTraefikMiddleware(dynamicClient, service.Namespace, "create", &authenticationSecret) if err != nil { logger.Error(err) return @@ -82,7 +84,7 @@ func createOrUpdateSparkUIIngressObject( } else { logger.Infof("Ingress %v already exists", ingressName) - logger.Infof("Updateing ingress with %v", ingressPath) + logger.Infof("Updating ingress with %v", ingressPath) ingressCopy := ingress.DeepCopy() ingressCopy.Spec.Rules[0].HTTP.Paths = append(ingress.Spec.Rules[0].HTTP.Paths, @@ -118,9 +120,13 @@ func createOrUpdateSparkUIIngressObject( } } +// Add function called by the informer when a service is created +// It takes the service object, creates the ingress path +// and calls the function responsible for creating or patching the Ingress object func Add( ctx context.Context, - clientset *kubernetes.Clientset, + clientset kubernetes.Interface, + dynamicClient dynamic.Interface, service *v1.Service, namespacedIngressPath bool, ingressName string, @@ -135,7 +141,7 @@ func Add( logger.Infof("Spark App Name: %v", sparkAppName) - var sparkUIPath string = buidSparkUiPath(namespacedIngressPath, service, sparkAppName) + var sparkUIPath string = buildSparkUIPath(namespacedIngressPath, service, sparkAppName) logger.Infof("Spark UI path: %v", sparkUIPath) @@ -153,13 +159,17 @@ func Add( } //Call the function responsible for creating or patching the Ingress object - createOrUpdateSparkUIIngressObject(ctx, clientset, service, ingressPath, ingressName, ingressType, *authenticationSecret) + createOrUpdateSparkUIIngressObject(ctx, clientset, dynamicClient, service, ingressPath, ingressName, ingressType, *authenticationSecret) } +// Delete function called by the informer when a service is deleted +// It takes the servicename, either deletes the ingress object or patch the existing one by +// removing the path that matches the sparkAppName func Delete( ctx context.Context, clientset *kubernetes.Clientset, + dynamicClient dynamic.Interface, service *v1.Service, namespacedIngressPath bool, ingressName string, @@ -179,7 +189,7 @@ func Delete( sparkAppName = service.Spec.Selector["spark-app-name"] - var sparkUIPath string = buidSparkUiPath(namespacedIngressPath, service, sparkAppName) + var sparkUIPath string = buildSparkUIPath(namespacedIngressPath, service, sparkAppName) logger.Infof("Spark UI path to remove: %v", sparkUIPath) @@ -206,7 +216,7 @@ func Delete( // Delete the Traefik middleware if ingressType == "traefik" { - ManageTraefikMiddleware(namespace, "delete", authenticationSecret) + ManageTraefikMiddleware(dynamicClient, namespace, "delete", authenticationSecret) log.Printf("Deleted middleware for authentication and url strip as ingress object is deleted") } return @@ -244,7 +254,7 @@ func Delete( log.Printf("Deleted path for sparkAppName %s from ingress %s", sparkAppName, ingressName) } -func buidSparkUiPath(namespacedIngressPath bool, service *v1.Service, sparkAppName string) string { +func buildSparkUIPath(namespacedIngressPath bool, service *v1.Service, sparkAppName string) string { var sparkUIPath string if namespacedIngressPath { diff --git a/controllers/auto_register_spark_ui_controller_test.go b/controllers/auto_register_spark_ui_controller_test.go new file mode 100644 index 0000000..4c1d6a3 --- /dev/null +++ b/controllers/auto_register_spark_ui_controller_test.go @@ -0,0 +1,122 @@ +package controllers + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/dynamic" + dynamicfake "k8s.io/client-go/dynamic/fake" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/fake" +) + +// Mock logger to capture log output +type MockLogger struct { + mock.Mock +} + +func (m *MockLogger) Infof(format string, args ...interface{}) { + m.Called(format, args) +} + +func (m *MockLogger) Error(err error) { + m.Called(err) +} + +func TestAdd(t *testing.T) { + // Create a mock logger + mockLogger := new(MockLogger) + + // Create a fake Kubernetes clientset + var clientset kubernetes.Interface = fake.NewSimpleClientset() + var dynamicClient dynamic.Interface = dynamicfake.NewSimpleDynamicClient(runtime.NewScheme()) + + // Define other parameters + ctx := context.TODO() + namespacedIngressPath := false + ingressName := "test-ingress" + ingressType := "nginx" + authenticationSecret := new(string) + + // Create a mock service with a specific selector + defaultService := &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + }, + Spec: v1.ServiceSpec{ + Selector: map[string]string{ + "spark-app-name": "test-spark-app", + }, + }, + } + + // Expect the logger to receive the correct log message + mockLogger.On("Infof", "Create ingress rule for Spark Application : %s \n", defaultService.GetName()).Return() + + // Call the Add function + Add(ctx, clientset, dynamicClient, defaultService, namespacedIngressPath, ingressName, ingressType, authenticationSecret) + + // Verify that the correct ingress was created + ingresses, err := clientset.NetworkingV1().Ingresses("").List(ctx, metav1.ListOptions{}) + assert.NoError(t, err) + + ingress := ingresses.Items[0] + assert.Equal(t, ingressName, ingress.Name) + assert.Equal(t, defaultService.Namespace, "default") + assert.Equal(t, "/test-spark-app(/|$)(.*)", ingress.Spec.Rules[0].HTTP.Paths[0].Path) + + namespacedIngressPath = true + + // Create a mock service with a specific selector + defaultService = &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + }, + Spec: v1.ServiceSpec{ + Selector: map[string]string{ + "spark-app-name": "default-spark-app", + }, + }, + } + + // Call the Add function + Add(ctx, clientset, dynamicClient, defaultService, namespacedIngressPath, ingressName, ingressType, authenticationSecret) + + // Verify that the correct ingress was created + ingresses, err = clientset.NetworkingV1().Ingresses("").List(ctx, metav1.ListOptions{}) + assert.NoError(t, err) + assert.Len(t, ingresses.Items, 1) + + ingress = ingresses.Items[0] + assert.Equal(t, defaultService.Namespace, "default") + assert.Equal(t, "/default/default-spark-app(/|$)(.*)", ingress.Spec.Rules[0].HTTP.Paths[1].Path) + + // ingressName = "traefik-ingress" + // ingressType = "traefik" + // namespacedIngressPath = false + + // // Create a mock service with a specific selector + // defaultService = &v1.Service{ + // ObjectMeta: metav1.ObjectMeta{ + // Namespace: "default", + // }, + // Spec: v1.ServiceSpec{ + // Selector: map[string]string{ + // "spark-app-name": "default-spark-app", + // }, + // }, + // } + + // Add(ctx, clientset, defaultService, namespacedIngressPath, ingressName, ingressType, authenticationSecret) + + // ingresses, _ = clientset.NetworkingV1().Ingresses("").List(ctx, metav1.ListOptions{}) + // ingress = ingresses.Items[1] + + // assert.Equal(t, "default-spark-ui-url-strip@kubernetescrd", ingress.Annotations["traefik.ingress.kubernetes.io/router.middlewares"], "Ingress does not have the expected Traefik middleware annotation") + +} diff --git a/controllers/traefik_middleware.go b/controllers/traefik_middleware.go index 089c319..db1cc1d 100644 --- a/controllers/traefik_middleware.go +++ b/controllers/traefik_middleware.go @@ -2,31 +2,16 @@ package controllers import ( "context" + "errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" - "k8s.io/client-go/rest" logger "k8s.io/klog/v2" ) -func ManageTraefikMiddleware(namespace, action string, authenticationSecret *string) error { - - // Extract the config from the clientset - config, err := rest.InClusterConfig() - if err != nil { - logger.Errorf("error creating in-cluster config: %v", err) - return err - } - - // Create the dynamic client to create generic resources - // This is needed since Treafik Middleware is a custom resource - dynamicClient, err := dynamic.NewForConfig(config) - if err != nil { - logger.Errorf("error creating dynamic client: %v", err) - return err - } +func ManageTraefikMiddleware(dynamicClient dynamic.Interface, namespace, action string, authenticationSecret *string) error { // Define the GVR (GroupVersionResource) gvr := schema.GroupVersionResource{ @@ -65,7 +50,7 @@ func ManageTraefikMiddleware(namespace, action string, authenticationSecret *str case "delete": // Delete the Middleware object - err = dynamicClient.Resource(gvr).Namespace(namespace).Delete(context.TODO(), "spark-ui-url-strip", metav1.DeleteOptions{}) + err := dynamicClient.Resource(gvr).Namespace(namespace).Delete(context.TODO(), "spark-ui-url-strip", metav1.DeleteOptions{}) if authenticationSecret != nil { err = dynamicClient.Resource(gvr).Namespace(namespace).Delete(context.TODO(), "spark-ui-url-auth", metav1.DeleteOptions{}) @@ -79,14 +64,14 @@ func ManageTraefikMiddleware(namespace, action string, authenticationSecret *str default: logger.Errorf("invalid action: %v", action) - return err + return errors.New("invalid action") } return nil } func createMiddlewareObject( - dynamicClient *dynamic.DynamicClient, + dynamicClient dynamic.Interface, gvr schema.GroupVersionResource, middlewareName string, namespace string, diff --git a/go.mod b/go.mod index 90bf835..68fbbd7 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.0 toolchain go1.22.5 require ( + github.com/stretchr/testify v1.8.4 k8s.io/api v0.30.3 k8s.io/apimachinery v0.30.3 k8s.io/client-go v0.30.3 @@ -15,6 +16,7 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -31,12 +33,17 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - golang.org/x/net v0.23.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect + golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.12.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/go.sum b/go.sum index ed9f036..3802cc0 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= @@ -57,6 +59,8 @@ github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8 github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -65,6 +69,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -77,6 +82,9 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -86,6 +94,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -96,21 +106,30 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/main.go b/main.go index f94f9b9..802de06 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/dynamic" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -34,6 +35,8 @@ func main() { } logger.Infof("Connected to kubernetes cluster") + dynamicClient, err := dynamic.NewForConfig(config) + // Check for the environment variable for spark service selector labelKey := os.Getenv("SPARK_LABEL_SERVICE_SELECTOR") if labelKey != "" { @@ -127,14 +130,14 @@ func main() { service := obj.(*v1.Service) if hasLabel(service, labelKey) { logger.Infof("Service %v created with label %v\n", service.GetName(), labelKey) - controllers.Add(ctx, clientset, service, namespacedIngressPath, ingressName, ingressType, authenticationSecret) + controllers.Add(ctx, clientset, dynamicClient, service, namespacedIngressPath, ingressName, ingressType, authenticationSecret) } }, DeleteFunc: func(obj interface{}) { service := obj.(*v1.Service) if hasLabel(service, labelKey) { logger.Infof("Service %v deleted with label %v \n", service.GetName(), labelKey) - controllers.Delete(ctx, clientset, service, namespacedIngressPath, ingressName, ingressType, authenticationSecret) + controllers.Delete(ctx, clientset, dynamicClient, service, namespacedIngressPath, ingressName, ingressType, authenticationSecret) } }, })