feat: adjust sample to mvp #1
+6
-1
@@ -24,4 +24,9 @@ go.work.sum
|
|||||||
|
|
||||||
# env file
|
# env file
|
||||||
.env
|
.env
|
||||||
vendor/*
|
|
||||||
|
# vendor directory
|
||||||
|
vendor/
|
||||||
|
|
||||||
|
# build artifacts
|
||||||
|
main
|
||||||
|
|||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch Package",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "auto",
|
||||||
|
"program": "${fileDirname}",
|
||||||
|
"args": ["--kubeconfig=/home/tbehrendt/.kube/config"],
|
||||||
|
"envFile": ".env"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
REPO_ROOT := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
ifneq (,$(wildcard ./.env))
|
||||||
|
include .env
|
||||||
|
export
|
||||||
|
endif
|
||||||
.PHONY: build run codegen
|
.PHONY: build run codegen
|
||||||
|
|
||||||
build:
|
build:
|
||||||
go build
|
go build -o main
|
||||||
|
|
||||||
run:
|
run:
|
||||||
make build
|
make build
|
||||||
./main
|
./main --kubeconfig=/home/tbehrendt/.kube/config
|
||||||
|
|
||||||
codegen:
|
codegen:
|
||||||
$(REPO_ROOT)/scripts/codegen.sh
|
./scripts/codegen.sh
|
||||||
|
|||||||
@@ -8,6 +8,12 @@ spec:
|
|||||||
- name: v1
|
- name: v1
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
|
additionalPrinterColumns:
|
||||||
|
- name: PK
|
||||||
|
type: string
|
||||||
|
jsonPath: .status.pk
|
||||||
schema:
|
schema:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
type: object
|
type: object
|
||||||
@@ -38,4 +44,6 @@ spec:
|
|||||||
names:
|
names:
|
||||||
kind: ProxyProvider
|
kind: ProxyProvider
|
||||||
plural: proxyproviders
|
plural: proxyproviders
|
||||||
|
shortNames:
|
||||||
|
- pp
|
||||||
scope: Namespaced
|
scope: Namespaced
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
apiVersion: samplecontroller.k8s.io/v1alpha1
|
|
||||||
kind: Foo
|
|
||||||
metadata:
|
|
||||||
name: example-foo
|
|
||||||
spec:
|
|
||||||
deploymentName: example-foo
|
|
||||||
replicas: 1
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# Example ProxyProvider CRD
|
||||||
|
apiVersion: proxyprovider.t000-n.de/v1
|
||||||
|
kind: ProxyProvider
|
||||||
|
metadata:
|
||||||
|
name: proxy-provider-example
|
||||||
|
namespace: kube-system
|
||||||
|
spec:
|
||||||
|
name: proxy-provider-example
|
||||||
|
authorization_flow: 16896c6d-b326-42d1-8d3f-93f32921962e
|
||||||
|
invalidation_flow: 7acac1ef-19e3-4a6f-8d8d-14ca7031d184
|
||||||
|
external_host: https://example.t00n.de
|
||||||
+72
-12
@@ -19,6 +19,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
@@ -39,10 +40,12 @@ import (
|
|||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
|
v1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1"
|
||||||
clientset "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
|
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"
|
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/v1"
|
informers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/proxyprovider/v1"
|
||||||
listers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/listers/proxyprovider/v1"
|
listers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/listers/proxyprovider/v1"
|
||||||
|
authentikapi "goauthentik.io/api/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const controllerAgentName = "proxy-provider-controller"
|
const controllerAgentName = "proxy-provider-controller"
|
||||||
@@ -56,8 +59,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
kubeclientset kubernetes.Interface
|
kubeclientset kubernetes.Interface
|
||||||
operatorclientset clientset.Interface
|
proxyProviderClientset clientset.Interface
|
||||||
|
authentik *authentikapi.APIClient
|
||||||
|
|
||||||
deploymentsLister appslisters.DeploymentLister
|
deploymentsLister appslisters.DeploymentLister
|
||||||
deploymentsSynced cache.InformerSynced
|
deploymentsSynced cache.InformerSynced
|
||||||
@@ -71,7 +75,8 @@ type Controller struct {
|
|||||||
func NewController(
|
func NewController(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
kubeclientset kubernetes.Interface,
|
kubeclientset kubernetes.Interface,
|
||||||
operatorclientset clientset.Interface,
|
proxyProviderClientset clientset.Interface,
|
||||||
|
authentik *authentikapi.APIClient,
|
||||||
deploymentInformer appsinformers.DeploymentInformer,
|
deploymentInformer appsinformers.DeploymentInformer,
|
||||||
proxyInformer informers.ProxyProviderInformer,
|
proxyInformer informers.ProxyProviderInformer,
|
||||||
) *Controller {
|
) *Controller {
|
||||||
@@ -90,14 +95,15 @@ func NewController(
|
|||||||
)
|
)
|
||||||
|
|
||||||
c := &Controller{
|
c := &Controller{
|
||||||
kubeclientset: kubeclientset,
|
kubeclientset: kubeclientset,
|
||||||
operatorclientset: operatorclientset,
|
proxyProviderClientset: proxyProviderClientset,
|
||||||
deploymentsLister: deploymentInformer.Lister(),
|
authentik: authentik,
|
||||||
deploymentsSynced: deploymentInformer.Informer().HasSynced,
|
deploymentsLister: deploymentInformer.Lister(),
|
||||||
proxyLister: proxyInformer.Lister(),
|
deploymentsSynced: deploymentInformer.Informer().HasSynced,
|
||||||
proxySynced: proxyInformer.Informer().HasSynced,
|
proxyLister: proxyInformer.Lister(),
|
||||||
workqueue: workqueue.NewTypedRateLimitingQueue(ratelimiter),
|
proxySynced: proxyInformer.Informer().HasSynced,
|
||||||
recorder: recorder,
|
workqueue: workqueue.NewTypedRateLimitingQueue(ratelimiter),
|
||||||
|
recorder: recorder,
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("Setting up event handlers")
|
logger.Info("Setting up event handlers")
|
||||||
@@ -181,8 +187,55 @@ func (c *Controller) syncHandler(ctx context.Context, objectRef cache.ObjectName
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.V(4).Info("sync ProxyProvider", "name", pp.Name)
|
logger.V(4).Info("sync ProxyProvider", "name", pp.Name)
|
||||||
|
|
||||||
|
if pp.Status.PK != "" {
|
||||||
|
// We retrieve the existing PP from the API by slug.
|
||||||
|
pk, err := strconv.ParseInt(pp.Status.PK, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error parsing PK: %v", err)
|
||||||
|
}
|
||||||
|
_, _, err = c.authentik.ProvidersApi.ProvidersAllRetrieve(ctx, int32(pk)).Execute()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error retrieving existing ProxyProvider: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We update the existing PP with the new spec.
|
||||||
|
proxyProviderRequest := &authentikapi.ProxyProviderRequest{
|
||||||
|
Name: pp.Spec.Name,
|
||||||
|
AuthorizationFlow: pp.Spec.AuthorizationFlow,
|
||||||
|
InvalidationFlow: pp.Spec.InvalidationFlow,
|
||||||
|
ExternalHost: pp.Spec.ExternalHost,
|
||||||
|
Mode: authentikapi.PROXYMODE_FORWARD_SINGLE.Ptr(),
|
||||||
|
}
|
||||||
|
resp, r, err := c.authentik.ProvidersApi.ProvidersProxyUpdate(ctx, int32(pk)).ProxyProviderRequest(*proxyProviderRequest).Execute()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error when calling `ProvidersAPI.ProvidersProxyUpdate`: %w with response %v", err, r)
|
||||||
|
}
|
||||||
|
pp.Status.PK = strconv.Itoa(int(resp.Pk))
|
||||||
|
err = c.updateProxyProviderStatus(ctx, pp)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error updating ProxyProvider status: %v", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
proxyProviderRequest := &authentikapi.ProxyProviderRequest{
|
||||||
|
Name: pp.Spec.Name,
|
||||||
|
AuthorizationFlow: pp.Spec.AuthorizationFlow,
|
||||||
|
InvalidationFlow: pp.Spec.InvalidationFlow,
|
||||||
|
ExternalHost: pp.Spec.ExternalHost,
|
||||||
|
Mode: authentikapi.PROXYMODE_FORWARD_SINGLE.Ptr(),
|
||||||
|
}
|
||||||
|
resp, r, err := c.authentik.ProvidersApi.ProvidersProxyCreate(ctx).ProxyProviderRequest(*proxyProviderRequest).Execute()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error when calling `ProvidersAPI.ProvidersProxyCreate`: %w with response %v", err, r)
|
||||||
|
}
|
||||||
|
pp.Status.PK = strconv.Itoa(int(resp.Pk))
|
||||||
|
err = c.updateProxyProviderStatus(ctx, pp)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error updating ProxyProvider status: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,3 +264,10 @@ func (c *Controller) handleObject(obj interface{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Controller) updateProxyProviderStatus(ctx context.Context, pp *v1.ProxyProvider) error {
|
||||||
|
ppCopy := pp.DeepCopy()
|
||||||
|
ppCopy.Status.PK = pp.Status.PK
|
||||||
|
_, err := c.proxyProviderClientset.ProxyproviderV1().ProxyProviders(pp.Namespace).UpdateStatus(ctx, ppCopy, metav1.UpdateOptions{FieldManager: FieldManager})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,14 +5,13 @@ go 1.26.3
|
|||||||
godebug default=go1.26
|
godebug default=go1.26
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
goauthentik.io/api/v3 v3.2026020.16
|
||||||
golang.org/x/time v0.15.0
|
golang.org/x/time v0.15.0
|
||||||
k8s.io/api v0.0.0-20260509204538-0dfb117cc6ec
|
k8s.io/api v0.0.0-20260509204538-0dfb117cc6ec
|
||||||
k8s.io/apimachinery v0.0.0-20260513183604-f9371b815e42
|
k8s.io/apimachinery v0.0.0-20260513183604-f9371b815e42
|
||||||
k8s.io/client-go v0.0.0-20260509205101-ca52b81a2940
|
k8s.io/client-go v0.0.0-20260509205101-ca52b81a2940
|
||||||
k8s.io/code-generator v0.0.0-20260509210052-5595d1310975
|
|
||||||
k8s.io/klog/v2 v2.140.0
|
k8s.io/klog/v2 v2.140.0
|
||||||
k8s.io/kube-openapi v0.0.0-20260511211612-da4e56fe5676
|
k8s.io/kube-openapi v0.0.0-20260511211612-da4e56fe5676
|
||||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2
|
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.4.0
|
sigs.k8s.io/structured-merge-diff/v6 v6.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -46,18 +45,15 @@ require (
|
|||||||
github.com/x448/float16 v0.8.4 // indirect
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
golang.org/x/mod v0.35.0 // indirect
|
|
||||||
golang.org/x/net v0.53.0 // indirect
|
golang.org/x/net v0.53.0 // indirect
|
||||||
golang.org/x/oauth2 v0.36.0 // indirect
|
golang.org/x/oauth2 v0.36.0 // indirect
|
||||||
golang.org/x/sync v0.20.0 // indirect
|
|
||||||
golang.org/x/sys v0.43.0 // indirect
|
golang.org/x/sys v0.43.0 // indirect
|
||||||
golang.org/x/term v0.42.0 // indirect
|
golang.org/x/term v0.42.0 // indirect
|
||||||
golang.org/x/text v0.36.0 // indirect
|
golang.org/x/text v0.36.0 // indirect
|
||||||
golang.org/x/tools v0.44.0 // indirect
|
|
||||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
|
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
k8s.io/gengo/v2 v2.0.0-20260408192533-25e2208e0dc3 // indirect
|
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||||
|
|||||||
@@ -84,14 +84,12 @@ go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
|
|||||||
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
|
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
|
||||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
goauthentik.io/api/v3 v3.2026020.16 h1:sEqcVRXYSJTYaSdU5PzSEdFUWDqCONm5BeL62F5k+58=
|
||||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
goauthentik.io/api/v3 v3.2026020.16/go.mod h1:82lqAz4jxzl6Cg0YDbhNtvvTG2rm6605ZhdJFnbbsl8=
|
||||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||||
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
|
||||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
|
||||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
|
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
|
||||||
@@ -100,12 +98,6 @@ golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
|||||||
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
||||||
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
||||||
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
||||||
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
|
|
||||||
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
|
|
||||||
golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=
|
|
||||||
golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
|
|
||||||
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
|
|
||||||
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=
|
|
||||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
|
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
|
||||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@@ -119,21 +111,12 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
k8s.io/api v0.0.0-20260509204538-0dfb117cc6ec h1:xf12Yh3ltN4fnNyP0CyyM0TwNVnZDfLJjV3+bf9fPFY=
|
k8s.io/api v0.0.0-20260509204538-0dfb117cc6ec h1:xf12Yh3ltN4fnNyP0CyyM0TwNVnZDfLJjV3+bf9fPFY=
|
||||||
k8s.io/api v0.0.0-20260509204538-0dfb117cc6ec/go.mod h1:C+fcNlNQ9TcKHspN+DD7UybdfnjDAGyBjfCd6W7ogbY=
|
k8s.io/api v0.0.0-20260509204538-0dfb117cc6ec/go.mod h1:C+fcNlNQ9TcKHspN+DD7UybdfnjDAGyBjfCd6W7ogbY=
|
||||||
k8s.io/apimachinery v0.0.0-20260509204146-64dfe1db2af5 h1:k2HBxRBq6w2QCj14oAhBosjMqqgNlj4dmLXFj8f1A+8=
|
|
||||||
k8s.io/apimachinery v0.0.0-20260509204146-64dfe1db2af5/go.mod h1:37ALVDWo0LgW74Y9rAdewmZo20SVCGGH34806wUMrko=
|
|
||||||
k8s.io/apimachinery v0.0.0-20260513183604-f9371b815e42 h1:rWdGOTor3z0WSyZcRl9ms4dn9Cw9CqmNBqXuf2z0k1k=
|
k8s.io/apimachinery v0.0.0-20260513183604-f9371b815e42 h1:rWdGOTor3z0WSyZcRl9ms4dn9Cw9CqmNBqXuf2z0k1k=
|
||||||
k8s.io/apimachinery v0.0.0-20260513183604-f9371b815e42/go.mod h1:hiubQ6UTHIdr0bS8ExXOJEywFVOoudnldm/l/NiNVlA=
|
k8s.io/apimachinery v0.0.0-20260513183604-f9371b815e42/go.mod h1:hiubQ6UTHIdr0bS8ExXOJEywFVOoudnldm/l/NiNVlA=
|
||||||
k8s.io/client-go v0.0.0-20260509205101-ca52b81a2940 h1:n5t5Jx3VpLdiAGxIvIHsZDmsExtZVwghUPLM3wFi6Go=
|
k8s.io/client-go v0.0.0-20260509205101-ca52b81a2940 h1:n5t5Jx3VpLdiAGxIvIHsZDmsExtZVwghUPLM3wFi6Go=
|
||||||
k8s.io/client-go v0.0.0-20260509205101-ca52b81a2940/go.mod h1:0e7OLwg7kdXISVFwn7ishFdvxfVgi7wsqHqsQPHl61w=
|
k8s.io/client-go v0.0.0-20260509205101-ca52b81a2940/go.mod h1:0e7OLwg7kdXISVFwn7ishFdvxfVgi7wsqHqsQPHl61w=
|
||||||
k8s.io/code-generator v0.0.0-20260509210052-5595d1310975 h1:hDrusFgTzvqcDJ7p13A9Eid4i8Y9uNSs/67lniaYHwM=
|
|
||||||
k8s.io/code-generator v0.0.0-20260509210052-5595d1310975/go.mod h1:mQXg0n0EeF4oU8aTwm9mzwoyAKqVRmUb9wLhjHnRq3I=
|
|
||||||
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b h1:gMplByicHV/TJBizHd9aVEsTYoJBnnUAT5MHlTkbjhQ=
|
|
||||||
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b/go.mod h1:CgujABENc3KuTrcsdpGmrrASjtQsWCT7R99mEV4U/fM=
|
|
||||||
k8s.io/gengo/v2 v2.0.0-20260408192533-25e2208e0dc3/go.mod h1:yvyl3l9E+UxlqOMUULdKTAYB0rEhsmjr7+2Vb/1pCSo=
|
|
||||||
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
|
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
|
||||||
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
|
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
|
||||||
k8s.io/kube-openapi v0.0.0-20260509150519-312035bf509b h1:WrpNVPKkCaOO9h77E1P2HLnhWDQxrxzpf2jfsM8WevY=
|
|
||||||
k8s.io/kube-openapi v0.0.0-20260509150519-312035bf509b/go.mod h1:V/QaCUYDa+0QpcHhVVc5l99Uz56wEMEXBSj9oCDkNDY=
|
|
||||||
k8s.io/kube-openapi v0.0.0-20260511211612-da4e56fe5676 h1:ahjrVu/DBcaAhw/GcblfaOvvQ2wi8kqXWvn62nud3UU=
|
k8s.io/kube-openapi v0.0.0-20260511211612-da4e56fe5676 h1:ahjrVu/DBcaAhw/GcblfaOvvQ2wi8kqXWvn62nud3UU=
|
||||||
k8s.io/kube-openapi v0.0.0-20260511211612-da4e56fe5676/go.mod h1:V/QaCUYDa+0QpcHhVVc5l99Uz56wEMEXBSj9oCDkNDY=
|
k8s.io/kube-openapi v0.0.0-20260511211612-da4e56fe5676/go.mod h1:V/QaCUYDa+0QpcHhVVc5l99Uz56wEMEXBSj9oCDkNDY=
|
||||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
|
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
|
||||||
@@ -142,8 +125,6 @@ sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5E
|
|||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=
|
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.4.0 h1:qmp2e3ZfFi1/jJbDGpD4mt3wyp6PE1NfKHCYLqgNQJo=
|
sigs.k8s.io/structured-merge-diff/v6 v6.4.0 h1:qmp2e3ZfFi1/jJbDGpD4mt3wyp6PE1NfKHCYLqgNQJo=
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.4.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
sigs.k8s.io/structured-merge-diff/v6 v6.4.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||||
|
|||||||
@@ -17,10 +17,14 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/signals"
|
"gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/signals"
|
||||||
|
authentikapi "goauthentik.io/api/v3"
|
||||||
kubeinformers "k8s.io/client-go/informers"
|
kubeinformers "k8s.io/client-go/informers"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
@@ -58,23 +62,29 @@ func main() {
|
|||||||
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
operatorClient, err := clientset.NewForConfig(cfg)
|
proxyProviderClient, err := clientset.NewForConfig(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err, "Error building kubernetes clientset")
|
logger.Error(err, "Error building proxy provider clientset")
|
||||||
|
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
authentikClient, err := newAuthentikAPIClient(os.Getenv("AUTENTIK_HOST"), os.Getenv("AUTENTIK_TOKEN"))
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err, "Error building Authentik API client")
|
||||||
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
kubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, time.Second*30)
|
kubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, time.Second*30)
|
||||||
operatorInformerFactory := informers.NewSharedInformerFactory(operatorClient, time.Second*30)
|
proxyProviderInformerFactory := informers.NewSharedInformerFactory(proxyProviderClient, time.Second*30)
|
||||||
|
|
||||||
controller := NewController(ctx, kubeClient, operatorClient,
|
controller := NewController(ctx, kubeClient, proxyProviderClient, authentikClient,
|
||||||
kubeInformerFactory.Apps().V1().Deployments(),
|
kubeInformerFactory.Apps().V1().Deployments(),
|
||||||
operatorInformerFactory.Proxyprovider().V1().ProxyProviders())
|
proxyProviderInformerFactory.Proxyprovider().V1().ProxyProviders())
|
||||||
|
|
||||||
// notice that there is no need to run Start methods in a separate goroutine. (i.e. go kubeInformerFactory.Start(ctx.done())
|
// notice that there is no need to run Start methods in a separate goroutine. (i.e. go kubeInformerFactory.Start(ctx.done())
|
||||||
// Start method is non-blocking and runs all registered informers in a dedicated goroutine.
|
// Start method is non-blocking and runs all registered informers in a dedicated goroutine.
|
||||||
kubeInformerFactory.Start(ctx.Done())
|
kubeInformerFactory.Start(ctx.Done())
|
||||||
operatorInformerFactory.Start(ctx.Done())
|
proxyProviderInformerFactory.Start(ctx.Done())
|
||||||
|
|
||||||
if err = controller.Run(ctx, 2); err != nil {
|
if err = controller.Run(ctx, 2); err != nil {
|
||||||
logger.Error(err, "Error running controller")
|
logger.Error(err, "Error running controller")
|
||||||
@@ -86,3 +96,27 @@ func init() {
|
|||||||
flag.StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
|
flag.StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
|
||||||
flag.StringVar(&masterURL, "master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
|
flag.StringVar(&masterURL, "master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newAuthentikAPIClient builds the OpenAPI-generated goauthentik client when AUTENTIK_HOST is set.
|
||||||
|
func newAuthentikAPIClient(host, token string) (*authentikapi.APIClient, error) {
|
||||||
|
if host == "" {
|
||||||
|
return nil, errors.New("authentik host is not set")
|
||||||
|
}
|
||||||
|
cfg := authentikapi.NewConfiguration()
|
||||||
|
if u, err := url.Parse(host); err == nil && u.Host != "" {
|
||||||
|
cfg.Scheme = u.Scheme
|
||||||
|
if cfg.Scheme == "" {
|
||||||
|
cfg.Scheme = "https"
|
||||||
|
}
|
||||||
|
cfg.Host = u.Host
|
||||||
|
} else {
|
||||||
|
cfg.Scheme = "https"
|
||||||
|
cfg.Host = host
|
||||||
|
}
|
||||||
|
if token == "" {
|
||||||
|
return nil, errors.New("authentik token is not set")
|
||||||
|
}
|
||||||
|
cfg.AddDefaultHeader("Authorization", "Bearer "+token)
|
||||||
|
|
||||||
|
return authentikapi.NewAPIClient(cfg), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// +genclient
|
// +genclient
|
||||||
|
// +kubebuilder:subresource:status
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
type ProxyProvider struct {
|
type ProxyProvider struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user