Compare commits

...

172 Commits
v0.5.1 ... main

Author SHA1 Message Date
Tobias Trabelsi
3efa4e68f1
Merge pull request #97 from Lerentis/feature/tt/refactor-templates
(feat): refactor bitwardenTemplate to handle more than one file
2024-10-06 22:37:34 +02:00
90a3e9f73d
(fix): fixed typo in changelog 2024-10-06 22:34:22 +02:00
559c08c187
(feat): refactor bitwardenTemplate to handle more than one file
(chore): update dependencies
(chore): drop old CRD versions
2024-10-06 22:32:30 +02:00
Tobias Trabelsi
25b1d0778e
Merge pull request #96 from bertrandp/patch-1
Update README.md, clarify use of BW_RELOGIN_INTERVAL
2024-10-01 21:12:41 +02:00
bertrandp
9005ea4658
Update README.md, clarify use of BW_RELOGIN_INTERVAL
BW_RELOGIN_INTERVAL default value is `3600` seconds.
2024-10-01 17:12:31 +02:00
Tobias Trabelsi
8c46aa2f41
Merge pull request #94 from Lerentis/dependabot/github_actions/mikefarah/yq-4.44.3
Bump mikefarah/yq from 4.44.2 to 4.44.3
2024-08-05 09:38:56 +02:00
dependabot[bot]
6a4a345688
Bump mikefarah/yq from 4.44.2 to 4.44.3
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.44.2 to 4.44.3.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.44.2...v4.44.3)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-05 06:54:39 +00:00
Tobias Trabelsi
aef0a5a33c
Merge pull request #93 from Lerentis/feature/tt/probe-handling
Update Dependencies
2024-08-04 23:45:32 +02:00
096bf6b5f6
remove probe function again but update dependencies 2024-08-04 23:40:53 +02:00
ffbf466416
updates and dedicated probe handler function 2024-08-04 22:20:42 +02:00
Tobias Trabelsi
0c0243c407
Merge pull request #91 from chrthal/bugfix/secret-recreation
Bugfix/secret recreation
2024-07-05 21:41:58 +02:00
Christoph Thalhammer
8f17ee7f17 Updated versions 2024-07-05 10:08:26 +02:00
Christoph Thalhammer
5dde6160de Updated old configuration checks 2024-07-02 16:01:15 +02:00
Tobias Trabelsi
e141888335
Merge pull request #89 from Lerentis/dependabot/github_actions/docker/build-push-action-6
Bump docker/build-push-action from 5 to 6
2024-06-29 23:33:36 +02:00
Tobias Trabelsi
d8dc1a2de9
Merge pull request #88 from Lerentis/feature/tt/skaffold-tests
fix release pipeline
2024-06-29 23:33:27 +02:00
fb342b36fc
simplifying skaffold tests 2024-06-29 23:27:42 +02:00
dependabot[bot]
c290d6aeaf
Bump docker/build-push-action from 5 to 6
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-24 06:23:53 +00:00
5b445ae668
still wip 2024-06-23 00:33:29 +02:00
baed77e570
align examples again 2024-06-22 23:03:52 +02:00
20527b348a
bump actions/download-artifact in order to fix release pipeline 2024-06-22 23:02:09 +02:00
bb50495347
akeleton for skaffold tests 2024-06-22 22:59:54 +02:00
Tobias Trabelsi
297fb37f13
Merge pull request #86 from chrthal/feature/custom-secret-type
Added custom secret type and attachment support for bitwardenSecret
2024-06-22 22:52:01 +02:00
Christoph Thalhammer
cd5ebde2ba Updated documentation 2024-06-19 11:24:30 +02:00
Christoph Thalhammer
38459629bc Updated CRDs and added custom secret type to templates 2024-06-19 11:24:22 +02:00
Tobias Trabelsi
f5b72a18ac
Merge pull request #87 from Lerentis/dependabot/github_actions/mikefarah/yq-4.44.2
Bump mikefarah/yq from 4.44.1 to 4.44.2
2024-06-18 08:29:09 +02:00
dependabot[bot]
1a08ada5e4
Bump mikefarah/yq from 4.44.1 to 4.44.2
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.44.1 to 4.44.2.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.44.1...v4.44.2)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-17 06:54:38 +00:00
Christoph Thalhammer
e1c8f49c11 fix CRD and updated docs 2024-06-13 16:38:04 +02:00
Christoph Thalhammer
892dc90e99 Added custom secret type and attachment support for bitwardenSecret 2024-06-13 15:28:01 +02:00
Tobias Trabelsi
c0a4add3b0
Merge pull request #84 from Lerentis/dependabot/pip/schedule-1.2.2
Bump schedule from 1.2.1 to 1.2.2
2024-05-30 15:32:46 +02:00
dependabot[bot]
09f978d9fe
Bump schedule from 1.2.1 to 1.2.2
Bumps [schedule](https://github.com/dbader/schedule) from 1.2.1 to 1.2.2.
- [Changelog](https://github.com/dbader/schedule/blob/master/HISTORY.rst)
- [Commits](https://github.com/dbader/schedule/compare/1.2.1...1.2.2)

---
updated-dependencies:
- dependency-name: schedule
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-27 06:14:42 +00:00
Tobias Trabelsi
f679aa1a2b
Merge pull request #82 from Lerentis/feature/tt/ownership-and-annotations
Set Ownership and allow custom Annotations
2024-05-19 00:11:52 +02:00
b01f410f9f
allow annotations and honor gc 2024-05-19 00:07:05 +02:00
1128051a5b
prepare changelog and set ownership to generated secrets 2024-05-18 22:50:18 +02:00
c9c36f1a37
update dependencies 2024-05-18 22:39:23 +02:00
Tobias Trabelsi
1820bd06c3
Merge pull request #77 from Lerentis/dependabot/github_actions/mikefarah/yq-4.43.1
Bump mikefarah/yq from 4.42.1 to 4.43.1
2024-03-26 15:42:00 +01:00
dependabot[bot]
fac9c5ef80
Bump mikefarah/yq from 4.42.1 to 4.43.1
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.42.1 to 4.43.1.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.42.1...v4.43.1)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-25 06:21:30 +00:00
Tobias Trabelsi
858c85bf2b
Merge pull request #76 from Lerentis/dependabot/github_actions/azure/setup-helm-4
Bump azure/setup-helm from 3 to 4
2024-03-11 21:32:57 +01:00
dependabot[bot]
ac8f6bc8e0
Bump azure/setup-helm from 3 to 4
Bumps [azure/setup-helm](https://github.com/azure/setup-helm) from 3 to 4.
- [Release notes](https://github.com/azure/setup-helm/releases)
- [Changelog](https://github.com/Azure/setup-helm/blob/main/CHANGELOG.md)
- [Commits](https://github.com/azure/setup-helm/compare/v3...v4)

---
updated-dependencies:
- dependency-name: azure/setup-helm
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 06:25:54 +00:00
Tobias Trabelsi
b35670f0fb
Merge pull request #75 from Lerentis/dependabot/github_actions/mikefarah/yq-4.42.1
Bump mikefarah/yq from 4.41.1 to 4.42.1
2024-02-28 08:26:04 +01:00
dependabot[bot]
63728bbc3a
Bump mikefarah/yq from 4.41.1 to 4.42.1
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.41.1 to 4.42.1.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.41.1...v4.42.1)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-26 06:10:14 +00:00
Tobias Trabelsi
8175280a48
Merge pull request #72 from Lerentis/dependabot/github_actions/mikefarah/yq-4.41.1
Bump mikefarah/yq from 4.40.7 to 4.41.1
2024-02-19 23:07:29 +01:00
dependabot[bot]
907c72e111
Bump mikefarah/yq from 4.40.7 to 4.41.1
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.40.7 to 4.41.1.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.40.7...v4.41.1)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-19 22:01:32 +00:00
Tobias Trabelsi
f33ae2839d
Merge pull request #74 from Lerentis/bugfix/tt/bw-cli-again
ditch different installation methodes for cpu arch
2024-02-19 23:00:50 +01:00
1758234a1f
skip that test again 2024-02-19 22:57:24 +01:00
30794c10b5
changelog and use run action 2024-02-19 22:52:18 +01:00
e58b390c43
ditch different installation methodes for cpu arch 2024-02-19 22:43:30 +01:00
Tobias Trabelsi
b2c7cc5c36
Merge pull request #65 from Lerentis/dependabot/pip/kubernetes-29.0.0
Bump kubernetes from 26.1.0 to 29.0.0
2024-02-12 08:11:49 +01:00
dependabot[bot]
d0753c5c9c
Bump kubernetes from 26.1.0 to 29.0.0
Bumps [kubernetes](https://github.com/kubernetes-client/python) from 26.1.0 to 29.0.0.
- [Release notes](https://github.com/kubernetes-client/python/releases)
- [Changelog](https://github.com/kubernetes-client/python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes-client/python/compare/v26.1.0...v29.0.0)

---
updated-dependencies:
- dependency-name: kubernetes
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 07:08:57 +00:00
Tobias Trabelsi
d5689ebf6e
Merge pull request #69 from Lerentis/dependabot/github_actions/mikefarah/yq-4.40.7
Bump mikefarah/yq from 4.40.5 to 4.40.7
2024-02-12 08:08:03 +01:00
Tobias Trabelsi
9320d4dcd6
Merge pull request #68 from Lerentis/dependabot/pip/kopf-1.37.1
Bump kopf from 1.36.2 to 1.37.1
2024-02-12 08:07:44 +01:00
dependabot[bot]
593526b8ac
Bump mikefarah/yq from 4.40.5 to 4.40.7
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.40.5 to 4.40.7.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.40.5...v4.40.7)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 06:23:05 +00:00
dependabot[bot]
3ef467ed75
Bump kopf from 1.36.2 to 1.37.1
Bumps [kopf](https://github.com/nolar/kopf) from 1.36.2 to 1.37.1.
- [Release notes](https://github.com/nolar/kopf/releases)
- [Commits](https://github.com/nolar/kopf/compare/1.36.2...1.37.1)

---
updated-dependencies:
- dependency-name: kopf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-22 06:23:10 +00:00
Tobias Trabelsi
fd1bf9caa2
Merge pull request #66 from Lerentis/fixup/tt/fix-release-pipeline
bump node version to fix arm build
2024-01-15 22:36:47 +01:00
2b75b919b2
add ah lint 2024-01-15 22:33:21 +01:00
be8f21e9c4
downgrade download-artifact action because of https://github.com/anchore/sbom-action/issues/434 2024-01-15 22:20:45 +01:00
69290f689d
bump node version to fix arm build 2024-01-15 22:20:11 +01:00
Tobias Trabelsi
aeedda8640
Merge pull request #64 from Lerentis/dependabot/pip/jinja2-3.1.3
Bump jinja2 from 3.1.2 to 3.1.3
2024-01-15 15:32:43 +01:00
dependabot[bot]
cef07ff4c5
Bump jinja2 from 3.1.2 to 3.1.3
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 06:12:02 +00:00
Tobias Trabelsi
2bf13bc8c5
Merge pull request #63 from Lerentis/fixup/fix-arm-node-version
fixup for arm
2024-01-07 21:25:05 +01:00
48754d4578
fixup for arm 2024-01-07 21:20:56 +01:00
Tobias Trabelsi
a2186ab3aa
Merge pull request #61 from Lerentis/Lerentis/issue60
Labels for Secrets and updates
2024-01-06 23:38:59 +01:00
9f4264d355
update dependencies 2024-01-06 23:37:22 +01:00
620d0f0b18
fix CRD and updated docs 2024-01-06 23:29:45 +01:00
ac0bc2d89d
also add labels to update handlers 2024-01-06 22:48:02 +01:00
f45e9ed6a4
bump chart and app version 2024-01-06 14:19:05 +01:00
1d147aad9a
WIP: Labels for Secrets 2024-01-06 14:10:45 +01:00
Tobias Trabelsi
e31899b7f2
Merge pull request #59 from Lerentis/dependabot/github_actions/mikefarah/yq-4.40.5
Bump mikefarah/yq from 4.40.4 to 4.40.5
2023-12-18 20:47:12 +01:00
Tobias Trabelsi
116c1d9c4e
Merge pull request #58 from Lerentis/dependabot/github_actions/actions/download-artifact-4
Bump actions/download-artifact from 3 to 4
2023-12-18 20:47:02 +01:00
dependabot[bot]
0e08d3cc5e
Bump mikefarah/yq from 4.40.4 to 4.40.5
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.40.4 to 4.40.5.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.40.4...v4.40.5)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 06:20:53 +00:00
dependabot[bot]
a58f4762d9
Bump actions/download-artifact from 3 to 4
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 06:20:36 +00:00
Tobias Trabelsi
f287bd80a1
Merge pull request #56 from Lerentis/dependabot/github_actions/mikefarah/yq-4.40.4
Bump mikefarah/yq from 4.40.3 to 4.40.4
2023-12-11 17:49:35 +01:00
Tobias Trabelsi
17fdd4a977
Merge pull request #57 from Lerentis/dependabot/github_actions/actions/setup-python-5
Bump actions/setup-python from 4 to 5
2023-12-11 17:49:17 +01:00
dependabot[bot]
2fde884ad5
Bump actions/setup-python from 4 to 5
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 06:40:27 +00:00
dependabot[bot]
cf186e84fb
Bump mikefarah/yq from 4.40.3 to 4.40.4
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.40.3 to 4.40.4.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.40.3...v4.40.4)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 06:48:49 +00:00
Tobias Trabelsi
bf5a0b2484
Merge pull request #55 from Lerentis/dependabot/github_actions/mikefarah/yq-4.40.3
Bump mikefarah/yq from 4.40.2 to 4.40.3
2023-11-27 07:52:18 +01:00
dependabot[bot]
3ba8f49b39
Bump mikefarah/yq from 4.40.2 to 4.40.3
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.40.2 to 4.40.3.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.40.2...v4.40.3)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 06:48:53 +00:00
Tobias Trabelsi
6a8945af21
Merge pull request #54 from Lerentis/dependabot/github_actions/mikefarah/yq-4.40.2
Bump mikefarah/yq from 4.40.1 to 4.40.2
2023-11-20 23:13:09 +01:00
dependabot[bot]
6160723a72
Bump mikefarah/yq from 4.40.1 to 4.40.2
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.40.1 to 4.40.2.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.40.1...v4.40.2)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 06:47:47 +00:00
Tobias Trabelsi
7527163f26
Merge pull request #52 from Lerentis/dependabot/github_actions/mikefarah/yq-4.40.1
Bump mikefarah/yq from 4.35.2 to 4.40.1
2023-11-13 08:19:36 +01:00
dependabot[bot]
c6ee9fdc39
Bump mikefarah/yq from 4.35.2 to 4.40.1
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.35.2 to 4.40.1.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.35.2...v4.40.1)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 06:14:33 +00:00
Tobias Trabelsi
313cf7d6e9
Merge pull request #51 from Lerentis/dependabot/github_actions/helm/chart-releaser-action-1.6.0
Bump helm/chart-releaser-action from 1.5.0 to 1.6.0
2023-11-06 08:43:57 +01:00
dependabot[bot]
8649c4e865
Bump helm/chart-releaser-action from 1.5.0 to 1.6.0
Bumps [helm/chart-releaser-action](https://github.com/helm/chart-releaser-action) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/helm/chart-releaser-action/releases)
- [Commits](https://github.com/helm/chart-releaser-action/compare/v1.5.0...v1.6.0)

---
updated-dependencies:
- dependency-name: helm/chart-releaser-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 07:25:38 +00:00
Tobias Trabelsi
23037bafc1
Merge pull request #50 from Lerentis/dependabot/github_actions/helm/chart-testing-action-2.6.1
Bump helm/chart-testing-action from 2.4.0 to 2.6.1
2023-11-06 08:24:11 +01:00
dependabot[bot]
be98eb9b88
Bump helm/chart-testing-action from 2.4.0 to 2.6.1
Bumps [helm/chart-testing-action](https://github.com/helm/chart-testing-action) from 2.4.0 to 2.6.1.
- [Release notes](https://github.com/helm/chart-testing-action/releases)
- [Commits](https://github.com/helm/chart-testing-action/compare/v2.4.0...v2.6.1)

---
updated-dependencies:
- dependency-name: helm/chart-testing-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 06:59:52 +00:00
Tobias Trabelsi
80d8db6924
Merge pull request #49 from Lerentis/bugfix/tt/fix-registry-credential-type
Fixed type and content of RegistryCredential
2023-10-27 15:29:18 +02:00
ttrabelsi
d6c207ba82 Fixed type and content of RegistryCredential 2023-10-27 15:22:00 +02:00
Tobias Trabelsi
fc37a12737
Merge pull request #45 from nicoangelo/feature/attachments 2023-10-16 22:58:02 +02:00
Nico Angelo
58b990db2a bump version 2023-10-16 13:28:12 +02:00
Nico Angelo
f3cba82c9f also populate logger for lookup 2023-10-16 13:10:41 +02:00
Nico Angelo
f7a0f43cab fix get attachment command 2023-10-16 13:10:41 +02:00
Nico Angelo
382b6776ce fetch attachments of items 2023-10-16 13:10:41 +02:00
Tobias Trabelsi
94bc6b10b1
Merge pull request #48 from Lerentis/Lerentis/issue47 2023-10-09 23:24:26 +02:00
53dae0aaaf
Added relogin schedule
Fixes #47
2023-10-09 23:18:04 +02:00
41a085c475
Downgrade bitwarden cli due to segfault on newer versions 2023-10-02 20:38:15 +02:00
Tobias Trabelsi
70546b7484
Merge pull request #31 from datalyze-solutions/sync-before-get 2023-10-02 20:35:41 +02:00
Tobias Trabelsi
ae5b39bbcb
Merge pull request #44 from Lerentis/dependabot/github_actions/mikefarah/yq-4.35.2
Bump mikefarah/yq from 4.35.1 to 4.35.2
2023-10-02 09:04:29 +02:00
dependabot[bot]
02dfca5a44
Bump mikefarah/yq from 4.35.1 to 4.35.2
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.35.1 to 4.35.2.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.35.1...v4.35.2)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 06:56:42 +00:00
Matthias Ludwig
31cba57a1a
chore: bump version to v0.8.0; add artifacthub changelog 2023-09-27 11:15:19 +02:00
Matthias Ludwig
f0a9258b71
feat: add time and force sync envs to trigger a sync before getting the secrets 2023-09-25 11:13:44 +02:00
Matthias Ludwig
63e6f8ab7b
Merge branch 'Lerentis:main' into sync-before-get 2023-09-22 13:06:31 +02:00
Tobias Trabelsi
9fe5bde4e8
Merge pull request #41 from Lerentis/dependabot/github_actions/docker/setup-qemu-action-3
Bump docker/setup-qemu-action from 2 to 3
2023-09-18 10:46:06 +02:00
Tobias Trabelsi
7e0a5b6b57
Merge pull request #40 from Lerentis/dependabot/github_actions/docker/login-action-3
Bump docker/login-action from 2 to 3
2023-09-18 10:45:56 +02:00
Tobias Trabelsi
b7ef2480be
Merge pull request #39 from Lerentis/dependabot/github_actions/docker/setup-buildx-action-3
Bump docker/setup-buildx-action from 2 to 3
2023-09-18 10:45:46 +02:00
dependabot[bot]
25a825b712
Bump docker/login-action from 2 to 3
Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 08:38:06 +00:00
dependabot[bot]
963446d9dc
Bump docker/setup-qemu-action from 2 to 3
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 08:38:00 +00:00
dependabot[bot]
bd000cc23a
Bump docker/setup-buildx-action from 2 to 3
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 08:37:51 +00:00
Tobias Trabelsi
72bb525e9a
Merge pull request #38 from Lerentis/dependabot/github_actions/docker/build-push-action-5
Bump docker/build-push-action from 4 to 5
2023-09-18 10:37:02 +02:00
dependabot[bot]
0bb67e4503
Bump docker/build-push-action from 4 to 5
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 08:03:01 +00:00
Tobias Trabelsi
3f35179983
Merge pull request #37 from Lerentis/dependabot/github_actions/actions/checkout-4
Bump actions/checkout from 3 to 4
2023-09-18 10:02:03 +02:00
dependabot[bot]
68ffb94870
Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 07:31:54 +00:00
Tobias Trabelsi
ddf13aae1c
Merge pull request #42 from Lerentis/bugfix/fix-docker-build
Bugfix/fix-docker-build
2023-09-18 09:31:01 +02:00
ttrabelsi
f63e0ac090 bump version and add release notes 2023-09-18 09:11:20 +02:00
ttrabelsi
39a49ab95b fix docker build by updating some dependencies 2023-09-18 09:11:05 +02:00
Tobias Trabelsi
187da26b30
Merge pull request #36 from mbathe19/main
feat: add probes to helm chart
2023-08-21 11:49:47 +02:00
Tobias Trabelsi
62a2b488d2
Update charts/bitwarden-crd-operator/Chart.yaml 2023-08-21 11:43:39 +02:00
Michel Bathe
bec7476ace fix: updatet chart version and added change log 2023-08-21 11:36:52 +02:00
Michel Bathe
d629fa600f feat: add probes to helm chart 2023-08-18 14:47:58 +02:00
Michel Bathe
ba8c35da9f feat: add probes to helm chart 2023-08-18 14:44:24 +02:00
Tobias Trabelsi
e85ea8357a
Merge pull request #35 from Lerentis/dependabot/github_actions/mikefarah/yq-4.35.1
Bump mikefarah/yq from 4.34.2 to 4.35.1
2023-08-14 14:34:49 +02:00
dependabot[bot]
69d1af8ba5
Bump mikefarah/yq from 4.34.2 to 4.35.1
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.34.2 to 4.35.1.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.34.2...v4.35.1)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-14 06:16:25 +00:00
Tobias Trabelsi
293ac2a0b0
Merge pull request #34 from Lerentis/dependabot/pip/kopf-1.36.2
Bump kopf from 1.36.1 to 1.36.2
2023-08-04 10:21:08 +02:00
dependabot[bot]
5c8d10b060
Bump kopf from 1.36.1 to 1.36.2
Bumps [kopf](https://github.com/nolar/kopf) from 1.36.1 to 1.36.2.
- [Release notes](https://github.com/nolar/kopf/releases)
- [Commits](https://github.com/nolar/kopf/compare/1.36.1...1.36.2)

---
updated-dependencies:
- dependency-name: kopf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 06:31:40 +00:00
Tobias Trabelsi
25ebf35835
Merge pull request #32 from Lerentis/dependabot/github_actions/mikefarah/yq-4.34.2
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-19 19:45:51 +02:00
dependabot[bot]
1427715823
Bump mikefarah/yq from 4.34.1 to 4.34.2
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.34.1 to 4.34.2.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.34.1...v4.34.2)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-17 06:41:40 +00:00
Matthias Ludwig
57b6d69b6b chore: add makefile and skaffold config to simplify local testing 2023-07-12 11:06:39 +02:00
Matthias Ludwig
0e33c33415 feat: add sync with bitwarden before getting a secret 2023-07-12 11:05:01 +02:00
Tobias Trabelsi
4d36cd468f
Merge pull request #30 from Lerentis/Lerentis/issue29
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2023-06-24 18:38:39 +02:00
6f099c4bf2
fix bw installation -.-
All checks were successful
continuous-integration/drone/push Build is passing
Fixes #29
2023-06-24 18:32:55 +02:00
Tobias Trabelsi
aa015cc7ba update dependencies 2023-05-31 10:17:59 +02:00
Tobias Trabelsi
2de9bbb0bf
Merge pull request #28 from Lerentis/dependabot/github_actions/mikefarah/yq-4.34.1
Bump mikefarah/yq from 4.33.3 to 4.34.1
2023-05-31 09:40:00 +02:00
dependabot[bot]
4505f3985c
Bump mikefarah/yq from 4.33.3 to 4.34.1
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.33.3 to 4.34.1.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.33.3...v4.34.1)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-29 07:00:59 +00:00
Tobias Trabelsi
82b684e460
Merge pull request #26 from Lerentis/Lerentis/issue25
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
use npm package on arm
2023-05-17 12:41:21 +02:00
Tobias Trabelsi
8ec698f50e
Merge branch 'main' into Lerentis/issue25
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-05-17 12:13:19 +02:00
Tobias Trabelsi
9b8fe1d8ef
Merge pull request #27 from Lerentis/dependabot/github_actions/helm/kind-action-1.5.0
All checks were successful
continuous-integration/drone/push Build is passing
Bump helm/kind-action from 1.4.0 to 1.5.0
2023-05-17 12:12:04 +02:00
dependabot[bot]
516f2a34cf
Bump helm/kind-action from 1.4.0 to 1.5.0
Bumps [helm/kind-action](https://github.com/helm/kind-action) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/helm/kind-action/releases)
- [Commits](https://github.com/helm/kind-action/compare/v1.4.0...v1.5.0)

---
updated-dependencies:
- dependency-name: helm/kind-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-15 07:00:51 +00:00
361d0866e9
linting should be okay for now
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2023-05-11 10:48:25 +02:00
9d4ade904e
fixed comment space... 2023-05-11 10:40:19 +02:00
8c3714f7e0
fix trailing spaces 2023-05-11 10:37:44 +02:00
36ae5cc602
prepare release 2023-05-11 10:35:30 +02:00
d908419b78
build test image in ci 2023-05-11 10:27:43 +02:00
2d399ff8ce
use npm package on arm 2023-05-11 10:22:15 +02:00
c753737497
#22 chart testing pr pipeline
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-10 10:41:59 +02:00
886fe3783d
fixed fields lookup
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
update libcrypte and libssl
2023-05-10 10:35:00 +02:00
Tobias Trabelsi
18a47f8ad2
Merge pull request #24 from Lerentis/dependabot/pip/kopf-1.36.1
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-10 10:00:36 +02:00
dependabot[bot]
e405734e72
Bump kopf from 1.36.0 to 1.36.1
Bumps [kopf](https://github.com/nolar/kopf) from 1.36.0 to 1.36.1.
- [Release notes](https://github.com/nolar/kopf/releases)
- [Commits](https://github.com/nolar/kopf/compare/1.36.0...1.36.1)

---
updated-dependencies:
- dependency-name: kopf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 07:00:31 +00:00
8bf4292991
bump chart version and image ref
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2023-04-26 16:39:00 +02:00
Tobias Trabelsi
b149b26485
Merge pull request #19 from nicoangelo/feature/use-cli-json-mode
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-26 16:35:02 +02:00
Nico Angelo
5263a811e1 add JSON output to changelog 2023-04-26 08:59:17 +02:00
Nico Angelo
4b59ff1aac fix 2023-04-26 08:54:36 +02:00
Nico Angelo
ad1cc9f646 switch to JSON mode of cli
pass around logger
2023-04-26 08:54:36 +02:00
0f518ab28d
hopefully fix permissions
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-22 15:37:14 +02:00
1bf2a24cf2
also setup builx for multiarch build
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-22 15:25:10 +02:00
a73e8ff982
fix build and push 2023-04-22 15:22:35 +02:00
Tobias Trabelsi
54a4ffa212
Merge pull request #20 from Lerentis/Lerentis/issue14 2023-04-22 15:17:55 +02:00
16040bf87a
Push to more Registries
Fixes #14
2023-04-22 15:15:53 +02:00
Tobias Trabelsi
9c1c7417e1
Merge pull request #18 from Lerentis/dependabot/github_actions/mikefarah/yq-4.33.3
All checks were successful
continuous-integration/drone/push Build is passing
Bump mikefarah/yq from 4.33.1 to 4.33.3
2023-04-21 16:01:23 +02:00
Tobias Trabelsi
0f9ca0869c bump chart
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2023-04-21 15:56:18 +02:00
Tobias Trabelsi
6fbf060044 update python version in image
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-21 15:51:51 +02:00
Tobias Trabelsi
3bb40cdcb4 autopep8 and bump alpine
Some checks failed
continuous-integration/drone/push Build is failing
2023-04-21 14:39:06 +02:00
dependabot[bot]
219c9d0413
Bump mikefarah/yq from 4.33.1 to 4.33.3
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.33.1 to 4.33.3.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.33.1...v4.33.3)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-17 07:00:46 +00:00
Tobias Trabelsi
4f92bfe86a
Merge pull request #16 from Lerentis/dependabot/github_actions/mikefarah/yq-4.33.1
All checks were successful
continuous-integration/drone/push Build is passing
Bump mikefarah/yq from 4.32.2 to 4.33.1
2023-03-27 16:44:16 +02:00
dependabot[bot]
640333cfc7
Bump mikefarah/yq from 4.32.2 to 4.33.1
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.32.2 to 4.33.1.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.32.2...v4.33.1)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 07:02:00 +00:00
Tobias Trabelsi
6a907f149f
Merge pull request #15 from Lerentis/dependabot/github_actions/mikefarah/yq-4.32.2
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-21 16:02:37 +01:00
dependabot[bot]
3db74524ca
Bump mikefarah/yq from 4.31.2 to 4.32.2
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.31.2 to 4.32.2.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.31.2...v4.32.2)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 07:02:57 +00:00
Tobias Trabelsi
e49df1fb4d
Merge pull request #13 from Lerentis/dependabot/github_actions/mikefarah/yq-4.31.2
Some checks are pending
continuous-integration/drone/push Build is running
2023-03-06 12:35:38 +01:00
dependabot[bot]
bb3ca7573b
Bump mikefarah/yq from 4.31.1 to 4.31.2
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.31.1 to 4.31.2.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.31.1...v4.31.2)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 07:05:17 +00:00
097712c6c6
version bump and release new helm chart
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2023-02-20 09:25:26 +01:00
Tobias Trabelsi
3845fd8045
Merge pull request #11 from Lerentis/dependabot/github_actions/mikefarah/yq-4.31.1
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-20 09:22:23 +01:00
Tobias Trabelsi
3caacac98a
Merge pull request #12 from Lerentis/dependabot/pip/kubernetes-26.1.0 2023-02-20 09:22:10 +01:00
dependabot[bot]
beeca5a6b6
Bump kubernetes from 25.3.0 to 26.1.0
Bumps [kubernetes](https://github.com/kubernetes-client/python) from 25.3.0 to 26.1.0.
- [Release notes](https://github.com/kubernetes-client/python/releases)
- [Changelog](https://github.com/kubernetes-client/python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes-client/python/compare/v25.3.0...v26.1.0)

---
updated-dependencies:
- dependency-name: kubernetes
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-20 07:04:54 +00:00
dependabot[bot]
2d4c8ec14b
Bump mikefarah/yq from 4.30.8 to 4.31.1
Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.30.8 to 4.31.1.
- [Release notes](https://github.com/mikefarah/yq/releases)
- [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt)
- [Commits](https://github.com/mikefarah/yq/compare/v4.30.8...v4.31.1)

---
updated-dependencies:
- dependency-name: mikefarah/yq
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-20 07:03:56 +00:00
10cc864275
mainternence release
All checks were successful
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing
2023-02-19 12:08:20 +01:00
23 changed files with 1139 additions and 225 deletions

View File

@ -8,11 +8,13 @@ on:
jobs: jobs:
release: release:
permissions: permissions:
id-token: write
contents: write contents: write
packages: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
@ -22,27 +24,48 @@ jobs:
git config user.email "$GITHUB_ACTOR@users.noreply.github.com" git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Install Helm - name: Install Helm
uses: azure/setup-helm@v3 uses: azure/setup-helm@v4
with: with:
version: v3.10.0 version: v3.10.0
- name: Run chart-releaser - name: Run chart-releaser
uses: helm/chart-releaser-action@v1.5.0 uses: helm/chart-releaser-action@v1.6.0
with: with:
charts_dir: charts charts_dir: charts
env: env:
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.30.8 uses: mikefarah/yq@v4.44.3
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
- name: "GHCR Login"
uses: docker/login-action@v3
with:
registry: ghcr.io
username: lerentis
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: "GHCR Build and Push"
id: docker_build
uses: docker/build-push-action@v6
with:
push: true
platforms: linux/amd64,linux/arm64
tags: ghcr.io/lerentis/bitwarden-crd-operator:${{ steps.app_version.outputs.result }}
- name: Create SBOM - name: Create SBOM
uses: anchore/sbom-action@v0 uses: anchore/sbom-action@v0
with: with:
image: lerentis/bitwarden-crd-operator:${{ steps.app_version.outputs.result }} image: ghcr.io/lerentis/bitwarden-crd-operator:${{ steps.app_version.outputs.result }}
- name: Publish SBOM - name: Publish SBOM
uses: anchore/sbom-action/publish-sbom@v0 uses: anchore/sbom-action/publish-sbom@v0
@ -54,7 +77,7 @@ jobs:
uses: WyriHaximus/github-action-get-previous-tag@v1 uses: WyriHaximus/github-action-get-previous-tag@v1
- name: Download SBOM from github action - name: Download SBOM from github action
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ${{ env.ANCHORE_SBOM_ACTION_PRIOR_ARTIFACT }} name: ${{ env.ANCHORE_SBOM_ACTION_PRIOR_ARTIFACT }}

66
.github/workflows/test-and-lint.yml vendored Normal file
View File

@ -0,0 +1,66 @@
name: Lint and Test
on: pull_request
jobs:
lint-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: v3.11.2
- uses: actions/setup-python@v5
with:
python-version: '3.9'
check-latest: true
- name: Set up chart-testing
uses: helm/chart-testing-action@v2.6.1
- name: Run chart-testing (list-changed)
id: list-changed
run: |
changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }})
if [[ -n "$changed" ]]; then
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Run chart-testing (lint)
if: steps.list-changed.outputs.changed == 'true'
run: ct lint --target-branch ${{ github.event.repository.default_branch }}
- name: Install ah cli
run: |
export AH_VERSION=1.17.0
curl -LO https://github.com/artifacthub/hub/releases/download/v${AH_VERSION}/ah_${AH_VERSION}_linux_amd64.tar.gz
tar -xf ah_${AH_VERSION}_linux_amd64.tar.gz
chmod +x ./ah
sudo mv ./ah /usr/bin/ah
rm LICENSE
- name: ah lint
run: |
ah lint
pr-build:
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: GHCR Build
id: docker_build
uses: docker/build-push-action@v6
with:
push: false
platforms: linux/amd64,linux/arm64
tags: ghcr.io/lerentis/bitwarden-crd-operator:dev

2
.gitignore vendored
View File

@ -166,3 +166,5 @@ lib
lib64 lib64
myvalues.yaml myvalues.yaml
.vscode

View File

@ -1,29 +1,30 @@
FROM alpine:latest as builder FROM alpine:3.20.3
ARG BW_VERSION=2022.11.0 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.licenses=MIT
RUN apk add wget unzip ARG PYTHON_VERSION=3.12.6-r0
ARG PIP_VERSION=24.0-r2
ARG GCOMPAT_VERSION=1.1.0-r4
ARG LIBCRYPTO_VERSION=3.3.2-r0
ARG BW_VERSION=2024.7.2
ARG NODE_VERSION=20.15.1-r0
RUN cd /tmp && wget https://github.com/bitwarden/clients/releases/download/cli-v${BW_VERSION}/bw-linux-${BW_VERSION}.zip && \ COPY requirements.txt /requirements.txt
unzip /tmp/bw-linux-${BW_VERSION}.zip
FROM alpine:3.17.1
ARG PYTHON_VERSION=3.10.9-r1
ARG PIP_VERSION=22.3.1-r1
ARG GCOMPAT_VERSION=1.1.0-r0
COPY --from=builder /tmp/bw /usr/local/bin/bw
COPY requirements.txt requirements.txt
RUN set -eux; \ RUN set -eux; \
apk update; \
apk del nodejs-current; \
apk add nodejs=${NODE_VERSION} npm; \
npm install -g @bitwarden/cli@${BW_VERSION}; \
addgroup -S -g 1000 bw-operator; \ addgroup -S -g 1000 bw-operator; \
adduser -S -D -u 1000 -G bw-operator bw-operator; \ adduser -S -D -u 1000 -G bw-operator bw-operator; \
mkdir -p /home/bw-operator; \ mkdir -p /home/bw-operator; \
chown -R bw-operator /home/bw-operator; \ chown -R bw-operator /home/bw-operator; \
chmod +x /usr/local/bin/bw; \ apk add gcc musl-dev libstdc++ gcompat=${GCOMPAT_VERSION} python3=${PYTHON_VERSION} py3-pip=${PIP_VERSION} libcrypto3=${LIBCRYPTO_VERSION}; \
apk add gcc musl-dev libstdc++ gcompat=${GCOMPAT_VERSION} python3=${PYTHON_VERSION} py-pip=${PIP_VERSION}; \ pip install -r /requirements.txt --no-warn-script-location --break-system-packages; \
pip install -r requirements.txt --no-warn-script-location; \ rm /requirements.txt; \
apk del --purge gcc musl-dev libstdc++; apk del --purge gcc musl-dev libstdc++;
COPY --chown=bw-operator:bw-operator src /home/bw-operator COPY --chown=bw-operator:bw-operator src /home/bw-operator

27
Makefile Normal file
View File

@ -0,0 +1,27 @@
deployment_name ?= bitwarden-crd-operator
namespace ?= bitwarden-crd-operator
label_filter = -l app.kubernetes.io/instance=bitwarden-crd-operator -l app.kubernetes.io/name=bitwarden-crd-operator
create-namespace:
kubectl create namespace ${namespace}
dev:
skaffold dev -n ${namespace}
run:
skaffold run -n ${namespace}
pods:
kubectl -n ${namespace} get pods
desc-pods:
kubectl -n ${namespace} describe pod ${label_filter}
delete-pods-force:
kubectl -n ${namespace} delete pod ${label_filter} --force
exec:
kubectl -n ${namespace} exec -it deployment/${deployment_name} -- sh
logs:
kubectl -n ${namespace} logs -f --tail 30 deployment/${deployment_name}

View File

@ -56,23 +56,29 @@ And you are set to create your first secret using this operator. For that you ne
```yaml ```yaml
--- ---
apiVersion: "lerentis.uploadfilter24.eu/v1beta4" apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
kind: BitwardenSecret kind: BitwardenSecret
metadata: metadata:
name: name-of-your-management-object name: name-of-your-management-object
spec: spec:
content: content:
- element: - element:
secretName: nameOfTheFieldInBitwarden # for example username secretName: nameOfTheFieldInBitwarden # for example username or filename
secretRef: nameOfTheKeyInTheSecretToBeCreated secretRef: nameOfTheKeyInTheSecretToBeCreated
secretScope: login # for custom entries on bitwarden use 'fields' secretScope: login # for custom entries on bitwarden use 'fields, for attachments use attachment'
- element: - element:
secretName: nameOfAnotherFieldInBitwarden # for example password secretName: nameOfAnotherFieldInBitwarden # for example password or filename
secretRef: nameOfAnotherKeyInTheSecretToBeCreated secretRef: nameOfAnotherKeyInTheSecretToBeCreated
secretScope: login # for custom entries on bitwarden use 'fields' secretScope: login # for custom entries on bitwarden use 'fields, for attachments use attachment'
id: "A Secret ID from bitwarden" id: "A Secret ID from bitwarden"
name: "Name of the secret to be created" name: "Name of the secret to be created"
secretType: # Optional (Default: Opaque)
namespace: "Namespace of the secret to be created" namespace: "Namespace of the secret to be created"
labels: # Optional
key: value
annotations: # Optional
key: value
``` ```
The ID can be extracted from the browser when you open a item the ID is in the URL. The resulting secret looks something like this: The ID can be extracted from the browser when you open a item the ID is in the URL. The resulting secret looks something like this:
@ -87,6 +93,8 @@ metadata:
annotations: annotations:
managed: bitwarden-secrets.lerentis.uploadfilter24.eu managed: bitwarden-secrets.lerentis.uploadfilter24.eu
managedObject: bw-operator/test managedObject: bw-operator/test
labels:
key: value
name: name-of-your-management-object name: name-of-your-management-object
namespace: default namespace: default
type: Opaque type: Opaque
@ -98,7 +106,7 @@ For managing registry credentials, or pull secrets, you can create another kind
```yaml ```yaml
--- ---
apiVersion: "lerentis.uploadfilter24.eu/v1beta4" apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
kind: RegistryCredential kind: RegistryCredential
metadata: metadata:
name: name-of-your-management-object name: name-of-your-management-object
@ -109,6 +117,10 @@ spec:
id: "A Secret ID from bitwarden" id: "A Secret ID from bitwarden"
name: "Name of the secret to be created" name: "Name of the secret to be created"
namespace: "Namespace of the secret to be created" namespace: "Namespace of the secret to be created"
labels: # Optional
key: value
annotations: # Optional
key: value
``` ```
The resulting secret looks something like this: The resulting secret looks something like this:
@ -122,6 +134,8 @@ metadata:
annotations: annotations:
managed: bitwarden-secrets.lerentis.uploadfilter24.eu managed: bitwarden-secrets.lerentis.uploadfilter24.eu
managedObject: bw-operator/test managedObject: bw-operator/test
labels:
key: value
name: name-of-your-management-object name: name-of-your-management-object
namespace: default namespace: default
type: dockerconfigjson type: dockerconfigjson
@ -129,28 +143,47 @@ type: dockerconfigjson
## BitwardenTemplate ## BitwardenTemplate
One of the more freely defined types that can be used with this operator you can just pass a whole template: One of the more freely defined types that can be used with this operator you can just pass a whole template. Also the lookup function `bitwarden_lookup` is available to reference parts of the secret:
```yaml ```yaml
--- ---
apiVersion: "lerentis.uploadfilter24.eu/v1beta4" apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
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)
namespace: "Namespace of the secret to be created" namespace: "Namespace of the secret to be created"
labels: # Optional
key: value
annotations: # Optional
key: value
content:
- element:
filename: config.yaml
template: | template: |
--- ---
api: api:
enabled: True enabled: True
key: {{ bitwarden_lookup("A Secret ID from bitwarden", "login or fields", "name of a field in bitwarden") }} key: {{ bitwarden_lookup("A Secret ID from bitwarden", "login or fields or attachment", "name of a field in bitwarden") }}
allowCrossOrigin: false allowCrossOrigin: false
apps: apps:
"some.app.identifier:some_version": "some.app.identifier:some_version":
pubkey: {{ bitwarden_lookup("A Secret ID from bitwarden", "login or fields", "name of a field in bitwarden") }} pubkey: {{ bitwarden_lookup("A Secret ID from bitwarden", "login or fields or attachment", "name of a field in bitwarden") }}
enabled: true 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:
@ -164,17 +197,25 @@ metadata:
annotations: annotations:
managed: bitwarden-template.lerentis.uploadfilter24.eu managed: bitwarden-template.lerentis.uploadfilter24.eu
managedObject: namespace/name-of-your-management-object managedObject: namespace/name-of-your-management-object
labels:
key: value
name: Name of the secret to be created name: Name of the secret to be created
namespace: Namespace of the secret to be created namespace: Namespace of the secret to be created
type: Opaque type: Opaque
``` ```
please note that the rendering engine for this template is jinja2, with an addition of a custom `bitwarden_lookup` function, so there are more possibilities to inject here. The signature of `bitwarden_lookup` is `(item_id, scope, field)`:
- `item_id`: The item ID of the secret in Bitwarden
- `scope`: one of `login`, `fields` or `attachment`
- `field`:
- when `scope` is `login`: either `username` or `password`
- when `scope` is `fields`: the name of a custom field
- when `scope` is `attachment`: the filename of a file attached to the item
## Short Term Roadmap Please note that the rendering engine for this template is jinja2, with an addition of a custom `bitwarden_lookup` function, so there are more possibilities to inject here.
- [ ] support more types ## Configurations parameters
- [x] offer option to use a existing secret in helm chart
- [x] host chart on gh pages 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.
- [x] write release pipeline
- [x] maybe extend spec to offer modification of keys as well 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.

View File

@ -4,9 +4,9 @@ description: Deploy the Bitwarden CRD Operator
type: application type: application
version: "v0.5.1" version: "v0.15.0"
appVersion: "0.5.1" appVersion: "0.14.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.23.0-0' kubeVersion: ">= 1.28.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: v1beta4 version: v1beta8
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: v1beta4 version: v1beta8
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: v1beta1 version: v1beta8
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/v1beta4 - apiVersion: lerentis.uploadfilter24.eu/v1beta8
kind: BitwardenSecret kind: BitwardenSecret
metadata: metadata:
name: test name: test
@ -61,8 +61,13 @@ annotations:
secretRef: passwordOfUser secretRef: passwordOfUser
id: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" id: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
name: "test-secret" name: "test-secret"
secretType: Obaque #Optional
namespace: "default" namespace: "default"
- apiVersion: lerentis.uploadfilter24.eu/v1beta4 labels:
key: value
annotations:
key: value
- apiVersion: lerentis.uploadfilter24.eu/v1beta8
kind: RegistryCredential kind: RegistryCredential
metadata: metadata:
name: test name: test
@ -73,14 +78,25 @@ annotations:
id: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" id: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
name: "test-regcred" name: "test-regcred"
namespace: "default" namespace: "default"
- apiVersion: "lerentis.uploadfilter24.eu/v1beta4" labels:
key: value
annotations:
key: value
- apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
kind: BitwardenTemplate kind: BitwardenTemplate
metadata: metadata:
name: test name: test
spec: spec:
filename: "config.yaml"
name: "test-regcred" name: "test-regcred"
secretType: Obaque #Optional
namespace: "default" namespace: "default"
labels:
key: value
annotations:
key: value
content:
- element:
filename: "config.yaml"
template: | template: |
--- ---
api: api:
@ -89,19 +105,21 @@ annotations:
allowCrossOrigin: false allowCrossOrigin: false
apps: apps:
"some.app.identifier:some_version": "some.app.identifier:some_version":
pubkey: {{ bitwarden_lookup("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "fields", "public_key") }} pubkey: {{ bitwarden_lookup("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "attachment", "public_key") }}
enabled: true enabled: true
artifacthub.io/license: MIT artifacthub.io/license: MIT
artifacthub.io/operator: "true" artifacthub.io/operator: "true"
artifacthub.io/containsSecurityUpdates: "false"
artifacthub.io/changes: | artifacthub.io/changes: |
- kind: fixed
description: "Unlocking bitwarden only when needed"
- kind: changed - kind: changed
description: "Allow switch of namespaces in CRDs" description: "BitwardenTemplate can now handle multiple files"
- kind: fixed
description: "Handle none existing keys gracefully"
- kind: changed - kind: changed
description: "Bump alpine minor release version" description: "Removed long deprecated versions"
- kind: changed
description: "Update kubernetes from v29.0.0 to v30.1.0"
- 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: lerentis/bitwarden-crd-operator:0.5.1 image: ghcr.io/lerentis/bitwarden-crd-operator:0.14.0

View File

@ -13,7 +13,52 @@ spec:
shortNames: shortNames:
- bws - bws
versions: versions:
- name: v1beta4 - name: v1beta7
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
secretType:
type: string
labels:
type: object
x-kubernetes-preserve-unknown-fields: true
annotations:
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- id
- namespace
- name
- name: v1beta8
served: true served: true
storage: true storage: true
schema: schema:
@ -45,6 +90,14 @@ spec:
type: string type: string
name: name:
type: string type: string
secretType:
type: string
labels:
type: object
x-kubernetes-preserve-unknown-fields: true
annotations:
type: object
x-kubernetes-preserve-unknown-fields: true
required: required:
- id - id
- namespace - namespace

View File

@ -13,9 +13,10 @@ spec:
shortNames: shortNames:
- bwt - bwt
versions: versions:
- name: v1beta4 - name: v1beta7
served: true served: true
storage: true storage: false
deprecated: true
schema: schema:
openAPIV3Schema: openAPIV3Schema:
type: object type: object
@ -31,8 +32,56 @@ spec:
type: string type: string
name: name:
type: string type: string
secretType:
type: string
labels:
type: object
x-kubernetes-preserve-unknown-fields: true
annotations:
type: object
x-kubernetes-preserve-unknown-fields: true
required: required:
- filename - filename
- 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

View File

@ -13,7 +13,43 @@ spec:
shortNames: shortNames:
- rgc - rgc
versions: versions:
- name: v1beta4 - name: v1beta7
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
annotations:
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- id
- namespace
- name
- usernameRef
- passwordRef
- registry
- name: v1beta8
served: true served: true
storage: true storage: true
schema: schema:
@ -35,6 +71,12 @@ spec:
type: string type: string
name: name:
type: string type: string
labels:
type: object
x-kubernetes-preserve-unknown-fields: true
annotations:
type: object
x-kubernetes-preserve-unknown-fields: true
required: required:
- id - id
- namespace - namespace

View File

@ -8,6 +8,8 @@ spec:
{{- if not .Values.autoscaling.enabled }} {{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }} replicas: {{ .Values.replicaCount }}
{{- end }} {{- end }}
strategy:
type: {{ .Values.deploymentStrategy }}
selector: selector:
matchLabels: matchLabels:
{{- include "bitwarden-crd-operator.selectorLabels" . | nindent 6 }} {{- include "bitwarden-crd-operator.selectorLabels" . | nindent 6 }}
@ -50,10 +52,20 @@ spec:
httpGet: httpGet:
path: /healthz path: /healthz
port: http port: http
failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
successThreshold: {{ .Values.livenessProbe.successThreshold }}
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /healthz path: /healthz
port: http port: http
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
successThreshold: {{ .Values.readinessProbe.successThreshold }}
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
resources: resources:
{{- toYaml .Values.resources | nindent 12 }} {{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }} {{- with .Values.nodeSelector }}

View File

@ -5,7 +5,7 @@
replicaCount: 1 replicaCount: 1
image: image:
repository: lerentis/bitwarden-crd-operator repository: ghcr.io/lerentis/bitwarden-crd-operator
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion. # Overrides the image tag whose default is the chart appVersion.
# tag: "0.1.0" # tag: "0.1.0"
@ -14,7 +14,13 @@ imagePullSecrets: []
nameOverride: "" nameOverride: ""
fullnameOverride: "" fullnameOverride: ""
#env: deploymentStrategy: "Recreate"
# env:
# - name: BW_FORCE_SYNC
# value: "false"
# - name: BW_SYNC_INTERVAL
# value: "900"
# - name: BW_HOST # - name: BW_HOST
# value: "define_it" # value: "define_it"
# - name: BW_CLIENTID # - name: BW_CLIENTID
@ -23,6 +29,8 @@ fullnameOverride: ""
# value: "define_it" # value: "define_it"
# - name: BW_PASSWORD # - name: BW_PASSWORD
# value: "define_id" # value: "define_id"
## - name: BW_RELOGIN_INTERVAL
## value: "3600"
externalConfigSecret: externalConfigSecret:
enabled: false enabled: false
@ -51,6 +59,20 @@ securityContext: {}
# runAsNonRoot: true # runAsNonRoot: true
# runAsUser: 1000 # runAsUser: 1000
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources: {} resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious # We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little # choice for the user. This also increases chances charts run on environments with little

View File

@ -1,8 +1,9 @@
--- ---
apiVersion: "lerentis.uploadfilter24.eu/v1beta4" apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
kind: BitwardenSecret kind: BitwardenSecret
metadata: metadata:
name: test name: test
namespace: default
spec: spec:
content: content:
- element: - element:
@ -15,4 +16,24 @@ spec:
secretScope: login secretScope: login
id: "88781348-c81c-4367-9801-550360c21295" id: "88781348-c81c-4367-9801-550360c21295"
name: "test-secret" name: "test-secret"
secretType: Opaque
namespace: "default"
labels:
key: value
app: example-app
annotations:
custom.annotation: is-used
---
apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
kind: BitwardenSecret
metadata:
name: test-scope
spec:
content:
- element:
secretName: public_key
secretRef: pubKey
secretScope: fields
id: "466fc4b0-ffca-4444-8d88-b59d4de3d928"
name: "test-scope"
namespace: "default" namespace: "default"

View File

@ -1,5 +1,5 @@
--- ---
apiVersion: "lerentis.uploadfilter24.eu/v1beta4" apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
kind: RegistryCredential kind: RegistryCredential
metadata: metadata:
name: test name: test
@ -10,3 +10,8 @@ spec:
id: "3b249ec7-9ce7-440a-9558-f34f3ab10680" id: "3b249ec7-9ce7-440a-9558-f34f3ab10680"
name: "test-regcred" name: "test-regcred"
namespace: "default" namespace: "default"
labels:
namespace: default
tenant: example-team
annotations:
custom.annotation: is-used

View File

@ -1,12 +1,19 @@
--- ---
apiVersion: "lerentis.uploadfilter24.eu/v1beta4" apiVersion: "lerentis.uploadfilter24.eu/v1beta8"
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:
key: value
app: example-app
annotations:
custom.annotation: is-used
content:
- element:
filename: config.yaml
template: | template: |
--- ---
api: api:
@ -17,3 +24,15 @@ spec:
"some.app.identifier:some_version": "some.app.identifier:some_version":
pubkey: {{ bitwarden_lookup("466fc4b0-ffca-4444-8d88-b59d4de3d928", "fields", "public_key") }} pubkey: {{ bitwarden_lookup("466fc4b0-ffca-4444-8d88-b59d4de3d928", "fields", "public_key") }}
enabled: true 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

View File

@ -1,3 +1,4 @@
kopf==1.36.0 kopf==1.37.2
kubernetes==25.3.0 kubernetes==30.1.0
Jinja2==3.1.2 Jinja2==3.1.4
schedule==1.2.2

57
skaffold.yaml Normal file
View File

@ -0,0 +1,57 @@
apiVersion: skaffold/v4beta9
kind: Config
metadata:
name: bitwarden-crd-operator
build:
tagPolicy:
sha256: {}
artifacts:
- image: ghcr.io/lerentis/bitwarden-crd-operator
docker:
dockerfile: Dockerfile
deploy:
helm:
releases:
- name: bitwarden-crd-operator
chartPath: charts/bitwarden-crd-operator
valuesFiles:
- ./charts/bitwarden-crd-operator/myvalues.yaml
setValueTemplates:
image.repository: "{{.IMAGE_REPO_ghcr_io_lerentis_bitwarden_crd_operator}}"
image.tag: "{{.IMAGE_TAG_ghcr_io_lerentis_bitwarden_crd_operator}}@{{.IMAGE_DIGEST_ghcr_io_lerentis_bitwarden_crd_operator}}"
hooks:
after:
- host:
command:
- kubectl
- apply
- -f
- ./example*.yaml
- host:
command:
- sleep
- '5'
- host:
command:
- kubectl
- get
- secret
- test-regcred
- host:
command:
- kubectl
- get
- secret
- test-scope
- host:
command:
- kubectl
- get
- secret
- test-secret
- host:
command:
- kubectl
- get
- secret
- test-template

View File

@ -1,20 +1,47 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import kopf
import os import os
import kopf
import schedule
import time
import threading
from utils.utils import command_wrapper, unlock_bw from utils.utils import command_wrapper, unlock_bw, sync_bw
@kopf.on.startup()
def bitwarden_signin(logger, **kwargs): def bitwarden_signin(logger, **kwargs):
if 'BW_HOST' in os.environ: if 'BW_HOST' in os.environ:
try: try:
command_wrapper(f"config server {os.getenv('BW_HOST')}") command_wrapper(logger, f"config server {os.getenv('BW_HOST')}")
except: except BaseException:
logger.warn("Revieved none zero exit code from server config") logger.warn("Received non-zero exit code from server config")
logger.warn("This is expected from startup") logger.warn("This is expected from startup")
pass pass
else: else:
logger.info(f"BW_HOST not set. Assuming SaaS installation") logger.info("BW_HOST not set. Assuming SaaS installation")
command_wrapper("login --apikey") command_wrapper(logger, "login --apikey")
unlock_bw(logger) unlock_bw(logger)
def run_continuously(interval=30):
cease_continuous_run = threading.Event()
class ScheduleThread(threading.Thread):
@classmethod
def run(cls):
while not cease_continuous_run.is_set():
schedule.run_pending()
time.sleep(interval)
continuous_thread = ScheduleThread()
continuous_thread.start()
return cease_continuous_run
@kopf.on.startup()
def load_schedules(logger, **kwargs):
bitwarden_signin(logger)
logger.info("Loading schedules")
bw_relogin_interval = float(os.environ.get('BW_RELOGIN_INTERVAL', 3600))
bw_sync_interval = float(os.environ.get('BW_SYNC_INTERVAL', 900))
schedule.every(bw_relogin_interval).seconds.do(bitwarden_signin, logger=logger)
logger.info(f"relogin scheduled every {bw_relogin_interval} seconds")
schedule.every(bw_sync_interval).seconds.do(sync_bw, logger=logger)
logger.info(f"sync scheduled every {bw_relogin_interval} seconds")
stop_run_continuously = run_continuously()

View File

@ -3,10 +3,17 @@ import kubernetes
import base64 import base64
import json import json
from utils.utils import unlock_bw, get_secret_from_bitwarden from utils.utils import unlock_bw, get_secret_from_bitwarden, bw_sync_interval
def create_dockerlogin(logger, secret, secret_json, username_ref, password_ref, registry):
secret.type = "dockerconfigjson" def create_dockerlogin(
logger,
secret,
secret_json,
username_ref,
password_ref,
registry):
secret.type = "kubernetes.io/dockerconfigjson"
secret.data = {} secret.data = {}
auths_dict = {} auths_dict = {}
registry_dict = {} registry_dict = {}
@ -15,14 +22,20 @@ def create_dockerlogin(logger, secret, secret_json, username_ref, password_ref,
_username = secret_json["login"][username_ref] _username = secret_json["login"][username_ref]
logger.info(f"Creating login with username: {_username}") logger.info(f"Creating login with username: {_username}")
_password = secret_json["login"][password_ref] _password = secret_json["login"][password_ref]
cred_field = str(base64.b64encode(f"{_username}:{_password}".encode("utf-8")), "utf-8") cred_field = str(
base64.b64encode(
f"{_username}:{_password}".encode("utf-8")),
"utf-8")
reg_auth_dict["username"] = _username
reg_auth_dict["password"] = _password
reg_auth_dict["auth"] = cred_field reg_auth_dict["auth"] = cred_field
registry_dict[registry] = reg_auth_dict registry_dict[registry] = reg_auth_dict
auths_dict["auths"] = registry_dict auths_dict["auths"] = registry_dict
secret.data[".dockerconfigjson"] = str(base64.b64encode(json.dumps(auths_dict).encode("utf-8")), "utf-8") secret.data[".dockerconfigjson"] = str(base64.b64encode(
json.dumps(auths_dict).encode("utf-8")), "utf-8")
return secret return secret
@kopf.on.create('registry-credential.lerentis.uploadfilter24.eu') @kopf.on.create('registry-credential.lerentis.uploadfilter24.eu')
def create_managed_registry_secret(spec, name, namespace, logger, **kwargs): def create_managed_registry_secret(spec, name, namespace, logger, **kwargs):
username_ref = spec.get('usernameRef') username_ref = spec.get('usernameRef')
@ -31,10 +44,12 @@ def create_managed_registry_secret(spec, name, namespace, logger, **kwargs):
id = spec.get('id') id = spec.get('id')
secret_name = spec.get('name') secret_name = spec.get('name')
secret_namespace = spec.get('namespace') secret_namespace = spec.get('namespace')
labels = spec.get('labels')
custom_annotations = spec.get('annotations')
unlock_bw(logger) unlock_bw(logger)
logger.info(f"Locking up secret with ID: {id}") logger.info(f"Locking up secret with ID: {id}")
secret_json_object = json.loads(get_secret_from_bitwarden(id)) secret_json_object = get_secret_from_bitwarden(logger, id)
api = kubernetes.client.CoreV1Api() api = kubernetes.client.CoreV1Api()
@ -42,19 +57,47 @@ def create_managed_registry_secret(spec, name, namespace, logger, **kwargs):
"managed": "registry-credential.lerentis.uploadfilter24.eu", "managed": "registry-credential.lerentis.uploadfilter24.eu",
"managedObject": f"{namespace}/{name}" "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)
obj = api.create_namespaced_secret( 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 = create_dockerlogin(
logger,
secret,
secret_json_object["data"],
username_ref,
password_ref,
registry)
# 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(
secret_namespace, secret secret_namespace, secret
) )
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')
@kopf.timer('registry-credential.lerentis.uploadfilter24.eu', interval=900) @kopf.timer('registry-credential.lerentis.uploadfilter24.eu', interval=bw_sync_interval)
def update_managed_registry_secret(spec, status, name, namespace, logger, body, **kwargs): def update_managed_registry_secret(
spec,
status,
name,
namespace,
logger,
body,
**kwargs):
username_ref = spec.get('usernameRef') username_ref = spec.get('usernameRef')
password_ref = spec.get('passwordRef') password_ref = spec.get('passwordRef')
@ -62,29 +105,37 @@ def update_managed_registry_secret(spec, status, name, namespace, logger, body,
id = spec.get('id') id = spec.get('id')
secret_name = spec.get('name') secret_name = spec.get('name')
secret_namespace = spec.get('namespace') secret_namespace = spec.get('namespace')
labels = spec.get('labels')
custom_annotations = spec.get('annotations')
old_config = None old_config = None
old_secret_name = None old_secret_name = None
old_secret_namespace = None old_secret_namespace = None
if 'kopf.zalando.org/last-handled-configuration' in body.metadata.annotations: 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_config = json.loads(
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')
secret_name = spec.get('name') secret_name = spec.get('name')
secret_namespace = spec.get('namespace') secret_namespace = spec.get('namespace')
if old_config is not None and (old_secret_name != secret_name or old_secret_namespace != secret_namespace): if old_config is not None and (
old_secret_name != secret_name or old_secret_namespace != secret_namespace):
# 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
# We have to delete the secret an recreate it # We have to delete the secret an recreate it
logger.info("Secret name or namespace changed, let's recreate it") logger.info("Secret name or namespace changed, let's recreate it")
delete_managed_secret(old_config['spec'], name, namespace, logger, **kwargs) delete_managed_secret(
old_config['spec'],
name,
namespace,
logger,
**kwargs)
create_managed_registry_secret(spec, name, namespace, logger, **kwargs) create_managed_registry_secret(spec, name, namespace, logger, **kwargs)
return return
unlock_bw(logger) unlock_bw(logger)
logger.info(f"Locking up secret with ID: {id}") logger.info(f"Locking up secret with ID: {id}")
secret_json_object = json.loads(get_secret_from_bitwarden(id)) secret_json_object = get_secret_from_bitwarden(logger, id)
api = kubernetes.client.CoreV1Api() api = kubernetes.client.CoreV1Api()
@ -92,18 +143,42 @@ def update_managed_registry_secret(spec, status, name, namespace, logger, body,
"managed": "registry-credential.lerentis.uploadfilter24.eu", "managed": "registry-credential.lerentis.uploadfilter24.eu",
"managedObject": f"{namespace}/{name}" "managedObject": f"{namespace}/{name}"
} }
if custom_annotations:
annotations.update(custom_annotations)
if not labels:
labels = {}
secret = kubernetes.client.V1Secret() secret = kubernetes.client.V1Secret()
secret.metadata = kubernetes.client.V1ObjectMeta(name=secret_name, annotations=annotations) secret.metadata = kubernetes.client.V1ObjectMeta(
secret = create_dockerlogin(logger, secret, secret_json_object, username_ref, password_ref, registry) name=secret_name, annotations=annotations, labels=labels)
secret = create_dockerlogin(
logger,
secret,
secret_json_object["data"],
username_ref,
password_ref,
registry)
# 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: try:
obj = api.replace_namespaced_secret( api.replace_namespaced_secret(
name=secret_name, name=secret_name,
body=secret, body=secret,
namespace="{}".format(secret_namespace)) namespace="{}".format(secret_namespace))
logger.info(f"Secret {secret_namespace}/{secret_name} has been updated") logger.info(
except: f"Secret {secret_namespace}/{secret_name} has been updated")
except BaseException as e:
logger.warn( logger.warn(
f"Could not update secret {secret_namespace}/{secret_name}!") f"Could not update secret {secret_namespace}/{secret_name}!")
logger.warn(
f"Exception: {e}"
)
@kopf.on.delete('registry-credential.lerentis.uploadfilter24.eu') @kopf.on.delete('registry-credential.lerentis.uploadfilter24.eu')
@ -114,6 +189,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(
except: f"Secret {secret_namespace}/{secret_name} has been deleted")
logger.warn(f"Could not delete secret {secret_namespace}/{secret_name}!") except BaseException:
logger.warn(
f"Could not delete secret {secret_namespace}/{secret_name}!")

113
src/kv.py
View File

@ -3,11 +3,9 @@ import kubernetes
import base64 import base64
import json 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, get_attachment, bw_sync_interval
def create_kv(logger, id, secret, secret_json, content_def):
def create_kv(secret, secret_json, content_def):
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():
@ -21,13 +19,22 @@ def create_kv(secret, secret_json, content_def):
if _secret_scope == "login": if _secret_scope == "login":
value = parse_login_scope(secret_json, _secret_key) value = parse_login_scope(secret_json, _secret_key)
if value is None: if value is None:
raise Exception(f"Field {_secret_key} has no value in bitwarden secret") raise Exception(
f"Field {_secret_key} has no value in bitwarden secret")
secret.data[_secret_ref] = str(base64.b64encode( secret.data[_secret_ref] = str(base64.b64encode(
value.encode("utf-8")), "utf-8") value.encode("utf-8")), "utf-8")
if _secret_scope == "fields": if _secret_scope == "fields":
value = parse_fields_scope(secret_json, _secret_key) value = parse_fields_scope(secret_json, _secret_key)
if value is None: if value is None:
raise Exception(f"Field {_secret_key} has no value in bitwarden secret") raise Exception(
f"Field {_secret_key} has no value in bitwarden secret")
secret.data[_secret_ref] = str(base64.b64encode(
value.encode("utf-8")), "utf-8")
if _secret_scope == "attachment":
value = get_attachment(logger, id, _secret_key)
if value is None:
raise Exception(
f"Attachment {_secret_key} has no value in bitwarden secret")
secret.data[_secret_ref] = str(base64.b64encode( secret.data[_secret_ref] = str(base64.b64encode(
value.encode("utf-8")), "utf-8") value.encode("utf-8")), "utf-8")
return secret return secret
@ -40,10 +47,13 @@ def create_managed_secret(spec, name, namespace, logger, body, **kwargs):
id = spec.get('id') id = spec.get('id')
secret_name = spec.get('name') secret_name = spec.get('name')
secret_namespace = spec.get('namespace') secret_namespace = spec.get('namespace')
labels = spec.get('labels')
custom_annotations = spec.get('annotations')
custom_secret_type = spec.get('secretType')
unlock_bw(logger) unlock_bw(logger)
logger.info(f"Locking up secret with ID: {id}") logger.info(f"Locking up secret with ID: {id}")
secret_json_object = json.loads(get_secret_from_bitwarden(id)) secret_json_object = get_secret_from_bitwarden(logger, id)
api = kubernetes.client.CoreV1Api() api = kubernetes.client.CoreV1Api()
@ -51,12 +61,28 @@ def create_managed_secret(spec, name, namespace, logger, body, **kwargs):
"managed": "bitwarden-secret.lerentis.uploadfilter24.eu", "managed": "bitwarden-secret.lerentis.uploadfilter24.eu",
"managedObject": f"{namespace}/{name}" "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 = kubernetes.client.V1Secret()
secret.metadata = kubernetes.client.V1ObjectMeta( secret.metadata = kubernetes.client.V1ObjectMeta(
name=secret_name, annotations=annotations) name=secret_name, annotations=annotations, labels=labels)
secret = create_kv(secret, secret_json_object, content_def) secret.type = custom_secret_type
secret = create_kv(logger, id, secret, secret_json_object, content_def)
obj = api.create_namespaced_secret( # 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), namespace="{}".format(secret_namespace),
body=secret body=secret
) )
@ -65,32 +91,57 @@ def create_managed_secret(spec, name, namespace, logger, body, **kwargs):
@kopf.on.update('bitwarden-secret.lerentis.uploadfilter24.eu') @kopf.on.update('bitwarden-secret.lerentis.uploadfilter24.eu')
@kopf.timer('bitwarden-secret.lerentis.uploadfilter24.eu', interval=900) @kopf.timer('bitwarden-secret.lerentis.uploadfilter24.eu', interval=bw_sync_interval)
def update_managed_secret(spec, status, name, namespace, logger, body, **kwargs): def update_managed_secret(
spec,
status,
name,
namespace,
logger,
body,
**kwargs):
content_def = body['spec']['content'] content_def = body['spec']['content']
id = spec.get('id') id = spec.get('id')
old_config = None old_config = None
old_secret_name = None old_secret_name = None
old_secret_namespace = None old_secret_namespace = None
old_secret_type = None
if 'kopf.zalando.org/last-handled-configuration' in body.metadata.annotations: 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_config = json.loads(
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')
secret_name = spec.get('name') secret_name = spec.get('name')
secret_namespace = spec.get('namespace') secret_namespace = spec.get('namespace')
labels = spec.get('labels')
custom_annotations = spec.get('annotations')
custom_secret_type = spec.get('secretType')
if old_config is not None and (old_secret_name != secret_name or old_secret_namespace != secret_namespace): if not custom_secret_type:
custom_secret_type = 'Opaque'
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 # If the name of the secret or the namespace of the secret is different
# We have to delete the secret an recreate it # We have to delete the secret an recreate it
logger.info("Secret name or namespace changed, let's recreate it") logger.info("Secret name, namespace or type changed, let's recreate it")
delete_managed_secret(old_config['spec'], name, namespace, logger, **kwargs) delete_managed_secret(
old_config['spec'],
name,
namespace,
logger,
**kwargs)
create_managed_secret(spec, name, namespace, logger, body, **kwargs) create_managed_secret(spec, name, namespace, logger, body, **kwargs)
return return
unlock_bw(logger) unlock_bw(logger)
logger.info(f"Locking up secret with ID: {id}") logger.info(f"Locking up secret with ID: {id}")
secret_json_object = json.loads(get_secret_from_bitwarden(id)) secret_json_object = get_secret_from_bitwarden(logger, id)
api = kubernetes.client.CoreV1Api() api = kubernetes.client.CoreV1Api()
@ -99,20 +150,36 @@ def update_managed_secret(spec, status, name, namespace, logger, body, **kwargs)
"managedObject": f"{namespace}/{name}" "managedObject": f"{namespace}/{name}"
} }
if custom_annotations:
annotations.update(custom_annotations)
if not labels:
labels = {}
secret = kubernetes.client.V1Secret() secret = kubernetes.client.V1Secret()
secret.metadata = kubernetes.client.V1ObjectMeta( secret.metadata = kubernetes.client.V1ObjectMeta(
name=secret_name, annotations=annotations) name=secret_name, annotations=annotations, labels=labels)
secret = create_kv(secret, secret_json_object, content_def) secret.type = custom_secret_type
secret = create_kv(logger, id, secret, secret_json_object, 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: try:
obj = api.replace_namespaced_secret( api.replace_namespaced_secret(
name=secret_name, name=secret_name,
body=secret, body=secret,
namespace="{}".format(secret_namespace)) namespace="{}".format(secret_namespace))
logger.info(f"Secret {secret_namespace}/{secret_name} has been updated") logger.info(
except: f"Secret {secret_namespace}/{secret_name} has been updated")
except BaseException as e:
logger.warn( logger.warn(
f"Could not update secret {secret_namespace}/{secret_name}!") f"Could not update secret {secret_namespace}/{secret_name}!")
logger.warn(
f"Exception: {e}"
)
@kopf.on.delete('bitwarden-secret.lerentis.uploadfilter24.eu') @kopf.on.delete('bitwarden-secret.lerentis.uploadfilter24.eu')
@ -125,6 +192,6 @@ def delete_managed_secret(spec, name, namespace, logger, **kwargs):
api.delete_namespaced_secret(secret_name, secret_namespace) api.delete_namespaced_secret(secret_name, secret_namespace)
logger.info( logger.info(
f"Secret {secret_namespace}/{secret_name} has been deleted") f"Secret {secret_namespace}/{secret_name} has been deleted")
except: except BaseException:
logger.warn( logger.warn(
f"Could not delete secret {secret_namespace}/{secret_name}!") f"Could not delete secret {secret_namespace}/{secret_name}!")

View File

@ -1,9 +1,15 @@
import json from utils.utils import get_secret_from_bitwarden, get_attachment, parse_fields_scope, parse_login_scope
from utils.utils import get_secret_from_bitwarden, parse_fields_scope, parse_login_scope
def bitwarden_lookup(id, scope, field): class BitwardenLookupHandler:
_secret_json = json.loads(get_secret_from_bitwarden(id))
def __init__(self, logger) -> None:
self.logger = logger
def bitwarden_lookup(self, id, scope, field):
if scope == "attachment":
return get_attachment(self.logger, id, field)
_secret_json = get_secret_from_bitwarden(self.logger, id)
if scope == "login": if scope == "login":
return parse_login_scope(_secret_json, field) return parse_login_scope(_secret_json, field)
if scope == "fields": if scope == "fields":

View File

@ -3,33 +3,54 @@ import base64
import kubernetes import kubernetes
import json import json
from utils.utils import unlock_bw from utils.utils import unlock_bw, bw_sync_interval
from lookups.bitwarden_lookup import bitwarden_lookup from lookups.bitwarden_lookup import BitwardenLookupHandler
from jinja2 import Environment, BaseLoader from jinja2 import Environment, BaseLoader
lookup_func_dict = { def render_template(logger, template):
"bitwarden_lookup": bitwarden_lookup,
}
def render_template(template):
jinja_template = Environment(loader=BaseLoader()).from_string(template) jinja_template = Environment(loader=BaseLoader()).from_string(template)
jinja_template.globals.update(lookup_func_dict) jinja_template.globals.update({
"bitwarden_lookup": BitwardenLookupHandler(logger).bitwarden_lookup,
})
return jinja_template.render() return jinja_template.render()
def create_template_secret(secret, filename, template):
secret.type = "Opaque" def create_template_secret(logger, secret, filename, template):
secret.data = {} secret.data = {}
secret.data[filename] = str(base64.b64encode(render_template(template).encode("utf-8")), "utf-8") secret.data[filename] = str(
base64.b64encode(
render_template(logger, template).encode("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') template = spec.get('template')
filename = spec.get('filename') if template is not None:
create_beta7_secret(spec, name, namespace, logger, body, **kwargs)
secret_name = spec.get('name') secret_name = spec.get('name')
secret_namespace = spec.get('namespace') 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) unlock_bw(logger)
@ -39,40 +60,127 @@ def create_managed_secret(spec, name, namespace, logger, body, **kwargs):
"managed": "bitwarden-template.lerentis.uploadfilter24.eu", "managed": "bitwarden-template.lerentis.uploadfilter24.eu",
"managedObject": f"{namespace}/{name}" "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)
obj = api.create_namespaced_secret( if custom_annotations:
secret_namespace, secret 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") logger.info(f"Secret {secret_namespace}/{secret_name} has been created")
@kopf.on.update('bitwarden-template.lerentis.uploadfilter24.eu')
@kopf.timer('bitwarden-template.lerentis.uploadfilter24.eu', interval=900) def create_beta7_secret(spec, name, namespace, logger, body, **kwargs):
def update_managed_secret(spec, status, name, namespace, logger, body, **kwargs):
template = spec.get('template') template = spec.get('template')
filename = spec.get('filename') filename = spec.get('filename')
secret_name = spec.get('name') secret_name = spec.get('name')
secret_namespace = spec.get('namespace') secret_namespace = spec.get('namespace')
labels = spec.get('labels')
custom_annotations = spec.get('annotations')
custom_secret_type = spec.get('secretType')
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_secret(logger, secret, filename, template)
# 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(
secret_namespace, secret
)
logger.info(f"Secret {secret_namespace}/{secret_name} has been created")
def update_beta7_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')
labels = spec.get('labels')
custom_annotations = spec.get('annotations')
custom_secret_type = spec.get('secretType')
if not custom_secret_type:
custom_secret_type = 'Opaque'
old_config = None old_config = None
old_secret_name = None old_secret_name = None
old_secret_namespace = None old_secret_namespace = None
old_secret_type = None
if 'kopf.zalando.org/last-handled-configuration' in body.metadata.annotations: 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_config = json.loads(
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')
secret_name = spec.get('name') secret_name = spec.get('name')
secret_namespace = spec.get('namespace') secret_namespace = spec.get('namespace')
if old_config is not None and (old_secret_name != secret_name or old_secret_namespace != secret_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 # If the name of the secret or the namespace of the secret is different
# We have to delete the secret an recreate it # We have to delete the secret an recreate it
logger.info("Secret name or namespace changed, let's recreate it") logger.info("Secret name or namespace changed, let's recreate it")
delete_managed_secret(old_config['spec'], name, namespace, logger, **kwargs) delete_managed_secret(
old_config['spec'],
name,
namespace,
logger,
**kwargs)
create_managed_secret(spec, name, namespace, logger, body, **kwargs) create_managed_secret(spec, name, namespace, logger, body, **kwargs)
return return
@ -84,19 +192,134 @@ def update_managed_secret(spec, status, name, namespace, logger, body, **kwargs)
"managed": "bitwarden-template.lerentis.uploadfilter24.eu", "managed": "bitwarden-template.lerentis.uploadfilter24.eu",
"managedObject": f"{namespace}/{name}" "managedObject": f"{namespace}/{name}"
} }
if custom_annotations:
annotations.update(custom_annotations)
if not labels:
labels = {}
secret = kubernetes.client.V1Secret() secret = kubernetes.client.V1Secret()
secret.metadata = kubernetes.client.V1ObjectMeta(name=secret_name, annotations=annotations) secret.metadata = kubernetes.client.V1ObjectMeta(
secret = create_template_secret(secret, filename, template) name=secret_name, annotations=annotations, labels=labels)
secret.type = custom_secret_type
secret = create_template_secret(logger, secret, filename, template)
# 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: try:
obj = api.replace_namespaced_secret( api.replace_namespaced_secret(
name=secret_name, name=secret_name,
body=secret, body=secret,
namespace="{}".format(secret_namespace)) namespace="{}".format(secret_namespace))
logger.info(f"Secret {secret_namespace}/{secret_name} has been updated") logger.info(
except: f"Secret {secret_namespace}/{secret_name} has been updated")
except BaseException as e:
logger.warn( logger.warn(
f"Could not update secret {secret_namespace}/{secret_name}!") f"Could not update secret {secret_namespace}/{secret_name}!")
logger.warn(
f"Exception: {e}"
)
@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):
@ -106,6 +329,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(
except: f"Secret {secret_namespace}/{secret_name} has been deleted")
logger.warn(f"Could not delete secret {secret_namespace}/{secret_name}!") except BaseException:
logger.warn(
f"Could not delete secret {secret_namespace}/{secret_name}!")

View File

@ -1,38 +1,91 @@
import os import os
import json import json
import subprocess import subprocess
import distutils
bw_sync_interval = float(os.environ.get(
'BW_SYNC_INTERVAL', 900))
class BitwardenCommandException(Exception): class BitwardenCommandException(Exception):
pass pass
def get_secret_from_bitwarden(id):
return command_wrapper(command=f"get item {id}") def get_secret_from_bitwarden(logger, id, force_sync=False):
sync_bw(logger, force=force_sync)
return command_wrapper(logger, command=f"get item {id}")
def sync_bw(logger, force=False):
def _sync(logger):
status_output = command_wrapper(logger, command=f"sync")
logger.info(f"Sync successful {status_output}")
return
if force:
_sync(logger)
return
global_force_sync = bool(distutils.util.strtobool(
os.environ.get('BW_FORCE_SYNC', "false")))
if global_force_sync:
logger.debug("Running forced sync")
status_output = _sync(logger)
logger.info(f"Sync successful {status_output}")
else:
logger.debug("Running scheduled sync")
status_output = _sync(logger)
logger.info(f"Sync successful {status_output}")
def get_attachment(logger, id, name):
return command_wrapper(logger, command=f"get attachment {name} --itemid {id}", raw=True)
def unlock_bw(logger): def unlock_bw(logger):
status_output = command_wrapper("status") status_output = command_wrapper(logger, "status", False)
status = json.loads(status_output)['status'] status = status_output['data']['template']['status']
if status == 'unlocked': if status == 'unlocked':
logger.info("Already unlocked") logger.info("Already unlocked")
return return
token_output = command_wrapper("unlock --passwordenv BW_PASSWORD") token_output = command_wrapper(logger, "unlock --passwordenv BW_PASSWORD")
tokens = token_output.split('"')[1::2] os.environ["BW_SESSION"] = token_output["data"]["raw"]
os.environ["BW_SESSION"] = tokens[1]
logger.info("Signin successful. Session exported") logger.info("Signin successful. Session exported")
def command_wrapper(command):
def command_wrapper(logger, command, use_success: bool = True, raw: bool = False):
system_env = dict(os.environ) 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) response_flag = "--raw" if raw else "--response"
sp = subprocess.Popen(
[f"bw {response_flag} {command}"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True,
shell=True,
env=system_env)
out, err = sp.communicate() out, err = sp.communicate()
if err: if err:
raise BitwardenCommandException(err) logger.warn(err)
return None
if raw:
return out.decode(encoding='UTF-8') return out.decode(encoding='UTF-8')
if "DEBUG" in system_env:
logger.info(out.decode(encoding='UTF-8'))
resp = json.loads(out.decode(encoding='UTF-8'))
if resp["success"] != None and (not use_success or (use_success and resp["success"] == True)):
return resp
logger.warn(resp)
return None
def parse_login_scope(secret_json, key): def parse_login_scope(secret_json, key):
return secret_json["login"][key] return secret_json["data"]["login"][key]
def parse_fields_scope(secret_json, key): def parse_fields_scope(secret_json, key):
if "fields" not in secret_json: if "fields" not in secret_json["data"]:
return None return None
for entry in secret_json["fields"]: for entry in secret_json["data"]["fields"]:
if entry['name'] == key: if entry['name'] == key:
return entry['value'] return entry['value']