Compare commits
20 Commits
a117fcbba6
...
379ae5e80f
Author | SHA1 | Date | |
---|---|---|---|
379ae5e80f | |||
77331c5080 | |||
197b718b85 | |||
10354ee11a | |||
64eac3d7c1 | |||
2e952ea8cd | |||
4308312a61 | |||
b5342ab86a | |||
13ddc853fb | |||
f085bf1088 | |||
0567dea6c5 | |||
4a589395d2 | |||
99977c1f8d | |||
1b2e0faece | |||
16dc78358d | |||
a80e03ac90 | |||
4741fc1f00 | |||
cc9a8c787f | |||
a4deeac442 | |||
713a6da6e9 |
2
.cargo/audit.toml
Normal file
2
.cargo/audit.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[advisories]
|
||||||
|
ignore = ["RUSTSEC-2024-0344"]
|
4
.dockerignore
Normal file
4
.dockerignore
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
*
|
||||||
|
!queries
|
||||||
|
!src
|
||||||
|
!Cargo.*
|
|
@ -7,25 +7,19 @@ on:
|
||||||
tags:
|
tags:
|
||||||
- v*.*.*
|
- v*.*.*
|
||||||
|
|
||||||
|
env:
|
||||||
|
OCI_REPO: git.huizinga.dev/dreaded_x/${{ gitea.event.repository.name}}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build container
|
name: Build container and manifests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Docker meta
|
- name: Get Git commit timestamps
|
||||||
id: meta
|
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
|
||||||
uses: docker/metadata-action@v5
|
|
||||||
with:
|
|
||||||
images: git.huizinga.dev/dreaded_x/${{ gitea.event.repository.name}}
|
|
||||||
tags: |
|
|
||||||
type=ref,event=branch
|
|
||||||
type=ref,event=pr
|
|
||||||
type=semver,pattern={{version}}
|
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
|
||||||
type=sha
|
|
||||||
|
|
||||||
- name: Login to registry
|
- name: Login to registry
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
|
@ -34,20 +28,8 @@ jobs:
|
||||||
username: ${{ gitea.actor }}
|
username: ${{ gitea.actor }}
|
||||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Set up Docker Buildx
|
||||||
uses: https://github.com/docker/build-push-action@v5
|
uses: docker/setup-buildx-action@v3
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
push: true
|
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
|
||||||
|
|
||||||
manifests:
|
|
||||||
name: Publish manifests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install kustomize
|
- name: Install kustomize
|
||||||
run: |
|
run: |
|
||||||
|
@ -58,26 +40,56 @@ jobs:
|
||||||
with:
|
with:
|
||||||
version: v2.5.0
|
version: v2.5.0
|
||||||
|
|
||||||
- name: Login to registry
|
- name: Docker meta
|
||||||
uses: docker/login-action@v3
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
with:
|
with:
|
||||||
registry: git.huizinga.dev
|
images: ${{ env.OCI_REPO }}
|
||||||
username: ${{ gitea.actor }}
|
tags: |
|
||||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
type=edge
|
||||||
|
type=ref,event=branch
|
||||||
|
type=semver,pattern=v{{version}}
|
||||||
|
type=semver,pattern=v{{major}}.{{minor}}
|
||||||
|
type=semver,pattern=v{{major}}
|
||||||
|
|
||||||
# TODO: Generate and include crds
|
- name: Build and export to docker
|
||||||
- name: Generate manifets
|
id: build
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
load: true
|
||||||
|
annotations: ${{ steps.meta.outputs.annotations }}
|
||||||
|
env:
|
||||||
|
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
|
||||||
|
|
||||||
|
- name: Generate CRDs
|
||||||
run: |
|
run: |
|
||||||
./kustomize build ./manifests | sed "s/\${SHA_SHORT}/$(git rev-parse --short HEAD)/" > ./app.yaml
|
docker run --rm ${{ steps.build.outputs.imageid }} /crdgen > ./manifests/crds.yaml
|
||||||
|
|
||||||
|
- name: Push container
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
id: push
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
sbom: true
|
||||||
|
provenance: mode=max
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
annotations: ${{ steps.meta.outputs.annotations }}
|
||||||
|
env:
|
||||||
|
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
|
||||||
|
|
||||||
|
- name: Kustomize manifests
|
||||||
|
run: |
|
||||||
|
./kustomize build ./manifests | sed "s/\${DIGEST}/${{ steps.push.outputs.digest }}/" > ./manifests.yaml
|
||||||
|
|
||||||
- name: Push manifests
|
- name: Push manifests
|
||||||
run: |
|
run: |
|
||||||
flux push artifact oci://git.huizinga.dev/dreaded_x/${{ gitea.event.repository.name }}/manifests:sha-$(git rev-parse --short HEAD) \
|
flux push artifact oci://$OCI_REPO/manifests:latest \
|
||||||
--path="./app.yaml" \
|
--path="./manifests.yaml" \
|
||||||
--source="$(git config --get remote.origin.url)" \
|
--source="$(git config --get remote.origin.url)" \
|
||||||
--revision="$(git branch --show-current)@sha1:$(git rev-parse HEAD)"
|
--revision="$(git rev-parse HEAD)" \
|
||||||
|
$(echo "${{ steps.meta.outputs.labels }}" | sed -e 's/^/-a /')
|
||||||
|
|
||||||
- name: Tag manifests
|
flux tag artifact oci://$OCI_REPO/manifests:latest \
|
||||||
run: |
|
$(echo "${{ steps.meta.outputs.tags }}" | sed -e 's/^.*:/--tag /')
|
||||||
flux tag artifact oci://git.huizinga.dev/dreaded_x/${{ gitea.event.repository.name }}/manifests:sha-$(git rev-parse --short HEAD) \
|
|
||||||
--tag latest
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
fail_fast: true
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.6.0
|
rev: v4.6.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
|
- id: check-yaml
|
||||||
- id: check-toml
|
- id: check-toml
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
- id: check-merge-conflict
|
- id: check-merge-conflict
|
||||||
|
@ -19,10 +22,12 @@ repos:
|
||||||
- id: fmt
|
- id: fmt
|
||||||
name: fmt
|
name: fmt
|
||||||
description: Format files with cargo fmt.
|
description: Format files with cargo fmt.
|
||||||
entry: cargo fmt
|
entry: cargo +nightly fmt
|
||||||
language: system
|
language: system
|
||||||
types: [rust]
|
types: [rust]
|
||||||
args: ["--", "--check"]
|
args: ["--", "--check"]
|
||||||
|
# For some reason some formatting is different depending on how you invoke?
|
||||||
|
pass_filenames: false
|
||||||
|
|
||||||
- id: clippy
|
- id: clippy
|
||||||
name: clippy
|
name: clippy
|
||||||
|
@ -30,7 +35,17 @@ repos:
|
||||||
entry: cargo clippy
|
entry: cargo clippy
|
||||||
language: system
|
language: system
|
||||||
args: ["--", "-D", "warnings"]
|
args: ["--", "-D", "warnings"]
|
||||||
types: [rust]
|
types: [file]
|
||||||
|
files: (\.rs|Cargo.lock)$
|
||||||
|
pass_filenames: false
|
||||||
|
|
||||||
|
- id: audit
|
||||||
|
name: audit
|
||||||
|
description: Audit packages
|
||||||
|
entry: cargo audit
|
||||||
|
language: system
|
||||||
|
types: [file]
|
||||||
|
files: (\.rs|Cargo.lock)$
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
|
|
||||||
- id: test
|
- id: test
|
||||||
|
@ -39,10 +54,11 @@ repos:
|
||||||
entry: cargo test
|
entry: cargo test
|
||||||
language: system
|
language: system
|
||||||
args: ["--workspace"]
|
args: ["--workspace"]
|
||||||
types: [rust]
|
types: [file]
|
||||||
|
files: (\.rs|Cargo.lock)$
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
|
|
||||||
- repo: https://github.com/pryorda/dockerfilelint-precommit-hooks
|
- repo: https://github.com/hadolint/hadolint
|
||||||
rev: v0.1.0
|
rev: v2.12.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: dockerfilelint
|
- id: hadolint
|
||||||
|
|
2
.rustfmt.toml
Normal file
2
.rustfmt.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
imports_granularity = "Module"
|
||||||
|
group_imports = "StdExternalCrate"
|
266
Cargo.lock
generated
266
Cargo.lock
generated
|
@ -27,7 +27,7 @@ dependencies = [
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.2.15",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"version_check",
|
"version_check",
|
||||||
"zerocopy",
|
"zerocopy 0.7.35",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -115,7 +115,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -126,7 +126,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -137,9 +137,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backon"
|
name = "backon"
|
||||||
version = "1.4.0"
|
version = "1.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49fef586913a57ff189f25c9b3d034356a5bf6b3fa9a7f067588fe1698ba1f5d"
|
checksum = "970d91570c01a8a5959b36ad7dd1c30642df24b6b3068710066f6809f7033bb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"gloo-timers",
|
"gloo-timers",
|
||||||
|
@ -234,15 +234,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.10.0"
|
version = "1.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9"
|
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.15"
|
version = "1.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af"
|
checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
@ -404,7 +404,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"strsim 0.10.0",
|
"strsim 0.10.0",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -428,7 +428,7 @@ dependencies = [
|
||||||
"cynic-codegen",
|
"cynic-codegen",
|
||||||
"darling",
|
"darling",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -452,7 +452,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"strsim 0.11.1",
|
"strsim 0.11.1",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -463,7 +463,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -483,7 +483,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -525,7 +525,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -543,7 +543,7 @@ dependencies = [
|
||||||
"enum-ordinalize",
|
"enum-ordinalize",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -575,7 +575,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -619,9 +619,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "foldhash"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
|
@ -688,7 +688,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -765,6 +765,20 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
|
"libc",
|
||||||
|
"r-efi",
|
||||||
|
"wasi 0.14.2+wasi-0.2.4",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.31.1"
|
version = "0.31.1"
|
||||||
|
@ -1139,7 +1153,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1342,7 +1356,7 @@ dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1390,9 +1404,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.170"
|
version = "0.2.171"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
|
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
|
@ -1411,7 +1425,6 @@ name = "lldap-controller"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
|
||||||
"chrono",
|
"chrono",
|
||||||
"cynic",
|
"cynic",
|
||||||
"futures",
|
"futures",
|
||||||
|
@ -1421,7 +1434,7 @@ dependencies = [
|
||||||
"lldap_auth",
|
"lldap_auth",
|
||||||
"passwords",
|
"passwords",
|
||||||
"queries",
|
"queries",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -1436,7 +1449,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lldap_auth"
|
name = "lldap_auth"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/lldap/lldap#049e882c359f1480ec3cb492a63a95eaf2efe6d1"
|
source = "git+https://github.com/lldap/lldap#20ade89633164ee069fca6f4b925a79a55c62f93"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
|
@ -1445,7 +1458,7 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.2.15",
|
||||||
"opaque-ke",
|
"opaque-ke",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
"rust-argon2",
|
"rust-argon2",
|
||||||
"serde",
|
"serde",
|
||||||
"sha2 0.9.9",
|
"sha2 0.9.9",
|
||||||
|
@ -1489,7 +1502,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex-syntax 0.8.5",
|
"regex-syntax 0.8.5",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1572,9 +1585,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.20.3"
|
version = "1.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opaque-debug"
|
name = "opaque-debug"
|
||||||
|
@ -1596,7 +1609,7 @@ dependencies = [
|
||||||
"generic-bytes",
|
"generic-bytes",
|
||||||
"hkdf",
|
"hkdf",
|
||||||
"hmac",
|
"hmac",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
"serde",
|
"serde",
|
||||||
"subtle",
|
"subtle",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
|
@ -1639,7 +1652,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"proc-macro2-diagnostics",
|
"proc-macro2-diagnostics",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1733,7 +1746,7 @@ dependencies = [
|
||||||
"pest_meta",
|
"pest_meta",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1749,22 +1762,22 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.1.9"
|
version = "1.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d"
|
checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-internal",
|
"pin-project-internal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-internal"
|
name = "pin-project-internal"
|
||||||
version = "1.1.9"
|
version = "1.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67"
|
checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1781,11 +1794,11 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.20"
|
version = "0.2.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy",
|
"zerocopy 0.8.23",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1811,7 +1824,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
"version_check",
|
"version_check",
|
||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
|
@ -1827,11 +1840,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quinn"
|
name = "quinn"
|
||||||
version = "0.11.6"
|
version = "0.11.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef"
|
checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"cfg_aliases",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"quinn-proto",
|
"quinn-proto",
|
||||||
"quinn-udp",
|
"quinn-udp",
|
||||||
|
@ -1841,17 +1855,18 @@ dependencies = [
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
"web-time",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quinn-proto"
|
name = "quinn-proto"
|
||||||
version = "0.11.9"
|
version = "0.11.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d"
|
checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.3.2",
|
||||||
"rand",
|
"rand 0.9.0",
|
||||||
"ring",
|
"ring",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"rustls",
|
"rustls",
|
||||||
|
@ -1874,18 +1889,24 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.39"
|
version = "1.0.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r-efi"
|
||||||
|
version = "5.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
|
@ -1893,10 +1914,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha 0.3.1",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||||
|
dependencies = [
|
||||||
|
"rand_chacha 0.9.0",
|
||||||
|
"rand_core 0.9.3",
|
||||||
|
"zerocopy 0.8.23",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand_chacha"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -1907,6 +1939,16 @@ dependencies = [
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.9.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
@ -1925,6 +1967,15 @@ dependencies = [
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.2.15",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.3.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "random-number"
|
name = "random-number"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
|
@ -1932,7 +1983,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fc8cdd49be664772ffc3dbfa743bb8c34b78f9cc6a9f50e56ae878546796067"
|
checksum = "7fc8cdd49be664772ffc3dbfa743bb8c34b78f9cc6a9f50e56ae878546796067"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
"random-number-macro-impl",
|
"random-number-macro-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1944,7 +1995,7 @@ checksum = "f5135143cb48d14289139e4615bffec0d59b4cbfd4ea2398a3770bd2abfc4aa2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1982,7 +2033,7 @@ checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2031,9 +2082,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.12.14"
|
version = "0.12.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "989e327e510263980e231de548a33e63d34962d29ae61b467389a1a09627a254"
|
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -2111,9 +2162,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.23"
|
version = "0.23.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395"
|
checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -2169,9 +2220,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.102.8"
|
version = "0.103.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
|
@ -2221,7 +2272,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde_derive_internals",
|
"serde_derive_internals",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2302,7 +2353,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2313,7 +2364,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2486,9 +2537,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.99"
|
version = "2.0.100"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2"
|
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2512,7 +2563,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2541,7 +2592,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2552,7 +2603,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2592,9 +2643,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.44.0"
|
version = "1.44.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a"
|
checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -2616,7 +2667,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2631,9 +2682,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.13"
|
version = "0.7.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
|
checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -2710,7 +2761,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2863,6 +2914,15 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.14.2+wasi-0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen-rt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.100"
|
version = "0.2.100"
|
||||||
|
@ -2885,7 +2945,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2920,7 +2980,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
@ -3006,9 +3066,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-link"
|
name = "windows-link"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3"
|
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-registry"
|
name = "windows-registry"
|
||||||
|
@ -3023,9 +3083,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-result"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189"
|
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
@ -3185,6 +3245,15 @@ version = "0.53.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rt"
|
||||||
|
version = "0.39.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "write16"
|
name = "write16"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -3223,7 +3292,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3233,8 +3302,16 @@ version = "0.7.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"zerocopy-derive 0.7.35",
|
||||||
"zerocopy-derive",
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.8.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy-derive 0.8.23",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3245,7 +3322,18 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.8.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3265,7 +3353,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3286,7 +3374,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3308,5 +3396,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.100",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "lldap-controller"
|
name = "lldap-controller"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
default-run = "lldap-controller"
|
default-run = "lldap-controller"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
|
@ -15,7 +15,7 @@ insta = { version = "1.42.2", features = ["yaml"] }
|
||||||
queries = { path = "./queries" }
|
queries = { path = "./queries" }
|
||||||
anyhow = "1.0.97"
|
anyhow = "1.0.97"
|
||||||
lldap_auth = { git = "https://github.com/lldap/lldap" }
|
lldap_auth = { git = "https://github.com/lldap/lldap" }
|
||||||
rand = { version = "0.8.0" }
|
rand = { version = "0.8.5" }
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.140"
|
||||||
cynic = { workspace = true, features = ["http-reqwest"] }
|
cynic = { workspace = true, features = ["http-reqwest"] }
|
||||||
tokio = { version = "1.44.0", features = ["full"] }
|
tokio = { version = "1.44.0", features = ["full"] }
|
||||||
|
@ -30,7 +30,6 @@ tracing = "0.1.41"
|
||||||
thiserror = "2.0.12"
|
thiserror = "2.0.12"
|
||||||
chrono = "0.4.40"
|
chrono = "0.4.40"
|
||||||
passwords = "3.1.16"
|
passwords = "3.1.16"
|
||||||
async-trait = "0.1.88"
|
|
||||||
reqwest = { version = "0.12.14", default-features = false, features = [
|
reqwest = { version = "0.12.14", default-features = false, features = [
|
||||||
"json",
|
"json",
|
||||||
"rustls-tls",
|
"rustls-tls",
|
||||||
|
|
28
Dockerfile
28
Dockerfile
|
@ -1,9 +1,21 @@
|
||||||
FROM rust:1.85 AS builder
|
FROM rust:1.85 AS base
|
||||||
WORKDIR /usr/src/lldap-controller
|
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
|
||||||
ADD . .
|
RUN cargo install cargo-chef --locked --version 0.1.71 && \
|
||||||
RUN cargo install --path .
|
cargo install cargo-auditable --locked --version 0.6.6
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
FROM debian:bookworm-slim
|
FROM base AS planner
|
||||||
COPY --from=builder /usr/local/cargo/bin/lldap-controller /usr/local/bin/lldap-controller
|
COPY . .
|
||||||
COPY --from=builder /usr/local/cargo/bin/crdgen /usr/local/bin/crdgen
|
RUN cargo chef prepare --recipe-path recipe.json
|
||||||
CMD ["lldap-controller"]
|
|
||||||
|
FROM base AS builder
|
||||||
|
COPY --from=planner /app/recipe.json recipe.json
|
||||||
|
RUN cargo chef cook --release --recipe-path recipe.json
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN cargo auditable build --release
|
||||||
|
|
||||||
|
FROM gcr.io/distroless/cc-debian12:nonroot AS runtime
|
||||||
|
COPY --from=builder /app/target/release/lldap-controller /lldap-controller
|
||||||
|
COPY --from=builder /app/target/release/crdgen /crdgen
|
||||||
|
CMD ["/lldap-controller"]
|
||||||
|
|
|
@ -21,7 +21,7 @@ spec:
|
||||||
securityContext: {}
|
securityContext: {}
|
||||||
containers:
|
containers:
|
||||||
- name: lldap-controller
|
- name: lldap-controller
|
||||||
image: git.huizinga.dev/dreaded_x/lldap-controller:sha-${SHA_SHORT}
|
image: git.huizinga.dev/dreaded_x/lldap-controller@${DIGEST}
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
securityContext: {}
|
securityContext: {}
|
||||||
resources:
|
resources:
|
||||||
|
|
|
@ -2,6 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
namespace: lldap
|
namespace: lldap
|
||||||
resources:
|
resources:
|
||||||
|
- ./crds.yaml
|
||||||
- ./service-account.yaml
|
- ./service-account.yaml
|
||||||
- ./cluster-role.yaml
|
- ./cluster-role.yaml
|
||||||
- ./cluster-role-binding.yaml
|
- ./cluster-role-binding.yaml
|
||||||
|
|
|
@ -86,11 +86,35 @@ pub struct GetGroups {
|
||||||
pub groups: Vec<Group>,
|
pub groups: Vec<Group>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryVariables, Debug)]
|
||||||
|
pub struct CreateGroupVariables<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
#[cynic(graphql_type = "Mutation", variables = "CreateGroupVariables")]
|
||||||
|
pub struct CreateGroup {
|
||||||
|
#[arguments(name: $name)]
|
||||||
|
pub create_group: Group,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryVariables, Debug)]
|
||||||
|
pub struct DeleteGroupVariables {
|
||||||
|
pub id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
#[cynic(graphql_type = "Mutation", variables = "DeleteGroupVariables")]
|
||||||
|
pub struct DeleteGroup {
|
||||||
|
#[arguments(groupId: $id)]
|
||||||
|
pub delete_group: Success,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use cynic::{MutationBuilder, QueryBuilder};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use cynic::MutationBuilder;
|
|
||||||
use cynic::QueryBuilder;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn delete_user_gql_output() {
|
fn delete_user_gql_output() {
|
||||||
|
@ -139,4 +163,18 @@ mod tests {
|
||||||
|
|
||||||
insta::assert_snapshot!(operation.query);
|
insta::assert_snapshot!(operation.query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_group_gql_output() {
|
||||||
|
let operation = CreateGroup::build(CreateGroupVariables { name: "group" });
|
||||||
|
|
||||||
|
insta::assert_snapshot!(operation.query);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn delete_group_gql_output() {
|
||||||
|
let operation = DeleteGroup::build(DeleteGroupVariables { id: 0 });
|
||||||
|
|
||||||
|
insta::assert_snapshot!(operation.query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
source: queries/src/lib.rs
|
||||||
|
expression: operation.query
|
||||||
|
---
|
||||||
|
mutation CreateGroup($name: String!) {
|
||||||
|
createGroup(name: $name) {
|
||||||
|
id
|
||||||
|
displayName
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
source: queries/src/lib.rs
|
||||||
|
expression: operation.query
|
||||||
|
---
|
||||||
|
mutation DeleteGroup($id: Int!) {
|
||||||
|
deleteGroup(groupId: $id) {
|
||||||
|
ok
|
||||||
|
}
|
||||||
|
}
|
4
rust-toolchain.toml
Normal file
4
rust-toolchain.toml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "1.85"
|
||||||
|
profile = "default"
|
||||||
|
components = ["rust-analyzer"]
|
|
@ -2,7 +2,8 @@ use kube::CustomResourceExt;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
print!(
|
print!(
|
||||||
"{}",
|
"{}---\n{}",
|
||||||
serde_yaml::to_string(&lldap_controller::resources::ServiceUser::crd()).unwrap()
|
serde_yaml::to_string(&lldap_controller::resources::ServiceUser::crd()).unwrap(),
|
||||||
|
serde_yaml::to_string(&lldap_controller::resources::Group::crd()).unwrap()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
use async_trait::async_trait;
|
|
||||||
use k8s_openapi::api::core::v1::Secret;
|
use k8s_openapi::api::core::v1::Secret;
|
||||||
use kube::{
|
use kube::runtime::events::{Event, EventType, Recorder, Reporter};
|
||||||
runtime::events::{Event, EventType, Recorder, Reporter},
|
use kube::{Resource, ResourceExt};
|
||||||
Resource, ResourceExt,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::lldap::LldapConfig;
|
use crate::lldap::LldapConfig;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
pub client: kube::Client,
|
pub client: kube::Client,
|
||||||
pub lldap_config: LldapConfig,
|
pub lldap_config: LldapConfig,
|
||||||
|
@ -28,7 +26,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[allow(async_fn_in_trait)]
|
||||||
pub trait ControllerEvents {
|
pub trait ControllerEvents {
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
|
@ -40,16 +38,23 @@ pub trait ControllerEvents {
|
||||||
where
|
where
|
||||||
T: Resource<DynamicType = ()> + Sync;
|
T: Resource<DynamicType = ()> + Sync;
|
||||||
|
|
||||||
|
async fn group_created<T>(&self, obj: &T, name: &str) -> Result<(), Self::Error>
|
||||||
|
where
|
||||||
|
T: Resource<DynamicType = ()> + Sync;
|
||||||
|
|
||||||
async fn user_deleted<T>(&self, obj: &T, username: &str) -> Result<(), Self::Error>
|
async fn user_deleted<T>(&self, obj: &T, username: &str) -> Result<(), Self::Error>
|
||||||
where
|
where
|
||||||
T: Resource<DynamicType = ()> + Sync;
|
T: Resource<DynamicType = ()> + Sync;
|
||||||
|
|
||||||
|
async fn group_deleted<T>(&self, obj: &T, name: &str) -> Result<(), Self::Error>
|
||||||
|
where
|
||||||
|
T: Resource<DynamicType = ()> + Sync;
|
||||||
|
|
||||||
async fn user_not_found<T>(&self, obj: &T, username: &str) -> Result<(), Self::Error>
|
async fn user_not_found<T>(&self, obj: &T, username: &str) -> Result<(), Self::Error>
|
||||||
where
|
where
|
||||||
T: Resource<DynamicType = ()> + Sync;
|
T: Resource<DynamicType = ()> + Sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl ControllerEvents for Recorder {
|
impl ControllerEvents for Recorder {
|
||||||
type Error = kube::Error;
|
type Error = kube::Error;
|
||||||
|
|
||||||
|
@ -87,6 +92,23 @@ impl ControllerEvents for Recorder {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn group_created<T>(&self, obj: &T, name: &str) -> Result<(), Self::Error>
|
||||||
|
where
|
||||||
|
T: Resource<DynamicType = ()> + Sync,
|
||||||
|
{
|
||||||
|
self.publish(
|
||||||
|
&Event {
|
||||||
|
type_: EventType::Normal,
|
||||||
|
reason: "GroupCreated".into(),
|
||||||
|
note: Some(format!("Created group '{name}'")),
|
||||||
|
action: "GroupCreated".into(),
|
||||||
|
secondary: None,
|
||||||
|
},
|
||||||
|
&obj.object_ref(&()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
async fn user_deleted<T>(&self, obj: &T, username: &str) -> Result<(), Self::Error>
|
async fn user_deleted<T>(&self, obj: &T, username: &str) -> Result<(), Self::Error>
|
||||||
where
|
where
|
||||||
T: Resource<DynamicType = ()> + Sync,
|
T: Resource<DynamicType = ()> + Sync,
|
||||||
|
@ -104,6 +126,23 @@ impl ControllerEvents for Recorder {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn group_deleted<T>(&self, obj: &T, name: &str) -> Result<(), Self::Error>
|
||||||
|
where
|
||||||
|
T: Resource<DynamicType = ()> + Sync,
|
||||||
|
{
|
||||||
|
self.publish(
|
||||||
|
&Event {
|
||||||
|
type_: EventType::Normal,
|
||||||
|
reason: "GroupDeleted".into(),
|
||||||
|
note: Some(format!("Deleted group '{name}'")),
|
||||||
|
action: "GroupDeleted".into(),
|
||||||
|
secondary: None,
|
||||||
|
},
|
||||||
|
&obj.object_ref(&()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
async fn user_not_found<T>(&self, obj: &T, username: &str) -> Result<(), Self::Error>
|
async fn user_not_found<T>(&self, obj: &T, username: &str) -> Result<(), Self::Error>
|
||||||
where
|
where
|
||||||
T: Resource<DynamicType = ()> + Sync,
|
T: Resource<DynamicType = ()> + Sync,
|
||||||
|
|
46
src/lldap.rs
46
src/lldap.rs
|
@ -1,19 +1,20 @@
|
||||||
use anyhow::Context;
|
|
||||||
use lldap_auth::opaque::AuthenticationError;
|
|
||||||
use lldap_auth::registration::ServerRegistrationStartResponse;
|
|
||||||
use lldap_auth::{opaque, registration};
|
|
||||||
use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION};
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::{debug, trace};
|
|
||||||
|
|
||||||
|
use anyhow::Context;
|
||||||
use cynic::http::{CynicReqwestError, ReqwestExt};
|
use cynic::http::{CynicReqwestError, ReqwestExt};
|
||||||
use cynic::{GraphQlError, GraphQlResponse, MutationBuilder, QueryBuilder};
|
use cynic::{GraphQlError, GraphQlResponse, MutationBuilder, QueryBuilder};
|
||||||
use lldap_auth::login::{ClientSimpleLoginRequest, ServerLoginResponse};
|
use lldap_auth::login::{ClientSimpleLoginRequest, ServerLoginResponse};
|
||||||
|
use lldap_auth::opaque::AuthenticationError;
|
||||||
|
use lldap_auth::registration::ServerRegistrationStartResponse;
|
||||||
|
use lldap_auth::{opaque, registration};
|
||||||
use queries::{
|
use queries::{
|
||||||
AddUserToGroup, AddUserToGroupVariables, CreateUser, CreateUserVariables, DeleteUser,
|
AddUserToGroup, AddUserToGroupVariables, CreateGroup, CreateGroupVariables, CreateUser,
|
||||||
DeleteUserVariables, GetGroups, GetUser, GetUserVariables, Group, RemoveUserFromGroup,
|
CreateUserVariables, DeleteGroup, DeleteGroupVariables, DeleteUser, DeleteUserVariables,
|
||||||
RemoveUserFromGroupVariables, User,
|
GetGroups, GetUser, GetUserVariables, Group, RemoveUserFromGroup, RemoveUserFromGroupVariables,
|
||||||
|
User,
|
||||||
};
|
};
|
||||||
|
use reqwest::header::{AUTHORIZATION, HeaderMap, HeaderValue};
|
||||||
|
use tracing::{debug, trace};
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -41,6 +42,7 @@ fn check_graphql_errors<T>(response: GraphQlResponse<T>) -> Result<T> {
|
||||||
.expect("Data should be valid if there are no error"))
|
.expect("Data should be valid if there are no error"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct LldapConfig {
|
pub struct LldapConfig {
|
||||||
username: String,
|
username: String,
|
||||||
password: String,
|
password: String,
|
||||||
|
@ -150,6 +152,32 @@ impl LldapClient {
|
||||||
Ok(check_graphql_errors(response)?.groups)
|
Ok(check_graphql_errors(response)?.groups)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn create_group(&self, name: &str) -> Result<Group> {
|
||||||
|
let operation = CreateGroup::build(CreateGroupVariables { name });
|
||||||
|
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/api/graphql", self.url))
|
||||||
|
.run_graphql(operation)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(check_graphql_errors(response)?.create_group)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_group(&self, id: i32) -> Result<()> {
|
||||||
|
let operation = DeleteGroup::build(DeleteGroupVariables { id });
|
||||||
|
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/api/graphql", self.url))
|
||||||
|
.run_graphql(operation)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
check_graphql_errors(response)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn add_user_to_group(&self, username: &str, group: i32) -> Result<()> {
|
pub async fn add_user_to_group(&self, username: &str, group: i32) -> Result<()> {
|
||||||
let operation = AddUserToGroup::build(AddUserToGroupVariables { username, group });
|
let operation = AddUserToGroup::build(AddUserToGroupVariables { username, group });
|
||||||
|
|
||||||
|
|
64
src/main.rs
64
src/main.rs
|
@ -1,32 +1,49 @@
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use k8s_openapi::api::core::v1::Secret;
|
use k8s_openapi::api::core::v1::Secret;
|
||||||
use kube::{
|
use kube::runtime::controller::{self, Action};
|
||||||
runtime::{controller::Action, Controller},
|
use kube::runtime::reflector::ObjectRef;
|
||||||
Api, Client as KubeClient,
|
use kube::runtime::{Controller, watcher};
|
||||||
};
|
use kube::{Api, Client as KubeClient, Resource};
|
||||||
use lldap_controller::{
|
use lldap_controller::context::Context;
|
||||||
context::Context,
|
use lldap_controller::lldap::LldapConfig;
|
||||||
lldap::LldapConfig,
|
use lldap_controller::resources::{self, Error, Group, ServiceUser, reconcile};
|
||||||
resources::{self, reconcile, ServiceUser},
|
|
||||||
};
|
|
||||||
use tracing::{debug, info, warn};
|
use tracing::{debug, info, warn};
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Registry};
|
use tracing_subscriber::layer::SubscriberExt;
|
||||||
|
use tracing_subscriber::util::SubscriberInitExt;
|
||||||
|
use tracing_subscriber::{EnvFilter, Registry};
|
||||||
|
|
||||||
fn error_policy(_obj: Arc<ServiceUser>, err: &resources::Error, _ctx: Arc<Context>) -> Action {
|
fn error_policy<T>(_obj: Arc<T>, err: &resources::Error, _ctx: Arc<Context>) -> Action {
|
||||||
warn!("error: {}", err);
|
warn!("error: {}", err);
|
||||||
Action::requeue(Duration::from_secs(5))
|
Action::requeue(Duration::from_secs(5))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn log_status<T>(
|
||||||
|
res: Result<(ObjectRef<T>, Action), controller::Error<Error, watcher::Error>>,
|
||||||
|
) where
|
||||||
|
T: Resource,
|
||||||
|
{
|
||||||
|
match res {
|
||||||
|
Ok(obj) => debug!("reconciled {:?}", obj.0.name),
|
||||||
|
Err(err) => warn!("reconcile failed: {}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
let logger = tracing_subscriber::fmt::layer().json();
|
|
||||||
let env_filter = EnvFilter::try_from_default_env()
|
let env_filter = EnvFilter::try_from_default_env()
|
||||||
.or_else(|_| EnvFilter::try_new("info"))
|
.or_else(|_| EnvFilter::try_new("info"))
|
||||||
.expect("Fallback should be valid");
|
.expect("Fallback should be valid");
|
||||||
|
|
||||||
Registry::default().with(logger).with(env_filter).init();
|
if std::env::var("CARGO").is_ok() {
|
||||||
|
let logger = tracing_subscriber::fmt::layer().compact();
|
||||||
|
Registry::default().with(logger).with(env_filter).init();
|
||||||
|
} else {
|
||||||
|
let logger = tracing_subscriber::fmt::layer().json();
|
||||||
|
Registry::default().with(logger).with(env_filter).init();
|
||||||
|
}
|
||||||
|
|
||||||
info!("Starting controller");
|
info!("Starting controller");
|
||||||
|
|
||||||
|
@ -41,17 +58,20 @@ async fn main() -> anyhow::Result<()> {
|
||||||
let service_users = Api::<ServiceUser>::all(client.clone());
|
let service_users = Api::<ServiceUser>::all(client.clone());
|
||||||
let secrets = Api::<Secret>::all(client.clone());
|
let secrets = Api::<Secret>::all(client.clone());
|
||||||
|
|
||||||
Controller::new(service_users.clone(), Default::default())
|
let service_user_controller = Controller::new(service_users, Default::default())
|
||||||
.owns(secrets, Default::default())
|
.owns(secrets, Default::default())
|
||||||
|
.shutdown_on_signal()
|
||||||
|
.run(reconcile, error_policy, Arc::new(data.clone()))
|
||||||
|
.for_each(log_status);
|
||||||
|
|
||||||
|
let groups = Api::<Group>::all(client.clone());
|
||||||
|
|
||||||
|
let group_controller = Controller::new(groups, Default::default())
|
||||||
.shutdown_on_signal()
|
.shutdown_on_signal()
|
||||||
.run(reconcile, error_policy, Arc::new(data))
|
.run(reconcile, error_policy, Arc::new(data))
|
||||||
.for_each(|res| async move {
|
.for_each(log_status);
|
||||||
match res {
|
|
||||||
Ok(obj) => debug!("reconciled {:?}", obj.0.name),
|
tokio::join!(service_user_controller, group_controller);
|
||||||
Err(err) => warn!("reconcile failed: {}", err),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
76
src/resources/group.rs
Normal file
76
src/resources/group.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use kube::CustomResource;
|
||||||
|
use kube::runtime::controller::Action;
|
||||||
|
use schemars::JsonSchema;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tracing::{debug, trace};
|
||||||
|
|
||||||
|
use super::{Error, Reconcile, Result};
|
||||||
|
use crate::context::{Context, ControllerEvents};
|
||||||
|
|
||||||
|
#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)]
|
||||||
|
#[kube(kind = "Group", group = "lldap.huizinga.dev", version = "v1")]
|
||||||
|
#[kube(
|
||||||
|
shortname = "lg",
|
||||||
|
doc = "Custom resource for managing Groups inside of LLDAP"
|
||||||
|
)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct GroupSpec {}
|
||||||
|
|
||||||
|
impl Reconcile for Group {
|
||||||
|
async fn reconcile(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action> {
|
||||||
|
let name = self
|
||||||
|
.metadata
|
||||||
|
.name
|
||||||
|
.clone()
|
||||||
|
.ok_or(Error::MissingObjectKey(".metadata.name"))?;
|
||||||
|
|
||||||
|
debug!(name, "Apply");
|
||||||
|
|
||||||
|
let lldap_client = ctx.lldap_config.build_client().await?;
|
||||||
|
|
||||||
|
trace!(name, "Get existing groups");
|
||||||
|
let groups = lldap_client.get_groups().await?;
|
||||||
|
|
||||||
|
if !groups.iter().any(|group| group.display_name == name) {
|
||||||
|
trace!("Group does not exist yet");
|
||||||
|
|
||||||
|
lldap_client.create_group(&name).await?;
|
||||||
|
|
||||||
|
ctx.recorder.group_created(self.as_ref(), &name).await?;
|
||||||
|
} else {
|
||||||
|
trace!("Group already exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Action::requeue(Duration::from_secs(3600)))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn cleanup(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action> {
|
||||||
|
let name = self
|
||||||
|
.metadata
|
||||||
|
.name
|
||||||
|
.clone()
|
||||||
|
.ok_or(Error::MissingObjectKey(".metadata.name"))?;
|
||||||
|
|
||||||
|
debug!(name, "Cleanup");
|
||||||
|
|
||||||
|
let lldap_client = ctx.lldap_config.build_client().await?;
|
||||||
|
|
||||||
|
trace!(name, "Get existing groups");
|
||||||
|
let groups = lldap_client.get_groups().await?;
|
||||||
|
|
||||||
|
if let Some(group) = groups.iter().find(|group| group.display_name == name) {
|
||||||
|
trace!(name, "Deleting group");
|
||||||
|
|
||||||
|
lldap_client.delete_group(group.id).await?;
|
||||||
|
|
||||||
|
ctx.recorder.group_deleted(self.as_ref(), &name).await?;
|
||||||
|
} else {
|
||||||
|
trace!(name, "Group does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Action::await_change())
|
||||||
|
}
|
||||||
|
}
|
66
src/resources/mod.rs
Normal file
66
src/resources/mod.rs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
mod group;
|
||||||
|
mod service_user;
|
||||||
|
|
||||||
|
use core::fmt;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use kube::runtime::controller::Action;
|
||||||
|
use kube::runtime::finalizer;
|
||||||
|
use kube::{Api, Resource, ResourceExt};
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
|
pub use self::group::Group;
|
||||||
|
pub use self::service_user::ServiceUser;
|
||||||
|
use crate::context::Context;
|
||||||
|
use crate::lldap;
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Failed to commit: {0}")]
|
||||||
|
Commit(#[from] kube::api::entry::CommitError),
|
||||||
|
#[error("Kube api error: {0}")]
|
||||||
|
Kube(#[from] kube::Error),
|
||||||
|
#[error("LLDAP error: {0}")]
|
||||||
|
Lldap(#[from] lldap::Error),
|
||||||
|
#[error("Finalizer error: {0}")]
|
||||||
|
Finalizer(#[source] Box<finalizer::Error<Self>>),
|
||||||
|
#[error("MissingObjectKey: {0}")]
|
||||||
|
MissingObjectKey(&'static str),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<finalizer::Error<Self>> for Error {
|
||||||
|
fn from(error: finalizer::Error<Self>) -> Self {
|
||||||
|
Self::Finalizer(Box::new(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Result<T, E = Error> = std::result::Result<T, E>;
|
||||||
|
|
||||||
|
trait Reconcile {
|
||||||
|
async fn reconcile(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action>;
|
||||||
|
|
||||||
|
async fn cleanup(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(obj, ctx))]
|
||||||
|
pub async fn reconcile<T>(obj: Arc<T>, ctx: Arc<Context>) -> Result<Action>
|
||||||
|
where
|
||||||
|
T: Resource + ResourceExt + Clone + Serialize + DeserializeOwned + fmt::Debug + Reconcile,
|
||||||
|
<T as Resource>::DynamicType: Default,
|
||||||
|
{
|
||||||
|
debug!(name = obj.name_any(), "Reconcile");
|
||||||
|
|
||||||
|
let service_users = Api::<T>::all(ctx.client.clone());
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
finalizer(&service_users, &ctx.controller_name, obj, |event| async {
|
||||||
|
match event {
|
||||||
|
finalizer::Event::Apply(obj) => obj.reconcile(ctx.clone()).await,
|
||||||
|
finalizer::Event::Cleanup(obj) => obj.cleanup(ctx.clone()).await,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await?,
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,50 +1,24 @@
|
||||||
use core::fmt;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use k8s_openapi::api::core::v1::Secret;
|
use k8s_openapi::api::core::v1::Secret;
|
||||||
use k8s_openapi::apimachinery::pkg::apis::meta::v1::OwnerReference;
|
use k8s_openapi::apimachinery::pkg::apis::meta::v1::OwnerReference;
|
||||||
use k8s_openapi::NamespaceResourceScope;
|
|
||||||
use kube::api::{ObjectMeta, Patch, PatchParams, PostParams};
|
use kube::api::{ObjectMeta, Patch, PatchParams, PostParams};
|
||||||
use kube::runtime::controller::Action;
|
use kube::runtime::controller::Action;
|
||||||
use kube::runtime::finalizer;
|
use kube::{Api, CustomResource, Resource};
|
||||||
use kube::{Api, CustomResource, Resource, ResourceExt};
|
|
||||||
use passwords::PasswordGenerator;
|
use passwords::PasswordGenerator;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::de::DeserializeOwned;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use tracing::{debug, instrument, trace, warn};
|
use tracing::{debug, trace, warn};
|
||||||
|
|
||||||
|
use super::{Error, Reconcile, Result};
|
||||||
use crate::context::{Context, ControllerEvents};
|
use crate::context::{Context, ControllerEvents};
|
||||||
use crate::lldap;
|
use crate::lldap;
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
#[error("Failed to commit: {0}")]
|
|
||||||
Commit(#[from] kube::api::entry::CommitError),
|
|
||||||
#[error("Kube api error: {0}")]
|
|
||||||
Kube(#[from] kube::Error),
|
|
||||||
#[error("LLDAP error: {0}")]
|
|
||||||
Lldap(#[from] lldap::Error),
|
|
||||||
#[error("Finalizer error: {0}")]
|
|
||||||
Finalizer(#[source] Box<finalizer::Error<Self>>),
|
|
||||||
#[error("MissingObjectKey: {0}")]
|
|
||||||
MissingObjectKey(&'static str),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<finalizer::Error<Self>> for Error {
|
|
||||||
fn from(error: finalizer::Error<Self>) -> Self {
|
|
||||||
Self::Finalizer(Box::new(error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|
||||||
|
|
||||||
#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)]
|
#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)]
|
||||||
#[kube(
|
#[kube(
|
||||||
kind = "ServiceUser",
|
kind = "ServiceUser",
|
||||||
|
@ -97,46 +71,10 @@ fn new_secret(username: &str, oref: OwnerReference) -> Secret {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
trait Reconcile {
|
|
||||||
async fn reconcile(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action>;
|
|
||||||
|
|
||||||
async fn cleanup(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(obj, ctx))]
|
|
||||||
pub async fn reconcile<T>(obj: Arc<T>, ctx: Arc<Context>) -> Result<Action>
|
|
||||||
where
|
|
||||||
T: Resource<Scope = NamespaceResourceScope>
|
|
||||||
+ ResourceExt
|
|
||||||
+ Clone
|
|
||||||
+ Serialize
|
|
||||||
+ DeserializeOwned
|
|
||||||
+ fmt::Debug
|
|
||||||
+ Reconcile,
|
|
||||||
<T as Resource>::DynamicType: Default,
|
|
||||||
{
|
|
||||||
debug!(name = obj.name_any(), "Reconcile");
|
|
||||||
|
|
||||||
let namespace = obj.namespace().expect("Resource is namespace scoped");
|
|
||||||
let service_users = Api::<T>::namespaced(ctx.client.clone(), &namespace);
|
|
||||||
|
|
||||||
Ok(
|
|
||||||
finalizer(&service_users, &ctx.controller_name, obj, |event| async {
|
|
||||||
match event {
|
|
||||||
finalizer::Event::Apply(obj) => obj.reconcile(ctx.clone()).await,
|
|
||||||
finalizer::Event::Cleanup(obj) => obj.cleanup(ctx.clone()).await,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.await?,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format_username(name: &str, namespace: &str) -> String {
|
fn format_username(name: &str, namespace: &str) -> String {
|
||||||
format!("{name}.{namespace}")
|
format!("{name}.{namespace}")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl Reconcile for ServiceUser {
|
impl Reconcile for ServiceUser {
|
||||||
async fn reconcile(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action> {
|
async fn reconcile(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action> {
|
||||||
let name = self
|
let name = self
|
||||||
|
@ -289,9 +227,10 @@ impl Reconcile for ServiceUser {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
|
||||||
use kube::CustomResourceExt;
|
use kube::CustomResourceExt;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn service_user_crd_output() {
|
fn service_user_crd_output() {
|
||||||
insta::assert_yaml_snapshot!(ServiceUser::crd());
|
insta::assert_yaml_snapshot!(ServiceUser::crd());
|
5
yaml/group.yaml
Normal file
5
yaml/group.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
apiVersion: lldap.huizinga.dev/v1
|
||||||
|
kind: Group
|
||||||
|
metadata:
|
||||||
|
name: test-group
|
||||||
|
spec: {}
|
|
@ -1,6 +1,5 @@
|
||||||
apiVersion: lldap.huizinga.dev/v1
|
apiVersion: lldap.huizinga.dev/v1
|
||||||
kind: ServiceUser
|
kind: ServiceUser
|
||||||
metadata:
|
metadata:
|
||||||
name: authelia
|
name: test-user
|
||||||
spec:
|
spec: {}
|
||||||
passwordManager: false
|
|
Loading…
Reference in New Issue
Block a user