Compare commits
No commits in common. "3efa4e68f17cfafe8d3a78fa9402851ddabf6673" and "e1418883353a37ff724ce3e897ca5fa69720555a" have entirely different histories.
3efa4e68f1
...
e141888335
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
|||||||
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|
||||||
- name: Get app version from chart
|
- name: Get app version from chart
|
||||||
uses: mikefarah/yq@v4.44.3
|
uses: mikefarah/yq@v4.44.2
|
||||||
id: app_version
|
id: app_version
|
||||||
with:
|
with:
|
||||||
cmd: yq '.appVersion' charts/bitwarden-crd-operator/Chart.yaml
|
cmd: yq '.appVersion' charts/bitwarden-crd-operator/Chart.yaml
|
||||||
|
12
Dockerfile
12
Dockerfile
@ -1,15 +1,15 @@
|
|||||||
FROM alpine:3.20.3
|
FROM alpine:3.19.1
|
||||||
|
|
||||||
LABEL org.opencontainers.image.source=https://github.com/Lerentis/bitwarden-crd-operator
|
LABEL org.opencontainers.image.source=https://github.com/Lerentis/bitwarden-crd-operator
|
||||||
LABEL org.opencontainers.image.description="Kubernetes Operator to create k8s secrets from bitwarden"
|
LABEL org.opencontainers.image.description="Kubernetes Operator to create k8s secrets from bitwarden"
|
||||||
LABEL org.opencontainers.image.licenses=MIT
|
LABEL org.opencontainers.image.licenses=MIT
|
||||||
|
|
||||||
ARG PYTHON_VERSION=3.12.6-r0
|
ARG PYTHON_VERSION=3.11.9-r0
|
||||||
ARG PIP_VERSION=24.0-r2
|
ARG PIP_VERSION=23.3.1-r0
|
||||||
ARG GCOMPAT_VERSION=1.1.0-r4
|
ARG GCOMPAT_VERSION=1.1.0-r4
|
||||||
ARG LIBCRYPTO_VERSION=3.3.2-r0
|
ARG LIBCRYPTO_VERSION=3.1.4-r5
|
||||||
ARG BW_VERSION=2024.7.2
|
ARG BW_VERSION=2023.7.0
|
||||||
ARG NODE_VERSION=20.15.1-r0
|
ARG NODE_VERSION=20.12.1-r0
|
||||||
|
|
||||||
COPY requirements.txt /requirements.txt
|
COPY requirements.txt /requirements.txt
|
||||||
|
|
||||||
|
44
README.md
44
README.md
@ -56,7 +56,7 @@ And you are set to create your first secret using this operator. For that you ne
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
|
apiVersion: "lerentis.uploadfilter24.eu/v1beta7"
|
||||||
kind: BitwardenSecret
|
kind: BitwardenSecret
|
||||||
metadata:
|
metadata:
|
||||||
name: name-of-your-management-object
|
name: name-of-your-management-object
|
||||||
@ -106,7 +106,7 @@ For managing registry credentials, or pull secrets, you can create another kind
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
|
apiVersion: "lerentis.uploadfilter24.eu/v1beta7"
|
||||||
kind: RegistryCredential
|
kind: RegistryCredential
|
||||||
metadata:
|
metadata:
|
||||||
name: name-of-your-management-object
|
name: name-of-your-management-object
|
||||||
@ -147,11 +147,12 @@ One of the more freely defined types that can be used with this operator you can
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
|
apiVersion: "lerentis.uploadfilter24.eu/v1beta7"
|
||||||
kind: BitwardenTemplate
|
kind: BitwardenTemplate
|
||||||
metadata:
|
metadata:
|
||||||
name: name-of-your-management-object
|
name: name-of-your-management-object
|
||||||
spec:
|
spec:
|
||||||
|
filename: "Key of the secret to be created"
|
||||||
name: "Name of the secret to be created"
|
name: "Name of the secret to be created"
|
||||||
secretType: # Optional (Default: Opaque)
|
secretType: # Optional (Default: Opaque)
|
||||||
namespace: "Namespace of the secret to be created"
|
namespace: "Namespace of the secret to be created"
|
||||||
@ -159,31 +160,16 @@ spec:
|
|||||||
key: value
|
key: value
|
||||||
annotations: # Optional
|
annotations: # Optional
|
||||||
key: value
|
key: value
|
||||||
content:
|
template: |
|
||||||
- element:
|
---
|
||||||
filename: config.yaml
|
api:
|
||||||
template: |
|
enabled: True
|
||||||
---
|
key: {{ bitwarden_lookup("A Secret ID from bitwarden", "login or fields or attachment", "name of a field in bitwarden") }}
|
||||||
api:
|
allowCrossOrigin: false
|
||||||
enabled: True
|
apps:
|
||||||
key: {{ bitwarden_lookup("A Secret ID from bitwarden", "login or fields or attachment", "name of a field in bitwarden") }}
|
"some.app.identifier:some_version":
|
||||||
allowCrossOrigin: false
|
pubkey: {{ bitwarden_lookup("A Secret ID from bitwarden", "login or fields or attachment", "name of a field in bitwarden") }}
|
||||||
apps:
|
enabled: true
|
||||||
"some.app.identifier:some_version":
|
|
||||||
pubkey: {{ bitwarden_lookup("A Secret ID from bitwarden", "login or fields or attachment", "name of a field in bitwarden") }}
|
|
||||||
enabled: true
|
|
||||||
- element:
|
|
||||||
filename: config2.yaml
|
|
||||||
template: |
|
|
||||||
---
|
|
||||||
api:
|
|
||||||
enabled: True
|
|
||||||
key: {{ bitwarden_lookup("A Secret ID from bitwarden", "login or fields or attachment", "name of a field in bitwarden") }}
|
|
||||||
allowCrossOrigin: false
|
|
||||||
apps:
|
|
||||||
"some.app.identifier:some_version":
|
|
||||||
pubkey: {{ bitwarden_lookup("A Secret ID from bitwarden", "login or fields or attachment", "name of a field in bitwarden") }}
|
|
||||||
enabled: false
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This will result in something like the following object:
|
This will result in something like the following object:
|
||||||
@ -218,4 +204,4 @@ Please note that the rendering engine for this template is jinja2, with an addit
|
|||||||
|
|
||||||
The operator uses the bitwarden cli in the background and does not communicate to the api directly. The cli mirrors the credential store locally but doesn't sync it on every get request. Instead it will sync each secret every 15 minutes (900 seconds). You can adjust the interval by setting `BW_SYNC_INTERVAL` in the values. If your secrets update very very frequently, you can force the operator to do a sync before each get by setting `BW_FORCE_SYNC="true"`. You might run into rate limits if you do this too frequent.
|
The operator uses the bitwarden cli in the background and does not communicate to the api directly. The cli mirrors the credential store locally but doesn't sync it on every get request. Instead it will sync each secret every 15 minutes (900 seconds). You can adjust the interval by setting `BW_SYNC_INTERVAL` in the values. If your secrets update very very frequently, you can force the operator to do a sync before each get by setting `BW_FORCE_SYNC="true"`. You might run into rate limits if you do this too frequent.
|
||||||
|
|
||||||
Additionally the bitwarden cli session may expire at some time. In order to create a new session, the login command is triggered from time to time. In what interval exactly can be configured with the env `BW_RELOGIN_INTERVAL` which defaults to `3600` seconds.
|
Additionally the bitwarden cli session may expire at some time. In order to create a new session, the login command is triggered from time to time. In what interval exactly can be configured with the env `BW_RELOGIN_INTERVAL` which defaults to 3600s.
|
||||||
|
@ -4,9 +4,9 @@ description: Deploy the Bitwarden CRD Operator
|
|||||||
|
|
||||||
type: application
|
type: application
|
||||||
|
|
||||||
version: "v0.15.0"
|
version: "v0.13.0"
|
||||||
|
|
||||||
appVersion: "0.14.0"
|
appVersion: "0.12.0"
|
||||||
|
|
||||||
keywords:
|
keywords:
|
||||||
- operator
|
- operator
|
||||||
@ -20,7 +20,7 @@ home: https://lerentis.github.io/bitwarden-crd-operator/
|
|||||||
sources:
|
sources:
|
||||||
- https://github.com/Lerentis/bitwarden-crd-operator
|
- https://github.com/Lerentis/bitwarden-crd-operator
|
||||||
|
|
||||||
kubeVersion: ">= 1.28.0-0"
|
kubeVersion: ">= 1.23.0-0"
|
||||||
|
|
||||||
maintainers:
|
maintainers:
|
||||||
- name: lerentis
|
- name: lerentis
|
||||||
@ -32,22 +32,22 @@ annotations:
|
|||||||
url: https://github.com/Lerentis/bitwarden-crd-operator
|
url: https://github.com/Lerentis/bitwarden-crd-operator
|
||||||
artifacthub.io/crds: |
|
artifacthub.io/crds: |
|
||||||
- kind: BitwardenSecret
|
- kind: BitwardenSecret
|
||||||
version: v1beta8
|
version: v1beta7
|
||||||
name: bitwarden-secret
|
name: bitwarden-secret
|
||||||
displayName: Bitwarden Secret
|
displayName: Bitwarden Secret
|
||||||
description: Management Object to create secrets from bitwarden
|
description: Management Object to create secrets from bitwarden
|
||||||
- kind: RegistryCredential
|
- kind: RegistryCredential
|
||||||
version: v1beta8
|
version: v1beta7
|
||||||
name: registry-credential
|
name: registry-credential
|
||||||
displayName: Regestry Credentials
|
displayName: Regestry Credentials
|
||||||
description: Management Object to create regestry secrets from bitwarden
|
description: Management Object to create regestry secrets from bitwarden
|
||||||
- kind: BitwardenTemplate
|
- kind: BitwardenTemplate
|
||||||
version: v1beta8
|
version: v1beta7
|
||||||
name: bitwarden-template
|
name: bitwarden-template
|
||||||
displayName: Bitwarden Template
|
displayName: Bitwarden Template
|
||||||
description: Management Object to create secrets from a jinja template with a bitwarden lookup
|
description: Management Object to create secrets from a jinja template with a bitwarden lookup
|
||||||
artifacthub.io/crdsExamples: |
|
artifacthub.io/crdsExamples: |
|
||||||
- apiVersion: lerentis.uploadfilter24.eu/v1beta8
|
- apiVersion: lerentis.uploadfilter24.eu/v1beta7
|
||||||
kind: BitwardenSecret
|
kind: BitwardenSecret
|
||||||
metadata:
|
metadata:
|
||||||
name: test
|
name: test
|
||||||
@ -67,7 +67,7 @@ annotations:
|
|||||||
key: value
|
key: value
|
||||||
annotations:
|
annotations:
|
||||||
key: value
|
key: value
|
||||||
- apiVersion: lerentis.uploadfilter24.eu/v1beta8
|
- apiVersion: lerentis.uploadfilter24.eu/v1beta7
|
||||||
kind: RegistryCredential
|
kind: RegistryCredential
|
||||||
metadata:
|
metadata:
|
||||||
name: test
|
name: test
|
||||||
@ -82,11 +82,12 @@ annotations:
|
|||||||
key: value
|
key: value
|
||||||
annotations:
|
annotations:
|
||||||
key: value
|
key: value
|
||||||
- apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
|
- apiVersion: "lerentis.uploadfilter24.eu/v1beta7"
|
||||||
kind: BitwardenTemplate
|
kind: BitwardenTemplate
|
||||||
metadata:
|
metadata:
|
||||||
name: test
|
name: test
|
||||||
spec:
|
spec:
|
||||||
|
filename: "config.yaml"
|
||||||
name: "test-regcred"
|
name: "test-regcred"
|
||||||
secretType: Obaque #Optional
|
secretType: Obaque #Optional
|
||||||
namespace: "default"
|
namespace: "default"
|
||||||
@ -94,32 +95,26 @@ annotations:
|
|||||||
key: value
|
key: value
|
||||||
annotations:
|
annotations:
|
||||||
key: value
|
key: value
|
||||||
content:
|
template: |
|
||||||
- element:
|
---
|
||||||
filename: "config.yaml"
|
api:
|
||||||
template: |
|
enabled: True
|
||||||
---
|
key: {{ bitwarden_lookup("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "fields", "key") }}
|
||||||
api:
|
allowCrossOrigin: false
|
||||||
enabled: True
|
apps:
|
||||||
key: {{ bitwarden_lookup("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "fields", "key") }}
|
"some.app.identifier:some_version":
|
||||||
allowCrossOrigin: false
|
pubkey: {{ bitwarden_lookup("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "attachment", "public_key") }}
|
||||||
apps:
|
enabled: true
|
||||||
"some.app.identifier:some_version":
|
|
||||||
pubkey: {{ bitwarden_lookup("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "attachment", "public_key") }}
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
artifacthub.io/license: MIT
|
artifacthub.io/license: MIT
|
||||||
artifacthub.io/operator: "true"
|
artifacthub.io/operator: "true"
|
||||||
artifacthub.io/containsSecurityUpdates: "false"
|
artifacthub.io/containsSecurityUpdates: "false"
|
||||||
artifacthub.io/changes: |
|
artifacthub.io/changes: |
|
||||||
- kind: changed
|
- kind: added
|
||||||
description: "BitwardenTemplate can now handle multiple files"
|
description: "Allow custom type for generated secrets"
|
||||||
- kind: changed
|
- kind: added
|
||||||
description: "Removed long deprecated versions"
|
description: "Allow attachments in generated secrets"
|
||||||
- kind: changed
|
- kind: added
|
||||||
description: "Update kubernetes from v29.0.0 to v30.1.0"
|
description: "Allow custom type in templated secrets"
|
||||||
- kind: changed
|
|
||||||
description: "Update alpine from 3.20.2 to 3.20.3"
|
|
||||||
artifacthub.io/images: |
|
artifacthub.io/images: |
|
||||||
- name: bitwarden-crd-operator
|
- name: bitwarden-crd-operator
|
||||||
image: ghcr.io/lerentis/bitwarden-crd-operator:0.14.0
|
image: ghcr.io/lerentis/bitwarden-crd-operator:0.12.0
|
||||||
|
@ -13,7 +13,7 @@ spec:
|
|||||||
shortNames:
|
shortNames:
|
||||||
- bws
|
- bws
|
||||||
versions:
|
versions:
|
||||||
- name: v1beta7
|
- name: v1beta4
|
||||||
served: true
|
served: true
|
||||||
storage: false
|
storage: false
|
||||||
deprecated: true
|
deprecated: true
|
||||||
@ -46,7 +46,82 @@ spec:
|
|||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
secretType:
|
required:
|
||||||
|
- id
|
||||||
|
- namespace
|
||||||
|
- name
|
||||||
|
- name: v1beta5
|
||||||
|
served: true
|
||||||
|
storage: false
|
||||||
|
deprecated: true
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
spec:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
element:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
secretName:
|
||||||
|
type: string
|
||||||
|
secretRef:
|
||||||
|
type: string
|
||||||
|
secretScope:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- secretName
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- namespace
|
||||||
|
- name
|
||||||
|
- name: v1beta6
|
||||||
|
served: true
|
||||||
|
storage: false
|
||||||
|
deprecated: true
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
spec:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
element:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
secretName:
|
||||||
|
type: string
|
||||||
|
secretRef:
|
||||||
|
type: string
|
||||||
|
secretScope:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- secretName
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
type: string
|
type: string
|
||||||
labels:
|
labels:
|
||||||
type: object
|
type: object
|
||||||
@ -58,7 +133,7 @@ spec:
|
|||||||
- id
|
- id
|
||||||
- namespace
|
- namespace
|
||||||
- name
|
- name
|
||||||
- name: v1beta8
|
- name: v1beta7
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
schema:
|
schema:
|
||||||
|
@ -13,10 +13,90 @@ spec:
|
|||||||
shortNames:
|
shortNames:
|
||||||
- bwt
|
- bwt
|
||||||
versions:
|
versions:
|
||||||
- name: v1beta7
|
- name: v1beta4
|
||||||
served: true
|
served: true
|
||||||
storage: false
|
storage: false
|
||||||
deprecated: true
|
deprecated: true
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
spec:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
filename:
|
||||||
|
type: string
|
||||||
|
template:
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- filename
|
||||||
|
- template
|
||||||
|
- namespace
|
||||||
|
- name
|
||||||
|
- name: v1beta5
|
||||||
|
served: true
|
||||||
|
storage: false
|
||||||
|
deprecated: true
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
spec:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
filename:
|
||||||
|
type: string
|
||||||
|
template:
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
|
required:
|
||||||
|
- filename
|
||||||
|
- template
|
||||||
|
- namespace
|
||||||
|
- name
|
||||||
|
- name: v1beta6
|
||||||
|
served: true
|
||||||
|
storage: false
|
||||||
|
deprecated: true
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
spec:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
filename:
|
||||||
|
type: string
|
||||||
|
template:
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
|
annotations:
|
||||||
|
type: object
|
||||||
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
|
required:
|
||||||
|
- filename
|
||||||
|
- template
|
||||||
|
- namespace
|
||||||
|
- name
|
||||||
|
- name: v1beta7
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
schema:
|
schema:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
type: object
|
type: object
|
||||||
@ -45,43 +125,3 @@ spec:
|
|||||||
- template
|
- template
|
||||||
- namespace
|
- namespace
|
||||||
- name
|
- name
|
||||||
- name: v1beta8
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
spec:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
namespace:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
secretType:
|
|
||||||
type: string
|
|
||||||
content:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
element:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
filename:
|
|
||||||
type: string
|
|
||||||
template:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- filename
|
|
||||||
- template
|
|
||||||
labels:
|
|
||||||
type: object
|
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
|
||||||
annotations:
|
|
||||||
type: object
|
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
|
||||||
required:
|
|
||||||
- namespace
|
|
||||||
- name
|
|
@ -13,7 +13,70 @@ spec:
|
|||||||
shortNames:
|
shortNames:
|
||||||
- rgc
|
- rgc
|
||||||
versions:
|
versions:
|
||||||
- name: v1beta7
|
- name: v1beta4
|
||||||
|
served: true
|
||||||
|
storage: false
|
||||||
|
deprecated: true
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
spec:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
usernameRef:
|
||||||
|
type: string
|
||||||
|
passwordRef:
|
||||||
|
type: string
|
||||||
|
registry:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- namespace
|
||||||
|
- name
|
||||||
|
- usernameRef
|
||||||
|
- passwordRef
|
||||||
|
- registry
|
||||||
|
- name: v1beta5
|
||||||
|
served: true
|
||||||
|
storage: false
|
||||||
|
deprecated: true
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
spec:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
usernameRef:
|
||||||
|
type: string
|
||||||
|
passwordRef:
|
||||||
|
type: string
|
||||||
|
registry:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- namespace
|
||||||
|
- name
|
||||||
|
- usernameRef
|
||||||
|
- passwordRef
|
||||||
|
- registry
|
||||||
|
- name: v1beta6
|
||||||
served: true
|
served: true
|
||||||
storage: false
|
storage: false
|
||||||
deprecated: true
|
deprecated: true
|
||||||
@ -49,7 +112,7 @@ spec:
|
|||||||
- usernameRef
|
- usernameRef
|
||||||
- passwordRef
|
- passwordRef
|
||||||
- registry
|
- registry
|
||||||
- name: v1beta8
|
- name: v1beta7
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
schema:
|
schema:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
|
apiVersion: "lerentis.uploadfilter24.eu/v1beta7"
|
||||||
kind: BitwardenSecret
|
kind: BitwardenSecret
|
||||||
metadata:
|
metadata:
|
||||||
name: test
|
name: test
|
||||||
@ -24,7 +24,7 @@ spec:
|
|||||||
annotations:
|
annotations:
|
||||||
custom.annotation: is-used
|
custom.annotation: is-used
|
||||||
---
|
---
|
||||||
apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
|
apiVersion: "lerentis.uploadfilter24.eu/v1beta7"
|
||||||
kind: BitwardenSecret
|
kind: BitwardenSecret
|
||||||
metadata:
|
metadata:
|
||||||
name: test-scope
|
name: test-scope
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
|
apiVersion: "lerentis.uploadfilter24.eu/v1beta7"
|
||||||
kind: RegistryCredential
|
kind: RegistryCredential
|
||||||
metadata:
|
metadata:
|
||||||
name: test
|
name: test
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
---
|
---
|
||||||
apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
|
apiVersion: "lerentis.uploadfilter24.eu/v1beta7"
|
||||||
kind: BitwardenTemplate
|
kind: BitwardenTemplate
|
||||||
metadata:
|
metadata:
|
||||||
name: test
|
name: test
|
||||||
spec:
|
spec:
|
||||||
|
filename: "config.yaml"
|
||||||
name: "test-template"
|
name: "test-template"
|
||||||
namespace: "default"
|
namespace: "default"
|
||||||
labels:
|
labels:
|
||||||
@ -11,28 +12,13 @@ spec:
|
|||||||
app: example-app
|
app: example-app
|
||||||
annotations:
|
annotations:
|
||||||
custom.annotation: is-used
|
custom.annotation: is-used
|
||||||
content:
|
template: |
|
||||||
- element:
|
---
|
||||||
filename: config.yaml
|
api:
|
||||||
template: |
|
enabled: True
|
||||||
---
|
key: {{ bitwarden_lookup("466fc4b0-ffca-4444-8d88-b59d4de3d928", "fields", "key") }}
|
||||||
api:
|
allowCrossOrigin: false
|
||||||
enabled: True
|
apps:
|
||||||
key: {{ bitwarden_lookup("466fc4b0-ffca-4444-8d88-b59d4de3d928", "fields", "key") }}
|
"some.app.identifier:some_version":
|
||||||
allowCrossOrigin: false
|
pubkey: {{ bitwarden_lookup("466fc4b0-ffca-4444-8d88-b59d4de3d928", "fields", "public_key") }}
|
||||||
apps:
|
enabled: true
|
||||||
"some.app.identifier:some_version":
|
|
||||||
pubkey: {{ bitwarden_lookup("466fc4b0-ffca-4444-8d88-b59d4de3d928", "fields", "public_key") }}
|
|
||||||
enabled: true
|
|
||||||
- element:
|
|
||||||
filename: config2.yaml
|
|
||||||
template: |
|
|
||||||
---
|
|
||||||
api:
|
|
||||||
enabled: True
|
|
||||||
key: {{ bitwarden_lookup("466fc4b0-ffca-4444-8d88-b59d4de3d928", "fields", "key") }}
|
|
||||||
allowCrossOrigin: false
|
|
||||||
apps:
|
|
||||||
"some.app.identifier:some_version":
|
|
||||||
pubkey: {{ bitwarden_lookup("466fc4b0-ffca-4444-8d88-b59d4de3d928", "fields", "public_key") }}
|
|
||||||
enabled: false
|
|
@ -1,4 +1,4 @@
|
|||||||
kopf==1.37.2
|
kopf==1.37.2
|
||||||
kubernetes==30.1.0
|
kubernetes==29.0.0
|
||||||
Jinja2==3.1.4
|
Jinja2==3.1.4
|
||||||
schedule==1.2.2
|
schedule==1.2.2
|
@ -112,7 +112,7 @@ def update_managed_secret(
|
|||||||
body.metadata.annotations['kopf.zalando.org/last-handled-configuration'])
|
body.metadata.annotations['kopf.zalando.org/last-handled-configuration'])
|
||||||
old_secret_name = old_config['spec'].get('name')
|
old_secret_name = old_config['spec'].get('name')
|
||||||
old_secret_namespace = old_config['spec'].get('namespace')
|
old_secret_namespace = old_config['spec'].get('namespace')
|
||||||
old_secret_type = old_config['spec'].get('secretType')
|
old_secret_type = old_config['spec'].get('type')
|
||||||
secret_name = spec.get('name')
|
secret_name = spec.get('name')
|
||||||
secret_namespace = spec.get('namespace')
|
secret_namespace = spec.get('namespace')
|
||||||
labels = spec.get('labels')
|
labels = spec.get('labels')
|
||||||
@ -122,9 +122,6 @@ def update_managed_secret(
|
|||||||
if not custom_secret_type:
|
if not custom_secret_type:
|
||||||
custom_secret_type = 'Opaque'
|
custom_secret_type = 'Opaque'
|
||||||
|
|
||||||
if not old_secret_type:
|
|
||||||
old_secret_type = 'Opaque'
|
|
||||||
|
|
||||||
if old_config is not None and (
|
if old_config is not None and (
|
||||||
old_secret_name != secret_name or old_secret_namespace != secret_namespace or old_secret_type != custom_secret_type):
|
old_secret_name != secret_name or old_secret_namespace != secret_namespace or old_secret_type != custom_secret_type):
|
||||||
# If the name of the secret or the namespace of the secret is different
|
# If the name of the secret or the namespace of the secret is different
|
||||||
|
169
src/template.py
169
src/template.py
@ -24,72 +24,9 @@ def create_template_secret(logger, secret, filename, template):
|
|||||||
"utf-8")
|
"utf-8")
|
||||||
return secret
|
return secret
|
||||||
|
|
||||||
def create_template_obj(logger, secret, content_def):
|
|
||||||
secret.data = {}
|
|
||||||
for eleml in content_def:
|
|
||||||
for k, elem in eleml.items():
|
|
||||||
for key, value in elem.items():
|
|
||||||
if key == "filename":
|
|
||||||
_file_name = value
|
|
||||||
if key == "template":
|
|
||||||
_template = value
|
|
||||||
secret.data[_file_name] = str(
|
|
||||||
base64.b64encode(
|
|
||||||
render_template(logger, _template).encode("utf-8")),
|
|
||||||
"utf-8")
|
|
||||||
return secret
|
|
||||||
|
|
||||||
|
|
||||||
@kopf.on.create('bitwarden-template.lerentis.uploadfilter24.eu')
|
@kopf.on.create('bitwarden-template.lerentis.uploadfilter24.eu')
|
||||||
def create_managed_secret(spec, name, namespace, logger, body, **kwargs):
|
def create_managed_secret(spec, name, namespace, logger, body, **kwargs):
|
||||||
template = spec.get('template')
|
|
||||||
if template is not None:
|
|
||||||
create_beta7_secret(spec, name, namespace, logger, body, **kwargs)
|
|
||||||
secret_name = spec.get('name')
|
|
||||||
secret_namespace = spec.get('namespace')
|
|
||||||
custom_secret_type = spec.get('secretType')
|
|
||||||
labels = spec.get('labels')
|
|
||||||
custom_annotations = spec.get('annotations')
|
|
||||||
content_def = spec.get('content')
|
|
||||||
|
|
||||||
unlock_bw(logger)
|
|
||||||
|
|
||||||
api = kubernetes.client.CoreV1Api()
|
|
||||||
|
|
||||||
annotations = {
|
|
||||||
"managed": "bitwarden-template.lerentis.uploadfilter24.eu",
|
|
||||||
"managedObject": f"{namespace}/{name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
if custom_annotations:
|
|
||||||
annotations.update(custom_annotations)
|
|
||||||
|
|
||||||
if not custom_secret_type:
|
|
||||||
custom_secret_type = 'Opaque'
|
|
||||||
|
|
||||||
if not labels:
|
|
||||||
labels = {}
|
|
||||||
|
|
||||||
secret = kubernetes.client.V1Secret()
|
|
||||||
secret.metadata = kubernetes.client.V1ObjectMeta(
|
|
||||||
name=secret_name, annotations=annotations, labels=labels)
|
|
||||||
secret.type = custom_secret_type
|
|
||||||
secret = create_template_obj(logger, secret, content_def)
|
|
||||||
|
|
||||||
# Garbage collection will delete the generated secret if the owner
|
|
||||||
# Is not in the same namespace as the generated secret
|
|
||||||
if secret_namespace == namespace:
|
|
||||||
kopf.append_owner_reference(secret)
|
|
||||||
|
|
||||||
api.create_namespaced_secret(
|
|
||||||
namespace="{}".format(secret_namespace),
|
|
||||||
body=secret
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info(f"Secret {secret_namespace}/{secret_name} has been created")
|
|
||||||
|
|
||||||
|
|
||||||
def create_beta7_secret(spec, name, namespace, logger, body, **kwargs):
|
|
||||||
|
|
||||||
template = spec.get('template')
|
template = spec.get('template')
|
||||||
filename = spec.get('filename')
|
filename = spec.get('filename')
|
||||||
@ -134,7 +71,10 @@ def create_beta7_secret(spec, name, namespace, logger, body, **kwargs):
|
|||||||
|
|
||||||
logger.info(f"Secret {secret_namespace}/{secret_name} has been created")
|
logger.info(f"Secret {secret_namespace}/{secret_name} has been created")
|
||||||
|
|
||||||
def update_beta7_secret(
|
|
||||||
|
@kopf.on.update('bitwarden-template.lerentis.uploadfilter24.eu')
|
||||||
|
@kopf.timer('bitwarden-template.lerentis.uploadfilter24.eu', interval=bw_sync_interval)
|
||||||
|
def update_managed_secret(
|
||||||
spec,
|
spec,
|
||||||
status,
|
status,
|
||||||
name,
|
name,
|
||||||
@ -163,13 +103,10 @@ def update_beta7_secret(
|
|||||||
body.metadata.annotations['kopf.zalando.org/last-handled-configuration'])
|
body.metadata.annotations['kopf.zalando.org/last-handled-configuration'])
|
||||||
old_secret_name = old_config['spec'].get('name')
|
old_secret_name = old_config['spec'].get('name')
|
||||||
old_secret_namespace = old_config['spec'].get('namespace')
|
old_secret_namespace = old_config['spec'].get('namespace')
|
||||||
old_secret_type = old_config['spec'].get('secretType')
|
old_secret_type = old_config['spec'].get('type')
|
||||||
secret_name = spec.get('name')
|
secret_name = spec.get('name')
|
||||||
secret_namespace = spec.get('namespace')
|
secret_namespace = spec.get('namespace')
|
||||||
|
|
||||||
if not old_secret_type:
|
|
||||||
old_secret_type = 'Opaque'
|
|
||||||
|
|
||||||
if old_config is not None and (
|
if old_config is not None and (
|
||||||
old_secret_name != secret_name or old_secret_namespace != secret_namespace or old_secret_type != custom_secret_type):
|
old_secret_name != secret_name or old_secret_namespace != secret_namespace or old_secret_type != custom_secret_type):
|
||||||
# If the name of the secret or the namespace of the secret is different
|
# If the name of the secret or the namespace of the secret is different
|
||||||
@ -225,102 +162,6 @@ def update_beta7_secret(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@kopf.on.update('bitwarden-template.lerentis.uploadfilter24.eu')
|
|
||||||
@kopf.timer('bitwarden-template.lerentis.uploadfilter24.eu', interval=bw_sync_interval)
|
|
||||||
def update_managed_secret(
|
|
||||||
spec,
|
|
||||||
status,
|
|
||||||
name,
|
|
||||||
namespace,
|
|
||||||
logger,
|
|
||||||
body,
|
|
||||||
**kwargs):
|
|
||||||
|
|
||||||
template = spec.get('template')
|
|
||||||
if template is not None:
|
|
||||||
update_beta7_secret(spec, status, name, namespace, logger, body, **kwargs)
|
|
||||||
secret_name = spec.get('name')
|
|
||||||
secret_namespace = spec.get('namespace')
|
|
||||||
labels = spec.get('labels')
|
|
||||||
custom_annotations = spec.get('annotations')
|
|
||||||
custom_secret_type = spec.get('secretType')
|
|
||||||
content_def = spec.get('content')
|
|
||||||
|
|
||||||
if not custom_secret_type:
|
|
||||||
custom_secret_type = 'Opaque'
|
|
||||||
|
|
||||||
old_config = None
|
|
||||||
old_secret_name = None
|
|
||||||
old_secret_namespace = None
|
|
||||||
old_secret_type = None
|
|
||||||
if 'kopf.zalando.org/last-handled-configuration' in body.metadata.annotations:
|
|
||||||
old_config = json.loads(
|
|
||||||
body.metadata.annotations['kopf.zalando.org/last-handled-configuration'])
|
|
||||||
old_secret_name = old_config['spec'].get('name')
|
|
||||||
old_secret_namespace = old_config['spec'].get('namespace')
|
|
||||||
old_secret_type = old_config['spec'].get('secretType')
|
|
||||||
secret_name = spec.get('name')
|
|
||||||
secret_namespace = spec.get('namespace')
|
|
||||||
|
|
||||||
if not old_secret_type:
|
|
||||||
old_secret_type = 'Opaque'
|
|
||||||
|
|
||||||
if old_config is not None and (
|
|
||||||
old_secret_name != secret_name or old_secret_namespace != secret_namespace or old_secret_type != custom_secret_type):
|
|
||||||
# If the name of the secret or the namespace of the secret is different
|
|
||||||
# We have to delete the secret an recreate it
|
|
||||||
logger.info("Secret name or namespace changed, let's recreate it")
|
|
||||||
delete_managed_secret(
|
|
||||||
old_config['spec'],
|
|
||||||
name,
|
|
||||||
namespace,
|
|
||||||
logger,
|
|
||||||
**kwargs)
|
|
||||||
create_managed_secret(spec, name, namespace, logger, body, **kwargs)
|
|
||||||
return
|
|
||||||
|
|
||||||
unlock_bw(logger)
|
|
||||||
|
|
||||||
api = kubernetes.client.CoreV1Api()
|
|
||||||
|
|
||||||
annotations = {
|
|
||||||
"managed": "bitwarden-template.lerentis.uploadfilter24.eu",
|
|
||||||
"managedObject": f"{namespace}/{name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
if custom_annotations:
|
|
||||||
annotations.update(custom_annotations)
|
|
||||||
|
|
||||||
if not labels:
|
|
||||||
labels = {}
|
|
||||||
|
|
||||||
secret = kubernetes.client.V1Secret()
|
|
||||||
secret.metadata = kubernetes.client.V1ObjectMeta(
|
|
||||||
name=secret_name, annotations=annotations, labels=labels)
|
|
||||||
secret.type = custom_secret_type
|
|
||||||
secret = create_template_obj(logger, secret, content_def)
|
|
||||||
|
|
||||||
# Garbage collection will delete the generated secret if the owner
|
|
||||||
# Is not in the same namespace as the generated secret
|
|
||||||
if secret_namespace == namespace:
|
|
||||||
kopf.append_owner_reference(secret)
|
|
||||||
|
|
||||||
try:
|
|
||||||
api.replace_namespaced_secret(
|
|
||||||
name=secret_name,
|
|
||||||
body=secret,
|
|
||||||
namespace="{}".format(secret_namespace))
|
|
||||||
logger.info(
|
|
||||||
f"Secret {secret_namespace}/{secret_name} has been updated")
|
|
||||||
except BaseException as e:
|
|
||||||
logger.warn(
|
|
||||||
f"Could not update secret {secret_namespace}/{secret_name}!")
|
|
||||||
logger.warn(
|
|
||||||
f"Exception: {e}"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@kopf.on.delete('bitwarden-template.lerentis.uploadfilter24.eu')
|
@kopf.on.delete('bitwarden-template.lerentis.uploadfilter24.eu')
|
||||||
def delete_managed_secret(spec, name, namespace, logger, **kwargs):
|
def delete_managed_secret(spec, name, namespace, logger, **kwargs):
|
||||||
secret_name = spec.get('name')
|
secret_name = spec.get('name')
|
||||||
|
Loading…
Reference in New Issue
Block a user