update and retry handler
This commit is contained in:
		| @@ -30,5 +30,5 @@ COPY --chown=bw-operator:bw-operator src /home/bw-operator | |||||||
|  |  | ||||||
| USER bw-operator | USER bw-operator | ||||||
|  |  | ||||||
| ENTRYPOINT [ "kopf", "run", "--all-namespaces", "--liveness=http://0.0.0.0:8080/healthz" ] | ENTRYPOINT [ "kopf", "run", "--log-format=json", "--all-namespaces", "--liveness=http://0.0.0.0:8080/healthz" ] | ||||||
| CMD [ "/home/bw-operator/bitwardenCrdOperator.py", "/home/bw-operator/kv.py", "/home/bw-operator/dockerlogin.py", "/home/bw-operator/template.py"] | CMD [ "/home/bw-operator/bitwardenCrdOperator.py", "/home/bw-operator/kv.py", "/home/bw-operator/dockerlogin.py", "/home/bw-operator/template.py"] | ||||||
|   | |||||||
| @@ -4,9 +4,9 @@ description: Deploy the Bitwarden CRD Operator | |||||||
|  |  | ||||||
| type: application | type: application | ||||||
|  |  | ||||||
| version: "v0.4.3" | version: "v0.5.0" | ||||||
|  |  | ||||||
| appVersion: "0.4.2" | appVersion: "0.5.0" | ||||||
|  |  | ||||||
| keywords: | keywords: | ||||||
|   - operator |   - operator | ||||||
| @@ -94,10 +94,12 @@ annotations: | |||||||
|   artifacthub.io/license: MIT |   artifacthub.io/license: MIT | ||||||
|   artifacthub.io/operator: "true"   |   artifacthub.io/operator: "true"   | ||||||
|   artifacthub.io/changes: | |   artifacthub.io/changes: | | ||||||
|     - kind: fixed |  | ||||||
|       description: "Updated Dependencies to fix CVEs" |  | ||||||
|     - kind: added |     - kind: added | ||||||
|       description: "Upload SBOM to GitHub Release" |       description: "Implemented update handling" | ||||||
|  |     - kind: changed | ||||||
|  |       description: "Changed default logging structure to json logging" | ||||||
|  |     - kind: changed | ||||||
|  |       description: "Secrets are periodically updated every 15 minutes" | ||||||
|   artifacthub.io/images: | |   artifacthub.io/images: | | ||||||
|     - name: bitwarden-crd-operator |     - name: bitwarden-crd-operator | ||||||
|       image: lerentis/bitwarden-crd-operator:0.4.2 |       image: lerentis/bitwarden-crd-operator:0.5.0 | ||||||
|   | |||||||
| @@ -53,8 +53,39 @@ def create_managed_registry_secret(spec, name, namespace, logger, **kwargs): | |||||||
|     logger.info(f"Registry Secret {secret_namespace}/{secret_name} has been created") |     logger.info(f"Registry Secret {secret_namespace}/{secret_name} has been created") | ||||||
|  |  | ||||||
| @kopf.on.update('registry-credential.lerentis.uploadfilter24.eu') | @kopf.on.update('registry-credential.lerentis.uploadfilter24.eu') | ||||||
| def my_handler(spec, old, new, diff, **_): | @kopf.timer('registry-credential.lerentis.uploadfilter24.eu', interval=900) | ||||||
|     pass | def update_managed_registry_secret(spec, status, name, namespace, logger, body, **kwargs): | ||||||
|  |  | ||||||
|  |     username_ref = spec.get('usernameRef') | ||||||
|  |     password_ref = spec.get('passwordRef') | ||||||
|  |     registry = spec.get('registry') | ||||||
|  |     id = spec.get('id') | ||||||
|  |     secret_name = spec.get('name') | ||||||
|  |     secret_namespace = spec.get('namespace') | ||||||
|  |  | ||||||
|  |     unlock_bw(logger) | ||||||
|  |     logger.info(f"Locking up secret with ID: {id}") | ||||||
|  |     secret_json_object = json.loads(get_secret_from_bitwarden(id)) | ||||||
|  |  | ||||||
|  |     api = kubernetes.client.CoreV1Api() | ||||||
|  |  | ||||||
|  |     annotations = { | ||||||
|  |         "managed": "registry-credential.lerentis.uploadfilter24.eu", | ||||||
|  |         "managedObject": f"{namespace}/{name}" | ||||||
|  |     } | ||||||
|  |     secret = kubernetes.client.V1Secret() | ||||||
|  |     secret.metadata = kubernetes.client.V1ObjectMeta(name=secret_name, annotations=annotations) | ||||||
|  |     secret = create_dockerlogin(logger, secret, secret_json_object, username_ref, password_ref, registry) | ||||||
|  |     try: | ||||||
|  |         obj = 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: | ||||||
|  |         logger.warn( | ||||||
|  |             f"Could not update secret {secret_namespace}/{secret_name}!") | ||||||
|  |  | ||||||
|  |  | ||||||
| @kopf.on.delete('registry-credential.lerentis.uploadfilter24.eu') | @kopf.on.delete('registry-credential.lerentis.uploadfilter24.eu') | ||||||
| def delete_managed_secret(spec, name, namespace, logger, **kwargs): | def delete_managed_secret(spec, name, namespace, logger, **kwargs): | ||||||
|   | |||||||
							
								
								
									
										59
									
								
								src/kv.py
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								src/kv.py
									
									
									
									
									
								
							| @@ -5,12 +5,13 @@ import json | |||||||
|  |  | ||||||
| from utils.utils import unlock_bw, get_secret_from_bitwarden, parse_login_scope, parse_fields_scope | from utils.utils import unlock_bw, get_secret_from_bitwarden, parse_login_scope, parse_fields_scope | ||||||
|  |  | ||||||
|  |  | ||||||
| def create_kv(secret, secret_json, content_def): | def create_kv(secret, secret_json, content_def): | ||||||
|     secret.type = "Opaque" |     secret.type = "Opaque" | ||||||
|     secret.data = {} |     secret.data = {} | ||||||
|     for eleml in content_def: |     for eleml in content_def: | ||||||
|         for k, elem in eleml.items(): |         for k, elem in eleml.items(): | ||||||
|             for key,value in elem.items(): |             for key, value in elem.items(): | ||||||
|                 if key == "secretName": |                 if key == "secretName": | ||||||
|                     _secret_key = value |                     _secret_key = value | ||||||
|                 if key == "secretRef": |                 if key == "secretRef": | ||||||
| @@ -18,11 +19,14 @@ def create_kv(secret, secret_json, content_def): | |||||||
|                 if key == "secretScope": |                 if key == "secretScope": | ||||||
|                     _secret_scope = value |                     _secret_scope = value | ||||||
|             if _secret_scope == "login": |             if _secret_scope == "login": | ||||||
|                 secret.data[_secret_ref] = str(base64.b64encode(parse_login_scope(secret_json, _secret_key).encode("utf-8")), "utf-8") |                 secret.data[_secret_ref] = str(base64.b64encode( | ||||||
|  |                     parse_login_scope(secret_json, _secret_key).encode("utf-8")), "utf-8") | ||||||
|             if _secret_scope == "fields": |             if _secret_scope == "fields": | ||||||
|                 secret.data[_secret_ref] = str(base64.b64encode(parse_fields_scope(secret_json, _secret_key).encode("utf-8")), "utf-8") |                 secret.data[_secret_ref] = str(base64.b64encode( | ||||||
|  |                     parse_fields_scope(secret_json, _secret_key).encode("utf-8")), "utf-8") | ||||||
|     return secret |     return secret | ||||||
|  |  | ||||||
|  |  | ||||||
| @kopf.on.create('bitwarden-secret.lerentis.uploadfilter24.eu') | @kopf.on.create('bitwarden-secret.lerentis.uploadfilter24.eu') | ||||||
| def create_managed_secret(spec, name, namespace, logger, body, **kwargs): | def create_managed_secret(spec, name, namespace, logger, body, **kwargs): | ||||||
|  |  | ||||||
| @@ -42,18 +46,53 @@ def create_managed_secret(spec, name, namespace, logger, body, **kwargs): | |||||||
|         "managedObject": f"{namespace}/{name}" |         "managedObject": f"{namespace}/{name}" | ||||||
|     } |     } | ||||||
|     secret = kubernetes.client.V1Secret() |     secret = kubernetes.client.V1Secret() | ||||||
|     secret.metadata = kubernetes.client.V1ObjectMeta(name=secret_name, annotations=annotations) |     secret.metadata = kubernetes.client.V1ObjectMeta( | ||||||
|  |         name=secret_name, annotations=annotations) | ||||||
|     secret = create_kv(secret, secret_json_object, content_def) |     secret = create_kv(secret, secret_json_object, content_def) | ||||||
|  |  | ||||||
|     obj = api.create_namespaced_secret( |     obj = api.create_namespaced_secret( | ||||||
|         secret_namespace, secret |         namespace="{}".format(secret_namespace), | ||||||
|  |         body=secret | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     logger.info(f"Secret {secret_namespace}/{secret_name} has been created") |     logger.info(f"Secret {secret_namespace}/{secret_name} has been created") | ||||||
|  |  | ||||||
|  |  | ||||||
| @kopf.on.update('bitwarden-secret.lerentis.uploadfilter24.eu') | @kopf.on.update('bitwarden-secret.lerentis.uploadfilter24.eu') | ||||||
| def my_handler(spec, old, new, diff, **_): | @kopf.timer('bitwarden-secret.lerentis.uploadfilter24.eu', interval=900) | ||||||
|     pass | def update_managed_secret(spec, status, name, namespace, logger, body, **kwargs): | ||||||
|  |  | ||||||
|  |     content_def = body['spec']['content'] | ||||||
|  |     id = spec.get('id') | ||||||
|  |     secret_name = spec.get('name') | ||||||
|  |     secret_namespace = spec.get('namespace') | ||||||
|  |  | ||||||
|  |     unlock_bw(logger) | ||||||
|  |     logger.info(f"Locking up secret with ID: {id}") | ||||||
|  |     secret_json_object = json.loads(get_secret_from_bitwarden(id)) | ||||||
|  |  | ||||||
|  |     api = kubernetes.client.CoreV1Api() | ||||||
|  |  | ||||||
|  |     annotations = { | ||||||
|  |         "managed": "bitwarden-secret.lerentis.uploadfilter24.eu", | ||||||
|  |         "managedObject": f"{namespace}/{name}" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     secret = kubernetes.client.V1Secret() | ||||||
|  |     secret.metadata = kubernetes.client.V1ObjectMeta( | ||||||
|  |         name=secret_name, annotations=annotations) | ||||||
|  |     secret = create_kv(secret, secret_json_object, content_def) | ||||||
|  |  | ||||||
|  |     try: | ||||||
|  |         obj = 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: | ||||||
|  |         logger.warn( | ||||||
|  |             f"Could not update secret {secret_namespace}/{secret_name}!") | ||||||
|  |  | ||||||
|  |  | ||||||
| @kopf.on.delete('bitwarden-secret.lerentis.uploadfilter24.eu') | @kopf.on.delete('bitwarden-secret.lerentis.uploadfilter24.eu') | ||||||
| def delete_managed_secret(spec, name, namespace, logger, **kwargs): | def delete_managed_secret(spec, name, namespace, logger, **kwargs): | ||||||
| @@ -63,6 +102,8 @@ def delete_managed_secret(spec, name, namespace, logger, **kwargs): | |||||||
|  |  | ||||||
|     try: |     try: | ||||||
|         api.delete_namespaced_secret(secret_name, secret_namespace) |         api.delete_namespaced_secret(secret_name, secret_namespace) | ||||||
|         logger.info(f"Secret {secret_namespace}/{secret_name} has been deleted") |         logger.info( | ||||||
|  |             f"Secret {secret_namespace}/{secret_name} has been deleted") | ||||||
|     except: |     except: | ||||||
|         logger.warn(f"Could not delete secret {secret_namespace}/{secret_name}!") |         logger.warn( | ||||||
|  |             f"Could not delete secret {secret_namespace}/{secret_name}!") | ||||||
|   | |||||||
| @@ -49,8 +49,35 @@ def create_managed_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") | ||||||
|  |  | ||||||
| @kopf.on.update('bitwarden-template.lerentis.uploadfilter24.eu') | @kopf.on.update('bitwarden-template.lerentis.uploadfilter24.eu') | ||||||
| def my_handler(spec, old, new, diff, **_): | @kopf.timer('bitwarden-template.lerentis.uploadfilter24.eu', interval=900) | ||||||
|     pass | def update_managed_secret(spec, status, name, namespace, logger, body, **kwargs): | ||||||
|  |  | ||||||
|  |     template = spec.get('template') | ||||||
|  |     filename = spec.get('filename') | ||||||
|  |     secret_name = spec.get('name') | ||||||
|  |     secret_namespace = spec.get('namespace') | ||||||
|  |  | ||||||
|  |     unlock_bw(logger) | ||||||
|  |  | ||||||
|  |     api = kubernetes.client.CoreV1Api() | ||||||
|  |  | ||||||
|  |     annotations = { | ||||||
|  |         "managed": "bitwarden-template.lerentis.uploadfilter24.eu", | ||||||
|  |         "managedObject": f"{namespace}/{name}" | ||||||
|  |     } | ||||||
|  |     secret = kubernetes.client.V1Secret() | ||||||
|  |     secret.metadata = kubernetes.client.V1ObjectMeta(name=secret_name, annotations=annotations) | ||||||
|  |     secret = create_template_secret(secret, filename, template) | ||||||
|  |  | ||||||
|  |     try: | ||||||
|  |         obj = 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: | ||||||
|  |         logger.warn( | ||||||
|  |             f"Could not update secret {secret_namespace}/{secret_name}!") | ||||||
|  |  | ||||||
| @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): | ||||||
| @@ -63,10 +90,3 @@ def delete_managed_secret(spec, name, namespace, logger, **kwargs): | |||||||
|         logger.info(f"Secret {secret_namespace}/{secret_name} has been deleted") |         logger.info(f"Secret {secret_namespace}/{secret_name} has been deleted") | ||||||
|     except: |     except: | ||||||
|         logger.warn(f"Could not delete secret {secret_namespace}/{secret_name}!") |         logger.warn(f"Could not delete secret {secret_namespace}/{secret_name}!") | ||||||
|  |  | ||||||
| #if __name__ == '__main__': |  | ||||||
| #    tpl = """ |  | ||||||
| #        Calling the 'bitwarden_lookup' function: |  | ||||||
| #        {{ bitwarden_lookup(2, 2) }} |  | ||||||
| #    """ |  | ||||||
| #    print(render_template(tpl)) |  | ||||||
		Reference in New Issue
	
	Block a user