Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 110f12b49d | |||
| fd75e6314e | |||
| 26bd576690 | |||
| 2a091df8b9 | |||
| 5219457d33 | |||
| 2d26cd82d1 | |||
| bc8e7e10e1 |
@@ -0,0 +1,8 @@
|
||||
*
|
||||
|
||||
!pkg
|
||||
!internal
|
||||
!controller.go
|
||||
!main.go
|
||||
!go.mod
|
||||
!go.sum
|
||||
@@ -0,0 +1,16 @@
|
||||
name: Go Cache Key
|
||||
description: Create a cache key for Go dependencies
|
||||
|
||||
outputs:
|
||||
hash:
|
||||
description: The cache key for Go dependencies
|
||||
value: ${{ steps.hash-go.outputs.hash }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Create cache key
|
||||
shell: bash
|
||||
id: hash-go
|
||||
run: |
|
||||
echo "hash=$(sha256sum go.mod go.sum | sha256sum | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
|
||||
@@ -0,0 +1,104 @@
|
||||
name: CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "go.mod"
|
||||
- "go.sum"
|
||||
- "**/*.go"
|
||||
- "Dockerfile"
|
||||
- "Makefile"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
DOCKER_REGISTRY: gitea.t000-n.de
|
||||
|
||||
jobs:
|
||||
build_and_push:
|
||||
name: Build and push
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [amd64]
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
- linux_${{ matrix.arch }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
- name: Login to Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
with:
|
||||
registry: ${{ env.DOCKER_REGISTRY }}
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
- name: Get Metadata
|
||||
id: meta
|
||||
run: |
|
||||
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}' | tr '[:upper:]' '[:lower:]') >> $GITHUB_OUTPUT
|
||||
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/${{ matrix.arch }}
|
||||
push: true
|
||||
provenance: false
|
||||
build-args: GOARCH=${{ matrix.arch }}
|
||||
tags: |
|
||||
${{ env.DOCKER_REGISTRY }}/t.behrendt/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }}-${{ matrix.arch }}
|
||||
|
||||
create_tag:
|
||||
name: Create tag
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
tag: ${{ steps.tag.outputs.new-tag }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment@ef0c23189db33220a73022d8c29a27709d0df440 # 0.1.32
|
||||
id: tag
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
prerelease: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
- run: |
|
||||
git tag ${{ steps.tag.outputs.new-tag }}
|
||||
git push origin ${{ steps.tag.outputs.new-tag }}
|
||||
- name: Set output
|
||||
run: |
|
||||
echo "tag=${{ steps.tag.outputs.new-tag }}" >> $GITHUB_OUTPUT
|
||||
|
||||
create_manifest:
|
||||
name: Create manifest
|
||||
needs:
|
||||
- build_and_push
|
||||
- create_tag
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Get Metadata
|
||||
id: meta
|
||||
run: |
|
||||
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}' | tr '[:upper:]' '[:lower:]') >> $GITHUB_OUTPUT
|
||||
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Login to Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
with:
|
||||
registry: ${{ env.DOCKER_REGISTRY }}
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Create manifest
|
||||
run: |
|
||||
docker manifest create ${{ env.DOCKER_REGISTRY }}/t.behrendt/${{ steps.meta.outputs.REPO_NAME }}:${{ needs.create_tag.outputs.tag }} \
|
||||
${{ env.DOCKER_REGISTRY }}/t.behrendt/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }}-amd64
|
||||
|
||||
docker manifest push ${{ env.DOCKER_REGISTRY }}/t.behrendt/${{ steps.meta.outputs.REPO_NAME }}:${{ needs.create_tag.outputs.tag }}
|
||||
+34
-20
@@ -8,30 +8,44 @@ env:
|
||||
RUNNER_TOOL_CACHE: /toolcache
|
||||
|
||||
jobs:
|
||||
install-dependencies:
|
||||
uses: ./.gitea/workflows/install-go-dependencies.yaml
|
||||
|
||||
build-check:
|
||||
name: build check
|
||||
needs: install-dependencies
|
||||
uses: ./.gitea/workflows/run-go-script.yaml
|
||||
with:
|
||||
script: build
|
||||
|
||||
check-format:
|
||||
name: check format
|
||||
needs: install-dependencies
|
||||
uses: ./.gitea/workflows/run-go-script.yaml
|
||||
with:
|
||||
script: check-format
|
||||
|
||||
check-lint:
|
||||
name: check lint
|
||||
needs: install-dependencies
|
||||
uses: ./.gitea/workflows/run-go-script.yaml
|
||||
with:
|
||||
script: lint
|
||||
|
||||
test:
|
||||
name: test
|
||||
needs: install-dependencies
|
||||
uses: ./.gitea/workflows/run-go-script.yaml
|
||||
with:
|
||||
script: test
|
||||
|
||||
image-check:
|
||||
name: image check
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
- linux_amd64
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- name: Create cache key
|
||||
id: hash-go
|
||||
run: echo "hash=$(sha256sum go.mod go.sum | sha256sum | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
|
||||
- name: cache go
|
||||
id: cache-go
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
path: |
|
||||
/go_path
|
||||
/go_cache
|
||||
key: go_path-${{ steps.hash-go.outputs.hash }}
|
||||
restore-keys: |-
|
||||
go_cache-${{ steps.hash-go.outputs.hash }}
|
||||
- name: build
|
||||
run: make build
|
||||
- name: Build image
|
||||
run: make build-image
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
name: Install Go Dependencies
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
install-dependencies:
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
- linux_amd64
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- name: Create cache key
|
||||
id: go-cache-key
|
||||
uses: ./.gitea/actions/go-cache-key
|
||||
- name: cache go
|
||||
id: cache-go
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
/go_path
|
||||
/go_cache
|
||||
key: go_path-${{ steps.go-cache-key.outputs.hash }}
|
||||
restore-keys: |-
|
||||
go_cache-${{ steps.go-cache-key.outputs.hash }}
|
||||
- name: Download dependencies
|
||||
run: go mod download
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Run Go Script
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
script:
|
||||
description: The script to run
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
run-script:
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
- linux_amd64
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- name: Create cache key
|
||||
id: go-cache-key
|
||||
uses: ./.gitea/actions/go-cache-key
|
||||
- name: Install dependencies from Cache
|
||||
id: cache-go
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
/go_path
|
||||
/go_cache
|
||||
key: go_path-${{ steps.go-cache-key.outputs.hash }}
|
||||
restore-keys: |-
|
||||
go_cache-${{ steps.go-cache-key.outputs.hash }}
|
||||
- name: Run script
|
||||
run: make ${{ inputs.script }}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
lcov.info
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
@@ -25,3 +26,9 @@ go.work.sum
|
||||
# env file
|
||||
.env
|
||||
|
||||
# vendor directory
|
||||
vendor/
|
||||
|
||||
# build artifacts
|
||||
main
|
||||
__debug_bin*
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "code-generator"]
|
||||
path = code-generator
|
||||
url = https://github.com/kubernetes/code-generator.git
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Package",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${fileDirname}",
|
||||
"args": ["--kubeconfig=/home/tbehrendt/.kube/config"],
|
||||
"envFile": ".env"
|
||||
}
|
||||
]
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
FROM docker.io/library/golang:1.25-alpine@sha256:04d017a27c481185c169884328a5761d052910fdced8c3b8edd686474efdf59b AS build
|
||||
FROM docker.io/library/golang:1.26.3@sha256:313faae491b410a35402c05d35e7518ae99103d957308e940e1ae2cfa0aac29b AS build
|
||||
|
||||
ARG GOARCH=amd64
|
||||
|
||||
@@ -9,6 +9,6 @@ COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} \
|
||||
go build -trimpath -ldflags="-s -w" -o main .
|
||||
|
||||
FROM gcr.io/distroless/static-debian12@sha256:20bc6c0bc4d625a22a8fde3e55f6515709b32055ef8fb9cfbddaa06d1760f838
|
||||
FROM gcr.io/distroless/static-debian12@sha256:9c346e4be81b5ca7ff31a0d89eaeade58b0f95cfd3baed1f36083ddb47ca3160
|
||||
COPY --from=build /app/main /
|
||||
CMD ["/main"]
|
||||
|
||||
@@ -1,6 +1,40 @@
|
||||
ifneq (,$(wildcard ./.env))
|
||||
include .env
|
||||
export
|
||||
endif
|
||||
.PHONY: build run codegen build-image test test-unit test-coverage lint format check-format
|
||||
|
||||
build:
|
||||
go build
|
||||
go build -o main
|
||||
|
||||
build-image:
|
||||
docker build -t authentik-kubernetes-operator:latest .
|
||||
|
||||
run:
|
||||
make build
|
||||
./main
|
||||
./main --kubeconfig=/home/tbehrendt/.kube/config
|
||||
|
||||
codegen:
|
||||
./scripts/codegen.sh
|
||||
|
||||
test: test-unit test-coverage
|
||||
|
||||
test-unit:
|
||||
go test ./... -coverprofile=coverage.out
|
||||
|
||||
test-coverage:
|
||||
go tool gcov2lcov -infile coverage.out > lcov.info
|
||||
|
||||
lint:
|
||||
go vet ./...
|
||||
|
||||
format:
|
||||
gofmt -w .
|
||||
|
||||
check-format:
|
||||
@OUTPUT=$$(gofmt -l .); \
|
||||
if [ -n "$$OUTPUT" ]; then \
|
||||
echo "Formatter failed for:"; \
|
||||
echo "$$OUTPUT"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
@@ -2,4 +2,98 @@
|
||||
|
||||
Authentik Kubernetes Operator allows to manage Authentik resources directly in Kubernetes using Custom Kubernetes Resources.
|
||||
|
||||
## Features
|
||||
The custom resources of this operator ultimately will mirror the Authentik resources. New resources will be added as there is a need for them.
|
||||
|
||||
Manual changes to the resources in Authentik will be overwritten by the operator. So always manage the resources in Kubernetes.
|
||||
|
||||
## Custom Resources
|
||||
|
||||
| Custom Resource | CRD File | Short Name |
|
||||
| --------------- | ---------------------------------------------------------- | ---------- |
|
||||
| ProxyProvider | [`proxyProvider.yaml`](`artifacts/crd/proxyProvider.yaml`) | pp |
|
||||
| Application | [`application.yaml`](`artifacts/crd/application.yaml`) | app |
|
||||
| PolicyBinding | [`policyBinding.yaml`](`artifacts/crd/policyBinding.yaml`) | pb |
|
||||
|
||||
### ProxyProvider
|
||||
|
||||
Currently only the "Forward Single" ProxyProvider is supported and only a reduced set of fields are exposed by the custom resources.
|
||||
|
||||
Example [`proxyProvider.yaml`](`artifacts/examples/proxyProvider.yaml`):
|
||||
|
||||
```yaml
|
||||
apiVersion: proxyprovider.t000-n.de/v1alpha1
|
||||
kind: ProxyProvider
|
||||
metadata:
|
||||
name: proxy-provider-example
|
||||
namespace: kube-system
|
||||
spec:
|
||||
name: proxy-provider-example
|
||||
# The ID of the authorization flow. In this example: "default-provider-authorization-implicit-consent (Authorize Application)"
|
||||
authorization_flow: 16896c6d-b326-42d1-8d3f-93f32921962e
|
||||
# The ID of the invalidation flow. In this example: "default-provider-invalidation-flow (Logged out of application)"
|
||||
invalidation_flow: 7acac1ef-19e3-4a6f-8d8d-14ca7031d184
|
||||
# The external host of your application.
|
||||
external_host: https://example.t00n.de
|
||||
# The ID of the outpost, which at current point in time can only be retrieved from Authentik directly. In this example: "Proxy-Forward-Auth-Auto"
|
||||
outpost: e004ffe7-4af6-4ac1-9e9d-522354799e1f
|
||||
```
|
||||
|
||||
The ProxyProvider will be created in Authentik and assigned to the configured outpost.
|
||||
|
||||
### Application
|
||||
|
||||
The Application only supports a reduced set of fields.
|
||||
|
||||
Example [`application.yaml`](`artifacts/examples/application.yaml`):
|
||||
|
||||
```yaml
|
||||
apiVersion: application.t000-n.de/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: application-example
|
||||
spec:
|
||||
name: Application Example
|
||||
slug: application-example
|
||||
# The ID of the provider, which can be retrieved from e.g. the ProxyPRovider via "kubectl get pp proxy-provider-example -o jsonpath='{.status.pk}'"
|
||||
provider: 105
|
||||
```
|
||||
|
||||
### PolicyBinding
|
||||
|
||||
The PolicyBinding is used to bind a policy to a target, e.g. allow a group or user to access an application.
|
||||
The PolicyBinding only supports a reduced set of fields.
|
||||
|
||||
Example [`policyBinding.yaml`](`artifacts/examples/policyBinding.yaml`):
|
||||
|
||||
```yaml
|
||||
apiVersion: policybinding.t000-n.de/v1alpha1
|
||||
kind: PolicyBinding
|
||||
metadata:
|
||||
name: policy-binding-example
|
||||
spec:
|
||||
group: 14ab813f-a7f9-481b-9b08-781953ae9ebf
|
||||
# The ID of the target, e.g. an Application, which can be retrieved from e.g. the Application via "kubectl get app application-example -o jsonpath='{.status.pk}'"
|
||||
target: 8dd85627-9c48-49c2-8afc-d73dd122ffc2
|
||||
# The order in which the policy is applied. This needs to be unique for each PolicyBinding.
|
||||
order: 1
|
||||
```
|
||||
|
||||
## Versioning
|
||||
|
||||
As soon as the operator covers an entire use case, the version will be raised to v1 and follow default versioning rules. Before that, the version will be v1alpha1.
|
||||
|
||||
## Development
|
||||
|
||||
### Guidelines & Tips
|
||||
|
||||
- Only do a single reconciliation at a time and then return.
|
||||
- This is because your references from the k8s API get stale after each update.
|
||||
- Whenever you update a resource, k8s API will send a new event to your controller, which will trigger a new reconciliation.
|
||||
- The API will periodically send a resource to the controller for re-syncing, giving the controller a chance to reconcile the state with the outside world.
|
||||
- Use finalizers to ensure that the controller gets a chance to reconcile the state with the outside world before the object is deleted. If no finalizer is present, the object is deleted immediately without the controller seeing it.
|
||||
- Use the resource's state to keep track of the current state of the outside world, e.g. identifiers of external resources, etc.
|
||||
|
||||
### References
|
||||
|
||||
- [Extend Kubernetes](https://kubernetes.io/docs/concepts/extend-kubernetes/#api-extensions)
|
||||
- [Example Controller Implementation](https://github.com/kubernetes/sample-controller)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: applications.application.t000-n.de
|
||||
spec:
|
||||
group: application.t000-n.de
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
additionalPrinterColumns:
|
||||
- name: PK
|
||||
type: string
|
||||
jsonPath: .status.pk
|
||||
- name: Name
|
||||
type: string
|
||||
jsonPath: .spec.name
|
||||
- name: Slug
|
||||
type: string
|
||||
jsonPath: .spec.slug
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: Application's display name
|
||||
slug:
|
||||
type: string
|
||||
description: Internal application name, used in URLs.
|
||||
pattern: ^[-a-zA-Z0-9_]+$
|
||||
provider:
|
||||
type: integer
|
||||
format: int32
|
||||
required:
|
||||
- name
|
||||
- slug
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
pk:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- pk
|
||||
names:
|
||||
kind: Application
|
||||
plural: applications
|
||||
shortNames:
|
||||
- app
|
||||
scope: Namespaced
|
||||
@@ -0,0 +1,53 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: policybindings.policybinding.t000-n.de
|
||||
spec:
|
||||
group: policybinding.t000-n.de
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
additionalPrinterColumns:
|
||||
- name: PK
|
||||
type: string
|
||||
jsonPath: .status.pk
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
policy:
|
||||
type: string
|
||||
format: uuid
|
||||
group:
|
||||
type: string
|
||||
format: uuid
|
||||
user:
|
||||
type: integer
|
||||
format: int32
|
||||
target:
|
||||
type: string
|
||||
format: uuid
|
||||
order:
|
||||
type: integer
|
||||
required:
|
||||
- target
|
||||
- order
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
pk:
|
||||
type: string
|
||||
required:
|
||||
- pk
|
||||
names:
|
||||
kind: PolicyBinding
|
||||
plural: policybindings
|
||||
shortNames:
|
||||
- pb
|
||||
scope: Namespaced
|
||||
@@ -0,0 +1,58 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: proxyproviders.proxyprovider.t000-n.de
|
||||
finalizers:
|
||||
- proxyprovider.t000-n.de/delete-authentik-proxyprovider
|
||||
spec:
|
||||
group: proxyprovider.t000-n.de
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
additionalPrinterColumns:
|
||||
- name: PK
|
||||
type: string
|
||||
jsonPath: .status.pk
|
||||
- name: Outpost
|
||||
type: string
|
||||
jsonPath: .spec.outpost
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
authorization_flow:
|
||||
type: string
|
||||
invalidation_flow:
|
||||
type: string
|
||||
external_host:
|
||||
type: string
|
||||
outpost:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- name
|
||||
- authorization_flow
|
||||
- invalidation_flow
|
||||
- external_host
|
||||
- outpost
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
pk:
|
||||
type: string
|
||||
required:
|
||||
- pk
|
||||
names:
|
||||
kind: ProxyProvider
|
||||
plural: proxyproviders
|
||||
shortNames:
|
||||
- pp
|
||||
scope: Namespaced
|
||||
@@ -0,0 +1,8 @@
|
||||
apiVersion: application.t000-n.de/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: application-example
|
||||
spec:
|
||||
name: Application Example
|
||||
slug: application-example
|
||||
provider: 105
|
||||
@@ -0,0 +1,8 @@
|
||||
apiVersion: policybinding.t000-n.de/v1alpha1
|
||||
kind: PolicyBinding
|
||||
metadata:
|
||||
name: policy-binding-example
|
||||
spec:
|
||||
group: 14ab813f-a7f9-481b-9b08-781953ae9ebf
|
||||
target: 8dd85627-9c48-49c2-8afc-d73dd122ffc2
|
||||
order: 1
|
||||
@@ -0,0 +1,12 @@
|
||||
# Example ProxyProvider CRD
|
||||
apiVersion: proxyprovider.t000-n.de/v1alpha1
|
||||
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
|
||||
outpost: ce8f74c0-88cd-47fe-96f5-d6507b739ceb
|
||||
@@ -1,3 +1,65 @@
|
||||
module gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator
|
||||
|
||||
go 1.26.3
|
||||
|
||||
godebug default=go1.26
|
||||
|
||||
require (
|
||||
goauthentik.io/api/v3 v3.2026050.0
|
||||
golang.org/x/time v0.15.0
|
||||
k8s.io/api v0.36.1
|
||||
k8s.io/apimachinery v0.36.1
|
||||
k8s.io/client-go v0.36.1
|
||||
k8s.io/klog/v2 v2.140.0
|
||||
k8s.io/kube-openapi v0.0.0-20260511211612-da4e56fe5676
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.1 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.22.4 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.4 // indirect
|
||||
github.com/go-openapi/swag v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/cmdutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/conv v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/fileutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/jsonname v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/loading v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/mangling v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/netutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/stringutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/typeutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
|
||||
github.com/google/gnostic-models v0.7.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/jandelgado/gcov2lcov v1.1.1 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/net v0.53.0 // indirect
|
||||
golang.org/x/oauth2 v0.36.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/term v0.42.0 // indirect
|
||||
golang.org/x/text v0.36.0 // indirect
|
||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||
)
|
||||
|
||||
replace k8s.io/code-generator => ./code-generator
|
||||
|
||||
tool github.com/jandelgado/gcov2lcov
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
|
||||
github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ=
|
||||
github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=
|
||||
github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=
|
||||
github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
|
||||
github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
|
||||
github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU=
|
||||
github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ=
|
||||
github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4=
|
||||
github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=
|
||||
github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=
|
||||
github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
|
||||
github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y=
|
||||
github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=
|
||||
github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
|
||||
github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
|
||||
github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo=
|
||||
github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM=
|
||||
github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
|
||||
github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=
|
||||
github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48=
|
||||
github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg=
|
||||
github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0=
|
||||
github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg=
|
||||
github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=
|
||||
github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
|
||||
github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=
|
||||
github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
|
||||
github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4=
|
||||
github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg=
|
||||
github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=
|
||||
github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
|
||||
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
||||
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jandelgado/gcov2lcov v1.1.1 h1:CHUNoAglvb34DqmMoZchnzDbA3yjpzT8EoUvVqcAY+s=
|
||||
github.com/jandelgado/gcov2lcov v1.1.1/go.mod h1:tMVUlMVtS1po2SB8UkADWhOT5Y5Q13XOce2AYU69JuI=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/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/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
|
||||
github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
|
||||
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=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
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/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
goauthentik.io/api/v3 v3.2026020.16 h1:sEqcVRXYSJTYaSdU5PzSEdFUWDqCONm5BeL62F5k+58=
|
||||
goauthentik.io/api/v3 v3.2026020.16/go.mod h1:82lqAz4jxzl6Cg0YDbhNtvvTG2rm6605ZhdJFnbbsl8=
|
||||
goauthentik.io/api/v3 v3.2026050.0 h1:yRChFww7FXjVZNtUFpRXescL/VAK88u/oRqbhwe/Xfc=
|
||||
goauthentik.io/api/v3 v3.2026050.0/go.mod h1:MC0irkuuJEorS4awXUTBnLR7/sYL6lNL50ELKlbUrAM=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
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/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
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/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
|
||||
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
||||
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/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
||||
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=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
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/go.mod h1:C+fcNlNQ9TcKHspN+DD7UybdfnjDAGyBjfCd6W7ogbY=
|
||||
k8s.io/api v0.36.0 h1:SgqDhZzHdOtMk40xVSvCXkP9ME0H05hPM3p9AB1kL80=
|
||||
k8s.io/api v0.36.0/go.mod h1:m1LVrGPNYax5NBHdO+QuAedXyuzTt4RryI/qnmNvs34=
|
||||
k8s.io/api v0.36.1 h1:XbL/EMj8K2aJpJtePmqUyQMsM0D4QI2pvl7YKJ20FTY=
|
||||
k8s.io/api v0.36.1/go.mod h1:KOWo4ey3TINlXjeHVuwB3i+tXXnu+UcwFBHlI/9dvEo=
|
||||
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.36.0 h1:jZyPzhd5Z+3h9vJLt0z9XdzW9VzNzWAUw+P1xZ9PXtQ=
|
||||
k8s.io/apimachinery v0.36.0/go.mod h1:FklypaRJt6n5wUIwWXIP6GJlIpUizTgfo1T/As+Tyxc=
|
||||
k8s.io/apimachinery v0.36.1 h1:G63Gjx2W+q0YD+72Vo8oY0nDnePVwnuzTmmy5ENrVSA=
|
||||
k8s.io/apimachinery v0.36.1/go.mod h1:ibYOR00vW/I1kzvi5SF0dRuJ52BvKtfvRdOn35GPQ+8=
|
||||
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.36.0 h1:pOYi7C4RHChYjMiHpZSpSbIM6ZxVbRXBy7CuiIwqA3c=
|
||||
k8s.io/client-go v0.36.0/go.mod h1:ZKKcpwF0aLYfkHFCjillCKaTK/yBkEDHTDXCFY6AS9Y=
|
||||
k8s.io/client-go v0.36.1 h1:FN/K8QIT2CEDt+2WB2HnWrUANZ50AP5GII43/SP2JR0=
|
||||
k8s.io/client-go v0.36.1/go.mod h1:s6rAnCtTGYDQnpNjEhSaISV+2O8jwruZ6m3QOYBFbtU=
|
||||
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
|
||||
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
|
||||
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/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
||||
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/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
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/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||
@@ -0,0 +1,18 @@
|
||||
API rule violation: names_match,gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1,ProxyProviderSpec,AuthorizationFlow
|
||||
API rule violation: names_match,gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1,ProxyProviderSpec,ExternalHost
|
||||
API rule violation: names_match,gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1,ProxyProviderSpec,InvalidationFlow
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,Quantity,Format
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,Quantity,d
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,Quantity,i
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,Quantity,s
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,int64Amount,scale
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/api/resource,int64Amount,value
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,APIResourceList,APIResources
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,Duration,Duration
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,InternalEvent,Object
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,InternalEvent,Type
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,MicroTime,Time
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,StatusCause,Type
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,Time,Time
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/runtime,Unknown,ContentEncoding
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/runtime,Unknown,ContentType
|
||||
@@ -0,0 +1,94 @@
|
||||
package baseController
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
type SyncHandler func(ctx context.Context, objRef cache.ObjectName) error
|
||||
|
||||
type Controller struct {
|
||||
workqueue workqueue.TypedRateLimitingInterface[cache.ObjectName]
|
||||
recorder record.EventRecorder
|
||||
synced cache.InformerSynced
|
||||
syncHandler SyncHandler
|
||||
}
|
||||
|
||||
func NewController(
|
||||
ctx context.Context,
|
||||
workqueue workqueue.TypedRateLimitingInterface[cache.ObjectName],
|
||||
recorder record.EventRecorder,
|
||||
synced cache.InformerSynced,
|
||||
syncHandler SyncHandler,
|
||||
) *Controller {
|
||||
return &Controller{
|
||||
workqueue: workqueue,
|
||||
recorder: recorder,
|
||||
synced: synced,
|
||||
syncHandler: syncHandler,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) Run(ctx context.Context, workers int) error {
|
||||
defer utilruntime.HandleCrash()
|
||||
defer c.workqueue.ShutDown()
|
||||
logger := klog.FromContext(ctx)
|
||||
|
||||
logger.Info("Starting PolicyBinding controller")
|
||||
|
||||
logger.Info("Waiting for informer caches to sync")
|
||||
if ok := cache.WaitForCacheSync(ctx.Done(), c.synced); !ok {
|
||||
return fmt.Errorf("failed to wait for caches to sync")
|
||||
}
|
||||
|
||||
logger.Info("Starting workers", "count", workers)
|
||||
for i := 0; i < workers; i++ {
|
||||
go wait.UntilWithContext(ctx, c.runWorker, time.Second)
|
||||
}
|
||||
|
||||
logger.Info("Started workers")
|
||||
<-ctx.Done()
|
||||
logger.Info("Shutting down workers")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) runWorker(ctx context.Context) {
|
||||
for c.processNextWorkItem(ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) processNextWorkItem(ctx context.Context) bool {
|
||||
objRef, shutdown := c.workqueue.Get()
|
||||
logger := klog.FromContext(ctx)
|
||||
if shutdown {
|
||||
return false
|
||||
}
|
||||
defer c.workqueue.Done(objRef)
|
||||
|
||||
err := c.syncHandler(ctx, objRef)
|
||||
if err == nil {
|
||||
c.workqueue.Forget(objRef)
|
||||
logger.Info("Successfully synced", "objectName", objRef)
|
||||
return true
|
||||
}
|
||||
utilruntime.HandleErrorWithContext(ctx, err, "Error syncing; requeuing for later retry", "objectReference", objRef)
|
||||
c.workqueue.AddRateLimited(objRef)
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Controller) Enqueue(obj interface{}) {
|
||||
objectRef, err := cache.ObjectToName(obj)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(err)
|
||||
return
|
||||
}
|
||||
c.workqueue.Add(objectRef)
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
// AI generated tests and not yet reviewed.
|
||||
package baseController
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
)
|
||||
|
||||
func newTestController(t *testing.T, synced cache.InformerSynced, syncHandler SyncHandler) (*Controller, workqueue.TypedRateLimitingInterface[cache.ObjectName]) {
|
||||
t.Helper()
|
||||
|
||||
ratelimiter := workqueue.NewTypedItemExponentialFailureRateLimiter[cache.ObjectName](time.Millisecond, time.Second)
|
||||
q := workqueue.NewTypedRateLimitingQueue(ratelimiter)
|
||||
t.Cleanup(q.ShutDown)
|
||||
|
||||
if synced == nil {
|
||||
synced = func() bool { return true }
|
||||
}
|
||||
|
||||
ctrl := NewController(
|
||||
context.Background(),
|
||||
q,
|
||||
record.NewFakeRecorder(10),
|
||||
synced,
|
||||
syncHandler,
|
||||
)
|
||||
return ctrl, q
|
||||
}
|
||||
|
||||
func TestController_processNextWorkItem_success(t *testing.T) {
|
||||
objRef := cache.ObjectName{Namespace: "default", Name: "test"}
|
||||
|
||||
var syncedRef cache.ObjectName
|
||||
ctrl, q := newTestController(t, nil, func(_ context.Context, ref cache.ObjectName) error {
|
||||
syncedRef = ref
|
||||
return nil
|
||||
})
|
||||
q.Add(objRef)
|
||||
|
||||
if !ctrl.processNextWorkItem(context.Background()) {
|
||||
t.Fatal("processNextWorkItem() = false, want true")
|
||||
}
|
||||
if syncedRef != objRef {
|
||||
t.Fatalf("syncHandler object = %+v, want %+v", syncedRef, objRef)
|
||||
}
|
||||
if q.Len() != 0 {
|
||||
t.Fatalf("queue length = %d, want 0 after successful sync", q.Len())
|
||||
}
|
||||
if q.NumRequeues(objRef) != 0 {
|
||||
t.Fatalf("requeues = %d, want 0 after successful sync", q.NumRequeues(objRef))
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_processNextWorkItem_syncError(t *testing.T) {
|
||||
objRef := cache.ObjectName{Namespace: "default", Name: "test"}
|
||||
syncErr := errors.New("sync failed")
|
||||
|
||||
ctrl, q := newTestController(t, nil, func(context.Context, cache.ObjectName) error {
|
||||
return syncErr
|
||||
})
|
||||
q.Add(objRef)
|
||||
|
||||
if !ctrl.processNextWorkItem(context.Background()) {
|
||||
t.Fatal("processNextWorkItem() = false, want true")
|
||||
}
|
||||
if q.NumRequeues(objRef) != 1 {
|
||||
t.Fatalf("requeues = %d, want 1 after sync error", q.NumRequeues(objRef))
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_processNextWorkItem_shutdown(t *testing.T) {
|
||||
ctrl, q := newTestController(t, nil, func(context.Context, cache.ObjectName) error {
|
||||
return nil
|
||||
})
|
||||
q.ShutDown()
|
||||
|
||||
if ctrl.processNextWorkItem(context.Background()) {
|
||||
t.Fatal("processNextWorkItem() = true, want false on shutdown")
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_Enqueue(t *testing.T) {
|
||||
ctrl, q := newTestController(t, nil, func(context.Context, cache.ObjectName) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
obj := &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
},
|
||||
}
|
||||
ctrl.Enqueue(obj)
|
||||
|
||||
if q.Len() != 1 {
|
||||
t.Fatalf("queue length = %d, want 1 after Enqueue", q.Len())
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_Enqueue_invalidObject(t *testing.T) {
|
||||
ctrl, q := newTestController(t, nil, func(context.Context, cache.ObjectName) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
ctrl.Enqueue("not-a-kubernetes-object")
|
||||
|
||||
if q.Len() != 0 {
|
||||
t.Fatalf("queue length = %d, want 0 for invalid object", q.Len())
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_Run_cacheSyncFails(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
ctrl, _ := newTestController(t, func() bool { return false }, func(context.Context, cache.ObjectName) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
cancel()
|
||||
}()
|
||||
|
||||
err := ctrl.Run(ctx, 1)
|
||||
if err == nil {
|
||||
t.Fatal("Run() error = nil, want cache sync failure")
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_Run_shutsDownOnCancel(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
ctrl, _ := newTestController(t, nil, func(context.Context, cache.ObjectName) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
errCh <- ctrl.Run(ctx, 1)
|
||||
}()
|
||||
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
cancel()
|
||||
|
||||
select {
|
||||
case err := <-errCh:
|
||||
if err != nil {
|
||||
t.Fatalf("Run() error = %v, want nil on context cancel", err)
|
||||
}
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("Run() did not return after context cancellation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_runWorker_processesQueuedItem(t *testing.T) {
|
||||
objRef := cache.ObjectName{Namespace: "default", Name: "test"}
|
||||
var calls atomic.Int32
|
||||
|
||||
ctrl, q := newTestController(t, nil, func(context.Context, cache.ObjectName) error {
|
||||
calls.Add(1)
|
||||
return nil
|
||||
})
|
||||
q.Add(objRef)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
go ctrl.runWorker(ctx)
|
||||
|
||||
deadline := time.Now().Add(2 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
if calls.Load() == 1 && q.Len() == 0 {
|
||||
cancel()
|
||||
return
|
||||
}
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
}
|
||||
cancel()
|
||||
t.Fatalf("runWorker did not process queued item: calls=%d queueLen=%d", calls.Load(), q.Len())
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"net/url"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/signals"
|
||||
authentikapi "goauthentik.io/api/v3"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
// Uncomment the following line to load the gcp plugin (only required to authenticate against GKE clusters).
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
|
||||
applicationcontroller "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/controllers/application"
|
||||
policybindingcontroller "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/controllers/policybinding"
|
||||
proxyprovidercontroller "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/controllers/proxyprovider"
|
||||
clientset "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
|
||||
informers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions"
|
||||
)
|
||||
|
||||
var (
|
||||
masterURL string
|
||||
kubeconfig string
|
||||
)
|
||||
|
||||
func main() {
|
||||
klog.InitFlags(nil)
|
||||
flag.Parse()
|
||||
|
||||
// set up signals so we handle the shutdown signal gracefully
|
||||
ctx := signals.SetupSignalHandler()
|
||||
logger := klog.FromContext(ctx)
|
||||
|
||||
cfg, err := clientcmd.BuildConfigFromFlags(masterURL, kubeconfig)
|
||||
if err != nil {
|
||||
logger.Error(err, "Error building kubeconfig")
|
||||
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
||||
}
|
||||
|
||||
kubeClient, err := kubernetes.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
logger.Error(err, "Error building kubernetes clientset")
|
||||
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
||||
}
|
||||
|
||||
clientset, err := clientset.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
proxyProviderInformerFactory := informers.NewSharedInformerFactory(clientset, time.Second*30)
|
||||
|
||||
ppController := proxyprovidercontroller.NewController(ctx, kubeClient, clientset, authentikClient,
|
||||
proxyProviderInformerFactory.Proxyprovider().V1alpha1().ProxyProviders(),
|
||||
)
|
||||
|
||||
applicationInformerFactory := informers.NewSharedInformerFactory(clientset, time.Second*30)
|
||||
appController := applicationcontroller.NewController(ctx, kubeClient, clientset, authentikClient,
|
||||
applicationInformerFactory.Application().V1alpha1().Applications(),
|
||||
)
|
||||
|
||||
policyBindingInformerFactory := informers.NewSharedInformerFactory(clientset, time.Second*30)
|
||||
pbController := policybindingcontroller.NewController(ctx, kubeClient, clientset, authentikClient,
|
||||
policyBindingInformerFactory.PolicyBinding().V1alpha1().PolicyBindings(),
|
||||
)
|
||||
|
||||
// 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.
|
||||
proxyProviderInformerFactory.Start(ctx.Done())
|
||||
applicationInformerFactory.Start(ctx.Done())
|
||||
policyBindingInformerFactory.Start(ctx.Done())
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(3)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := ppController.Run(ctx, 2); err != nil {
|
||||
logger.Error(err, "Error running proxy provider controller")
|
||||
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := appController.Run(ctx, 2); err != nil {
|
||||
logger.Error(err, "Error running application controller")
|
||||
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := pbController.Run(ctx, 2); err != nil {
|
||||
logger.Error(err, "Error running policy binding controller")
|
||||
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
||||
}
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func init() {
|
||||
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.")
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:openapi-gen=true
|
||||
// +groupName=application.t000-n.de
|
||||
// +groupGoName=Application
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the application API.
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +kubebuilder:subresource:status
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type Application struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ApplicationSpec `json:"spec"`
|
||||
Status ApplicationStatus `json:"status"`
|
||||
}
|
||||
|
||||
type ApplicationSpec struct {
|
||||
Name string `json:"name"`
|
||||
Slug string `json:"slug"`
|
||||
Provider int32 `json:"provider,omitempty"`
|
||||
}
|
||||
|
||||
type ApplicationStatus struct {
|
||||
PK string `json:"pk"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type ApplicationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []Application `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Application) DeepCopyInto(out *Application) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
out.Status = in.Status
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application.
|
||||
func (in *Application) DeepCopy() *Application {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Application)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Application) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ApplicationList) DeepCopyInto(out *ApplicationList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Application, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationList.
|
||||
func (in *ApplicationList) DeepCopy() *ApplicationList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ApplicationList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ApplicationList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ApplicationSpec) DeepCopyInto(out *ApplicationSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSpec.
|
||||
func (in *ApplicationSpec) DeepCopy() *ApplicationSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ApplicationSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ApplicationStatus) DeepCopyInto(out *ApplicationStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationStatus.
|
||||
func (in *ApplicationStatus) DeepCopy() *ApplicationStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ApplicationStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by register-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName specifies the group name used to register the objects.
|
||||
const GroupName = "application.t000-n.de"
|
||||
|
||||
// GroupVersion specifies the group and the version used to register the objects.
|
||||
var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha1"}
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
//
|
||||
// Deprecated: use GroupVersion instead.
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
// Deprecated: use Install instead
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
Install = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addKnownTypes)
|
||||
}
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Application{},
|
||||
&ApplicationList{},
|
||||
)
|
||||
// AddToGroupVersion allows the serialization of client types like ListOptions.
|
||||
v1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:openapi-gen=true
|
||||
// +groupName=policybinding.t000-n.de
|
||||
// +groupGoName=PolicyBinding
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the policybinding API.
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +kubebuilder:subresource:status
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type PolicyBinding struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec PolicyBindingSpec `json:"spec"`
|
||||
Status PolicyBindingStatus `json:"status"`
|
||||
}
|
||||
|
||||
type PolicyBindingSpec struct {
|
||||
Policy string `json:"policy,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
User int32 `json:"user,omitempty"`
|
||||
Target string `json:"target"`
|
||||
Order int32 `json:"order"`
|
||||
}
|
||||
|
||||
type PolicyBindingStatus struct {
|
||||
PK string `json:"pk"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type PolicyBindingList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []PolicyBinding `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyBinding) DeepCopyInto(out *PolicyBinding) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
out.Status = in.Status
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyBinding.
|
||||
func (in *PolicyBinding) DeepCopy() *PolicyBinding {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyBinding)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PolicyBinding) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyBindingList) DeepCopyInto(out *PolicyBindingList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]PolicyBinding, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyBindingList.
|
||||
func (in *PolicyBindingList) DeepCopy() *PolicyBindingList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyBindingList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PolicyBindingList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyBindingSpec) DeepCopyInto(out *PolicyBindingSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyBindingSpec.
|
||||
func (in *PolicyBindingSpec) DeepCopy() *PolicyBindingSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyBindingSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyBindingStatus) DeepCopyInto(out *PolicyBindingStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyBindingStatus.
|
||||
func (in *PolicyBindingStatus) DeepCopy() *PolicyBindingStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyBindingStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by register-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName specifies the group name used to register the objects.
|
||||
const GroupName = "policybinding.t000-n.de"
|
||||
|
||||
// GroupVersion specifies the group and the version used to register the objects.
|
||||
var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha1"}
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
//
|
||||
// Deprecated: use GroupVersion instead.
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
// Deprecated: use Install instead
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
Install = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addKnownTypes)
|
||||
}
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&PolicyBinding{},
|
||||
&PolicyBindingList{},
|
||||
)
|
||||
// AddToGroupVersion allows the serialization of client types like ListOptions.
|
||||
v1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:openapi-gen=true
|
||||
// +groupName=proxyprovider.t000-n.de
|
||||
|
||||
// Package v1 is the v1 version of the API.
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +kubebuilder:subresource:status
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type ProxyProvider struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ProxyProviderSpec `json:"spec"`
|
||||
Status ProxyProviderStatus `json:"status"`
|
||||
}
|
||||
|
||||
type ProxyProviderSpec struct {
|
||||
Name string `json:"name"`
|
||||
AuthorizationFlow string `json:"authorization_flow"`
|
||||
InvalidationFlow string `json:"invalidation_flow"`
|
||||
ExternalHost string `json:"external_host"`
|
||||
Outpost string `json:"outpost"`
|
||||
}
|
||||
|
||||
type ProxyProviderStatus struct {
|
||||
PK string `json:"pk"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type ProxyProviderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []ProxyProvider `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ProxyProvider) DeepCopyInto(out *ProxyProvider) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
out.Status = in.Status
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyProvider.
|
||||
func (in *ProxyProvider) DeepCopy() *ProxyProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ProxyProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ProxyProvider) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ProxyProviderList) DeepCopyInto(out *ProxyProviderList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ProxyProvider, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyProviderList.
|
||||
func (in *ProxyProviderList) DeepCopy() *ProxyProviderList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ProxyProviderList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ProxyProviderList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ProxyProviderSpec) DeepCopyInto(out *ProxyProviderSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyProviderSpec.
|
||||
func (in *ProxyProviderSpec) DeepCopy() *ProxyProviderSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ProxyProviderSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ProxyProviderStatus) DeepCopyInto(out *ProxyProviderStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyProviderStatus.
|
||||
func (in *ProxyProviderStatus) DeepCopy() *ProxyProviderStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ProxyProviderStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by register-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName specifies the group name used to register the objects.
|
||||
const GroupName = "proxyprovider.t000-n.de"
|
||||
|
||||
// GroupVersion specifies the group and the version used to register the objects.
|
||||
var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha1"}
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
//
|
||||
// Deprecated: use GroupVersion instead.
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
// Deprecated: use Install instead
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
Install = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addKnownTypes)
|
||||
}
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&ProxyProvider{},
|
||||
&ProxyProviderList{},
|
||||
)
|
||||
// AddToGroupVersion allows the serialization of client types like ListOptions.
|
||||
v1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"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"
|
||||
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"
|
||||
listers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/listers/application/v1alpha1"
|
||||
authentikapi "goauthentik.io/api/v3"
|
||||
)
|
||||
|
||||
const controllerAgentName = "application-controller"
|
||||
|
||||
const (
|
||||
SuccessSynced = "Synced"
|
||||
ErrResourceExists = "ErrResourceExists"
|
||||
MessageResourceExists = "Resource %q already exists and is not managed by Application"
|
||||
MessageResourceSynced = "Application synced successfully"
|
||||
FieldManager = controllerAgentName
|
||||
)
|
||||
|
||||
// Finalizers
|
||||
const (
|
||||
DeleteAuthentikApplicationFinalizer = "application.t000-n.de/delete-authentik-application"
|
||||
)
|
||||
|
||||
type ApplicationController struct {
|
||||
kubeclientset kubernetes.Interface
|
||||
applicationClientset clientset.Interface
|
||||
authentik *authentikapi.APIClient
|
||||
|
||||
applicationListener listers.ApplicationLister
|
||||
|
||||
controller *baseController.Controller
|
||||
}
|
||||
|
||||
func NewController(
|
||||
ctx context.Context,
|
||||
kubeclientset kubernetes.Interface,
|
||||
applicationClientset clientset.Interface,
|
||||
authentik *authentikapi.APIClient,
|
||||
applicationInformer informers.ApplicationInformer,
|
||||
) *ApplicationController {
|
||||
logger := klog.FromContext(ctx)
|
||||
|
||||
utilruntime.Must(operatorscheme.AddToScheme(scheme.Scheme))
|
||||
logger.V(4).Info("Creating event broadcaster")
|
||||
|
||||
eventBroadcaster := record.NewBroadcaster(record.WithContext(ctx))
|
||||
eventBroadcaster.StartStructuredLogging(0)
|
||||
eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeclientset.CoreV1().Events("")})
|
||||
recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName})
|
||||
ratelimiter := workqueue.NewTypedMaxOfRateLimiter(
|
||||
workqueue.NewTypedItemExponentialFailureRateLimiter[cache.ObjectName](5*time.Millisecond, 1000*time.Second),
|
||||
&workqueue.TypedBucketRateLimiter[cache.ObjectName]{Limiter: rate.NewLimiter(rate.Limit(50), 300)},
|
||||
)
|
||||
|
||||
c := &ApplicationController{
|
||||
kubeclientset: kubeclientset,
|
||||
applicationClientset: applicationClientset,
|
||||
authentik: authentik,
|
||||
applicationListener: applicationInformer.Lister(),
|
||||
}
|
||||
c.controller = baseController.NewController(
|
||||
ctx,
|
||||
workqueue.NewTypedRateLimitingQueue(ratelimiter),
|
||||
recorder,
|
||||
applicationInformer.Informer().HasSynced,
|
||||
c.syncHandler,
|
||||
)
|
||||
|
||||
logger.Info("Setting up event handlers")
|
||||
applicationInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: c.controller.Enqueue,
|
||||
UpdateFunc: func(_, newObj interface{}) {
|
||||
c.controller.Enqueue(newObj)
|
||||
},
|
||||
})
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *ApplicationController) Run(ctx context.Context, workers int) error {
|
||||
return c.controller.Run(ctx, workers)
|
||||
}
|
||||
|
||||
func (c *ApplicationController) syncHandler(ctx context.Context, objectRef cache.ObjectName) error {
|
||||
logger := klog.LoggerWithValues(klog.FromContext(ctx), "objectRef", objectRef)
|
||||
|
||||
app, err := c.applicationListener.Applications(objectRef.Namespace).Get(objectRef.Name)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
logger.V(4).Info("Application no longer exists")
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
logger.V(4).Info("sync Application", "name", app.Name)
|
||||
|
||||
if !app.ObjectMeta.DeletionTimestamp.IsZero() {
|
||||
logger.Info("Reconciling deletion of Application", "name", app.Name)
|
||||
return c.reconcileDelete(ctx, app)
|
||||
}
|
||||
|
||||
if app.Status.PK == "" {
|
||||
logger.Info("Reconciling creation of Application", "name", app.Name)
|
||||
return c.reconcileCreate(ctx, app)
|
||||
}
|
||||
|
||||
// Check if all finalizers are present. If not, we add them. Same pattern as above, just needs a helper function to check for presence of a finalizer.
|
||||
if !slices.Contains(app.ObjectMeta.Finalizers, DeleteAuthentikApplicationFinalizer) {
|
||||
logger.Info("Ensuring finalizers are present", "name", app.Name)
|
||||
return c.ensureFinalizers(ctx, app)
|
||||
}
|
||||
|
||||
logger.Info("Reconciling update of Application", "name", app.Name)
|
||||
return c.reconcileUpdate(ctx, app)
|
||||
}
|
||||
|
||||
func (c *ApplicationController) ensureFinalizers(ctx context.Context, app *v1alpha1.Application) error {
|
||||
app.ObjectMeta.Finalizers = append(app.ObjectMeta.Finalizers, DeleteAuthentikApplicationFinalizer)
|
||||
return c.updateApplication(ctx, app)
|
||||
}
|
||||
|
||||
func (c *ApplicationController) reconcileDelete(ctx context.Context, app *v1alpha1.Application) error {
|
||||
r, err := c.authentik.CoreApi.CoreApplicationsDestroy(ctx, app.Spec.Slug).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 {
|
||||
return fmt.Errorf("error when calling `CoreAPI.CoreApplicationsDestroy`: %w with response %v", err, r)
|
||||
}
|
||||
}
|
||||
|
||||
app.ObjectMeta.Finalizers = slices.Delete(app.ObjectMeta.Finalizers, slices.Index(app.ObjectMeta.Finalizers, DeleteAuthentikApplicationFinalizer), 1)
|
||||
return c.updateApplication(ctx, app)
|
||||
}
|
||||
|
||||
func (c *ApplicationController) reconcileUpdate(ctx context.Context, app *v1alpha1.Application) error {
|
||||
_, r, err := c.authentik.CoreApi.CoreApplicationsRetrieve(ctx, app.Spec.Slug).Execute()
|
||||
if err != nil {
|
||||
if r != nil && r.StatusCode == http.StatusNotFound {
|
||||
// This handles an edge-case, where when the Application on Authentik has been deleted, e.g. by mistake. We just remove the PK and return.
|
||||
// During the next reconciliation, the Application will be re-created.
|
||||
app.Status.PK = ""
|
||||
return c.updateApplicationStatus(ctx, app)
|
||||
}
|
||||
return fmt.Errorf("error retrieving existing Application: %v with response %v", err, r)
|
||||
}
|
||||
|
||||
patchedApplicationRequest := &authentikapi.PatchedApplicationRequest{
|
||||
Name: &app.Spec.Name,
|
||||
Slug: &app.Spec.Slug,
|
||||
Provider: *authentikapi.NewNullableInt32(&app.Spec.Provider),
|
||||
}
|
||||
resp, r, err := c.authentik.CoreApi.CoreApplicationsPartialUpdate(ctx, app.Spec.Slug).PatchedApplicationRequest(*patchedApplicationRequest).Execute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when calling `CoreAPI.CoreApplicationsPartialUpdate`: %w with response %v", err, r)
|
||||
}
|
||||
|
||||
app.Status.PK = resp.Pk
|
||||
return c.updateApplicationStatus(ctx, app)
|
||||
}
|
||||
|
||||
func (c *ApplicationController) reconcileCreate(ctx context.Context, app *v1alpha1.Application) error {
|
||||
applicationRequest := &authentikapi.ApplicationRequest{
|
||||
Name: app.Spec.Name,
|
||||
Slug: app.Spec.Slug,
|
||||
Provider: *authentikapi.NewNullableInt32(&app.Spec.Provider),
|
||||
}
|
||||
resp, r, err := c.authentik.CoreApi.CoreApplicationsCreate(ctx).ApplicationRequest(*applicationRequest).Execute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when calling `CoreAPI.CoreApplicationsCreate`: %w with response %v", err, r)
|
||||
}
|
||||
|
||||
app.Status.PK = resp.Pk
|
||||
return c.updateApplicationStatus(ctx, app)
|
||||
}
|
||||
|
||||
func (c *ApplicationController) updateApplicationStatus(ctx context.Context, app *v1alpha1.Application) error {
|
||||
appCopy := app.DeepCopy()
|
||||
_, err := c.applicationClientset.ApplicationV1alpha1().Applications(appCopy.Namespace).UpdateStatus(ctx, appCopy, metav1.UpdateOptions{FieldManager: FieldManager})
|
||||
return err
|
||||
}
|
||||
|
||||
// Update metadata, spec, etc. of the Application object.
|
||||
func (c *ApplicationController) updateApplication(ctx context.Context, app *v1alpha1.Application) error {
|
||||
appCopy := app.DeepCopy()
|
||||
_, err := c.applicationClientset.ApplicationV1alpha1().Applications(appCopy.Namespace).Update(ctx, appCopy, metav1.UpdateOptions{FieldManager: FieldManager})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error updating Application metadata: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
// AI generated tests and not yet reviewed.
|
||||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
|
||||
operatorfake "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/fake"
|
||||
operatorinformers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions"
|
||||
authentikapi "goauthentik.io/api/v3"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
func TestController_syncHandler_create(t *testing.T) {
|
||||
const wantPK = "42"
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
applicationCreate: func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusCreated, map[string]any{"pk": wantPK})
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, testApplication(), server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: "default", Name: "test-app"})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
|
||||
got := getApplication(t, ctrl, "default", "test-app")
|
||||
if got.Status.PK != wantPK {
|
||||
t.Fatalf("status.pk = %q, want %q", got.Status.PK, wantPK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_ensureFinalizers(t *testing.T) {
|
||||
app := testApplication()
|
||||
app.Status.PK = "42"
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
got := getApplication(t, ctrl, app.Namespace, app.Name)
|
||||
if !slices.Contains(got.Finalizers, DeleteAuthentikApplicationFinalizer) {
|
||||
t.Fatalf("finalizers = %v, want %q", got.Finalizers, DeleteAuthentikApplicationFinalizer)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_update(t *testing.T) {
|
||||
app := testApplication()
|
||||
app.Status.PK = "42"
|
||||
app.Finalizers = []string{DeleteAuthentikApplicationFinalizer}
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
applicationRetrieve: func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{"pk": "42"})
|
||||
},
|
||||
applicationPartialUpdate: func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{"pk": "42"})
|
||||
},
|
||||
})
|
||||
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)
|
||||
}
|
||||
|
||||
got := getApplication(t, ctrl, app.Namespace, app.Name)
|
||||
if got.Status.PK != "42" {
|
||||
t.Fatalf("status.pk = %q, want 42", got.Status.PK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_update_applicationNotFound(t *testing.T) {
|
||||
app := testApplication()
|
||||
app.Status.PK = "42"
|
||||
app.Finalizers = []string{DeleteAuthentikApplicationFinalizer}
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
applicationRetrieve: func(w http.ResponseWriter, _ *http.Request) {
|
||||
http.NotFound(w, nil)
|
||||
},
|
||||
})
|
||||
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)
|
||||
}
|
||||
|
||||
got := getApplication(t, ctrl, app.Namespace, app.Name)
|
||||
if got.Status.PK != "" {
|
||||
t.Fatalf("status.pk = %q, want empty after application not found", got.Status.PK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_delete(t *testing.T) {
|
||||
now := metav1.Now()
|
||||
app := testApplication()
|
||||
app.Status.PK = "42"
|
||||
app.DeletionTimestamp = &now
|
||||
app.Finalizers = []string{DeleteAuthentikApplicationFinalizer}
|
||||
|
||||
var destroyCalled bool
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
applicationDestroy: func(w http.ResponseWriter, r *http.Request) {
|
||||
destroyCalled = true
|
||||
if r.Method != http.MethodDelete {
|
||||
t.Errorf("destroy method = %s, want DELETE", r.Method)
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
},
|
||||
})
|
||||
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 !destroyCalled {
|
||||
t.Fatal("expected Authentik destroy call")
|
||||
}
|
||||
|
||||
got := getApplication(t, ctrl, app.Namespace, app.Name)
|
||||
if slices.Contains(got.Finalizers, DeleteAuthentikApplicationFinalizer) {
|
||||
t.Fatalf("finalizers = %v, want finalizer removed", got.Finalizers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_delete_providerAlreadyGone(t *testing.T) {
|
||||
now := metav1.Now()
|
||||
app := testApplication()
|
||||
app.Status.PK = "42"
|
||||
app.DeletionTimestamp = &now
|
||||
app.Finalizers = []string{DeleteAuthentikApplicationFinalizer}
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
applicationDestroy: func(w http.ResponseWriter, _ *http.Request) {
|
||||
http.NotFound(w, nil)
|
||||
},
|
||||
})
|
||||
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)
|
||||
}
|
||||
|
||||
got := getApplication(t, ctrl, app.Namespace, app.Name)
|
||||
if slices.Contains(got.Finalizers, DeleteAuthentikApplicationFinalizer) {
|
||||
t.Fatalf("finalizers = %v, want finalizer removed after 404", got.Finalizers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_notFound(t *testing.T) {
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, nil, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: "default", Name: "missing"})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v, want nil for missing object", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_delete_usesSlugNotPK(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)
|
||||
},
|
||||
})
|
||||
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 destroySlug != app.Spec.Slug {
|
||||
t.Fatalf("destroy slug = %q, want %q (delete must use spec.slug, not status.pk)", destroySlug, app.Spec.Slug)
|
||||
}
|
||||
}
|
||||
|
||||
// --- test helpers ---
|
||||
|
||||
func testApplication() *v1alpha1.Application {
|
||||
return &v1alpha1.Application{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
||||
Kind: "Application",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-app",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
Name: "My Application",
|
||||
Slug: "my-app",
|
||||
Provider: 7,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newTestController(t *testing.T, app *v1alpha1.Application, authentikURL string) (*ApplicationController, context.Context, context.CancelFunc) {
|
||||
t.Helper()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctrl, _, stop := newTestControllerWithContext(t, ctx, app, authentikURL)
|
||||
return ctrl, ctx, func() {
|
||||
cancel()
|
||||
stop()
|
||||
}
|
||||
}
|
||||
|
||||
func newTestControllerWithContext(t *testing.T, ctx context.Context, app *v1alpha1.Application, authentikURL string) (*ApplicationController, context.Context, func()) {
|
||||
t.Helper()
|
||||
|
||||
authentikClient := newAuthentikAPIClientForTest(t, authentikURL)
|
||||
|
||||
var objects []runtime.Object
|
||||
if app != nil {
|
||||
objects = append(objects, app)
|
||||
}
|
||||
applicationClient := operatorfake.NewSimpleClientset(objects...)
|
||||
|
||||
informerFactory := operatorinformers.NewSharedInformerFactory(applicationClient, 0)
|
||||
applicationInformer := informerFactory.Application().V1alpha1().Applications()
|
||||
|
||||
ctrl := NewController(ctx, fake.NewClientset(), applicationClient, authentikClient, applicationInformer)
|
||||
|
||||
informerFactory.Start(ctx.Done())
|
||||
for informerType, synced := range informerFactory.WaitForCacheSync(ctx.Done()) {
|
||||
if !synced {
|
||||
t.Fatalf("informer %v failed to sync", informerType)
|
||||
}
|
||||
}
|
||||
|
||||
return ctrl, ctx, func() {}
|
||||
}
|
||||
|
||||
func newAuthentikAPIClientForTest(t *testing.T, serverURL string) *authentikapi.APIClient {
|
||||
t.Helper()
|
||||
|
||||
u, err := url.Parse(serverURL)
|
||||
if err != nil {
|
||||
t.Fatalf("parse server URL: %v", err)
|
||||
}
|
||||
|
||||
cfg := authentikapi.NewConfiguration()
|
||||
cfg.Scheme = u.Scheme
|
||||
cfg.Host = u.Host
|
||||
|
||||
return authentikapi.NewAPIClient(cfg)
|
||||
}
|
||||
|
||||
type authentikTestHandlers struct {
|
||||
applicationCreate http.HandlerFunc
|
||||
applicationRetrieve http.HandlerFunc
|
||||
applicationPartialUpdate http.HandlerFunc
|
||||
applicationDestroy http.HandlerFunc
|
||||
}
|
||||
|
||||
func newAuthentikTestServer(t *testing.T, handlers authentikTestHandlers) *httptest.Server {
|
||||
t.Helper()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.URL.Path
|
||||
|
||||
switch {
|
||||
case path == "/api/v3/core/applications/" && r.Method == http.MethodPost:
|
||||
if handlers.applicationCreate != nil {
|
||||
handlers.applicationCreate(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
|
||||
case strings.HasPrefix(path, "/api/v3/core/applications/") && strings.HasSuffix(path, "/"):
|
||||
slugPath := strings.TrimPrefix(path, "/api/v3/core/applications/")
|
||||
if slugPath == "" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
if handlers.applicationRetrieve != nil {
|
||||
handlers.applicationRetrieve(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
case http.MethodPatch:
|
||||
if handlers.applicationPartialUpdate != nil {
|
||||
handlers.applicationPartialUpdate(w, r)
|
||||
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)
|
||||
}
|
||||
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
|
||||
return httptest.NewServer(handler)
|
||||
}
|
||||
|
||||
func writeJSON(t *testing.T, w http.ResponseWriter, status int, body any) {
|
||||
t.Helper()
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
if err := json.NewEncoder(w).Encode(body); err != nil {
|
||||
t.Fatalf("write JSON response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func getApplication(t *testing.T, ctrl *ApplicationController, namespace, name string) *v1alpha1.Application {
|
||||
t.Helper()
|
||||
|
||||
got, err := ctrl.applicationClientset.ApplicationV1alpha1().Applications(namespace).Get(
|
||||
context.Background(), name, metav1.GetOptions{},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("get Application: %v", err)
|
||||
}
|
||||
return got
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package policybinding
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"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"
|
||||
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"
|
||||
listers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/listers/policybinding/v1alpha1"
|
||||
authentikapi "goauthentik.io/api/v3"
|
||||
)
|
||||
|
||||
const controllerAgentName = "policybinding-controller"
|
||||
|
||||
const (
|
||||
SuccessSynced = "Synced"
|
||||
ErrResourceExists = "ErrResourceExists"
|
||||
MessageResourceExists = "Resource %q already exists and is not managed by PolicyBinding"
|
||||
MessageResourceSynced = "PolicyBinding synced successfully"
|
||||
FieldManager = controllerAgentName
|
||||
)
|
||||
|
||||
// Finalizers
|
||||
const (
|
||||
DeleteAuthentikPolicyBindingFinalizer = "policybinding.t000-n.de/delete-authentik-policybinding"
|
||||
)
|
||||
|
||||
type PolicyBindingController struct {
|
||||
kubeclientset kubernetes.Interface
|
||||
policyBindingClientset clientset.Interface
|
||||
authentik *authentikapi.APIClient
|
||||
|
||||
policyBindingListener listers.PolicyBindingLister
|
||||
|
||||
controller *baseController.Controller
|
||||
}
|
||||
|
||||
func NewController(
|
||||
ctx context.Context,
|
||||
kubeclientset kubernetes.Interface,
|
||||
policyBindingClientset clientset.Interface,
|
||||
authentik *authentikapi.APIClient,
|
||||
policyBindingInformer informers.PolicyBindingInformer,
|
||||
) *PolicyBindingController {
|
||||
logger := klog.FromContext(ctx)
|
||||
|
||||
utilruntime.Must(operatorscheme.AddToScheme(scheme.Scheme))
|
||||
logger.V(4).Info("Creating event broadcaster")
|
||||
|
||||
eventBroadcaster := record.NewBroadcaster(record.WithContext(ctx))
|
||||
eventBroadcaster.StartStructuredLogging(0)
|
||||
eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeclientset.CoreV1().Events("")})
|
||||
recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName})
|
||||
ratelimiter := workqueue.NewTypedMaxOfRateLimiter(
|
||||
workqueue.NewTypedItemExponentialFailureRateLimiter[cache.ObjectName](5*time.Millisecond, 1000*time.Second),
|
||||
&workqueue.TypedBucketRateLimiter[cache.ObjectName]{Limiter: rate.NewLimiter(rate.Limit(50), 300)},
|
||||
)
|
||||
|
||||
c := &PolicyBindingController{
|
||||
kubeclientset: kubeclientset,
|
||||
policyBindingClientset: policyBindingClientset,
|
||||
authentik: authentik,
|
||||
policyBindingListener: policyBindingInformer.Lister(),
|
||||
}
|
||||
c.controller = baseController.NewController(
|
||||
ctx,
|
||||
workqueue.NewTypedRateLimitingQueue(ratelimiter),
|
||||
recorder,
|
||||
policyBindingInformer.Informer().HasSynced,
|
||||
c.syncHandler,
|
||||
)
|
||||
|
||||
logger.Info("Setting up event handlers")
|
||||
policyBindingInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: c.controller.Enqueue,
|
||||
UpdateFunc: func(_, newObj interface{}) {
|
||||
c.controller.Enqueue(newObj)
|
||||
},
|
||||
})
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *PolicyBindingController) Run(ctx context.Context, workers int) error {
|
||||
return c.controller.Run(ctx, workers)
|
||||
}
|
||||
|
||||
func (c *PolicyBindingController) syncHandler(ctx context.Context, objectRef cache.ObjectName) error {
|
||||
logger := klog.LoggerWithValues(klog.FromContext(ctx), "objectRef", objectRef)
|
||||
|
||||
pb, err := c.policyBindingListener.PolicyBindings(objectRef.Namespace).Get(objectRef.Name)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
logger.V(4).Info("PolicyBinding no longer exists")
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
logger.V(4).Info("sync PolicyBinding", "name", pb.Name)
|
||||
|
||||
if !pb.ObjectMeta.DeletionTimestamp.IsZero() {
|
||||
logger.Info("Reconciling deletion of PolicyBinding", "name", pb.Name)
|
||||
return c.reconcileDelete(ctx, pb)
|
||||
}
|
||||
|
||||
if pb.Status.PK == "" {
|
||||
logger.Info("Reconciling creation of PolicyBinding", "name", pb.Name)
|
||||
return c.reconcileCreate(ctx, pb)
|
||||
}
|
||||
|
||||
// Check if all finalizers are present. If not, we add them. Same pattern as above, just needs a helper function to check for presence of a finalizer.
|
||||
if !slices.Contains(pb.ObjectMeta.Finalizers, DeleteAuthentikPolicyBindingFinalizer) {
|
||||
logger.Info("Ensuring finalizers are present", "name", pb.Name)
|
||||
return c.ensureFinalizers(ctx, pb)
|
||||
}
|
||||
|
||||
logger.Info("Reconciling update of PolicyBinding", "name", pb.Name)
|
||||
return c.reconcileUpdate(ctx, pb)
|
||||
}
|
||||
|
||||
func (c *PolicyBindingController) ensureFinalizers(ctx context.Context, pb *v1alpha1.PolicyBinding) error {
|
||||
pb.ObjectMeta.Finalizers = append(pb.ObjectMeta.Finalizers, DeleteAuthentikPolicyBindingFinalizer)
|
||||
return c.updatePolicyBinding(ctx, pb)
|
||||
}
|
||||
|
||||
func (c *PolicyBindingController) reconcileDelete(ctx context.Context, pb *v1alpha1.PolicyBinding) error {
|
||||
r, err := c.authentik.PoliciesApi.PoliciesBindingsDestroy(ctx, pb.Status.PK).Execute()
|
||||
if err != nil {
|
||||
// This handles an edge-case, where when the PolicyBinding 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 {
|
||||
return fmt.Errorf("error when calling `PoliciesAPI.PoliciesBindingsDestroy`: %w with response %v", err, r)
|
||||
}
|
||||
}
|
||||
|
||||
pb.ObjectMeta.Finalizers = slices.Delete(pb.ObjectMeta.Finalizers, slices.Index(pb.ObjectMeta.Finalizers, DeleteAuthentikPolicyBindingFinalizer), 1)
|
||||
return c.updatePolicyBinding(ctx, pb)
|
||||
}
|
||||
|
||||
func (c *PolicyBindingController) reconcileUpdate(ctx context.Context, pb *v1alpha1.PolicyBinding) error {
|
||||
_, r, err := c.authentik.PoliciesApi.PoliciesBindingsRetrieve(ctx, pb.Status.PK).Execute()
|
||||
if err != nil {
|
||||
if r != nil && r.StatusCode == http.StatusNotFound {
|
||||
// This handles an edge-case, where when the PolicyBinding on Authentik has been deleted, e.g. by mistake. We just remove the PK and return.
|
||||
// During the next reconciliation, the PolicyBinding will be re-created.
|
||||
pb.Status.PK = ""
|
||||
return c.updatePolicyBindingStatus(ctx, pb)
|
||||
}
|
||||
return fmt.Errorf("error retrieving existing PolicyBinding: %v with response %v", err, r)
|
||||
}
|
||||
|
||||
patchedPolicyBindingRequest := &authentikapi.PatchedPolicyBindingRequest{
|
||||
Target: &pb.Spec.Target,
|
||||
Order: &pb.Spec.Order,
|
||||
}
|
||||
if pb.Spec.Policy != "" {
|
||||
patchedPolicyBindingRequest.SetPolicy(pb.Spec.Policy)
|
||||
}
|
||||
if pb.Spec.Group != "" {
|
||||
patchedPolicyBindingRequest.SetGroup(pb.Spec.Group)
|
||||
}
|
||||
if pb.Spec.User != 0 {
|
||||
patchedPolicyBindingRequest.SetUser(pb.Spec.User)
|
||||
}
|
||||
|
||||
resp, r, err := c.authentik.PoliciesApi.PoliciesBindingsPartialUpdate(ctx, pb.Status.PK).PatchedPolicyBindingRequest(*patchedPolicyBindingRequest).Execute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when calling `PoliciesAPI.PoliciesBindingsPartialUpdate`: %w with response %v", err, r)
|
||||
}
|
||||
|
||||
pb.Status.PK = resp.Pk
|
||||
return c.updatePolicyBindingStatus(ctx, pb)
|
||||
}
|
||||
|
||||
func (c *PolicyBindingController) reconcileCreate(ctx context.Context, pb *v1alpha1.PolicyBinding) error {
|
||||
policyBindingRequest := &authentikapi.PolicyBindingRequest{
|
||||
Target: pb.Spec.Target,
|
||||
Order: pb.Spec.Order,
|
||||
}
|
||||
if pb.Spec.Policy != "" {
|
||||
policyBindingRequest.SetPolicy(pb.Spec.Policy)
|
||||
}
|
||||
if pb.Spec.Group != "" {
|
||||
policyBindingRequest.SetGroup(pb.Spec.Group)
|
||||
}
|
||||
if pb.Spec.User != 0 {
|
||||
policyBindingRequest.SetUser(pb.Spec.User)
|
||||
}
|
||||
|
||||
resp, r, err := c.authentik.PoliciesApi.PoliciesBindingsCreate(ctx).PolicyBindingRequest(*policyBindingRequest).Execute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when calling `PoliciesAPI.PoliciesBindingsCreate`: %w with response %v", err, r)
|
||||
}
|
||||
|
||||
pb.Status.PK = resp.Pk
|
||||
return c.updatePolicyBindingStatus(ctx, pb)
|
||||
}
|
||||
|
||||
func (c *PolicyBindingController) updatePolicyBindingStatus(ctx context.Context, pb *v1alpha1.PolicyBinding) error {
|
||||
pbCopy := pb.DeepCopy()
|
||||
_, err := c.policyBindingClientset.PolicyBindingV1alpha1().PolicyBindings(pbCopy.Namespace).UpdateStatus(ctx, pbCopy, metav1.UpdateOptions{FieldManager: FieldManager})
|
||||
return err
|
||||
}
|
||||
|
||||
// Update metadata, spec, etc. of the PolicyBinding object.
|
||||
func (c *PolicyBindingController) updatePolicyBinding(ctx context.Context, pb *v1alpha1.PolicyBinding) error {
|
||||
pbCopy := pb.DeepCopy()
|
||||
_, err := c.policyBindingClientset.PolicyBindingV1alpha1().PolicyBindings(pbCopy.Namespace).Update(ctx, pbCopy, metav1.UpdateOptions{FieldManager: FieldManager})
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
// AI generated tests and not yet reviewed.
|
||||
package policybinding
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
|
||||
operatorfake "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/fake"
|
||||
operatorinformers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions"
|
||||
authentikapi "goauthentik.io/api/v3"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
func TestController_syncHandler_create(t *testing.T) {
|
||||
const wantPK = "42"
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
policyBindingCreate: func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusCreated, map[string]any{"pk": wantPK})
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, testPolicyBinding(), server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: "default", Name: "test-pb"})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
|
||||
got := getPolicyBinding(t, ctrl, "default", "test-pb")
|
||||
if got.Status.PK != wantPK {
|
||||
t.Fatalf("status.pk = %q, want %q", got.Status.PK, wantPK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_ensureFinalizers(t *testing.T) {
|
||||
pb := testPolicyBinding()
|
||||
pb.Status.PK = "42"
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pb, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pb.Namespace, Name: pb.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
|
||||
got := getPolicyBinding(t, ctrl, pb.Namespace, pb.Name)
|
||||
if !slices.Contains(got.Finalizers, DeleteAuthentikPolicyBindingFinalizer) {
|
||||
t.Fatalf("finalizers = %v, want %q", got.Finalizers, DeleteAuthentikPolicyBindingFinalizer)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_update(t *testing.T) {
|
||||
pb := testPolicyBinding()
|
||||
pb.Status.PK = "42"
|
||||
pb.Finalizers = []string{DeleteAuthentikPolicyBindingFinalizer}
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
policyBindingRetrieve: func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{"pk": "42"})
|
||||
},
|
||||
policyBindingPartialUpdate: func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{"pk": "42"})
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pb, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pb.Namespace, Name: pb.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
|
||||
got := getPolicyBinding(t, ctrl, pb.Namespace, pb.Name)
|
||||
if got.Status.PK != "42" {
|
||||
t.Fatalf("status.pk = %q, want 42", got.Status.PK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_update_policyBindingNotFound(t *testing.T) {
|
||||
pb := testPolicyBinding()
|
||||
pb.Status.PK = "42"
|
||||
pb.Finalizers = []string{DeleteAuthentikPolicyBindingFinalizer}
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
policyBindingRetrieve: func(w http.ResponseWriter, _ *http.Request) {
|
||||
http.NotFound(w, nil)
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pb, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pb.Namespace, Name: pb.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
|
||||
got := getPolicyBinding(t, ctrl, pb.Namespace, pb.Name)
|
||||
if got.Status.PK != "" {
|
||||
t.Fatalf("status.pk = %q, want empty after policy binding not found", got.Status.PK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_delete(t *testing.T) {
|
||||
now := metav1.Now()
|
||||
pb := testPolicyBinding()
|
||||
pb.Status.PK = "42"
|
||||
pb.DeletionTimestamp = &now
|
||||
pb.Finalizers = []string{DeleteAuthentikPolicyBindingFinalizer}
|
||||
|
||||
var destroyCalled bool
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
policyBindingDestroy: func(w http.ResponseWriter, r *http.Request) {
|
||||
destroyCalled = true
|
||||
if r.Method != http.MethodDelete {
|
||||
t.Errorf("destroy method = %s, want DELETE", r.Method)
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pb, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pb.Namespace, Name: pb.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
if !destroyCalled {
|
||||
t.Fatal("expected Authentik destroy call")
|
||||
}
|
||||
|
||||
got := getPolicyBinding(t, ctrl, pb.Namespace, pb.Name)
|
||||
if slices.Contains(got.Finalizers, DeleteAuthentikPolicyBindingFinalizer) {
|
||||
t.Fatalf("finalizers = %v, want finalizer removed", got.Finalizers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_delete_policyBindingAlreadyGone(t *testing.T) {
|
||||
now := metav1.Now()
|
||||
pb := testPolicyBinding()
|
||||
pb.Status.PK = "42"
|
||||
pb.DeletionTimestamp = &now
|
||||
pb.Finalizers = []string{DeleteAuthentikPolicyBindingFinalizer}
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
policyBindingDestroy: func(w http.ResponseWriter, _ *http.Request) {
|
||||
http.NotFound(w, nil)
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pb, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pb.Namespace, Name: pb.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
|
||||
got := getPolicyBinding(t, ctrl, pb.Namespace, pb.Name)
|
||||
if slices.Contains(got.Finalizers, DeleteAuthentikPolicyBindingFinalizer) {
|
||||
t.Fatalf("finalizers = %v, want finalizer removed after 404", got.Finalizers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_notFound(t *testing.T) {
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, nil, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: "default", Name: "missing"})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v, want nil for missing object", err)
|
||||
}
|
||||
}
|
||||
|
||||
// --- test helpers ---
|
||||
|
||||
func testPolicyBinding() *v1alpha1.PolicyBinding {
|
||||
return &v1alpha1.PolicyBinding{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
||||
Kind: "PolicyBinding",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-pb",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v1alpha1.PolicyBindingSpec{
|
||||
Group: "14ab813f-a7f9-481b-9b08-781953ae9ebf",
|
||||
Target: "8dd85627-9c48-49c2-8afc-d73dd122ffc2",
|
||||
Order: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newTestController(t *testing.T, pb *v1alpha1.PolicyBinding, authentikURL string) (*PolicyBindingController, context.Context, context.CancelFunc) {
|
||||
t.Helper()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctrl, _, stop := newTestControllerWithContext(t, ctx, pb, authentikURL)
|
||||
return ctrl, ctx, func() {
|
||||
cancel()
|
||||
stop()
|
||||
}
|
||||
}
|
||||
|
||||
func newTestControllerWithContext(t *testing.T, ctx context.Context, pb *v1alpha1.PolicyBinding, authentikURL string) (*PolicyBindingController, context.Context, func()) {
|
||||
t.Helper()
|
||||
|
||||
authentikClient := newAuthentikAPIClientForTest(t, authentikURL)
|
||||
|
||||
var objects []runtime.Object
|
||||
if pb != nil {
|
||||
objects = append(objects, pb)
|
||||
}
|
||||
policyBindingClient := operatorfake.NewSimpleClientset(objects...)
|
||||
|
||||
informerFactory := operatorinformers.NewSharedInformerFactory(policyBindingClient, 0)
|
||||
policyBindingInformer := informerFactory.PolicyBinding().V1alpha1().PolicyBindings()
|
||||
|
||||
ctrl := NewController(ctx, fake.NewClientset(), policyBindingClient, authentikClient, policyBindingInformer)
|
||||
|
||||
informerFactory.Start(ctx.Done())
|
||||
for informerType, synced := range informerFactory.WaitForCacheSync(ctx.Done()) {
|
||||
if !synced {
|
||||
t.Fatalf("informer %v failed to sync", informerType)
|
||||
}
|
||||
}
|
||||
|
||||
return ctrl, ctx, func() {}
|
||||
}
|
||||
|
||||
func newAuthentikAPIClientForTest(t *testing.T, serverURL string) *authentikapi.APIClient {
|
||||
t.Helper()
|
||||
|
||||
u, err := url.Parse(serverURL)
|
||||
if err != nil {
|
||||
t.Fatalf("parse server URL: %v", err)
|
||||
}
|
||||
|
||||
cfg := authentikapi.NewConfiguration()
|
||||
cfg.Scheme = u.Scheme
|
||||
cfg.Host = u.Host
|
||||
|
||||
return authentikapi.NewAPIClient(cfg)
|
||||
}
|
||||
|
||||
type authentikTestHandlers struct {
|
||||
policyBindingCreate http.HandlerFunc
|
||||
policyBindingRetrieve http.HandlerFunc
|
||||
policyBindingPartialUpdate http.HandlerFunc
|
||||
policyBindingDestroy http.HandlerFunc
|
||||
}
|
||||
|
||||
func newAuthentikTestServer(t *testing.T, handlers authentikTestHandlers) *httptest.Server {
|
||||
t.Helper()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.URL.Path
|
||||
|
||||
switch {
|
||||
case path == "/api/v3/policies/bindings/" && r.Method == http.MethodPost:
|
||||
if handlers.policyBindingCreate != nil {
|
||||
handlers.policyBindingCreate(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
|
||||
case strings.HasPrefix(path, "/api/v3/policies/bindings/") && strings.HasSuffix(path, "/"):
|
||||
idPath := strings.TrimPrefix(path, "/api/v3/policies/bindings/")
|
||||
if idPath == "" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
if handlers.policyBindingRetrieve != nil {
|
||||
handlers.policyBindingRetrieve(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
case http.MethodPatch:
|
||||
if handlers.policyBindingPartialUpdate != nil {
|
||||
handlers.policyBindingPartialUpdate(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
case http.MethodDelete:
|
||||
if handlers.policyBindingDestroy != nil {
|
||||
handlers.policyBindingDestroy(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
default:
|
||||
http.Error(w, "unexpected method on policy binding instance", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
|
||||
return httptest.NewServer(handler)
|
||||
}
|
||||
|
||||
func writeJSON(t *testing.T, w http.ResponseWriter, status int, body any) {
|
||||
t.Helper()
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
if err := json.NewEncoder(w).Encode(body); err != nil {
|
||||
t.Fatalf("write JSON response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func getPolicyBinding(t *testing.T, ctrl *PolicyBindingController, namespace, name string) *v1alpha1.PolicyBinding {
|
||||
t.Helper()
|
||||
|
||||
got, err := ctrl.policyBindingClientset.PolicyBindingV1alpha1().PolicyBindings(namespace).Get(
|
||||
context.Background(), name, metav1.GetOptions{},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("get PolicyBinding: %v", err)
|
||||
}
|
||||
return got
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package proxyprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"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"
|
||||
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"
|
||||
listers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/listers/proxyprovider/v1alpha1"
|
||||
authentikapi "goauthentik.io/api/v3"
|
||||
)
|
||||
|
||||
const controllerAgentName = "proxy-provider-controller"
|
||||
|
||||
const (
|
||||
SuccessSynced = "Synced"
|
||||
ErrResourceExists = "ErrResourceExists"
|
||||
MessageResourceExists = "Resource %q already exists and is not managed by ProxyProvider"
|
||||
MessageResourceSynced = "ProxyProvider synced successfully"
|
||||
FieldManager = controllerAgentName
|
||||
)
|
||||
|
||||
// Finalizers
|
||||
const (
|
||||
DeleteAuthentikProxyProviderFinalizer = "proxyprovider.t000-n.de/delete-authentik-proxyprovider"
|
||||
)
|
||||
|
||||
type ProxyProviderController struct {
|
||||
kubeclientset kubernetes.Interface
|
||||
proxyProviderClientset clientset.Interface
|
||||
authentik *authentikapi.APIClient
|
||||
|
||||
proxyLister listers.ProxyProviderLister
|
||||
|
||||
controller *baseController.Controller
|
||||
}
|
||||
|
||||
func NewController(
|
||||
ctx context.Context,
|
||||
kubeclientset kubernetes.Interface,
|
||||
proxyProviderClientset clientset.Interface,
|
||||
authentik *authentikapi.APIClient,
|
||||
proxyInformer informers.ProxyProviderInformer,
|
||||
) *ProxyProviderController {
|
||||
logger := klog.FromContext(ctx)
|
||||
|
||||
utilruntime.Must(operatorscheme.AddToScheme(scheme.Scheme))
|
||||
logger.V(4).Info("Creating event broadcaster")
|
||||
|
||||
eventBroadcaster := record.NewBroadcaster(record.WithContext(ctx))
|
||||
eventBroadcaster.StartStructuredLogging(0)
|
||||
eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeclientset.CoreV1().Events("")})
|
||||
recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName})
|
||||
ratelimiter := workqueue.NewTypedMaxOfRateLimiter(
|
||||
workqueue.NewTypedItemExponentialFailureRateLimiter[cache.ObjectName](5*time.Millisecond, 1000*time.Second),
|
||||
&workqueue.TypedBucketRateLimiter[cache.ObjectName]{Limiter: rate.NewLimiter(rate.Limit(50), 300)},
|
||||
)
|
||||
|
||||
c := &ProxyProviderController{
|
||||
kubeclientset: kubeclientset,
|
||||
proxyProviderClientset: proxyProviderClientset,
|
||||
authentik: authentik,
|
||||
proxyLister: proxyInformer.Lister(),
|
||||
}
|
||||
c.controller = baseController.NewController(
|
||||
ctx,
|
||||
workqueue.NewTypedRateLimitingQueue(ratelimiter),
|
||||
recorder,
|
||||
proxyInformer.Informer().HasSynced,
|
||||
c.syncHandler,
|
||||
)
|
||||
|
||||
logger.Info("Setting up event handlers")
|
||||
proxyInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: c.controller.Enqueue,
|
||||
UpdateFunc: func(_, newObj interface{}) {
|
||||
c.controller.Enqueue(newObj)
|
||||
},
|
||||
})
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *ProxyProviderController) Run(ctx context.Context, workers int) error {
|
||||
return c.controller.Run(ctx, workers)
|
||||
}
|
||||
|
||||
func (c *ProxyProviderController) syncHandler(ctx context.Context, objectRef cache.ObjectName) error {
|
||||
logger := klog.LoggerWithValues(klog.FromContext(ctx), "objectRef", objectRef)
|
||||
|
||||
pp, err := c.proxyLister.ProxyProviders(objectRef.Namespace).Get(objectRef.Name)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
logger.V(4).Info("ProxyProvider no longer exists")
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
logger.V(4).Info("sync ProxyProvider", "name", pp.Name)
|
||||
|
||||
if !pp.ObjectMeta.DeletionTimestamp.IsZero() {
|
||||
logger.Info("Reconciling deletion of ProxyProvider", "name", pp.Name)
|
||||
return c.reconcileDelete(ctx, pp)
|
||||
}
|
||||
|
||||
if pp.Status.PK == "" {
|
||||
logger.Info("Reconciling creation of ProxyProvider", "name", pp.Name)
|
||||
return c.reconcileCreate(ctx, pp)
|
||||
}
|
||||
|
||||
// Check if all finalizers are present. If not, we add them. Same pattern as above, just needs a helper function to check for presence of a finalizer.
|
||||
if !slices.Contains(pp.ObjectMeta.Finalizers, DeleteAuthentikProxyProviderFinalizer) {
|
||||
logger.Info("Ensuring finalizers are present", "name", pp.Name)
|
||||
return c.ensureFinalizers(ctx, pp)
|
||||
}
|
||||
|
||||
logger.Info("Reconciling update of ProxyProvider", "name", pp.Name)
|
||||
return c.reconcileUpdate(ctx, pp)
|
||||
}
|
||||
|
||||
func (c *ProxyProviderController) ensureFinalizers(ctx context.Context, pp *v1alpha1.ProxyProvider) error {
|
||||
pp.ObjectMeta.Finalizers = append(pp.ObjectMeta.Finalizers, DeleteAuthentikProxyProviderFinalizer)
|
||||
return c.updateProxyProvider(ctx, pp)
|
||||
}
|
||||
|
||||
func (c *ProxyProviderController) reconcileDelete(ctx context.Context, pp *v1alpha1.ProxyProvider) error {
|
||||
pk, err := strconv.ParseInt(pp.Status.PK, 10, 32)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing PK: %v", err)
|
||||
}
|
||||
|
||||
err = c.reconcileOutpost(ctx, pp.Spec.Outpost, int32(pk), ReconcileOutpostModeRemove)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when calling `reconcileOutpost`: %w", err)
|
||||
}
|
||||
|
||||
// Delete ProxyProvider
|
||||
r, err := c.authentik.ProvidersApi.ProvidersProxyDestroy(ctx, int32(pk)).Execute()
|
||||
if err != nil {
|
||||
// This handles an edge-case, where when the ProxyProvider 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 {
|
||||
return fmt.Errorf("error when calling `ProvidersAPI.ProvidersProxyDestroy`: %w with response %v", err, r)
|
||||
}
|
||||
}
|
||||
|
||||
pp.ObjectMeta.Finalizers = slices.Delete(pp.ObjectMeta.Finalizers, slices.Index(pp.ObjectMeta.Finalizers, DeleteAuthentikProxyProviderFinalizer), 1)
|
||||
return c.updateProxyProvider(ctx, pp)
|
||||
}
|
||||
|
||||
func (c *ProxyProviderController) reconcileUpdate(ctx context.Context, pp *v1alpha1.ProxyProvider) error {
|
||||
// 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)
|
||||
}
|
||||
_, r, err := c.authentik.ProvidersApi.ProvidersAllRetrieve(ctx, int32(pk)).Execute()
|
||||
if err != nil {
|
||||
if r != nil && r.StatusCode == http.StatusNotFound {
|
||||
// This handles an edge-case, where when the PorxyProvider on Authentik has been deleted, e.g. by mistake. We just remove the PK and return.
|
||||
// During the next reconciliation, the ProxyProvider will be re-created.
|
||||
pp.Status.PK = ""
|
||||
return c.updateProxyProviderStatus(ctx, pp)
|
||||
}
|
||||
return fmt.Errorf("error retrieving existing ProxyProvider: %v with response %v", err, r)
|
||||
}
|
||||
|
||||
proxyProviderRequest := &authentikapi.PatchedProxyProviderRequest{
|
||||
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.ProvidersProxyPartialUpdate(ctx, int32(pk)).PatchedProxyProviderRequest(*proxyProviderRequest).Execute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when calling `ProvidersAPI.ProvidersProxyPartialUpdate`: %w with response %v", err, r)
|
||||
}
|
||||
pp.Status.PK = strconv.Itoa(int(resp.Pk))
|
||||
|
||||
err = c.reconcileOutpost(ctx, pp.Spec.Outpost, int32(pk), ReconcileOutpostModeAdd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when calling `reconcileOutpost`: %w", err)
|
||||
}
|
||||
|
||||
return c.updateProxyProviderStatus(ctx, pp)
|
||||
}
|
||||
|
||||
func (c *ProxyProviderController) reconcileCreate(ctx context.Context, pp *v1alpha1.ProxyProvider) error {
|
||||
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)
|
||||
}
|
||||
|
||||
err = c.reconcileOutpost(ctx, pp.Spec.Outpost, resp.Pk, ReconcileOutpostModeAdd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when calling `reconcileOutpost`: %w", err)
|
||||
}
|
||||
|
||||
pp.Status.PK = strconv.Itoa(int(resp.Pk))
|
||||
return c.updateProxyProviderStatus(ctx, pp)
|
||||
}
|
||||
|
||||
func (c *ProxyProviderController) updateProxyProviderStatus(ctx context.Context, pp *v1alpha1.ProxyProvider) error {
|
||||
ppCopy := pp.DeepCopy()
|
||||
_, err := c.proxyProviderClientset.ProxyproviderV1alpha1().ProxyProviders(ppCopy.Namespace).UpdateStatus(ctx, ppCopy, metav1.UpdateOptions{FieldManager: FieldManager})
|
||||
return err
|
||||
}
|
||||
|
||||
// Update metadata, spec, etc. of the ProxyProvider object.
|
||||
func (c *ProxyProviderController) updateProxyProvider(ctx context.Context, pp *v1alpha1.ProxyProvider) error {
|
||||
ppCopy := pp.DeepCopy()
|
||||
_, err := c.proxyProviderClientset.ProxyproviderV1alpha1().ProxyProviders(ppCopy.Namespace).Update(ctx, ppCopy, metav1.UpdateOptions{FieldManager: FieldManager})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error updating ProxyProvider metadata: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ReconcileOutpostMode string
|
||||
|
||||
const (
|
||||
ReconcileOutpostModeAdd ReconcileOutpostMode = "add"
|
||||
ReconcileOutpostModeRemove ReconcileOutpostMode = "remove"
|
||||
)
|
||||
|
||||
func (c *ProxyProviderController) reconcileOutpost(ctx context.Context, outpostId string, providerPk int32, mode ReconcileOutpostMode) error {
|
||||
logger := klog.LoggerWithValues(klog.FromContext(ctx), "outpostId", outpostId, "providerPk", providerPk, "mode", mode)
|
||||
|
||||
outpost, r, err := c.authentik.OutpostsApi.OutpostsInstancesRetrieve(ctx, outpostId).Execute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when calling `OutpostsAPI.OutpostsInstancesRetrieve`: %w with response %v", err, r)
|
||||
}
|
||||
updated := false
|
||||
|
||||
switch mode {
|
||||
case ReconcileOutpostModeAdd:
|
||||
if !slices.Contains(outpost.Providers, providerPk) {
|
||||
outpost.Providers = append(outpost.Providers, providerPk)
|
||||
updated = true
|
||||
} else {
|
||||
logger.V(4).Info("Provider already in outpost")
|
||||
}
|
||||
case ReconcileOutpostModeRemove:
|
||||
if slices.Contains(outpost.Providers, providerPk) {
|
||||
outpost.Providers = slices.Delete(outpost.Providers, slices.Index(outpost.Providers, providerPk), 1)
|
||||
updated = true
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid mode: %s", mode)
|
||||
}
|
||||
|
||||
if !updated {
|
||||
return nil
|
||||
}
|
||||
|
||||
outpostPartialUpdateRequest := &authentikapi.PatchedOutpostRequest{
|
||||
Providers: outpost.Providers,
|
||||
}
|
||||
_, r, err = c.authentik.OutpostsApi.OutpostsInstancesPartialUpdate(ctx, outpostId).PatchedOutpostRequest(*outpostPartialUpdateRequest).Execute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when calling `OutpostsAPI.OutpostsInstancesPartialUpdate`: %w with response %v", err, r)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,547 @@
|
||||
// AI generated tests and not yet reviewed.
|
||||
package proxyprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
||||
operatorfake "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/fake"
|
||||
operatorinformers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions"
|
||||
authentikapi "goauthentik.io/api/v3"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
const testOutpostID = "550e8400-e29b-41d4-a716-446655440000"
|
||||
|
||||
func TestController_syncHandler_create(t *testing.T) {
|
||||
const wantPK = 42
|
||||
|
||||
var outpostPartialUpdateCalled bool
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
proxyCreate: func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusCreated, map[string]any{"pk": wantPK})
|
||||
},
|
||||
outpostRetrieve: outpostRetrieveHandler(t, nil),
|
||||
outpostPartialUpdate: func(w http.ResponseWriter, r *http.Request) {
|
||||
outpostPartialUpdateCalled = true
|
||||
var body struct {
|
||||
Providers []int32 `json:"providers"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
t.Fatalf("decode outpost patch body: %v", err)
|
||||
}
|
||||
if !slices.Contains(body.Providers, wantPK) {
|
||||
t.Fatalf("patched providers = %v, want to contain %d", body.Providers, wantPK)
|
||||
}
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{"pk": testOutpostID, "providers": body.Providers})
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, testProxyProvider(), server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: "default", Name: "test-pp"})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
if !outpostPartialUpdateCalled {
|
||||
t.Fatal("expected Authentik outpost partial update call")
|
||||
}
|
||||
|
||||
got := getProxyProvider(t, ctrl, "default", "test-pp")
|
||||
if got.Status.PK != "42" {
|
||||
t.Fatalf("status.pk = %q, want 42", got.Status.PK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_create_providerAlreadyInOutpost(t *testing.T) {
|
||||
const wantPK = 42
|
||||
|
||||
var outpostPartialUpdateCalled bool
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
proxyCreate: func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusCreated, map[string]any{"pk": wantPK})
|
||||
},
|
||||
outpostRetrieve: outpostRetrieveHandler(t, []int32{wantPK}),
|
||||
outpostPartialUpdate: func(w http.ResponseWriter, _ *http.Request) {
|
||||
outpostPartialUpdateCalled = true
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, testProxyProvider(), server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: "default", Name: "test-pp"})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
if outpostPartialUpdateCalled {
|
||||
t.Fatal("did not expect Authentik outpost partial update when provider is already present")
|
||||
}
|
||||
|
||||
got := getProxyProvider(t, ctrl, "default", "test-pp")
|
||||
if got.Status.PK != "42" {
|
||||
t.Fatalf("status.pk = %q, want 42", got.Status.PK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_ensureFinalizers(t *testing.T) {
|
||||
pp := testProxyProvider()
|
||||
pp.Status.PK = "42"
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
|
||||
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
||||
if !slices.Contains(got.Finalizers, DeleteAuthentikProxyProviderFinalizer) {
|
||||
t.Fatalf("finalizers = %v, want %q", got.Finalizers, DeleteAuthentikProxyProviderFinalizer)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_update(t *testing.T) {
|
||||
pp := testProxyProvider()
|
||||
pp.Status.PK = "42"
|
||||
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
||||
|
||||
var outpostPartialUpdateCalled bool
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
allRetrieve: func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{"pk": 42})
|
||||
},
|
||||
proxyPartialUpdate: func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{"pk": 42})
|
||||
},
|
||||
outpostRetrieve: outpostRetrieveHandler(t, nil),
|
||||
outpostPartialUpdate: func(w http.ResponseWriter, r *http.Request) {
|
||||
outpostPartialUpdateCalled = true
|
||||
var body struct {
|
||||
Providers []int32 `json:"providers"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
t.Fatalf("decode outpost patch body: %v", err)
|
||||
}
|
||||
if !slices.Contains(body.Providers, 42) {
|
||||
t.Fatalf("patched providers = %v, want to contain 42", body.Providers)
|
||||
}
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{"pk": testOutpostID, "providers": body.Providers})
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
if !outpostPartialUpdateCalled {
|
||||
t.Fatal("expected Authentik outpost partial update call")
|
||||
}
|
||||
|
||||
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
||||
if got.Status.PK != "42" {
|
||||
t.Fatalf("status.pk = %q, want 42", got.Status.PK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_update_providerNotFound(t *testing.T) {
|
||||
pp := testProxyProvider()
|
||||
pp.Status.PK = "42"
|
||||
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
allRetrieve: func(w http.ResponseWriter, _ *http.Request) {
|
||||
http.NotFound(w, nil)
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
|
||||
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
||||
if got.Status.PK != "" {
|
||||
t.Fatalf("status.pk = %q, want empty after provider not found", got.Status.PK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_delete(t *testing.T) {
|
||||
const wantPK int32 = 42
|
||||
now := metav1.Now()
|
||||
pp := testProxyProvider()
|
||||
pp.Status.PK = "42"
|
||||
pp.DeletionTimestamp = &now
|
||||
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
||||
|
||||
var outpostPartialUpdateCalled, destroyCalled bool
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
outpostRetrieve: outpostRetrieveHandler(t, []int32{wantPK}),
|
||||
outpostPartialUpdate: func(w http.ResponseWriter, r *http.Request) {
|
||||
outpostPartialUpdateCalled = true
|
||||
var body struct {
|
||||
Providers []int32 `json:"providers"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
t.Fatalf("decode outpost patch body: %v", err)
|
||||
}
|
||||
if slices.Contains(body.Providers, wantPK) {
|
||||
t.Fatalf("patched providers = %v, want provider %d removed", body.Providers, wantPK)
|
||||
}
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{"pk": testOutpostID, "providers": body.Providers})
|
||||
},
|
||||
proxyDestroy: func(w http.ResponseWriter, r *http.Request) {
|
||||
destroyCalled = true
|
||||
if r.Method != http.MethodDelete {
|
||||
t.Errorf("destroy method = %s, want DELETE", r.Method)
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
if !outpostPartialUpdateCalled {
|
||||
t.Fatal("expected Authentik outpost partial update call")
|
||||
}
|
||||
if !destroyCalled {
|
||||
t.Fatal("expected Authentik destroy call")
|
||||
}
|
||||
|
||||
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
||||
if slices.Contains(got.Finalizers, DeleteAuthentikProxyProviderFinalizer) {
|
||||
t.Fatalf("finalizers = %v, want finalizer removed", got.Finalizers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_delete_providerNotInOutpost(t *testing.T) {
|
||||
now := metav1.Now()
|
||||
pp := testProxyProvider()
|
||||
pp.Status.PK = "42"
|
||||
pp.DeletionTimestamp = &now
|
||||
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
||||
|
||||
var outpostPartialUpdateCalled, destroyCalled bool
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
outpostRetrieve: outpostRetrieveHandler(t, nil),
|
||||
outpostPartialUpdate: func(w http.ResponseWriter, _ *http.Request) {
|
||||
outpostPartialUpdateCalled = true
|
||||
},
|
||||
proxyDestroy: func(w http.ResponseWriter, _ *http.Request) {
|
||||
destroyCalled = true
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
if outpostPartialUpdateCalled {
|
||||
t.Fatal("did not expect Authentik outpost partial update when provider is not in outpost")
|
||||
}
|
||||
if !destroyCalled {
|
||||
t.Fatal("expected Authentik destroy call")
|
||||
}
|
||||
|
||||
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
||||
if slices.Contains(got.Finalizers, DeleteAuthentikProxyProviderFinalizer) {
|
||||
t.Fatalf("finalizers = %v, want finalizer removed", got.Finalizers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_delete_providerAlreadyGone(t *testing.T) {
|
||||
const wantPK int32 = 42
|
||||
now := metav1.Now()
|
||||
pp := testProxyProvider()
|
||||
pp.Status.PK = "42"
|
||||
pp.DeletionTimestamp = &now
|
||||
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{
|
||||
outpostRetrieve: outpostRetrieveHandler(t, []int32{wantPK}),
|
||||
outpostPartialUpdate: func(w http.ResponseWriter, r *http.Request) {
|
||||
var body struct {
|
||||
Providers []int32 `json:"providers"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
t.Fatalf("decode outpost patch body: %v", err)
|
||||
}
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{"pk": testOutpostID, "providers": body.Providers})
|
||||
},
|
||||
proxyDestroy: func(w http.ResponseWriter, _ *http.Request) {
|
||||
http.NotFound(w, nil)
|
||||
},
|
||||
})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v", err)
|
||||
}
|
||||
|
||||
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
||||
if slices.Contains(got.Finalizers, DeleteAuthentikProxyProviderFinalizer) {
|
||||
t.Fatalf("finalizers = %v, want finalizer removed after 404", got.Finalizers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_notFound(t *testing.T) {
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, nil, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: "default", Name: "missing"})
|
||||
if err != nil {
|
||||
t.Fatalf("syncHandler() error = %v, want nil for missing object", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_syncHandler_invalidPK(t *testing.T) {
|
||||
pp := testProxyProvider()
|
||||
pp.Status.PK = "not-a-number"
|
||||
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
||||
|
||||
server := newAuthentikTestServer(t, authentikTestHandlers{})
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
||||
if err == nil {
|
||||
t.Fatal("syncHandler() error = nil, want parse error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "error parsing PK") {
|
||||
t.Fatalf("syncHandler() error = %v, want PK parse error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// --- test helpers ---
|
||||
|
||||
func testProxyProvider() *v1alpha1.ProxyProvider {
|
||||
return &v1alpha1.ProxyProvider{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
||||
Kind: "ProxyProvider",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-pp",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v1alpha1.ProxyProviderSpec{
|
||||
Name: "my-app",
|
||||
AuthorizationFlow: "flow-auth",
|
||||
InvalidationFlow: "flow-invalidate",
|
||||
ExternalHost: "https://app.example.com",
|
||||
Outpost: testOutpostID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newTestController(t *testing.T, pp *v1alpha1.ProxyProvider, authentikURL string) (*ProxyProviderController, context.Context, context.CancelFunc) {
|
||||
t.Helper()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctrl, _, stop := newTestControllerWithContext(t, ctx, pp, authentikURL)
|
||||
return ctrl, ctx, func() {
|
||||
cancel()
|
||||
stop()
|
||||
}
|
||||
}
|
||||
|
||||
func newTestControllerWithContext(t *testing.T, ctx context.Context, pp *v1alpha1.ProxyProvider, authentikURL string) (*ProxyProviderController, context.Context, func()) {
|
||||
t.Helper()
|
||||
|
||||
authentikClient := newAuthentikAPIClientForTest(t, authentikURL)
|
||||
|
||||
var objects []runtime.Object
|
||||
if pp != nil {
|
||||
objects = append(objects, pp)
|
||||
}
|
||||
proxyClient := operatorfake.NewSimpleClientset(objects...)
|
||||
|
||||
informerFactory := operatorinformers.NewSharedInformerFactory(proxyClient, 0)
|
||||
proxyInformer := informerFactory.Proxyprovider().V1alpha1().ProxyProviders()
|
||||
|
||||
ctrl := NewController(ctx, fake.NewClientset(), proxyClient, authentikClient, proxyInformer)
|
||||
|
||||
informerFactory.Start(ctx.Done())
|
||||
for informerType, synced := range informerFactory.WaitForCacheSync(ctx.Done()) {
|
||||
if !synced {
|
||||
t.Fatalf("informer %v failed to sync", informerType)
|
||||
}
|
||||
}
|
||||
|
||||
return ctrl, ctx, func() {}
|
||||
}
|
||||
|
||||
func newAuthentikAPIClientForTest(t *testing.T, serverURL string) *authentikapi.APIClient {
|
||||
t.Helper()
|
||||
|
||||
u, err := url.Parse(serverURL)
|
||||
if err != nil {
|
||||
t.Fatalf("parse server URL: %v", err)
|
||||
}
|
||||
|
||||
cfg := authentikapi.NewConfiguration()
|
||||
cfg.Scheme = u.Scheme
|
||||
cfg.Host = u.Host
|
||||
|
||||
return authentikapi.NewAPIClient(cfg)
|
||||
}
|
||||
|
||||
type authentikTestHandlers struct {
|
||||
proxyCreate http.HandlerFunc
|
||||
proxyDestroy http.HandlerFunc
|
||||
proxyPartialUpdate http.HandlerFunc
|
||||
allRetrieve http.HandlerFunc
|
||||
outpostRetrieve http.HandlerFunc
|
||||
outpostPartialUpdate http.HandlerFunc
|
||||
}
|
||||
|
||||
func outpostRetrieveHandler(t *testing.T, providers []int32) http.HandlerFunc {
|
||||
t.Helper()
|
||||
return func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]any{
|
||||
"pk": testOutpostID,
|
||||
"providers": providers,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newAuthentikTestServer(t *testing.T, handlers authentikTestHandlers) *httptest.Server {
|
||||
t.Helper()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.URL.Path
|
||||
|
||||
switch {
|
||||
case path == "/api/v3/providers/proxy/" && r.Method == http.MethodPost:
|
||||
if handlers.proxyCreate != nil {
|
||||
handlers.proxyCreate(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
|
||||
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
|
||||
}
|
||||
switch r.Method {
|
||||
case http.MethodDelete:
|
||||
if handlers.proxyDestroy != nil {
|
||||
handlers.proxyDestroy(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
case http.MethodPatch:
|
||||
if handlers.proxyPartialUpdate != nil {
|
||||
handlers.proxyPartialUpdate(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
default:
|
||||
http.Error(w, "unexpected method on proxy instance", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
case strings.HasPrefix(path, "/api/v3/providers/all/") && strings.HasSuffix(path, "/"):
|
||||
if r.Method == http.MethodGet && handlers.allRetrieve != nil {
|
||||
handlers.allRetrieve(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
|
||||
case strings.HasPrefix(path, "/api/v3/outposts/instances/") && strings.HasSuffix(path, "/"):
|
||||
idPath := strings.TrimPrefix(path, "/api/v3/outposts/instances/")
|
||||
idPath = strings.TrimSuffix(idPath, "/")
|
||||
if idPath == "" || strings.Contains(idPath, "/") {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
if handlers.outpostRetrieve != nil {
|
||||
handlers.outpostRetrieve(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
case http.MethodPatch:
|
||||
if handlers.outpostPartialUpdate != nil {
|
||||
handlers.outpostPartialUpdate(w, r)
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
default:
|
||||
http.Error(w, "unexpected method on outpost instance", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
|
||||
return httptest.NewServer(handler)
|
||||
}
|
||||
|
||||
func writeJSON(t *testing.T, w http.ResponseWriter, status int, body any) {
|
||||
t.Helper()
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
if err := json.NewEncoder(w).Encode(body); err != nil {
|
||||
t.Fatalf("write JSON response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func getProxyProvider(t *testing.T, ctrl *ProxyProviderController, namespace, name string) *v1alpha1.ProxyProvider {
|
||||
t.Helper()
|
||||
|
||||
got, err := ctrl.proxyProviderClientset.ProxyproviderV1alpha1().ProxyProviders(namespace).Get(
|
||||
context.Background(), name, metav1.GetOptions{},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("get ProxyProvider: %v", err)
|
||||
}
|
||||
return got
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
)
|
||||
|
||||
// ApplicationApplyConfiguration represents a declarative configuration of the Application type for use
|
||||
// with apply.
|
||||
type ApplicationApplyConfiguration struct {
|
||||
v1.TypeMetaApplyConfiguration `json:""`
|
||||
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
|
||||
Spec *ApplicationSpecApplyConfiguration `json:"spec,omitempty"`
|
||||
Status *ApplicationStatusApplyConfiguration `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Application constructs a declarative configuration of the Application type for use with
|
||||
// apply.
|
||||
func Application(name, namespace string) *ApplicationApplyConfiguration {
|
||||
b := &ApplicationApplyConfiguration{}
|
||||
b.WithName(name)
|
||||
b.WithNamespace(namespace)
|
||||
b.WithKind("Application")
|
||||
b.WithAPIVersion("application.t000-n.de/v1alpha1")
|
||||
return b
|
||||
}
|
||||
|
||||
func (b ApplicationApplyConfiguration) IsApplyConfiguration() {}
|
||||
|
||||
// WithKind sets the Kind field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Kind field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithKind(value string) *ApplicationApplyConfiguration {
|
||||
b.TypeMetaApplyConfiguration.Kind = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the APIVersion field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithAPIVersion(value string) *ApplicationApplyConfiguration {
|
||||
b.TypeMetaApplyConfiguration.APIVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithName sets the Name field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Name field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithName(value string) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Name = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGenerateName sets the GenerateName field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the GenerateName field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithGenerateName(value string) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.GenerateName = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithNamespace sets the Namespace field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Namespace field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithNamespace(value string) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Namespace = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUID sets the UID field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the UID field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithUID(value types.UID) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.UID = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the ResourceVersion field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithResourceVersion(value string) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.ResourceVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGeneration sets the Generation field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Generation field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithGeneration(value int64) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Generation = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the CreationTimestamp field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the DeletionTimestamp field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithLabels puts the entries into the Labels field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, the entries provided by each call will be put on the Labels field,
|
||||
// overwriting an existing map entries in Labels field with the same key.
|
||||
func (b *ApplicationApplyConfiguration) WithLabels(entries map[string]string) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
|
||||
b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.ObjectMetaApplyConfiguration.Labels[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAnnotations puts the entries into the Annotations field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, the entries provided by each call will be put on the Annotations field,
|
||||
// overwriting an existing map entries in Annotations field with the same key.
|
||||
func (b *ApplicationApplyConfiguration) WithAnnotations(entries map[string]string) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
|
||||
b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.ObjectMetaApplyConfiguration.Annotations[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the OwnerReferences field.
|
||||
func (b *ApplicationApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
if values[i] == nil {
|
||||
panic("nil value passed to WithOwnerReferences")
|
||||
}
|
||||
b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithFinalizers adds the given value to the Finalizers field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the Finalizers field.
|
||||
func (b *ApplicationApplyConfiguration) WithFinalizers(values ...string) *ApplicationApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *ApplicationApplyConfiguration) ensureObjectMetaApplyConfigurationExists() {
|
||||
if b.ObjectMetaApplyConfiguration == nil {
|
||||
b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{}
|
||||
}
|
||||
}
|
||||
|
||||
// WithSpec sets the Spec field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Spec field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithSpec(value *ApplicationSpecApplyConfiguration) *ApplicationApplyConfiguration {
|
||||
b.Spec = value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithStatus sets the Status field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Status field is set to the value of the last call.
|
||||
func (b *ApplicationApplyConfiguration) WithStatus(value *ApplicationStatusApplyConfiguration) *ApplicationApplyConfiguration {
|
||||
b.Status = value
|
||||
return b
|
||||
}
|
||||
|
||||
// GetKind retrieves the value of the Kind field in the declarative configuration.
|
||||
func (b *ApplicationApplyConfiguration) GetKind() *string {
|
||||
return b.TypeMetaApplyConfiguration.Kind
|
||||
}
|
||||
|
||||
// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
|
||||
func (b *ApplicationApplyConfiguration) GetAPIVersion() *string {
|
||||
return b.TypeMetaApplyConfiguration.APIVersion
|
||||
}
|
||||
|
||||
// GetName retrieves the value of the Name field in the declarative configuration.
|
||||
func (b *ApplicationApplyConfiguration) GetName() *string {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
return b.ObjectMetaApplyConfiguration.Name
|
||||
}
|
||||
|
||||
// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
|
||||
func (b *ApplicationApplyConfiguration) GetNamespace() *string {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
return b.ObjectMetaApplyConfiguration.Namespace
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// ApplicationSpecApplyConfiguration represents a declarative configuration of the ApplicationSpec type for use
|
||||
// with apply.
|
||||
type ApplicationSpecApplyConfiguration struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Slug *string `json:"slug,omitempty"`
|
||||
Provider *int32 `json:"provider,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationSpecApplyConfiguration constructs a declarative configuration of the ApplicationSpec type for use with
|
||||
// apply.
|
||||
func ApplicationSpec() *ApplicationSpecApplyConfiguration {
|
||||
return &ApplicationSpecApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithName sets the Name field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Name field is set to the value of the last call.
|
||||
func (b *ApplicationSpecApplyConfiguration) WithName(value string) *ApplicationSpecApplyConfiguration {
|
||||
b.Name = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithSlug sets the Slug field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Slug field is set to the value of the last call.
|
||||
func (b *ApplicationSpecApplyConfiguration) WithSlug(value string) *ApplicationSpecApplyConfiguration {
|
||||
b.Slug = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithProvider sets the Provider field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Provider field is set to the value of the last call.
|
||||
func (b *ApplicationSpecApplyConfiguration) WithProvider(value int32) *ApplicationSpecApplyConfiguration {
|
||||
b.Provider = &value
|
||||
return b
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// ApplicationStatusApplyConfiguration represents a declarative configuration of the ApplicationStatus type for use
|
||||
// with apply.
|
||||
type ApplicationStatusApplyConfiguration struct {
|
||||
PK *string `json:"pk,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationStatusApplyConfiguration constructs a declarative configuration of the ApplicationStatus type for use with
|
||||
// apply.
|
||||
func ApplicationStatus() *ApplicationStatusApplyConfiguration {
|
||||
return &ApplicationStatusApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithPK sets the PK field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the PK field is set to the value of the last call.
|
||||
func (b *ApplicationStatusApplyConfiguration) WithPK(value string) *ApplicationStatusApplyConfiguration {
|
||||
b.PK = &value
|
||||
return b
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
sync "sync"
|
||||
|
||||
typed "sigs.k8s.io/structured-merge-diff/v6/typed"
|
||||
)
|
||||
|
||||
func Parser() *typed.Parser {
|
||||
parserOnce.Do(func() {
|
||||
var err error
|
||||
parser, err = typed.NewParser(schemaYAML)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to parse schema: %v", err))
|
||||
}
|
||||
})
|
||||
return parser
|
||||
}
|
||||
|
||||
var parserOnce sync.Once
|
||||
var parser *typed.Parser
|
||||
var schemaYAML = typed.YAMLObject(`types:
|
||||
- name: __untyped_atomic_
|
||||
scalar: untyped
|
||||
list:
|
||||
elementType:
|
||||
namedType: __untyped_atomic_
|
||||
elementRelationship: atomic
|
||||
map:
|
||||
elementType:
|
||||
namedType: __untyped_atomic_
|
||||
elementRelationship: atomic
|
||||
- name: __untyped_deduced_
|
||||
scalar: untyped
|
||||
list:
|
||||
elementType:
|
||||
namedType: __untyped_atomic_
|
||||
elementRelationship: atomic
|
||||
map:
|
||||
elementType:
|
||||
namedType: __untyped_deduced_
|
||||
elementRelationship: separable
|
||||
`)
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
)
|
||||
|
||||
// PolicyBindingApplyConfiguration represents a declarative configuration of the PolicyBinding type for use
|
||||
// with apply.
|
||||
type PolicyBindingApplyConfiguration struct {
|
||||
v1.TypeMetaApplyConfiguration `json:""`
|
||||
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
|
||||
Spec *PolicyBindingSpecApplyConfiguration `json:"spec,omitempty"`
|
||||
Status *PolicyBindingStatusApplyConfiguration `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// PolicyBinding constructs a declarative configuration of the PolicyBinding type for use with
|
||||
// apply.
|
||||
func PolicyBinding(name, namespace string) *PolicyBindingApplyConfiguration {
|
||||
b := &PolicyBindingApplyConfiguration{}
|
||||
b.WithName(name)
|
||||
b.WithNamespace(namespace)
|
||||
b.WithKind("PolicyBinding")
|
||||
b.WithAPIVersion("policybinding.t000-n.de/v1alpha1")
|
||||
return b
|
||||
}
|
||||
|
||||
func (b PolicyBindingApplyConfiguration) IsApplyConfiguration() {}
|
||||
|
||||
// WithKind sets the Kind field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Kind field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithKind(value string) *PolicyBindingApplyConfiguration {
|
||||
b.TypeMetaApplyConfiguration.Kind = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the APIVersion field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithAPIVersion(value string) *PolicyBindingApplyConfiguration {
|
||||
b.TypeMetaApplyConfiguration.APIVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithName sets the Name field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Name field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithName(value string) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Name = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGenerateName sets the GenerateName field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the GenerateName field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithGenerateName(value string) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.GenerateName = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithNamespace sets the Namespace field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Namespace field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithNamespace(value string) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Namespace = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUID sets the UID field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the UID field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithUID(value types.UID) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.UID = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the ResourceVersion field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithResourceVersion(value string) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.ResourceVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGeneration sets the Generation field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Generation field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithGeneration(value int64) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Generation = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the CreationTimestamp field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the DeletionTimestamp field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithLabels puts the entries into the Labels field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, the entries provided by each call will be put on the Labels field,
|
||||
// overwriting an existing map entries in Labels field with the same key.
|
||||
func (b *PolicyBindingApplyConfiguration) WithLabels(entries map[string]string) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
|
||||
b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.ObjectMetaApplyConfiguration.Labels[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAnnotations puts the entries into the Annotations field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, the entries provided by each call will be put on the Annotations field,
|
||||
// overwriting an existing map entries in Annotations field with the same key.
|
||||
func (b *PolicyBindingApplyConfiguration) WithAnnotations(entries map[string]string) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
|
||||
b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.ObjectMetaApplyConfiguration.Annotations[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the OwnerReferences field.
|
||||
func (b *PolicyBindingApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
if values[i] == nil {
|
||||
panic("nil value passed to WithOwnerReferences")
|
||||
}
|
||||
b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithFinalizers adds the given value to the Finalizers field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the Finalizers field.
|
||||
func (b *PolicyBindingApplyConfiguration) WithFinalizers(values ...string) *PolicyBindingApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PolicyBindingApplyConfiguration) ensureObjectMetaApplyConfigurationExists() {
|
||||
if b.ObjectMetaApplyConfiguration == nil {
|
||||
b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{}
|
||||
}
|
||||
}
|
||||
|
||||
// WithSpec sets the Spec field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Spec field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithSpec(value *PolicyBindingSpecApplyConfiguration) *PolicyBindingApplyConfiguration {
|
||||
b.Spec = value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithStatus sets the Status field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Status field is set to the value of the last call.
|
||||
func (b *PolicyBindingApplyConfiguration) WithStatus(value *PolicyBindingStatusApplyConfiguration) *PolicyBindingApplyConfiguration {
|
||||
b.Status = value
|
||||
return b
|
||||
}
|
||||
|
||||
// GetKind retrieves the value of the Kind field in the declarative configuration.
|
||||
func (b *PolicyBindingApplyConfiguration) GetKind() *string {
|
||||
return b.TypeMetaApplyConfiguration.Kind
|
||||
}
|
||||
|
||||
// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
|
||||
func (b *PolicyBindingApplyConfiguration) GetAPIVersion() *string {
|
||||
return b.TypeMetaApplyConfiguration.APIVersion
|
||||
}
|
||||
|
||||
// GetName retrieves the value of the Name field in the declarative configuration.
|
||||
func (b *PolicyBindingApplyConfiguration) GetName() *string {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
return b.ObjectMetaApplyConfiguration.Name
|
||||
}
|
||||
|
||||
// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
|
||||
func (b *PolicyBindingApplyConfiguration) GetNamespace() *string {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
return b.ObjectMetaApplyConfiguration.Namespace
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// PolicyBindingSpecApplyConfiguration represents a declarative configuration of the PolicyBindingSpec type for use
|
||||
// with apply.
|
||||
type PolicyBindingSpecApplyConfiguration struct {
|
||||
Policy *string `json:"policy,omitempty"`
|
||||
Group *string `json:"group,omitempty"`
|
||||
User *int32 `json:"user,omitempty"`
|
||||
Target *string `json:"target,omitempty"`
|
||||
Order *int32 `json:"order,omitempty"`
|
||||
}
|
||||
|
||||
// PolicyBindingSpecApplyConfiguration constructs a declarative configuration of the PolicyBindingSpec type for use with
|
||||
// apply.
|
||||
func PolicyBindingSpec() *PolicyBindingSpecApplyConfiguration {
|
||||
return &PolicyBindingSpecApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithPolicy sets the Policy field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Policy field is set to the value of the last call.
|
||||
func (b *PolicyBindingSpecApplyConfiguration) WithPolicy(value string) *PolicyBindingSpecApplyConfiguration {
|
||||
b.Policy = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGroup sets the Group field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Group field is set to the value of the last call.
|
||||
func (b *PolicyBindingSpecApplyConfiguration) WithGroup(value string) *PolicyBindingSpecApplyConfiguration {
|
||||
b.Group = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUser sets the User field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the User field is set to the value of the last call.
|
||||
func (b *PolicyBindingSpecApplyConfiguration) WithUser(value int32) *PolicyBindingSpecApplyConfiguration {
|
||||
b.User = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithTarget sets the Target field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Target field is set to the value of the last call.
|
||||
func (b *PolicyBindingSpecApplyConfiguration) WithTarget(value string) *PolicyBindingSpecApplyConfiguration {
|
||||
b.Target = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOrder sets the Order field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Order field is set to the value of the last call.
|
||||
func (b *PolicyBindingSpecApplyConfiguration) WithOrder(value int32) *PolicyBindingSpecApplyConfiguration {
|
||||
b.Order = &value
|
||||
return b
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// PolicyBindingStatusApplyConfiguration represents a declarative configuration of the PolicyBindingStatus type for use
|
||||
// with apply.
|
||||
type PolicyBindingStatusApplyConfiguration struct {
|
||||
PK *string `json:"pk,omitempty"`
|
||||
}
|
||||
|
||||
// PolicyBindingStatusApplyConfiguration constructs a declarative configuration of the PolicyBindingStatus type for use with
|
||||
// apply.
|
||||
func PolicyBindingStatus() *PolicyBindingStatusApplyConfiguration {
|
||||
return &PolicyBindingStatusApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithPK sets the PK field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the PK field is set to the value of the last call.
|
||||
func (b *PolicyBindingStatusApplyConfiguration) WithPK(value string) *PolicyBindingStatusApplyConfiguration {
|
||||
b.PK = &value
|
||||
return b
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
)
|
||||
|
||||
// ProxyProviderApplyConfiguration represents a declarative configuration of the ProxyProvider type for use
|
||||
// with apply.
|
||||
type ProxyProviderApplyConfiguration struct {
|
||||
v1.TypeMetaApplyConfiguration `json:""`
|
||||
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
|
||||
Spec *ProxyProviderSpecApplyConfiguration `json:"spec,omitempty"`
|
||||
Status *ProxyProviderStatusApplyConfiguration `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// ProxyProvider constructs a declarative configuration of the ProxyProvider type for use with
|
||||
// apply.
|
||||
func ProxyProvider(name, namespace string) *ProxyProviderApplyConfiguration {
|
||||
b := &ProxyProviderApplyConfiguration{}
|
||||
b.WithName(name)
|
||||
b.WithNamespace(namespace)
|
||||
b.WithKind("ProxyProvider")
|
||||
b.WithAPIVersion("proxyprovider.t000-n.de/v1alpha1")
|
||||
return b
|
||||
}
|
||||
|
||||
func (b ProxyProviderApplyConfiguration) IsApplyConfiguration() {}
|
||||
|
||||
// WithKind sets the Kind field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Kind field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithKind(value string) *ProxyProviderApplyConfiguration {
|
||||
b.TypeMetaApplyConfiguration.Kind = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the APIVersion field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithAPIVersion(value string) *ProxyProviderApplyConfiguration {
|
||||
b.TypeMetaApplyConfiguration.APIVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithName sets the Name field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Name field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithName(value string) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Name = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGenerateName sets the GenerateName field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the GenerateName field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithGenerateName(value string) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.GenerateName = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithNamespace sets the Namespace field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Namespace field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithNamespace(value string) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Namespace = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUID sets the UID field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the UID field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithUID(value types.UID) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.UID = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the ResourceVersion field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithResourceVersion(value string) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.ResourceVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGeneration sets the Generation field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Generation field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithGeneration(value int64) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Generation = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the CreationTimestamp field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the DeletionTimestamp field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithLabels puts the entries into the Labels field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, the entries provided by each call will be put on the Labels field,
|
||||
// overwriting an existing map entries in Labels field with the same key.
|
||||
func (b *ProxyProviderApplyConfiguration) WithLabels(entries map[string]string) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
|
||||
b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.ObjectMetaApplyConfiguration.Labels[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAnnotations puts the entries into the Annotations field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, the entries provided by each call will be put on the Annotations field,
|
||||
// overwriting an existing map entries in Annotations field with the same key.
|
||||
func (b *ProxyProviderApplyConfiguration) WithAnnotations(entries map[string]string) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
|
||||
b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.ObjectMetaApplyConfiguration.Annotations[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the OwnerReferences field.
|
||||
func (b *ProxyProviderApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
if values[i] == nil {
|
||||
panic("nil value passed to WithOwnerReferences")
|
||||
}
|
||||
b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithFinalizers adds the given value to the Finalizers field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the Finalizers field.
|
||||
func (b *ProxyProviderApplyConfiguration) WithFinalizers(values ...string) *ProxyProviderApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *ProxyProviderApplyConfiguration) ensureObjectMetaApplyConfigurationExists() {
|
||||
if b.ObjectMetaApplyConfiguration == nil {
|
||||
b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{}
|
||||
}
|
||||
}
|
||||
|
||||
// WithSpec sets the Spec field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Spec field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithSpec(value *ProxyProviderSpecApplyConfiguration) *ProxyProviderApplyConfiguration {
|
||||
b.Spec = value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithStatus sets the Status field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Status field is set to the value of the last call.
|
||||
func (b *ProxyProviderApplyConfiguration) WithStatus(value *ProxyProviderStatusApplyConfiguration) *ProxyProviderApplyConfiguration {
|
||||
b.Status = value
|
||||
return b
|
||||
}
|
||||
|
||||
// GetKind retrieves the value of the Kind field in the declarative configuration.
|
||||
func (b *ProxyProviderApplyConfiguration) GetKind() *string {
|
||||
return b.TypeMetaApplyConfiguration.Kind
|
||||
}
|
||||
|
||||
// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
|
||||
func (b *ProxyProviderApplyConfiguration) GetAPIVersion() *string {
|
||||
return b.TypeMetaApplyConfiguration.APIVersion
|
||||
}
|
||||
|
||||
// GetName retrieves the value of the Name field in the declarative configuration.
|
||||
func (b *ProxyProviderApplyConfiguration) GetName() *string {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
return b.ObjectMetaApplyConfiguration.Name
|
||||
}
|
||||
|
||||
// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
|
||||
func (b *ProxyProviderApplyConfiguration) GetNamespace() *string {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
return b.ObjectMetaApplyConfiguration.Namespace
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// ProxyProviderSpecApplyConfiguration represents a declarative configuration of the ProxyProviderSpec type for use
|
||||
// with apply.
|
||||
type ProxyProviderSpecApplyConfiguration struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
AuthorizationFlow *string `json:"authorization_flow,omitempty"`
|
||||
InvalidationFlow *string `json:"invalidation_flow,omitempty"`
|
||||
ExternalHost *string `json:"external_host,omitempty"`
|
||||
Outpost *string `json:"outpost,omitempty"`
|
||||
}
|
||||
|
||||
// ProxyProviderSpecApplyConfiguration constructs a declarative configuration of the ProxyProviderSpec type for use with
|
||||
// apply.
|
||||
func ProxyProviderSpec() *ProxyProviderSpecApplyConfiguration {
|
||||
return &ProxyProviderSpecApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithName sets the Name field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Name field is set to the value of the last call.
|
||||
func (b *ProxyProviderSpecApplyConfiguration) WithName(value string) *ProxyProviderSpecApplyConfiguration {
|
||||
b.Name = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAuthorizationFlow sets the AuthorizationFlow field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the AuthorizationFlow field is set to the value of the last call.
|
||||
func (b *ProxyProviderSpecApplyConfiguration) WithAuthorizationFlow(value string) *ProxyProviderSpecApplyConfiguration {
|
||||
b.AuthorizationFlow = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithInvalidationFlow sets the InvalidationFlow field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the InvalidationFlow field is set to the value of the last call.
|
||||
func (b *ProxyProviderSpecApplyConfiguration) WithInvalidationFlow(value string) *ProxyProviderSpecApplyConfiguration {
|
||||
b.InvalidationFlow = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithExternalHost sets the ExternalHost field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the ExternalHost field is set to the value of the last call.
|
||||
func (b *ProxyProviderSpecApplyConfiguration) WithExternalHost(value string) *ProxyProviderSpecApplyConfiguration {
|
||||
b.ExternalHost = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOutpost sets the Outpost field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Outpost field is set to the value of the last call.
|
||||
func (b *ProxyProviderSpecApplyConfiguration) WithOutpost(value string) *ProxyProviderSpecApplyConfiguration {
|
||||
b.Outpost = &value
|
||||
return b
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// ProxyProviderStatusApplyConfiguration represents a declarative configuration of the ProxyProviderStatus type for use
|
||||
// with apply.
|
||||
type ProxyProviderStatusApplyConfiguration struct {
|
||||
PK *string `json:"pk,omitempty"`
|
||||
}
|
||||
|
||||
// ProxyProviderStatusApplyConfiguration constructs a declarative configuration of the ProxyProviderStatus type for use with
|
||||
// apply.
|
||||
func ProxyProviderStatus() *ProxyProviderStatusApplyConfiguration {
|
||||
return &ProxyProviderStatusApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithPK sets the PK field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the PK field is set to the value of the last call.
|
||||
func (b *ProxyProviderStatusApplyConfiguration) WithPK(value string) *ProxyProviderStatusApplyConfiguration {
|
||||
b.PK = &value
|
||||
return b
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package applyconfiguration
|
||||
|
||||
import (
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
||||
applicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration/application/v1alpha1"
|
||||
internal "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration/internal"
|
||||
applyconfigurationpolicybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration/policybinding/v1alpha1"
|
||||
applyconfigurationproxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration/proxyprovider/v1alpha1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
managedfields "k8s.io/apimachinery/pkg/util/managedfields"
|
||||
)
|
||||
|
||||
// ForKind returns an apply configuration type for the given GroupVersionKind, or nil if no
|
||||
// apply configuration type exists for the given GroupVersionKind.
|
||||
func ForKind(kind schema.GroupVersionKind) interface{} {
|
||||
switch kind {
|
||||
// Group=application.t000-n.de, Version=v1alpha1
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("Application"):
|
||||
return &applicationv1alpha1.ApplicationApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("ApplicationSpec"):
|
||||
return &applicationv1alpha1.ApplicationSpecApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("ApplicationStatus"):
|
||||
return &applicationv1alpha1.ApplicationStatusApplyConfiguration{}
|
||||
|
||||
// Group=policybinding.t000-n.de, Version=v1alpha1
|
||||
case policybindingv1alpha1.SchemeGroupVersion.WithKind("PolicyBinding"):
|
||||
return &applyconfigurationpolicybindingv1alpha1.PolicyBindingApplyConfiguration{}
|
||||
case policybindingv1alpha1.SchemeGroupVersion.WithKind("PolicyBindingSpec"):
|
||||
return &applyconfigurationpolicybindingv1alpha1.PolicyBindingSpecApplyConfiguration{}
|
||||
case policybindingv1alpha1.SchemeGroupVersion.WithKind("PolicyBindingStatus"):
|
||||
return &applyconfigurationpolicybindingv1alpha1.PolicyBindingStatusApplyConfiguration{}
|
||||
|
||||
// Group=proxyprovider.t000-n.de, Version=v1alpha1
|
||||
case proxyproviderv1alpha1.SchemeGroupVersion.WithKind("ProxyProvider"):
|
||||
return &applyconfigurationproxyproviderv1alpha1.ProxyProviderApplyConfiguration{}
|
||||
case proxyproviderv1alpha1.SchemeGroupVersion.WithKind("ProxyProviderSpec"):
|
||||
return &applyconfigurationproxyproviderv1alpha1.ProxyProviderSpecApplyConfiguration{}
|
||||
case proxyproviderv1alpha1.SchemeGroupVersion.WithKind("ProxyProviderStatus"):
|
||||
return &applyconfigurationproxyproviderv1alpha1.ProxyProviderStatusApplyConfiguration{}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewTypeConverter(scheme *runtime.Scheme) managedfields.TypeConverter {
|
||||
return managedfields.NewSchemeTypeConverter(scheme, internal.Parser())
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package versioned
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
http "net/http"
|
||||
|
||||
applicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/application/v1alpha1"
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/policybinding/v1alpha1"
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/proxyprovider/v1alpha1"
|
||||
discovery "k8s.io/client-go/discovery"
|
||||
rest "k8s.io/client-go/rest"
|
||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
ApplicationV1alpha1() applicationv1alpha1.ApplicationV1alpha1Interface
|
||||
PolicyBindingV1alpha1() policybindingv1alpha1.PolicyBindingV1alpha1Interface
|
||||
ProxyproviderV1alpha1() proxyproviderv1alpha1.ProxyproviderV1alpha1Interface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups.
|
||||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
applicationV1alpha1 *applicationv1alpha1.ApplicationV1alpha1Client
|
||||
policyBindingV1alpha1 *policybindingv1alpha1.PolicyBindingV1alpha1Client
|
||||
proxyproviderV1alpha1 *proxyproviderv1alpha1.ProxyproviderV1alpha1Client
|
||||
}
|
||||
|
||||
// ApplicationV1alpha1 retrieves the ApplicationV1alpha1Client
|
||||
func (c *Clientset) ApplicationV1alpha1() applicationv1alpha1.ApplicationV1alpha1Interface {
|
||||
return c.applicationV1alpha1
|
||||
}
|
||||
|
||||
// PolicyBindingV1alpha1 retrieves the PolicyBindingV1alpha1Client
|
||||
func (c *Clientset) PolicyBindingV1alpha1() policybindingv1alpha1.PolicyBindingV1alpha1Interface {
|
||||
return c.policyBindingV1alpha1
|
||||
}
|
||||
|
||||
// ProxyproviderV1alpha1 retrieves the ProxyproviderV1alpha1Client
|
||||
func (c *Clientset) ProxyproviderV1alpha1() proxyproviderv1alpha1.ProxyproviderV1alpha1Interface {
|
||||
return c.proxyproviderV1alpha1
|
||||
}
|
||||
|
||||
// Discovery retrieves the DiscoveryClient
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.DiscoveryClient
|
||||
}
|
||||
|
||||
// NewForConfig creates a new Clientset for the given config.
|
||||
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
||||
// NewForConfig will generate a rate-limiter in configShallowCopy.
|
||||
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||
func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
|
||||
if configShallowCopy.UserAgent == "" {
|
||||
configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
// share the transport between all clients
|
||||
httpClient, err := rest.HTTPClientFor(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
}
|
||||
|
||||
// NewForConfigAndClient creates a new Clientset for the given config and http client.
|
||||
// Note the http client provided takes precedence over the configured transport values.
|
||||
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
||||
// NewForConfigAndClient will generate a rate-limiter in configShallowCopy.
|
||||
func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
||||
if configShallowCopy.Burst <= 0 {
|
||||
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
|
||||
}
|
||||
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
||||
}
|
||||
|
||||
var cs Clientset
|
||||
var err error
|
||||
cs.applicationV1alpha1, err = applicationv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.policyBindingV1alpha1, err = policybindingv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.proxyproviderV1alpha1, err = proxyproviderv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cs, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new Clientset for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
cs, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return cs
|
||||
}
|
||||
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
func New(c rest.Interface) *Clientset {
|
||||
var cs Clientset
|
||||
cs.applicationV1alpha1 = applicationv1alpha1.New(c)
|
||||
cs.policyBindingV1alpha1 = policybindingv1alpha1.New(c)
|
||||
cs.proxyproviderV1alpha1 = proxyproviderv1alpha1.New(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
return &cs
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
applyconfiguration "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration"
|
||||
clientset "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
|
||||
applicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/application/v1alpha1"
|
||||
fakeapplicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/application/v1alpha1/fake"
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/policybinding/v1alpha1"
|
||||
fakepolicybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/policybinding/v1alpha1/fake"
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/proxyprovider/v1alpha1"
|
||||
fakeproxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/proxyprovider/v1alpha1/fake"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/discovery"
|
||||
fakediscovery "k8s.io/client-go/discovery/fake"
|
||||
"k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// NewSimpleClientset returns a clientset that will respond with the provided objects.
|
||||
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
|
||||
// without applying any field management, validations and/or defaults. It shouldn't be considered a replacement
|
||||
// for a real clientset and is mostly useful in simple unit tests.
|
||||
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
|
||||
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
|
||||
for _, obj := range objects {
|
||||
if err := o.Add(obj); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
cs := &Clientset{tracker: o}
|
||||
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
|
||||
cs.AddReactor("*", "*", testing.ObjectReaction(o))
|
||||
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
|
||||
var opts metav1.ListOptions
|
||||
if watchAction, ok := action.(testing.WatchActionImpl); ok {
|
||||
opts = watchAction.ListOptions
|
||||
}
|
||||
gvr := action.GetResource()
|
||||
ns := action.GetNamespace()
|
||||
watch, err := o.Watch(gvr, ns, opts)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return true, watch, nil
|
||||
})
|
||||
|
||||
return cs
|
||||
}
|
||||
|
||||
// Clientset implements clientset.Interface. Meant to be embedded into a
|
||||
// struct to get a default implementation. This makes faking out just the method
|
||||
// you want to test easier.
|
||||
type Clientset struct {
|
||||
testing.Fake
|
||||
discovery *fakediscovery.FakeDiscovery
|
||||
tracker testing.ObjectTracker
|
||||
}
|
||||
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
return c.discovery
|
||||
}
|
||||
|
||||
func (c *Clientset) Tracker() testing.ObjectTracker {
|
||||
return c.tracker
|
||||
}
|
||||
|
||||
// IsWatchListSemanticsUnSupported informs the reflector that this client
|
||||
// doesn't support WatchList semantics.
|
||||
//
|
||||
// This is a synthetic method whose sole purpose is to satisfy the optional
|
||||
// interface check performed by the reflector.
|
||||
// Returning true signals that WatchList can NOT be used.
|
||||
// No additional logic is implemented here.
|
||||
func (c *Clientset) IsWatchListSemanticsUnSupported() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// NewClientset returns a clientset that will respond with the provided objects.
|
||||
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
|
||||
// without applying any validations and/or defaults. It shouldn't be considered a replacement
|
||||
// for a real clientset and is mostly useful in simple unit tests.
|
||||
//
|
||||
// Compared to NewSimpleClientset, the Clientset returned here supports field tracking and thus
|
||||
// server-side apply. Beware though that support in that for CRDs is missing
|
||||
// (https://github.com/kubernetes/kubernetes/issues/126850).
|
||||
func NewClientset(objects ...runtime.Object) *Clientset {
|
||||
o := testing.NewFieldManagedObjectTracker(
|
||||
scheme,
|
||||
codecs.UniversalDecoder(),
|
||||
applyconfiguration.NewTypeConverter(scheme),
|
||||
)
|
||||
for _, obj := range objects {
|
||||
if err := o.Add(obj); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
cs := &Clientset{tracker: o}
|
||||
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
|
||||
cs.AddReactor("*", "*", testing.ObjectReaction(o))
|
||||
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
|
||||
var opts metav1.ListOptions
|
||||
if watchAction, ok := action.(testing.WatchActionImpl); ok {
|
||||
opts = watchAction.ListOptions
|
||||
}
|
||||
gvr := action.GetResource()
|
||||
ns := action.GetNamespace()
|
||||
watch, err := o.Watch(gvr, ns, opts)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return true, watch, nil
|
||||
})
|
||||
|
||||
return cs
|
||||
}
|
||||
|
||||
var (
|
||||
_ clientset.Interface = &Clientset{}
|
||||
_ testing.FakeClient = &Clientset{}
|
||||
)
|
||||
|
||||
// ApplicationV1alpha1 retrieves the ApplicationV1alpha1Client
|
||||
func (c *Clientset) ApplicationV1alpha1() applicationv1alpha1.ApplicationV1alpha1Interface {
|
||||
return &fakeapplicationv1alpha1.FakeApplicationV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// PolicyBindingV1alpha1 retrieves the PolicyBindingV1alpha1Client
|
||||
func (c *Clientset) PolicyBindingV1alpha1() policybindingv1alpha1.PolicyBindingV1alpha1Interface {
|
||||
return &fakepolicybindingv1alpha1.FakePolicyBindingV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// ProxyproviderV1alpha1 retrieves the ProxyproviderV1alpha1Client
|
||||
func (c *Clientset) ProxyproviderV1alpha1() proxyproviderv1alpha1.ProxyproviderV1alpha1Interface {
|
||||
return &fakeproxyproviderv1alpha1.FakeProxyproviderV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated fake clientset.
|
||||
package fake
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
applicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
)
|
||||
|
||||
var scheme = runtime.NewScheme()
|
||||
var codecs = serializer.NewCodecFactory(scheme)
|
||||
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
applicationv1alpha1.AddToScheme,
|
||||
policybindingv1alpha1.AddToScheme,
|
||||
proxyproviderv1alpha1.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
// of clientsets, like in:
|
||||
//
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
//
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
//
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
var AddToScheme = localSchemeBuilder.AddToScheme
|
||||
|
||||
func init() {
|
||||
v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
|
||||
utilruntime.Must(AddToScheme(scheme))
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package contains the scheme of the automatically generated clientset.
|
||||
package scheme
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package scheme
|
||||
|
||||
import (
|
||||
applicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
)
|
||||
|
||||
var Scheme = runtime.NewScheme()
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
applicationv1alpha1.AddToScheme,
|
||||
policybindingv1alpha1.AddToScheme,
|
||||
proxyproviderv1alpha1.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
// of clientsets, like in:
|
||||
//
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
//
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
//
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
var AddToScheme = localSchemeBuilder.AddToScheme
|
||||
|
||||
func init() {
|
||||
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
|
||||
utilruntime.Must(AddToScheme(Scheme))
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
applicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
|
||||
applyconfigurationapplicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration/application/v1alpha1"
|
||||
scheme "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
gentype "k8s.io/client-go/gentype"
|
||||
)
|
||||
|
||||
// ApplicationsGetter has a method to return a ApplicationInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ApplicationsGetter interface {
|
||||
Applications(namespace string) ApplicationInterface
|
||||
}
|
||||
|
||||
// ApplicationInterface has methods to work with Application resources.
|
||||
type ApplicationInterface interface {
|
||||
Create(ctx context.Context, application *applicationv1alpha1.Application, opts v1.CreateOptions) (*applicationv1alpha1.Application, error)
|
||||
Update(ctx context.Context, application *applicationv1alpha1.Application, opts v1.UpdateOptions) (*applicationv1alpha1.Application, error)
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
UpdateStatus(ctx context.Context, application *applicationv1alpha1.Application, opts v1.UpdateOptions) (*applicationv1alpha1.Application, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*applicationv1alpha1.Application, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*applicationv1alpha1.ApplicationList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *applicationv1alpha1.Application, err error)
|
||||
Apply(ctx context.Context, application *applyconfigurationapplicationv1alpha1.ApplicationApplyConfiguration, opts v1.ApplyOptions) (result *applicationv1alpha1.Application, err error)
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus().
|
||||
ApplyStatus(ctx context.Context, application *applyconfigurationapplicationv1alpha1.ApplicationApplyConfiguration, opts v1.ApplyOptions) (result *applicationv1alpha1.Application, err error)
|
||||
ApplicationExpansion
|
||||
}
|
||||
|
||||
// applications implements ApplicationInterface
|
||||
type applications struct {
|
||||
*gentype.ClientWithListAndApply[*applicationv1alpha1.Application, *applicationv1alpha1.ApplicationList, *applyconfigurationapplicationv1alpha1.ApplicationApplyConfiguration]
|
||||
}
|
||||
|
||||
// newApplications returns a Applications
|
||||
func newApplications(c *ApplicationV1alpha1Client, namespace string) *applications {
|
||||
return &applications{
|
||||
gentype.NewClientWithListAndApply[*applicationv1alpha1.Application, *applicationv1alpha1.ApplicationList, *applyconfigurationapplicationv1alpha1.ApplicationApplyConfiguration](
|
||||
"applications",
|
||||
c.RESTClient(),
|
||||
scheme.ParameterCodec,
|
||||
namespace,
|
||||
func() *applicationv1alpha1.Application { return &applicationv1alpha1.Application{} },
|
||||
func() *applicationv1alpha1.ApplicationList { return &applicationv1alpha1.ApplicationList{} },
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
http "net/http"
|
||||
|
||||
applicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
|
||||
scheme "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type ApplicationV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
ApplicationsGetter
|
||||
}
|
||||
|
||||
// ApplicationV1alpha1Client is used to interact with features provided by the application.t000-n.de group.
|
||||
type ApplicationV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *ApplicationV1alpha1Client) Applications(namespace string) ApplicationInterface {
|
||||
return newApplications(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new ApplicationV1alpha1Client for the given config.
|
||||
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||
func NewForConfig(c *rest.Config) (*ApplicationV1alpha1Client, error) {
|
||||
config := *c
|
||||
setConfigDefaults(&config)
|
||||
httpClient, err := rest.HTTPClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewForConfigAndClient(&config, httpClient)
|
||||
}
|
||||
|
||||
// NewForConfigAndClient creates a new ApplicationV1alpha1Client for the given config and http client.
|
||||
// Note the http client provided takes precedence over the configured transport values.
|
||||
func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ApplicationV1alpha1Client, error) {
|
||||
config := *c
|
||||
setConfigDefaults(&config)
|
||||
client, err := rest.RESTClientForConfigAndClient(&config, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ApplicationV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new ApplicationV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *ApplicationV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new ApplicationV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *ApplicationV1alpha1Client {
|
||||
return &ApplicationV1alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) {
|
||||
gv := applicationv1alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *ApplicationV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
|
||||
applicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration/application/v1alpha1"
|
||||
typedapplicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/application/v1alpha1"
|
||||
gentype "k8s.io/client-go/gentype"
|
||||
)
|
||||
|
||||
// fakeApplications implements ApplicationInterface
|
||||
type fakeApplications struct {
|
||||
*gentype.FakeClientWithListAndApply[*v1alpha1.Application, *v1alpha1.ApplicationList, *applicationv1alpha1.ApplicationApplyConfiguration]
|
||||
Fake *FakeApplicationV1alpha1
|
||||
}
|
||||
|
||||
func newFakeApplications(fake *FakeApplicationV1alpha1, namespace string) typedapplicationv1alpha1.ApplicationInterface {
|
||||
return &fakeApplications{
|
||||
gentype.NewFakeClientWithListAndApply[*v1alpha1.Application, *v1alpha1.ApplicationList, *applicationv1alpha1.ApplicationApplyConfiguration](
|
||||
fake.Fake,
|
||||
namespace,
|
||||
v1alpha1.SchemeGroupVersion.WithResource("applications"),
|
||||
v1alpha1.SchemeGroupVersion.WithKind("Application"),
|
||||
func() *v1alpha1.Application { return &v1alpha1.Application{} },
|
||||
func() *v1alpha1.ApplicationList { return &v1alpha1.ApplicationList{} },
|
||||
func(dst, src *v1alpha1.ApplicationList) { dst.ListMeta = src.ListMeta },
|
||||
func(list *v1alpha1.ApplicationList) []*v1alpha1.Application {
|
||||
return gentype.ToPointerSlice(list.Items)
|
||||
},
|
||||
func(list *v1alpha1.ApplicationList, items []*v1alpha1.Application) {
|
||||
list.Items = gentype.FromPointerSlice(items)
|
||||
},
|
||||
),
|
||||
fake,
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/application/v1alpha1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeApplicationV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeApplicationV1alpha1) Applications(namespace string) v1alpha1.ApplicationInterface {
|
||||
return newFakeApplications(c, namespace)
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeApplicationV1alpha1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type ApplicationExpansion interface{}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration/policybinding/v1alpha1"
|
||||
typedpolicybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/policybinding/v1alpha1"
|
||||
gentype "k8s.io/client-go/gentype"
|
||||
)
|
||||
|
||||
// fakePolicyBindings implements PolicyBindingInterface
|
||||
type fakePolicyBindings struct {
|
||||
*gentype.FakeClientWithListAndApply[*v1alpha1.PolicyBinding, *v1alpha1.PolicyBindingList, *policybindingv1alpha1.PolicyBindingApplyConfiguration]
|
||||
Fake *FakePolicyBindingV1alpha1
|
||||
}
|
||||
|
||||
func newFakePolicyBindings(fake *FakePolicyBindingV1alpha1, namespace string) typedpolicybindingv1alpha1.PolicyBindingInterface {
|
||||
return &fakePolicyBindings{
|
||||
gentype.NewFakeClientWithListAndApply[*v1alpha1.PolicyBinding, *v1alpha1.PolicyBindingList, *policybindingv1alpha1.PolicyBindingApplyConfiguration](
|
||||
fake.Fake,
|
||||
namespace,
|
||||
v1alpha1.SchemeGroupVersion.WithResource("policybindings"),
|
||||
v1alpha1.SchemeGroupVersion.WithKind("PolicyBinding"),
|
||||
func() *v1alpha1.PolicyBinding { return &v1alpha1.PolicyBinding{} },
|
||||
func() *v1alpha1.PolicyBindingList { return &v1alpha1.PolicyBindingList{} },
|
||||
func(dst, src *v1alpha1.PolicyBindingList) { dst.ListMeta = src.ListMeta },
|
||||
func(list *v1alpha1.PolicyBindingList) []*v1alpha1.PolicyBinding {
|
||||
return gentype.ToPointerSlice(list.Items)
|
||||
},
|
||||
func(list *v1alpha1.PolicyBindingList, items []*v1alpha1.PolicyBinding) {
|
||||
list.Items = gentype.FromPointerSlice(items)
|
||||
},
|
||||
),
|
||||
fake,
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/policybinding/v1alpha1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakePolicyBindingV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakePolicyBindingV1alpha1) PolicyBindings(namespace string) v1alpha1.PolicyBindingInterface {
|
||||
return newFakePolicyBindings(c, namespace)
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakePolicyBindingV1alpha1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type PolicyBindingExpansion interface{}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
|
||||
applyconfigurationpolicybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration/policybinding/v1alpha1"
|
||||
scheme "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
gentype "k8s.io/client-go/gentype"
|
||||
)
|
||||
|
||||
// PolicyBindingsGetter has a method to return a PolicyBindingInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PolicyBindingsGetter interface {
|
||||
PolicyBindings(namespace string) PolicyBindingInterface
|
||||
}
|
||||
|
||||
// PolicyBindingInterface has methods to work with PolicyBinding resources.
|
||||
type PolicyBindingInterface interface {
|
||||
Create(ctx context.Context, policyBinding *policybindingv1alpha1.PolicyBinding, opts v1.CreateOptions) (*policybindingv1alpha1.PolicyBinding, error)
|
||||
Update(ctx context.Context, policyBinding *policybindingv1alpha1.PolicyBinding, opts v1.UpdateOptions) (*policybindingv1alpha1.PolicyBinding, error)
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
UpdateStatus(ctx context.Context, policyBinding *policybindingv1alpha1.PolicyBinding, opts v1.UpdateOptions) (*policybindingv1alpha1.PolicyBinding, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*policybindingv1alpha1.PolicyBinding, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*policybindingv1alpha1.PolicyBindingList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *policybindingv1alpha1.PolicyBinding, err error)
|
||||
Apply(ctx context.Context, policyBinding *applyconfigurationpolicybindingv1alpha1.PolicyBindingApplyConfiguration, opts v1.ApplyOptions) (result *policybindingv1alpha1.PolicyBinding, err error)
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus().
|
||||
ApplyStatus(ctx context.Context, policyBinding *applyconfigurationpolicybindingv1alpha1.PolicyBindingApplyConfiguration, opts v1.ApplyOptions) (result *policybindingv1alpha1.PolicyBinding, err error)
|
||||
PolicyBindingExpansion
|
||||
}
|
||||
|
||||
// policyBindings implements PolicyBindingInterface
|
||||
type policyBindings struct {
|
||||
*gentype.ClientWithListAndApply[*policybindingv1alpha1.PolicyBinding, *policybindingv1alpha1.PolicyBindingList, *applyconfigurationpolicybindingv1alpha1.PolicyBindingApplyConfiguration]
|
||||
}
|
||||
|
||||
// newPolicyBindings returns a PolicyBindings
|
||||
func newPolicyBindings(c *PolicyBindingV1alpha1Client, namespace string) *policyBindings {
|
||||
return &policyBindings{
|
||||
gentype.NewClientWithListAndApply[*policybindingv1alpha1.PolicyBinding, *policybindingv1alpha1.PolicyBindingList, *applyconfigurationpolicybindingv1alpha1.PolicyBindingApplyConfiguration](
|
||||
"policybindings",
|
||||
c.RESTClient(),
|
||||
scheme.ParameterCodec,
|
||||
namespace,
|
||||
func() *policybindingv1alpha1.PolicyBinding { return &policybindingv1alpha1.PolicyBinding{} },
|
||||
func() *policybindingv1alpha1.PolicyBindingList { return &policybindingv1alpha1.PolicyBindingList{} },
|
||||
),
|
||||
}
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
http "net/http"
|
||||
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
|
||||
scheme "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type PolicyBindingV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
PolicyBindingsGetter
|
||||
}
|
||||
|
||||
// PolicyBindingV1alpha1Client is used to interact with features provided by the policybinding.t000-n.de group.
|
||||
type PolicyBindingV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *PolicyBindingV1alpha1Client) PolicyBindings(namespace string) PolicyBindingInterface {
|
||||
return newPolicyBindings(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new PolicyBindingV1alpha1Client for the given config.
|
||||
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||
func NewForConfig(c *rest.Config) (*PolicyBindingV1alpha1Client, error) {
|
||||
config := *c
|
||||
setConfigDefaults(&config)
|
||||
httpClient, err := rest.HTTPClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewForConfigAndClient(&config, httpClient)
|
||||
}
|
||||
|
||||
// NewForConfigAndClient creates a new PolicyBindingV1alpha1Client for the given config and http client.
|
||||
// Note the http client provided takes precedence over the configured transport values.
|
||||
func NewForConfigAndClient(c *rest.Config, h *http.Client) (*PolicyBindingV1alpha1Client, error) {
|
||||
config := *c
|
||||
setConfigDefaults(&config)
|
||||
client, err := rest.RESTClientForConfigAndClient(&config, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &PolicyBindingV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new PolicyBindingV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *PolicyBindingV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new PolicyBindingV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *PolicyBindingV1alpha1Client {
|
||||
return &PolicyBindingV1alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) {
|
||||
gv := policybindingv1alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *PolicyBindingV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration/proxyprovider/v1alpha1"
|
||||
typedproxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/proxyprovider/v1alpha1"
|
||||
gentype "k8s.io/client-go/gentype"
|
||||
)
|
||||
|
||||
// fakeProxyProviders implements ProxyProviderInterface
|
||||
type fakeProxyProviders struct {
|
||||
*gentype.FakeClientWithListAndApply[*v1alpha1.ProxyProvider, *v1alpha1.ProxyProviderList, *proxyproviderv1alpha1.ProxyProviderApplyConfiguration]
|
||||
Fake *FakeProxyproviderV1alpha1
|
||||
}
|
||||
|
||||
func newFakeProxyProviders(fake *FakeProxyproviderV1alpha1, namespace string) typedproxyproviderv1alpha1.ProxyProviderInterface {
|
||||
return &fakeProxyProviders{
|
||||
gentype.NewFakeClientWithListAndApply[*v1alpha1.ProxyProvider, *v1alpha1.ProxyProviderList, *proxyproviderv1alpha1.ProxyProviderApplyConfiguration](
|
||||
fake.Fake,
|
||||
namespace,
|
||||
v1alpha1.SchemeGroupVersion.WithResource("proxyproviders"),
|
||||
v1alpha1.SchemeGroupVersion.WithKind("ProxyProvider"),
|
||||
func() *v1alpha1.ProxyProvider { return &v1alpha1.ProxyProvider{} },
|
||||
func() *v1alpha1.ProxyProviderList { return &v1alpha1.ProxyProviderList{} },
|
||||
func(dst, src *v1alpha1.ProxyProviderList) { dst.ListMeta = src.ListMeta },
|
||||
func(list *v1alpha1.ProxyProviderList) []*v1alpha1.ProxyProvider {
|
||||
return gentype.ToPointerSlice(list.Items)
|
||||
},
|
||||
func(list *v1alpha1.ProxyProviderList, items []*v1alpha1.ProxyProvider) {
|
||||
list.Items = gentype.FromPointerSlice(items)
|
||||
},
|
||||
),
|
||||
fake,
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/typed/proxyprovider/v1alpha1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeProxyproviderV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeProxyproviderV1alpha1) ProxyProviders(namespace string) v1alpha1.ProxyProviderInterface {
|
||||
return newFakeProxyProviders(c, namespace)
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeProxyproviderV1alpha1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type ProxyProviderExpansion interface{}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
||||
applyconfigurationproxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/applyconfiguration/proxyprovider/v1alpha1"
|
||||
scheme "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
gentype "k8s.io/client-go/gentype"
|
||||
)
|
||||
|
||||
// ProxyProvidersGetter has a method to return a ProxyProviderInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ProxyProvidersGetter interface {
|
||||
ProxyProviders(namespace string) ProxyProviderInterface
|
||||
}
|
||||
|
||||
// ProxyProviderInterface has methods to work with ProxyProvider resources.
|
||||
type ProxyProviderInterface interface {
|
||||
Create(ctx context.Context, proxyProvider *proxyproviderv1alpha1.ProxyProvider, opts v1.CreateOptions) (*proxyproviderv1alpha1.ProxyProvider, error)
|
||||
Update(ctx context.Context, proxyProvider *proxyproviderv1alpha1.ProxyProvider, opts v1.UpdateOptions) (*proxyproviderv1alpha1.ProxyProvider, error)
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
UpdateStatus(ctx context.Context, proxyProvider *proxyproviderv1alpha1.ProxyProvider, opts v1.UpdateOptions) (*proxyproviderv1alpha1.ProxyProvider, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*proxyproviderv1alpha1.ProxyProvider, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*proxyproviderv1alpha1.ProxyProviderList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *proxyproviderv1alpha1.ProxyProvider, err error)
|
||||
Apply(ctx context.Context, proxyProvider *applyconfigurationproxyproviderv1alpha1.ProxyProviderApplyConfiguration, opts v1.ApplyOptions) (result *proxyproviderv1alpha1.ProxyProvider, err error)
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus().
|
||||
ApplyStatus(ctx context.Context, proxyProvider *applyconfigurationproxyproviderv1alpha1.ProxyProviderApplyConfiguration, opts v1.ApplyOptions) (result *proxyproviderv1alpha1.ProxyProvider, err error)
|
||||
ProxyProviderExpansion
|
||||
}
|
||||
|
||||
// proxyProviders implements ProxyProviderInterface
|
||||
type proxyProviders struct {
|
||||
*gentype.ClientWithListAndApply[*proxyproviderv1alpha1.ProxyProvider, *proxyproviderv1alpha1.ProxyProviderList, *applyconfigurationproxyproviderv1alpha1.ProxyProviderApplyConfiguration]
|
||||
}
|
||||
|
||||
// newProxyProviders returns a ProxyProviders
|
||||
func newProxyProviders(c *ProxyproviderV1alpha1Client, namespace string) *proxyProviders {
|
||||
return &proxyProviders{
|
||||
gentype.NewClientWithListAndApply[*proxyproviderv1alpha1.ProxyProvider, *proxyproviderv1alpha1.ProxyProviderList, *applyconfigurationproxyproviderv1alpha1.ProxyProviderApplyConfiguration](
|
||||
"proxyproviders",
|
||||
c.RESTClient(),
|
||||
scheme.ParameterCodec,
|
||||
namespace,
|
||||
func() *proxyproviderv1alpha1.ProxyProvider { return &proxyproviderv1alpha1.ProxyProvider{} },
|
||||
func() *proxyproviderv1alpha1.ProxyProviderList { return &proxyproviderv1alpha1.ProxyProviderList{} },
|
||||
),
|
||||
}
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
http "net/http"
|
||||
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
||||
scheme "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type ProxyproviderV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
ProxyProvidersGetter
|
||||
}
|
||||
|
||||
// ProxyproviderV1alpha1Client is used to interact with features provided by the proxyprovider.t000-n.de group.
|
||||
type ProxyproviderV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *ProxyproviderV1alpha1Client) ProxyProviders(namespace string) ProxyProviderInterface {
|
||||
return newProxyProviders(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new ProxyproviderV1alpha1Client for the given config.
|
||||
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||
func NewForConfig(c *rest.Config) (*ProxyproviderV1alpha1Client, error) {
|
||||
config := *c
|
||||
setConfigDefaults(&config)
|
||||
httpClient, err := rest.HTTPClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewForConfigAndClient(&config, httpClient)
|
||||
}
|
||||
|
||||
// NewForConfigAndClient creates a new ProxyproviderV1alpha1Client for the given config and http client.
|
||||
// Note the http client provided takes precedence over the configured transport values.
|
||||
func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ProxyproviderV1alpha1Client, error) {
|
||||
config := *c
|
||||
setConfigDefaults(&config)
|
||||
client, err := rest.RESTClientForConfigAndClient(&config, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ProxyproviderV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new ProxyproviderV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *ProxyproviderV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new ProxyproviderV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *ProxyproviderV1alpha1Client {
|
||||
return &ProxyproviderV1alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) {
|
||||
gv := proxyproviderv1alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *ProxyproviderV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package application
|
||||
|
||||
import (
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/application/v1alpha1"
|
||||
internalinterfaces "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1alpha1 provides access to shared informers for resources in V1alpha1.
|
||||
V1alpha1() v1alpha1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1alpha1 returns a new v1alpha1.Interface.
|
||||
func (g *group) V1alpha1() v1alpha1.Interface {
|
||||
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
time "time"
|
||||
|
||||
apisapplicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
|
||||
versioned "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
|
||||
internalinterfaces "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
applicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/listers/application/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// ApplicationInformer provides access to a shared informer and lister for
|
||||
// Applications.
|
||||
type ApplicationInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() applicationv1alpha1.ApplicationLister
|
||||
}
|
||||
|
||||
type applicationInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewApplicationInformer constructs a new informer for Application type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewApplicationInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewApplicationInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers})
|
||||
}
|
||||
|
||||
// NewFilteredApplicationInformer constructs a new informer for Application type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredApplicationInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return NewApplicationInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions})
|
||||
}
|
||||
|
||||
// NewApplicationInformerWithOptions constructs a new informer for Application type with additional options.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewApplicationInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer {
|
||||
gvr := schema.GroupVersionResource{Group: "application.t000-n.de", Version: "v1alpha1", Resource: "applications"}
|
||||
identifier := options.InformerName.WithResource(gvr)
|
||||
tweakListOptions := options.TweakListOptions
|
||||
return cache.NewSharedIndexInformerWithOptions(
|
||||
cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{
|
||||
ListFunc: func(opts v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.ApplicationV1alpha1().Applications(namespace).List(context.Background(), opts)
|
||||
},
|
||||
WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.ApplicationV1alpha1().Applications(namespace).Watch(context.Background(), opts)
|
||||
},
|
||||
ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.ApplicationV1alpha1().Applications(namespace).List(ctx, opts)
|
||||
},
|
||||
WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.ApplicationV1alpha1().Applications(namespace).Watch(ctx, opts)
|
||||
},
|
||||
}, client),
|
||||
&apisapplicationv1alpha1.Application{},
|
||||
cache.SharedIndexInformerOptions{
|
||||
ResyncPeriod: options.ResyncPeriod,
|
||||
Indexers: options.Indexers,
|
||||
Identifier: identifier,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (f *applicationInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewApplicationInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions})
|
||||
}
|
||||
|
||||
func (f *applicationInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&apisapplicationv1alpha1.Application{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *applicationInformer) Lister() applicationv1alpha1.ApplicationLister {
|
||||
return applicationv1alpha1.NewApplicationLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
internalinterfaces "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// Applications returns a ApplicationInformer.
|
||||
Applications() ApplicationInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// Applications returns a ApplicationInformer.
|
||||
func (v *version) Applications() ApplicationInformer {
|
||||
return &applicationInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package externalversions
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
time "time"
|
||||
|
||||
versioned "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
|
||||
application "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/application"
|
||||
internalinterfaces "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
policybinding "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/policybinding"
|
||||
proxyprovider "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/proxyprovider"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
wait "k8s.io/apimachinery/pkg/util/wait"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// SharedInformerOption defines the functional option type for SharedInformerFactory.
|
||||
type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory
|
||||
|
||||
type sharedInformerFactory struct {
|
||||
client versioned.Interface
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
lock sync.Mutex
|
||||
defaultResync time.Duration
|
||||
customResync map[reflect.Type]time.Duration
|
||||
transform cache.TransformFunc
|
||||
informerName *cache.InformerName
|
||||
|
||||
informers map[reflect.Type]cache.SharedIndexInformer
|
||||
// startedInformers is used for tracking which informers have been started.
|
||||
// This allows Start() to be called multiple times safely.
|
||||
startedInformers map[reflect.Type]bool
|
||||
// wg tracks how many goroutines were started.
|
||||
wg sync.WaitGroup
|
||||
// shuttingDown is true when Shutdown has been called. It may still be running
|
||||
// because it needs to wait for goroutines.
|
||||
shuttingDown bool
|
||||
}
|
||||
|
||||
// WithCustomResyncConfig sets a custom resync period for the specified informer types.
|
||||
func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption {
|
||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
||||
for k, v := range resyncConfig {
|
||||
factory.customResync[reflect.TypeOf(k)] = v
|
||||
}
|
||||
return factory
|
||||
}
|
||||
}
|
||||
|
||||
// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory.
|
||||
func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption {
|
||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
||||
factory.tweakListOptions = tweakListOptions
|
||||
return factory
|
||||
}
|
||||
}
|
||||
|
||||
// WithNamespace limits the SharedInformerFactory to the specified namespace.
|
||||
func WithNamespace(namespace string) SharedInformerOption {
|
||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
||||
factory.namespace = namespace
|
||||
return factory
|
||||
}
|
||||
}
|
||||
|
||||
// WithTransform sets a transform on all informers.
|
||||
func WithTransform(transform cache.TransformFunc) SharedInformerOption {
|
||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
||||
factory.transform = transform
|
||||
return factory
|
||||
}
|
||||
}
|
||||
|
||||
// WithInformerName sets the InformerName for informer identity used in metrics.
|
||||
// The InformerName must be created via cache.NewInformerName() at startup,
|
||||
// which validates global uniqueness. Each informer type will register its
|
||||
// GVR under this name.
|
||||
func WithInformerName(informerName *cache.InformerName) SharedInformerOption {
|
||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
||||
factory.informerName = informerName
|
||||
return factory
|
||||
}
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) InformerName() *cache.InformerName {
|
||||
return f.informerName
|
||||
}
|
||||
|
||||
// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces.
|
||||
func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
|
||||
return NewSharedInformerFactoryWithOptions(client, defaultResync)
|
||||
}
|
||||
|
||||
// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory.
|
||||
// Listers obtained via this SharedInformerFactory will be subject to the same filters
|
||||
// as specified here.
|
||||
//
|
||||
// Deprecated: Please use NewSharedInformerFactoryWithOptions instead
|
||||
func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {
|
||||
return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))
|
||||
}
|
||||
|
||||
// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
|
||||
func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
|
||||
factory := &sharedInformerFactory{
|
||||
client: client,
|
||||
namespace: v1.NamespaceAll,
|
||||
defaultResync: defaultResync,
|
||||
informers: make(map[reflect.Type]cache.SharedIndexInformer),
|
||||
startedInformers: make(map[reflect.Type]bool),
|
||||
customResync: make(map[reflect.Type]time.Duration),
|
||||
}
|
||||
|
||||
// Apply all options
|
||||
for _, opt := range options {
|
||||
factory = opt(factory)
|
||||
}
|
||||
|
||||
return factory
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
|
||||
f.StartWithContext(wait.ContextForChannel(stopCh))
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) StartWithContext(ctx context.Context) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
if f.shuttingDown {
|
||||
return
|
||||
}
|
||||
|
||||
for informerType, informer := range f.informers {
|
||||
if !f.startedInformers[informerType] {
|
||||
f.wg.Go(func() {
|
||||
informer.RunWithContext(ctx)
|
||||
})
|
||||
f.startedInformers[informerType] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Shutdown() {
|
||||
f.lock.Lock()
|
||||
f.shuttingDown = true
|
||||
f.lock.Unlock()
|
||||
|
||||
// Will return immediately if there is nothing to wait for.
|
||||
f.wg.Wait()
|
||||
f.informerName.Release()
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
|
||||
result := f.WaitForCacheSyncWithContext(wait.ContextForChannel(stopCh))
|
||||
return result.Synced
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult {
|
||||
informers := func() map[reflect.Type]cache.SharedIndexInformer {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
informers := map[reflect.Type]cache.SharedIndexInformer{}
|
||||
for informerType, informer := range f.informers {
|
||||
if f.startedInformers[informerType] {
|
||||
informers[informerType] = informer
|
||||
}
|
||||
}
|
||||
return informers
|
||||
}()
|
||||
|
||||
// Wait for informers to sync, without polling.
|
||||
cacheSyncs := make([]cache.DoneChecker, 0, len(informers))
|
||||
for _, informer := range informers {
|
||||
cacheSyncs = append(cacheSyncs, informer.HasSyncedChecker())
|
||||
}
|
||||
cache.WaitFor(ctx, "" /* no logging */, cacheSyncs...)
|
||||
|
||||
res := cache.SyncResult{
|
||||
Synced: make(map[reflect.Type]bool, len(informers)),
|
||||
}
|
||||
failed := false
|
||||
for informType, informer := range informers {
|
||||
hasSynced := informer.HasSynced()
|
||||
if !hasSynced {
|
||||
failed = true
|
||||
}
|
||||
res.Synced[informType] = hasSynced
|
||||
}
|
||||
if failed {
|
||||
// context.Cause is more informative than ctx.Err().
|
||||
// This must be non-nil, otherwise WaitFor wouldn't have stopped
|
||||
// prematurely.
|
||||
res.Err = context.Cause(ctx)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// InformerFor returns the SharedIndexInformer for obj using an internal
|
||||
// client.
|
||||
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
informerType := reflect.TypeOf(obj)
|
||||
informer, exists := f.informers[informerType]
|
||||
if exists {
|
||||
return informer
|
||||
}
|
||||
|
||||
resyncPeriod, exists := f.customResync[informerType]
|
||||
if !exists {
|
||||
resyncPeriod = f.defaultResync
|
||||
}
|
||||
|
||||
informer = newFunc(f.client, resyncPeriod)
|
||||
if f.transform != nil {
|
||||
informer.SetTransform(f.transform)
|
||||
}
|
||||
f.informers[informerType] = informer
|
||||
|
||||
return informer
|
||||
}
|
||||
|
||||
// SharedInformerFactory provides shared informers for resources in all known
|
||||
// API group versions.
|
||||
//
|
||||
// It is typically used like this:
|
||||
//
|
||||
// ctx, cancel := context.WithCancel(context.Background())
|
||||
// defer cancel()
|
||||
// factory := NewSharedInformerFactory(client, resyncPeriod)
|
||||
// defer factory.Shutdown() // Returns immediately if nothing was started.
|
||||
// genericInformer := factory.ForResource(resource)
|
||||
// typedInformer := factory.SomeAPIGroup().V1().SomeType()
|
||||
// handle, err := typeInformer.Informer().AddEventHandler(...)
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("register event handler: %v", err)
|
||||
// }
|
||||
// defer typeInformer.Informer().RemoveEventHandler(handle) // Avoids leaking goroutines.
|
||||
// factory.StartWithContext(ctx) // Start processing these informers.
|
||||
// synced := factory.WaitForCacheSyncWithContext(ctx)
|
||||
// if err := synced.AsError(); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// for v := range synced {
|
||||
// // Only if desired log some information similar to this.
|
||||
// fmt.Fprintf(os.Stdout, "cache synced: %s", v)
|
||||
// }
|
||||
//
|
||||
// // Also make sure that all of the initial cache events have been delivered.
|
||||
// if !WaitFor(ctx, "event handler sync", handle.HasSyncedChecker()) {
|
||||
// // Must have failed because of context.
|
||||
// return fmt.Errorf("sync event handler: %w", context.Cause(ctx))
|
||||
// }
|
||||
//
|
||||
// // Creating informers can also be created after Start, but then
|
||||
// // Start must be called again:
|
||||
// anotherGenericInformer := factory.ForResource(resource)
|
||||
// factory.StartWithContext(ctx)
|
||||
type SharedInformerFactory interface {
|
||||
internalinterfaces.SharedInformerFactory
|
||||
|
||||
// Start initializes all requested informers. They are handled in goroutines
|
||||
// which run until the stop channel gets closed.
|
||||
// Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync.
|
||||
//
|
||||
// Contextual logging: StartWithContext should be used instead of Start in code which supports contextual logging.
|
||||
Start(stopCh <-chan struct{})
|
||||
|
||||
// StartWithContext initializes all requested informers. They are handled in goroutines
|
||||
// which run until the context gets canceled.
|
||||
// Warning: StartWithContext does not block. When run in a go-routine, it will race with a later WaitForCacheSync.
|
||||
StartWithContext(ctx context.Context)
|
||||
|
||||
// Shutdown marks a factory as shutting down. At that point no new
|
||||
// informers can be started anymore and Start will return without
|
||||
// doing anything.
|
||||
//
|
||||
// In addition, Shutdown blocks until all goroutines have terminated. For that
|
||||
// to happen, the close channel(s) that they were started with must be closed,
|
||||
// either before Shutdown gets called or while it is waiting.
|
||||
//
|
||||
// Shutdown may be called multiple times, even concurrently. All such calls will
|
||||
// block until all goroutines have terminated.
|
||||
Shutdown()
|
||||
|
||||
// WaitForCacheSync blocks until all started informers' caches were synced
|
||||
// or the stop channel gets closed.
|
||||
//
|
||||
// Contextual logging: WaitForCacheSync should be used instead of WaitForCacheSync in code which supports contextual logging. It also returns a more useful result.
|
||||
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
|
||||
|
||||
// WaitForCacheSyncWithContext blocks until all started informers' caches were synced
|
||||
// or the context gets canceled.
|
||||
WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult
|
||||
|
||||
// ForResource gives generic access to a shared informer of the matching type.
|
||||
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
|
||||
|
||||
// InformerFor returns the SharedIndexInformer for obj using an internal
|
||||
// client.
|
||||
InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer
|
||||
|
||||
Application() application.Interface
|
||||
PolicyBinding() policybinding.Interface
|
||||
Proxyprovider() proxyprovider.Interface
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Application() application.Interface {
|
||||
return application.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) PolicyBinding() policybinding.Interface {
|
||||
return policybinding.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Proxyprovider() proxyprovider.Interface {
|
||||
return proxyprovider.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package externalversions
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
|
||||
// sharedInformers based on type
|
||||
type GenericInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() cache.GenericLister
|
||||
}
|
||||
|
||||
type genericInformer struct {
|
||||
informer cache.SharedIndexInformer
|
||||
resource schema.GroupResource
|
||||
}
|
||||
|
||||
// Informer returns the SharedIndexInformer.
|
||||
func (f *genericInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.informer
|
||||
}
|
||||
|
||||
// Lister returns the GenericLister.
|
||||
func (f *genericInformer) Lister() cache.GenericLister {
|
||||
return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)
|
||||
}
|
||||
|
||||
// ForResource gives generic access to a shared informer of the matching type
|
||||
// TODO extend this to unknown resources with a client pool
|
||||
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
|
||||
switch resource {
|
||||
// Group=application.t000-n.de, Version=v1alpha1
|
||||
case v1alpha1.SchemeGroupVersion.WithResource("applications"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Application().V1alpha1().Applications().Informer()}, nil
|
||||
|
||||
// Group=policybinding.t000-n.de, Version=v1alpha1
|
||||
case policybindingv1alpha1.SchemeGroupVersion.WithResource("policybindings"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.PolicyBinding().V1alpha1().PolicyBindings().Informer()}, nil
|
||||
|
||||
// Group=proxyprovider.t000-n.de, Version=v1alpha1
|
||||
case proxyproviderv1alpha1.SchemeGroupVersion.WithResource("proxyproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Proxyprovider().V1alpha1().ProxyProviders().Informer()}, nil
|
||||
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no informer found for %v", resource)
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package internalinterfaces
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
versioned "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
|
||||
type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer
|
||||
|
||||
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
|
||||
type SharedInformerFactory interface {
|
||||
Start(stopCh <-chan struct{})
|
||||
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
|
||||
InformerName() *cache.InformerName
|
||||
}
|
||||
|
||||
// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
|
||||
type TweakListOptionsFunc func(*v1.ListOptions)
|
||||
|
||||
// InformerOptions holds the options for creating an informer.
|
||||
type InformerOptions struct {
|
||||
// ResyncPeriod is the resync period for this informer.
|
||||
// If not set, defaults to 0 (no resync).
|
||||
ResyncPeriod time.Duration
|
||||
|
||||
// Indexers are the indexers for this informer.
|
||||
Indexers cache.Indexers
|
||||
|
||||
// InformerName is used to uniquely identify this informer for metrics.
|
||||
// If not set, metrics will not be published for this informer.
|
||||
// Use cache.NewInformerName() to create an InformerName at startup.
|
||||
InformerName *cache.InformerName
|
||||
|
||||
// TweakListOptions is an optional function to modify the list options.
|
||||
TweakListOptions TweakListOptionsFunc
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package policybinding
|
||||
|
||||
import (
|
||||
internalinterfaces "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/policybinding/v1alpha1"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1alpha1 provides access to shared informers for resources in V1alpha1.
|
||||
V1alpha1() v1alpha1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1alpha1 returns a new v1alpha1.Interface.
|
||||
func (g *group) V1alpha1() v1alpha1.Interface {
|
||||
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
internalinterfaces "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// PolicyBindings returns a PolicyBindingInformer.
|
||||
PolicyBindings() PolicyBindingInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// PolicyBindings returns a PolicyBindingInformer.
|
||||
func (v *version) PolicyBindings() PolicyBindingInformer {
|
||||
return &policyBindingInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
time "time"
|
||||
|
||||
apispolicybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
|
||||
versioned "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
|
||||
internalinterfaces "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/listers/policybinding/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// PolicyBindingInformer provides access to a shared informer and lister for
|
||||
// PolicyBindings.
|
||||
type PolicyBindingInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() policybindingv1alpha1.PolicyBindingLister
|
||||
}
|
||||
|
||||
type policyBindingInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewPolicyBindingInformer constructs a new informer for PolicyBinding type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewPolicyBindingInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewPolicyBindingInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers})
|
||||
}
|
||||
|
||||
// NewFilteredPolicyBindingInformer constructs a new informer for PolicyBinding type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredPolicyBindingInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return NewPolicyBindingInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions})
|
||||
}
|
||||
|
||||
// NewPolicyBindingInformerWithOptions constructs a new informer for PolicyBinding type with additional options.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewPolicyBindingInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer {
|
||||
gvr := schema.GroupVersionResource{Group: "policybinding.t000-n.de", Version: "v1alpha1", Resource: "policybindings"}
|
||||
identifier := options.InformerName.WithResource(gvr)
|
||||
tweakListOptions := options.TweakListOptions
|
||||
return cache.NewSharedIndexInformerWithOptions(
|
||||
cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{
|
||||
ListFunc: func(opts v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.PolicyBindingV1alpha1().PolicyBindings(namespace).List(context.Background(), opts)
|
||||
},
|
||||
WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.PolicyBindingV1alpha1().PolicyBindings(namespace).Watch(context.Background(), opts)
|
||||
},
|
||||
ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.PolicyBindingV1alpha1().PolicyBindings(namespace).List(ctx, opts)
|
||||
},
|
||||
WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.PolicyBindingV1alpha1().PolicyBindings(namespace).Watch(ctx, opts)
|
||||
},
|
||||
}, client),
|
||||
&apispolicybindingv1alpha1.PolicyBinding{},
|
||||
cache.SharedIndexInformerOptions{
|
||||
ResyncPeriod: options.ResyncPeriod,
|
||||
Indexers: options.Indexers,
|
||||
Identifier: identifier,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (f *policyBindingInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewPolicyBindingInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions})
|
||||
}
|
||||
|
||||
func (f *policyBindingInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&apispolicybindingv1alpha1.PolicyBinding{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *policyBindingInformer) Lister() policybindingv1alpha1.PolicyBindingLister {
|
||||
return policybindingv1alpha1.NewPolicyBindingLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package proxyprovider
|
||||
|
||||
import (
|
||||
internalinterfaces "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/proxyprovider/v1alpha1"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1alpha1 provides access to shared informers for resources in V1alpha1.
|
||||
V1alpha1() v1alpha1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1alpha1 returns a new v1alpha1.Interface.
|
||||
func (g *group) V1alpha1() v1alpha1.Interface {
|
||||
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
internalinterfaces "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// ProxyProviders returns a ProxyProviderInformer.
|
||||
ProxyProviders() ProxyProviderInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// ProxyProviders returns a ProxyProviderInformer.
|
||||
func (v *version) ProxyProviders() ProxyProviderInformer {
|
||||
return &proxyProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
time "time"
|
||||
|
||||
apisproxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
||||
versioned "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned"
|
||||
internalinterfaces "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/listers/proxyprovider/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// ProxyProviderInformer provides access to a shared informer and lister for
|
||||
// ProxyProviders.
|
||||
type ProxyProviderInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() proxyproviderv1alpha1.ProxyProviderLister
|
||||
}
|
||||
|
||||
type proxyProviderInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewProxyProviderInformer constructs a new informer for ProxyProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewProxyProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewProxyProviderInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers})
|
||||
}
|
||||
|
||||
// NewFilteredProxyProviderInformer constructs a new informer for ProxyProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredProxyProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return NewProxyProviderInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions})
|
||||
}
|
||||
|
||||
// NewProxyProviderInformerWithOptions constructs a new informer for ProxyProvider type with additional options.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewProxyProviderInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer {
|
||||
gvr := schema.GroupVersionResource{Group: "proxyprovider.t000-n.de", Version: "v1alpha1", Resource: "proxyproviders"}
|
||||
identifier := options.InformerName.WithResource(gvr)
|
||||
tweakListOptions := options.TweakListOptions
|
||||
return cache.NewSharedIndexInformerWithOptions(
|
||||
cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{
|
||||
ListFunc: func(opts v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.ProxyproviderV1alpha1().ProxyProviders(namespace).List(context.Background(), opts)
|
||||
},
|
||||
WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.ProxyproviderV1alpha1().ProxyProviders(namespace).Watch(context.Background(), opts)
|
||||
},
|
||||
ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.ProxyproviderV1alpha1().ProxyProviders(namespace).List(ctx, opts)
|
||||
},
|
||||
WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&opts)
|
||||
}
|
||||
return client.ProxyproviderV1alpha1().ProxyProviders(namespace).Watch(ctx, opts)
|
||||
},
|
||||
}, client),
|
||||
&apisproxyproviderv1alpha1.ProxyProvider{},
|
||||
cache.SharedIndexInformerOptions{
|
||||
ResyncPeriod: options.ResyncPeriod,
|
||||
Indexers: options.Indexers,
|
||||
Identifier: identifier,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (f *proxyProviderInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewProxyProviderInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions})
|
||||
}
|
||||
|
||||
func (f *proxyProviderInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&apisproxyproviderv1alpha1.ProxyProvider{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *proxyProviderInformer) Lister() proxyproviderv1alpha1.ProxyProviderLister {
|
||||
return proxyproviderv1alpha1.NewProxyProviderLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
applicationv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/application/v1alpha1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
listers "k8s.io/client-go/listers"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// ApplicationLister helps list Applications.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type ApplicationLister interface {
|
||||
// List lists all Applications in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*applicationv1alpha1.Application, err error)
|
||||
// Applications returns an object that can list and get Applications.
|
||||
Applications(namespace string) ApplicationNamespaceLister
|
||||
ApplicationListerExpansion
|
||||
}
|
||||
|
||||
// applicationLister implements the ApplicationLister interface.
|
||||
type applicationLister struct {
|
||||
listers.ResourceIndexer[*applicationv1alpha1.Application]
|
||||
}
|
||||
|
||||
// NewApplicationLister returns a new ApplicationLister.
|
||||
func NewApplicationLister(indexer cache.Indexer) ApplicationLister {
|
||||
return &applicationLister{listers.New[*applicationv1alpha1.Application](indexer, applicationv1alpha1.Resource("application"))}
|
||||
}
|
||||
|
||||
// Applications returns an object that can list and get Applications.
|
||||
func (s *applicationLister) Applications(namespace string) ApplicationNamespaceLister {
|
||||
return applicationNamespaceLister{listers.NewNamespaced[*applicationv1alpha1.Application](s.ResourceIndexer, namespace)}
|
||||
}
|
||||
|
||||
// ApplicationNamespaceLister helps list and get Applications.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type ApplicationNamespaceLister interface {
|
||||
// List lists all Applications in the indexer for a given namespace.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*applicationv1alpha1.Application, err error)
|
||||
// Get retrieves the Application from the indexer for a given namespace and name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*applicationv1alpha1.Application, error)
|
||||
ApplicationNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// applicationNamespaceLister implements the ApplicationNamespaceLister
|
||||
// interface.
|
||||
type applicationNamespaceLister struct {
|
||||
listers.ResourceIndexer[*applicationv1alpha1.Application]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// ApplicationListerExpansion allows custom methods to be added to
|
||||
// ApplicationLister.
|
||||
type ApplicationListerExpansion interface{}
|
||||
|
||||
// ApplicationNamespaceListerExpansion allows custom methods to be added to
|
||||
// ApplicationNamespaceLister.
|
||||
type ApplicationNamespaceListerExpansion interface{}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// PolicyBindingListerExpansion allows custom methods to be added to
|
||||
// PolicyBindingLister.
|
||||
type PolicyBindingListerExpansion interface{}
|
||||
|
||||
// PolicyBindingNamespaceListerExpansion allows custom methods to be added to
|
||||
// PolicyBindingNamespaceLister.
|
||||
type PolicyBindingNamespaceListerExpansion interface{}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
policybindingv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/policybinding/v1alpha1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
listers "k8s.io/client-go/listers"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// PolicyBindingLister helps list PolicyBindings.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type PolicyBindingLister interface {
|
||||
// List lists all PolicyBindings in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*policybindingv1alpha1.PolicyBinding, err error)
|
||||
// PolicyBindings returns an object that can list and get PolicyBindings.
|
||||
PolicyBindings(namespace string) PolicyBindingNamespaceLister
|
||||
PolicyBindingListerExpansion
|
||||
}
|
||||
|
||||
// policyBindingLister implements the PolicyBindingLister interface.
|
||||
type policyBindingLister struct {
|
||||
listers.ResourceIndexer[*policybindingv1alpha1.PolicyBinding]
|
||||
}
|
||||
|
||||
// NewPolicyBindingLister returns a new PolicyBindingLister.
|
||||
func NewPolicyBindingLister(indexer cache.Indexer) PolicyBindingLister {
|
||||
return &policyBindingLister{listers.New[*policybindingv1alpha1.PolicyBinding](indexer, policybindingv1alpha1.Resource("policybinding"))}
|
||||
}
|
||||
|
||||
// PolicyBindings returns an object that can list and get PolicyBindings.
|
||||
func (s *policyBindingLister) PolicyBindings(namespace string) PolicyBindingNamespaceLister {
|
||||
return policyBindingNamespaceLister{listers.NewNamespaced[*policybindingv1alpha1.PolicyBinding](s.ResourceIndexer, namespace)}
|
||||
}
|
||||
|
||||
// PolicyBindingNamespaceLister helps list and get PolicyBindings.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type PolicyBindingNamespaceLister interface {
|
||||
// List lists all PolicyBindings in the indexer for a given namespace.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*policybindingv1alpha1.PolicyBinding, err error)
|
||||
// Get retrieves the PolicyBinding from the indexer for a given namespace and name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*policybindingv1alpha1.PolicyBinding, error)
|
||||
PolicyBindingNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// policyBindingNamespaceLister implements the PolicyBindingNamespaceLister
|
||||
// interface.
|
||||
type policyBindingNamespaceLister struct {
|
||||
listers.ResourceIndexer[*policybindingv1alpha1.PolicyBinding]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// ProxyProviderListerExpansion allows custom methods to be added to
|
||||
// ProxyProviderLister.
|
||||
type ProxyProviderListerExpansion interface{}
|
||||
|
||||
// ProxyProviderNamespaceListerExpansion allows custom methods to be added to
|
||||
// ProxyProviderNamespaceLister.
|
||||
type ProxyProviderNamespaceListerExpansion interface{}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
proxyproviderv1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
listers "k8s.io/client-go/listers"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// ProxyProviderLister helps list ProxyProviders.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type ProxyProviderLister interface {
|
||||
// List lists all ProxyProviders in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*proxyproviderv1alpha1.ProxyProvider, err error)
|
||||
// ProxyProviders returns an object that can list and get ProxyProviders.
|
||||
ProxyProviders(namespace string) ProxyProviderNamespaceLister
|
||||
ProxyProviderListerExpansion
|
||||
}
|
||||
|
||||
// proxyProviderLister implements the ProxyProviderLister interface.
|
||||
type proxyProviderLister struct {
|
||||
listers.ResourceIndexer[*proxyproviderv1alpha1.ProxyProvider]
|
||||
}
|
||||
|
||||
// NewProxyProviderLister returns a new ProxyProviderLister.
|
||||
func NewProxyProviderLister(indexer cache.Indexer) ProxyProviderLister {
|
||||
return &proxyProviderLister{listers.New[*proxyproviderv1alpha1.ProxyProvider](indexer, proxyproviderv1alpha1.Resource("proxyprovider"))}
|
||||
}
|
||||
|
||||
// ProxyProviders returns an object that can list and get ProxyProviders.
|
||||
func (s *proxyProviderLister) ProxyProviders(namespace string) ProxyProviderNamespaceLister {
|
||||
return proxyProviderNamespaceLister{listers.NewNamespaced[*proxyproviderv1alpha1.ProxyProvider](s.ResourceIndexer, namespace)}
|
||||
}
|
||||
|
||||
// ProxyProviderNamespaceLister helps list and get ProxyProviders.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type ProxyProviderNamespaceLister interface {
|
||||
// List lists all ProxyProviders in the indexer for a given namespace.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*proxyproviderv1alpha1.ProxyProvider, err error)
|
||||
// Get retrieves the ProxyProvider from the indexer for a given namespace and name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*proxyproviderv1alpha1.ProxyProvider, error)
|
||||
ProxyProviderNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// proxyProviderNamespaceLister implements the ProxyProviderNamespaceLister
|
||||
// interface.
|
||||
type proxyProviderNamespaceLister struct {
|
||||
listers.ResourceIndexer[*proxyproviderv1alpha1.ProxyProvider]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package signals
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/signal"
|
||||
)
|
||||
|
||||
var onlyOneSignalHandler = make(chan struct{})
|
||||
|
||||
// SetupSignalHandler registered for SIGTERM and SIGINT. A context is returned
|
||||
// which is cancelled on one of these signals. If a second signal is caught,
|
||||
// the program is terminated with exit code 1.
|
||||
func SetupSignalHandler() context.Context {
|
||||
close(onlyOneSignalHandler) // panics when called twice
|
||||
|
||||
c := make(chan os.Signal, 2)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
signal.Notify(c, shutdownSignals...)
|
||||
go func() {
|
||||
<-c
|
||||
cancel()
|
||||
<-c
|
||||
os.Exit(1) // second signal. Exit directly.
|
||||
}()
|
||||
|
||||
return ctx
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user