diff --git a/README.md b/README.md index f28e73c..8cd0f09 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,14 @@ Bitwarden CRD Operator is a kubernetes Operator based on [kopf](https://github.com/nolar/kopf/). The goal is to create kubernetes native secret objects from bitwarden. +

+ Bitwarden CRD Operator Logo +

+ > DISCLAIMER: > This project is still very work in progress :) + ## Getting started You will need a `ClientID` and `ClientSecret` ([where to get these](https://bitwarden.com/help/personal-api-key/)) as well as your password. diff --git a/charts/bitwarden-crd-operator/Chart.yaml b/charts/bitwarden-crd-operator/Chart.yaml index 47562a6..e8bd95e 100644 --- a/charts/bitwarden-crd-operator/Chart.yaml +++ b/charts/bitwarden-crd-operator/Chart.yaml @@ -4,9 +4,9 @@ description: Deploy the Bitwarden CRD Operator type: application -version: "v0.3.2" +version: "v0.4.0" -appVersion: "0.3.0" +appVersion: "0.4.0" keywords: - operator @@ -69,10 +69,10 @@ annotations: artifacthub.io/license: MIT artifacthub.io/operator: "true" artifacthub.io/changes: | - - kind: changed - description: "Switched to Alpine image" - kind: added - description: "Added CRDs Example to artifactshub" + description: "Added Template CRD" + - kind: added + description: "Added logo" artifacthub.io/images: | - name: bitwarden-crd-operator image: lerentis/bitwarden-crd-operator:0.3.0 diff --git a/charts/bitwarden-crd-operator/crds/template.yaml b/charts/bitwarden-crd-operator/crds/template.yaml new file mode 100644 index 0000000..9a5dd75 --- /dev/null +++ b/charts/bitwarden-crd-operator/crds/template.yaml @@ -0,0 +1,34 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: bitwarden-templates.lerentis.uploadfilter24.eu +spec: + scope: Namespaced + group: lerentis.uploadfilter24.eu + names: + kind: BitwardenTemplate + plural: bitwarden-templates + singular: bitwarden-template + shortNames: + - bwt + versions: + - name: v1beta1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + template: + type: string + namespace: + type: string + name: + type: string + required: + - template + - namespace + - name diff --git a/charts/bitwarden-crd-operator/templates/clusterrole.yaml b/charts/bitwarden-crd-operator/templates/clusterrole.yaml index d015f4e..71857bf 100644 --- a/charts/bitwarden-crd-operator/templates/clusterrole.yaml +++ b/charts/bitwarden-crd-operator/templates/clusterrole.yaml @@ -4,7 +4,7 @@ metadata: name: {{ include "bitwarden-crd-operator.serviceAccountName" . }}-role rules: - apiGroups: ["lerentis.uploadfilter24.eu"] - resources: ["bitwarden-secrets", "registry-credentials"] + resources: ["bitwarden-secrets", "registry-credentials", "bitwarden-templates"] verbs: ["get", "watch", "list", "create", "delete", "patch", "update"] - apiGroups: [""] resources: ["secrets"] diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..513ff57 Binary files /dev/null and b/logo.png differ diff --git a/requirements.txt b/requirements.txt index 7b030cb..9851629 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ kopf==1.35.6 kubernetes==25.3.0 +Jinja2==3.1.2 diff --git a/src/bitwardenCrdOperator.py b/src/bitwardenCrdOperator.py index 4eee3b7..4c3be14 100755 --- a/src/bitwardenCrdOperator.py +++ b/src/bitwardenCrdOperator.py @@ -1,26 +1,8 @@ #!/usr/bin/env python3 import kopf import os -import subprocess - -def get_secret_from_bitwarden(logger, id): - logger.info(f"Locking up secret with ID: {id}") - return command_wrapper(logger, f"get item {id}") - -def unlock_bw(logger): - token_output = command_wrapper(logger, "unlock --passwordenv BW_PASSWORD") - tokens = token_output.split('"')[1::2] - os.environ["BW_SESSION"] = tokens[1] - logger.info("Signin successful. Session exported") - -def command_wrapper(logger, command): - system_env = dict(os.environ) - sp = subprocess.Popen([f"bw {command}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, shell=True, env=system_env) - out, err = sp.communicate() - if err: - logger.warn(f"Error during bw cli invokement: {err}") - return out.decode(encoding='UTF-8') +from utils.utils import command_wrapper, unlock_bw @kopf.on.startup() def bitwarden_signin(logger, **kwargs): diff --git a/src/dockerlogin.py b/src/dockerlogin.py index 4171c27..94fd48b 100644 --- a/src/dockerlogin.py +++ b/src/dockerlogin.py @@ -3,7 +3,7 @@ import kubernetes import base64 import json -from bitwardenCrdOperator import unlock_bw, get_secret_from_bitwarden +from utils.utils import unlock_bw, get_secret_from_bitwarden def create_dockerlogin(logger, secret, secret_json, username_ref, password_ref, registry): secret.type = "dockerconfigjson" diff --git a/src/filters/__init__.py b/src/filters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/filters/bitwarden_filter.py b/src/filters/bitwarden_filter.py new file mode 100644 index 0000000..cf0183c --- /dev/null +++ b/src/filters/bitwarden_filter.py @@ -0,0 +1,8 @@ +from utils.utils import get_secret_from_bitwarden + + +def datetime_format(value, format="%H:%M %d-%m-%y"): + return value.strftime(format) + +def bitwarden_lookup(value, id, field): + pass \ No newline at end of file diff --git a/src/kv.py b/src/kv.py index 59e97b1..9b65b78 100644 --- a/src/kv.py +++ b/src/kv.py @@ -3,7 +3,7 @@ import kubernetes import base64 import json -from bitwardenCrdOperator import unlock_bw, get_secret_from_bitwarden +from utils.utils import unlock_bw, get_secret_from_bitwarden def create_kv(secret, secret_json, content_def): secret.type = "Opaque" diff --git a/src/template.py b/src/template.py new file mode 100644 index 0000000..ca5d40e --- /dev/null +++ b/src/template.py @@ -0,0 +1,7 @@ +import kopf +from filters.bitwarden_filter import bitwarden_lookup +from jinja2 import Environment + + +Environment.filters["bitwarden"] = bitwarden_lookup + diff --git a/src/utils/__init__.py b/src/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/utils.py b/src/utils/utils.py new file mode 100644 index 0000000..86e0472 --- /dev/null +++ b/src/utils/utils.py @@ -0,0 +1,20 @@ +import os +import subprocess + +def get_secret_from_bitwarden(logger, id): + logger.info(f"Locking up secret with ID: {id}") + return command_wrapper(logger, f"get item {id}") + +def unlock_bw(logger): + token_output = command_wrapper(logger, "unlock --passwordenv BW_PASSWORD") + tokens = token_output.split('"')[1::2] + os.environ["BW_SESSION"] = tokens[1] + logger.info("Signin successful. Session exported") + +def command_wrapper(logger, command): + system_env = dict(os.environ) + sp = subprocess.Popen([f"bw {command}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, shell=True, env=system_env) + out, err = sp.communicate() + if err: + logger.warn(f"Error during bw cli invokement: {err}") + return out.decode(encoding='UTF-8') \ No newline at end of file