Compare commits

..

4 Commits

Author SHA1 Message Date
t.behrendt ac560e207b docs: update docs
CI / image check (pull_request) Successful in 58s
CI / install-dependencies (pull_request) Successful in 1m27s
CI / build check (pull_request) Successful in 25s
CI / test (pull_request) Successful in 24s
CI / check lint (pull_request) Successful in 3m11s
CI / check format (pull_request) Successful in 6m23s
2026-05-19 21:16:49 +02:00
t.behrendt 7311822b83 refactor: consolidate common controller code 2026-05-19 21:16:48 +02:00
t.behrendt 9ec29fd0c6 feat: add bare policy binding controller 2026-05-19 21:16:48 +02:00
t.behrendt adb7d7a296 feat: add bare application controller 2026-05-19 21:16:48 +02:00
6 changed files with 37 additions and 33 deletions
+4 -4
View File
@@ -37,8 +37,8 @@ import (
"k8s.io/client-go/util/workqueue"
"k8s.io/klog/v2"
"gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/internal/baseController"
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
controllers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/controllers"
clientset "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
operatorscheme "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/scheme"
informers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/application/v1alpha1"
@@ -68,7 +68,7 @@ type ApplicationController struct {
applicationListener listers.ApplicationLister
controller *baseController.Controller
controller *controllers.Controller
}
func NewController(
@@ -98,7 +98,7 @@ func NewController(
authentik: authentik,
applicationListener: applicationInformer.Lister(),
}
c.controller = baseController.NewController(
c.controller = controllers.NewController(
ctx,
workqueue.NewTypedRateLimitingQueue(ratelimiter),
recorder,
@@ -160,7 +160,7 @@ func (c *ApplicationController) ensureFinalizers(ctx context.Context, app *v1alp
}
func (c *ApplicationController) reconcileDelete(ctx context.Context, app *v1alpha1.Application) error {
r, err := c.authentik.CoreApi.CoreApplicationsDestroy(ctx, app.Spec.Slug).Execute()
r, err := c.authentik.CoreApi.CoreApplicationsDestroy(ctx, app.Status.PK).Execute()
if err != nil {
// This handles an edge-case, where when the Application on Authentik has already been deleted, but the finalizer is still present. We just remove the finalizer and return.
if r != nil && r.StatusCode != http.StatusNotFound {
+25 -21
View File
@@ -130,7 +130,7 @@ func TestController_syncHandler_delete(t *testing.T) {
var destroyCalled bool
server := newAuthentikTestServer(t, authentikTestHandlers{
applicationDestroy: func(w http.ResponseWriter, r *http.Request) {
proxyDestroy: func(w http.ResponseWriter, r *http.Request) {
destroyCalled = true
if r.Method != http.MethodDelete {
t.Errorf("destroy method = %s, want DELETE", r.Method)
@@ -165,7 +165,7 @@ func TestController_syncHandler_delete_providerAlreadyGone(t *testing.T) {
app.Finalizers = []string{DeleteAuthentikApplicationFinalizer}
server := newAuthentikTestServer(t, authentikTestHandlers{
applicationDestroy: func(w http.ResponseWriter, _ *http.Request) {
proxyDestroy: func(w http.ResponseWriter, _ *http.Request) {
http.NotFound(w, nil)
},
})
@@ -198,31 +198,25 @@ func TestController_syncHandler_notFound(t *testing.T) {
}
}
func TestController_syncHandler_delete_usesSlugNotPK(t *testing.T) {
func TestController_syncHandler_invalidPK(t *testing.T) {
now := metav1.Now()
app := testApplication()
app.Status.PK = "not-a-number"
app.DeletionTimestamp = &now
app.Finalizers = []string{DeleteAuthentikApplicationFinalizer}
var destroySlug string
server := newAuthentikTestServer(t, authentikTestHandlers{
applicationDestroy: func(w http.ResponseWriter, r *http.Request) {
destroySlug = strings.TrimSuffix(strings.TrimPrefix(r.URL.Path, "/api/v3/core/applications/"), "/")
w.WriteHeader(http.StatusNoContent)
},
})
server := newAuthentikTestServer(t, authentikTestHandlers{})
t.Cleanup(server.Close)
ctrl, ctx, cancel := newTestController(t, app, server.URL)
t.Cleanup(cancel)
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: app.Namespace, Name: app.Name})
if err != nil {
t.Fatalf("syncHandler() error = %v", err)
if err == nil {
t.Fatal("syncHandler() error = nil, want parse error")
}
if destroySlug != app.Spec.Slug {
t.Fatalf("destroy slug = %q, want %q (delete must use spec.slug, not status.pk)", destroySlug, app.Spec.Slug)
if !strings.Contains(err.Error(), "error parsing PK") {
t.Fatalf("syncHandler() error = %v, want PK parse error", err)
}
}
@@ -301,7 +295,7 @@ type authentikTestHandlers struct {
applicationCreate http.HandlerFunc
applicationRetrieve http.HandlerFunc
applicationPartialUpdate http.HandlerFunc
applicationDestroy http.HandlerFunc
proxyDestroy http.HandlerFunc
}
func newAuthentikTestServer(t *testing.T, handlers authentikTestHandlers) *httptest.Server {
@@ -337,16 +331,26 @@ func newAuthentikTestServer(t *testing.T, handlers authentikTestHandlers) *httpt
return
}
http.NotFound(w, r)
case http.MethodDelete:
if handlers.applicationDestroy != nil {
handlers.applicationDestroy(w, r)
return
}
http.NotFound(w, r)
default:
http.Error(w, "unexpected method on application instance", http.StatusMethodNotAllowed)
}
case strings.HasPrefix(path, "/api/v3/providers/proxy/") && strings.HasSuffix(path, "/"):
idPath := strings.TrimPrefix(path, "/api/v3/providers/proxy/")
if idPath == "" {
http.NotFound(w, r)
return
}
if r.Method == http.MethodDelete {
if handlers.proxyDestroy != nil {
handlers.proxyDestroy(w, r)
return
}
http.NotFound(w, r)
return
}
http.Error(w, "unexpected method on proxy instance", http.StatusMethodNotAllowed)
default:
http.NotFound(w, r)
}
@@ -1,4 +1,4 @@
package baseController
package controllers
import (
"context"
@@ -1,5 +1,5 @@
// AI generated tests and not yet reviewed.
package baseController
package controllers
import (
"context"
+3 -3
View File
@@ -37,8 +37,8 @@ import (
"k8s.io/client-go/util/workqueue"
"k8s.io/klog/v2"
"gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/internal/baseController"
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
controllers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/controllers"
clientset "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
operatorscheme "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/scheme"
informers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/policybinding/v1alpha1"
@@ -68,7 +68,7 @@ type PolicyBindingController struct {
policyBindingListener listers.PolicyBindingLister
controller *baseController.Controller
controller *controllers.Controller
}
func NewController(
@@ -98,7 +98,7 @@ func NewController(
authentik: authentik,
policyBindingListener: policyBindingInformer.Lister(),
}
c.controller = baseController.NewController(
c.controller = controllers.NewController(
ctx,
workqueue.NewTypedRateLimitingQueue(ratelimiter),
recorder,
+3 -3
View File
@@ -38,8 +38,8 @@ import (
"k8s.io/client-go/util/workqueue"
"k8s.io/klog/v2"
"gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/internal/baseController"
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
controllers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/controllers"
clientset "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
operatorscheme "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/scheme"
informers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/proxyprovider/v1alpha1"
@@ -69,7 +69,7 @@ type ProxyProviderController struct {
proxyLister listers.ProxyProviderLister
controller *baseController.Controller
controller *controllers.Controller
}
func NewController(
@@ -99,7 +99,7 @@ func NewController(
authentik: authentik,
proxyLister: proxyInformer.Lister(),
}
c.controller = baseController.NewController(
c.controller = controllers.NewController(
ctx,
workqueue.NewTypedRateLimitingQueue(ratelimiter),
recorder,