mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-02-19 20:39:51 +00:00
Compare commits
226 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa06d8d6ae | ||
|
|
887f4adc01 | ||
|
|
e6e35fff2f | ||
|
|
c22044016a | ||
|
|
21022f35dd | ||
|
|
e1bfdc0d6e | ||
|
|
da064dafcd | ||
|
|
6e80052847 | ||
|
|
5dc7965530 | ||
|
|
0a46fcb912 | ||
|
|
9f6356c3a8 | ||
|
|
07b5bcafd3 | ||
|
|
d829378ce1 | ||
|
|
a03ce238b7 | ||
|
|
e7adc8dc95 | ||
|
|
d5786e5aa6 | ||
|
|
c9dbeac2f3 | ||
|
|
0cbc96ab25 | ||
|
|
426fc11bd5 | ||
|
|
34e2c7729c | ||
|
|
2d01f345b2 | ||
|
|
7b34fc457d | ||
|
|
aa9b6ab378 | ||
|
|
41a626cdc4 | ||
|
|
4ec2ff1d44 | ||
|
|
93cbe205f4 | ||
|
|
12b254c622 | ||
|
|
49fb307529 | ||
|
|
ace0d74c23 | ||
|
|
b74095be25 | ||
|
|
8ba9e9af1b | ||
|
|
7d7adf9c58 | ||
|
|
46a4e0dba1 | ||
|
|
8083cb59c9 | ||
|
|
ed9e1d4c47 | ||
|
|
20807ad8f3 | ||
|
|
7ecc6346f3 | ||
|
|
7d5eb0117c | ||
|
|
4be8566b79 | ||
|
|
2120e6d33e | ||
|
|
fcf58371d5 | ||
|
|
0a17c2ae7f | ||
|
|
1eef6fbb95 | ||
|
|
ee02e24d96 | ||
|
|
d07904ce03 | ||
|
|
59cb9694c0 | ||
|
|
8d498bb925 | ||
|
|
da66f40462 | ||
|
|
462ff47ed0 | ||
|
|
007cdd1c2d | ||
|
|
d0dbda7958 | ||
|
|
b923ce053c | ||
|
|
c695f480ff | ||
|
|
1d53811c48 | ||
|
|
c9b006fe97 | ||
|
|
6ff9d4b38a | ||
|
|
375643ab06 | ||
|
|
8a0be8a639 | ||
|
|
633263ace7 | ||
|
|
1e767be94d | ||
|
|
258300686e | ||
|
|
f82c2f468b | ||
|
|
5143c5cedc | ||
|
|
e6f7031128 | ||
|
|
3dc74c8791 | ||
|
|
f077028bdb | ||
|
|
8ff1044c47 | ||
|
|
df2bf1c98a | ||
|
|
aade294e78 | ||
|
|
f3b9728963 | ||
|
|
6278febf86 | ||
|
|
fd80e5c339 | ||
|
|
55c010c96e | ||
|
|
7a74268fc1 | ||
|
|
a75d7ab0ba | ||
|
|
650d535f67 | ||
|
|
7894300cce | ||
|
|
6184ff0499 | ||
|
|
4916b8f3ec | ||
|
|
b8636974a0 | ||
|
|
2b29fa7a08 | ||
|
|
cbcab2f08d | ||
|
|
a4b88d3b46 | ||
|
|
62e5e856b3 | ||
|
|
d49fcb7609 | ||
|
|
d86c8efd02 | ||
|
|
4dd46dd407 | ||
|
|
630f9e281f | ||
|
|
1659987274 | ||
|
|
93f7ebbc49 | ||
|
|
5df2add177 | ||
|
|
0394cc3e72 | ||
|
|
6313467dd1 | ||
|
|
2ca0043588 | ||
|
|
855d80ea62 | ||
|
|
f24b6b1b43 | ||
|
|
a7814af471 | ||
|
|
99d24da9ee | ||
|
|
6d03aa7305 | ||
|
|
2763fb77fa | ||
|
|
59e5ace956 | ||
|
|
f5bbeef2cb | ||
|
|
da478fcaeb | ||
|
|
3f5bc4a885 | ||
|
|
fd24ae82fb | ||
|
|
65030a1d7d | ||
|
|
48eab4e4cd | ||
|
|
a49c57bb5b | ||
|
|
d620b0457d | ||
|
|
1d9fcc7a0d | ||
|
|
2ed12d2f45 | ||
|
|
4b6864c155 | ||
|
|
34c4b94b7b | ||
|
|
db9107a3aa | ||
|
|
a089714625 | ||
|
|
b0bb26cd3e | ||
|
|
414cebd15f | ||
|
|
8930090dc6 | ||
|
|
eb7a77a920 | ||
|
|
9af5913086 | ||
|
|
26309d7992 | ||
|
|
8116434c66 | ||
|
|
0590624289 | ||
|
|
1a11a6c4a5 | ||
|
|
c657b55da9 | ||
|
|
58540b52bd | ||
|
|
323ac75c06 | ||
|
|
3de52e8139 | ||
|
|
d58fd0f2d7 | ||
|
|
00af2860fc | ||
|
|
3dd20349b6 | ||
|
|
9e4068850c | ||
|
|
446b8ea744 | ||
|
|
cfb2c6cddf | ||
|
|
0df02dbcb8 | ||
|
|
6b9e763f10 | ||
|
|
fb4f0cfe42 | ||
|
|
5a34c09447 | ||
|
|
c26f68efff | ||
|
|
206ce71ec6 | ||
|
|
b408d53cb7 | ||
|
|
a5f544a10b | ||
|
|
78c631b4f5 | ||
|
|
3096e2f55d | ||
|
|
532e880de0 | ||
|
|
913b9e83b9 | ||
|
|
9ebbbed785 | ||
|
|
7d78f5f488 | ||
|
|
e06054e500 | ||
|
|
3905f5dea6 | ||
|
|
b1a2eeb875 | ||
|
|
44365e6cc6 | ||
|
|
22451b51eb | ||
|
|
874de7339b | ||
|
|
337aa779fb | ||
|
|
4ba1d28fb5 | ||
|
|
5efb4fbfcf | ||
|
|
4afcfbbb27 | ||
|
|
82995a3e66 | ||
|
|
0571e419a3 | ||
|
|
3bfa02e929 | ||
|
|
dc44eaabf7 | ||
|
|
a42097512c | ||
|
|
e6695478cb | ||
|
|
2250e38903 | ||
|
|
d6962218c4 | ||
|
|
df80539a3c | ||
|
|
cb924972b1 | ||
|
|
b16bcda8fb | ||
|
|
915e493b4a | ||
|
|
79e4c72385 | ||
|
|
c6c3a1b00b | ||
|
|
4828729c80 | ||
|
|
daa28b4cbb | ||
|
|
55bd0b4453 | ||
|
|
448dabe8b7 | ||
|
|
661476c8c1 | ||
|
|
e068b57e60 | ||
|
|
cdfc2ccc9b | ||
|
|
419eb8f6fa | ||
|
|
65043821b4 | ||
|
|
859fbf8316 | ||
|
|
f78dbaf06e | ||
|
|
07202d06ba | ||
|
|
7dec7be15b | ||
|
|
d972c2fd30 | ||
|
|
00b59fa843 | ||
|
|
e418f74e34 | ||
|
|
c2f3694808 | ||
|
|
c0d5d6fcb2 | ||
|
|
9a3a8b0cac | ||
|
|
2a6fb1eb30 | ||
|
|
b1fcb28878 | ||
|
|
6594a3bade | ||
|
|
894a42c258 | ||
|
|
d81185bcbc | ||
|
|
8fe29e89af | ||
|
|
44af534fc5 | ||
|
|
a8dbd0c7a4 | ||
|
|
85fe29159b | ||
|
|
06d6903abf | ||
|
|
ffa2b15da4 | ||
|
|
0323488f41 | ||
|
|
883122829f | ||
|
|
a529910bba | ||
|
|
537f25cbdf | ||
|
|
a3079668d7 | ||
|
|
97874c2a7e | ||
|
|
0a07c0565b | ||
|
|
9c1b9487d9 | ||
|
|
9e85e1592f | ||
|
|
c35cf71402 | ||
|
|
74cd6cea1a | ||
|
|
6b25dbe2d7 | ||
|
|
0d5f2dfc70 | ||
|
|
7e8ae2320c | ||
|
|
c334b2afe8 | ||
|
|
3ef5af6bc6 | ||
|
|
297e5c7674 | ||
|
|
e5ec492da4 | ||
|
|
f343623b30 | ||
|
|
c8e2b7488c | ||
|
|
e983c19473 | ||
|
|
c5808ef036 | ||
|
|
559287cef5 | ||
|
|
1bdb9f2879 |
4
.github/actions/setup-caches/action.yaml
vendored
4
.github/actions/setup-caches/action.yaml
vendored
@@ -9,11 +9,11 @@ inputs:
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d # v3.2.2
|
||||
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('**/go.sum') }}-${{ hashFiles('Makefile') }}
|
||||
- uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d # v3.2.2
|
||||
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
if: ${{ inputs.build-cache-key }}
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
|
||||
2
.github/configs/ct.yaml
vendored
2
.github/configs/ct.yaml
vendored
@@ -2,6 +2,8 @@ remote: origin
|
||||
target-branch: main
|
||||
chart-dirs:
|
||||
- charts
|
||||
chart-repos:
|
||||
- capsule=https://projectcapsule.github.io/charts/
|
||||
helm-extra-args: "--timeout 600s"
|
||||
validate-chart-schema: false
|
||||
validate-maintainers: false
|
||||
|
||||
16
.github/dependabot.yml
vendored
16
.github/dependabot.yml
vendored
@@ -1,16 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: gomod
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
rebase-strategy: disabled
|
||||
commit-message:
|
||||
prefix: "feat(deps)"
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
rebase-strategy: disabled
|
||||
commit-message:
|
||||
prefix: "ci(deps)"
|
||||
4
.github/workflows/check-actions.yml
vendored
4
.github/workflows/check-actions.yml
vendored
@@ -14,9 +14,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Ensure SHA pinned actions
|
||||
uses: zgosalvez/github-actions-ensure-sha-pinned-actions@ba37328d4ea95eaf8b3bd6c6cef308f709a5f2ec # v3.0.3
|
||||
uses: zgosalvez/github-actions-ensure-sha-pinned-actions@c3a2b64f69b7a1542a68f44d9edbd9ec3fc1455e # v3.0.20
|
||||
with:
|
||||
# slsa-github-generator requires using a semver tag for reusable workflows.
|
||||
# See: https://github.com/slsa-framework/slsa-github-generator#referencing-slsa-builders-and-generators
|
||||
|
||||
6
.github/workflows/check-commit.yml
vendored
6
.github/workflows/check-commit.yml
vendored
@@ -13,11 +13,11 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
commit_lint:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: wagoid/commitlint-github-action@5ce82f5d814d4010519d15f0552aec4f17a1e1fe #v5.4.5
|
||||
- uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6.2.1
|
||||
with:
|
||||
firstParent: true
|
||||
|
||||
2
.github/workflows/check-pr.yml
vendored
2
.github/workflows/check-pr.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
name: Validate PR title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@e9fabac35e210fea40ca5b14c0da95a099eff26f
|
||||
- uses: amannn/action-semantic-pull-request@40166f00814508ec3201fc8595b393d451c8cd80
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
|
||||
4
.github/workflows/codecov.yml
vendored
4
.github/workflows/codecov.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Setup caches
|
||||
uses: ./.github/actions/setup-caches
|
||||
timeout-minutes: 5
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
run: make test
|
||||
- name: Upload Report to Codecov
|
||||
if: steps.checksecret.outputs.result == 'true'
|
||||
uses: codecov/codecov-action@0cfda1dd0a4ad9efc75517f399d859cd1ea4ced1 # v4.0.2
|
||||
uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
|
||||
with:
|
||||
file: ./coverage.out
|
||||
fail_ci_if_error: true
|
||||
|
||||
13
.github/workflows/diff.yml
vendored
13
.github/workflows/diff.yml
vendored
@@ -14,20 +14,17 @@ concurrency:
|
||||
jobs:
|
||||
diff:
|
||||
name: diff
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
|
||||
with:
|
||||
go-version: '1.21'
|
||||
- run: make installer
|
||||
go-version-file: 'go.mod'
|
||||
- run: make manifests
|
||||
- name: Checking if YAML installer file is not aligned
|
||||
run: if [[ $(git diff | wc -l) -gt 0 ]]; then echo ">>> Untracked generated files have not been committed" && git --no-pager diff && exit 1; fi
|
||||
- run: make apidoc
|
||||
- name: Checking if the CRDs documentation is not aligned
|
||||
run: if [[ $(git diff | wc -l) -gt 0 ]]; then echo ">>> CRDs generated documentation have not been committed" && git --no-pager diff && exit 1; fi
|
||||
- name: Checking if YAML installer generated untracked files
|
||||
run: test -z "$(git ls-files --others --exclude-standard 2> /dev/null)"
|
||||
- name: Checking if source code is not formatted
|
||||
|
||||
18
.github/workflows/docker-publish.yml
vendored
18
.github/workflows/docker-publish.yml
vendored
@@ -15,12 +15,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
id-token: write
|
||||
id-token: write
|
||||
outputs:
|
||||
capsule-digest: ${{ steps.publish-capsule.outputs.digest }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Setup caches
|
||||
uses: ./.github/actions/setup-caches
|
||||
timeout-minutes: 5
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
with:
|
||||
build-cache-key: publish-images
|
||||
- name: Run Trivy vulnerability (Repo)
|
||||
uses: aquasecurity/trivy-action@84384bd6e777ef152729993b8145ea352e9dd3ef # v0.17.0
|
||||
uses: aquasecurity/trivy-action@18f2510ee396bbf400402947b394f2dd8c87dbb0 # v0.29.0
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
ignore-unfixed: true
|
||||
@@ -36,10 +36,10 @@ jobs:
|
||||
output: 'trivy-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0
|
||||
uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
|
||||
- name: Publish Capsule
|
||||
id: publish-capsule
|
||||
uses: peak-scale/github-actions/make-ko-publish@38322faabccd75abfa581c435e367d446b6d2c3b # v0.1.0
|
||||
uses: peak-scale/github-actions/make-ko-publish@a441cca016861c546ab7e065277e40ce41a3eb84 # v0.2.0
|
||||
with:
|
||||
makefile-target: ko-publish-capsule
|
||||
registry: ghcr.io
|
||||
@@ -49,8 +49,8 @@ jobs:
|
||||
version: ${{ github.ref_name }}
|
||||
sign-image: true
|
||||
sbom-name: capsule
|
||||
sbom-repository: ghcr.io/${{ github.repository_owner }}/sbom
|
||||
signature-repository: ghcr.io/${{ github.repository_owner }}/signatures
|
||||
sbom-repository: ghcr.io/${{ github.repository_owner }}/capsule
|
||||
signature-repository: ghcr.io/${{ github.repository_owner }}/capsule
|
||||
main-path: ./
|
||||
env:
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
@@ -60,10 +60,10 @@ jobs:
|
||||
id-token: write # To sign the provenance.
|
||||
packages: write # To upload assets to release.
|
||||
actions: read # To read the workflow path.
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
|
||||
with:
|
||||
image: ghcr.io/${{ github.repository_owner }}/capsule
|
||||
digest: "${{ needs.publish-images.outputs.capsule-digest }}"
|
||||
registry-username: ${{ github.actor }}
|
||||
secrets:
|
||||
registry-password: ${{ secrets.GITHUB_TOKEN }}
|
||||
registry-password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
4
.github/workflows/docs-lint.yml
vendored
4
.github/workflows/docs-lint.yml
vendored
@@ -22,10 +22,10 @@ jobs:
|
||||
name: Spell Check
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
node-version: 18
|
||||
- run: make docs-lint
|
||||
25
.github/workflows/e2e.yml
vendored
25
.github/workflows/e2e.yml
vendored
@@ -37,26 +37,17 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
k8s-version: [ 'v1.22.4', 'v1.23.6', 'v1.24.7', 'v1.25.3', 'v1.26.3', 'v1.27.2', 'v1.28.0', 'v1.29.0']
|
||||
runs-on: ubuntu-20.04
|
||||
k8s-version: [ 'v1.24.7', 'v1.25.3', 'v1.26.3', 'v1.27.2', 'v1.28.0', 'v1.29.0', 'v1.30.0', 'v1.31.0' ]
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
|
||||
with:
|
||||
go-version: '1.21'
|
||||
- run: make manifests
|
||||
- name: Checking if manifests are disaligned
|
||||
run: test -z "$(git diff 2> /dev/null)"
|
||||
- name: Checking if manifests generated untracked files
|
||||
run: test -z "$(git ls-files --others --exclude-standard 2> /dev/null)"
|
||||
- uses: engineerd/setup-kind@aa272fe2a7309878ffc2a81c56cfe3ef108ae7d0 # v0.5.0
|
||||
go-version-file: 'go.mod'
|
||||
- uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4
|
||||
with:
|
||||
skipClusterCreation: true
|
||||
version: v0.14.0
|
||||
- uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3
|
||||
with:
|
||||
version: 3.3.4
|
||||
version: v3.14.2
|
||||
- name: e2e testing
|
||||
run: make e2e/${{ matrix.k8s-version }}
|
||||
run: KIND_K8S_VERSION=${{ matrix.k8s-version }} make e2e
|
||||
|
||||
8
.github/workflows/fossa.yml
vendored
8
.github/workflows/fossa.yml
vendored
@@ -13,10 +13,10 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
fossa-scan:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout Code"
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Check secret
|
||||
id: checksecret
|
||||
uses: ./.github/actions/exists
|
||||
@@ -24,12 +24,12 @@ jobs:
|
||||
value: ${{ secrets.FOSSA_API_KEY }}
|
||||
- name: "Run FOSSA Scan"
|
||||
if: steps.checksecret.outputs.result == 'true'
|
||||
uses: fossas/fossa-action@47ef11b1e1e3812e88dae436ccbd2d0cbd1adab0 # v1.3.3
|
||||
uses: fossas/fossa-action@93a52ecf7c3ac7eb40f5de77fd69b1a19524de94 # v1.5.0
|
||||
with:
|
||||
api-key: ${{ secrets.FOSSA_API_KEY }}
|
||||
- name: "Run FOSSA Test"
|
||||
if: steps.checksecret.outputs.result == 'true'
|
||||
uses: fossas/fossa-action@47ef11b1e1e3812e88dae436ccbd2d0cbd1adab0 # v1.3.3
|
||||
uses: fossas/fossa-action@93a52ecf7c3ac7eb40f5de77fd69b1a19524de94 # v1.5.0
|
||||
with:
|
||||
api-key: ${{ secrets.FOSSA_API_KEY }}
|
||||
run-tests: true
|
||||
|
||||
25
.github/workflows/gosec.yml
vendored
25
.github/workflows/gosec.yml
vendored
@@ -1,5 +1,10 @@
|
||||
name: CI gosec
|
||||
permissions: {}
|
||||
permissions:
|
||||
# required for all workflows
|
||||
security-events: write
|
||||
# only required for workflows in private repositories
|
||||
actions: read
|
||||
contents: read
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
@@ -12,13 +17,21 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
GO111MODULE: on
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Run Gosec Security Scanner
|
||||
uses: securego/gosec@26e57d6b340778c2983cd61775bc7e8bb41d002a # v2.19.0
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
|
||||
with:
|
||||
args: ./...
|
||||
go-version-file: 'go.mod'
|
||||
- name: Run Gosec Security Scanner
|
||||
uses: securego/gosec@e0cca6fe95306b7e7790d6f1bf6a7bec6d622459 # v2.22.0
|
||||
with:
|
||||
args: '-no-fail -fmt sarif -out gosec.sarif ./...'
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@08bc0cf022445eacafaa248bf48da20f26b8fd40
|
||||
with:
|
||||
sarif_file: gosec.sarif
|
||||
|
||||
|
||||
21
.github/workflows/helm-publish.yml
vendored
21
.github/workflows/helm-publish.yml
vendored
@@ -2,7 +2,8 @@ name: Publish charts
|
||||
permissions: read-all
|
||||
on:
|
||||
push:
|
||||
tags: [ "helm-v*" ]
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -12,9 +13,9 @@ jobs:
|
||||
publish-helm:
|
||||
# Skip this Release on forks
|
||||
if: github.repository_owner == 'projectcapsule'
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: "Extract Version"
|
||||
id: extract_version
|
||||
run: |
|
||||
@@ -27,6 +28,7 @@ jobs:
|
||||
token: "${{ secrets.HELM_CHARTS_PUSH_TOKEN }}"
|
||||
linting: off
|
||||
chart_version: ${{ steps.extract_version.outputs.version }}
|
||||
app_version: ${{ steps.extract_version.outputs.version }}
|
||||
charts_dir: charts
|
||||
charts_url: https://${{ github.repository_owner }}.github.io/charts
|
||||
owner: ${{ github.repository_owner }}
|
||||
@@ -34,7 +36,7 @@ jobs:
|
||||
branch: gh-pages
|
||||
commit_username: ${{ github.actor }}
|
||||
publish-helm-oci:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
@@ -42,8 +44,8 @@ jobs:
|
||||
outputs:
|
||||
chart-digest: ${{ steps.helm_publish.outputs.digest }}
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
|
||||
- name: "Extract Version"
|
||||
id: extract_version
|
||||
run: |
|
||||
@@ -52,24 +54,25 @@ jobs:
|
||||
echo "version=$(echo $VERSION)" >> $GITHUB_OUTPUT
|
||||
- name: Helm | Publish
|
||||
id: helm_publish
|
||||
uses: peak-scale/github-actions/helm-oci-chart@38322faabccd75abfa581c435e367d446b6d2c3b # v0.1.0
|
||||
uses: peak-scale/github-actions/helm-oci-chart@a441cca016861c546ab7e065277e40ce41a3eb84 # v0.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
repository: ${{ github.repository_owner }}/charts
|
||||
name: "capsule"
|
||||
version: ${{ steps.extract_version.outputs.version }}
|
||||
app-version: ${{ steps.extract_version.outputs.version }}
|
||||
registry-username: ${{ github.actor }}
|
||||
registry-password: ${{ secrets.GITHUB_TOKEN }}
|
||||
update-dependencies: 'true' # Defaults to false
|
||||
sign-image: 'true'
|
||||
signature-repository: ghcr.io/${{ github.repository_owner }}/signatures
|
||||
signature-repository: ghcr.io/${{ github.repository_owner }}/charts/capsule
|
||||
helm-provenance:
|
||||
needs: publish-helm-oci
|
||||
permissions:
|
||||
id-token: write # To sign the provenance.
|
||||
packages: write # To upload assets to release.
|
||||
actions: read # To read the workflow path.
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
|
||||
with:
|
||||
image: ghcr.io/${{ github.repository_owner }}/charts/capsule
|
||||
digest: "${{ needs.publish-helm-oci.outputs.chart-digest }}"
|
||||
|
||||
8
.github/workflows/helm-test.yml
vendored
8
.github/workflows/helm-test.yml
vendored
@@ -11,17 +11,17 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3
|
||||
- uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4
|
||||
- name: Linting Chart
|
||||
run: helm lint ./charts/capsule
|
||||
- name: Setup Chart Linting
|
||||
id: lint
|
||||
uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 # v2.6.1
|
||||
uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b # v2.7.0
|
||||
- name: Run chart-testing (list-changed)
|
||||
id: list-changed
|
||||
run: |
|
||||
|
||||
10
.github/workflows/lint.yml
vendored
10
.github/workflows/lint.yml
vendored
@@ -14,14 +14,14 @@ concurrency:
|
||||
jobs:
|
||||
golangci:
|
||||
name: lint
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
|
||||
with:
|
||||
go-version: '1.21'
|
||||
go-version-file: 'go.mod'
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804 # v4.0.0
|
||||
uses: golangci/golangci-lint-action@e60da84bfae8c7920a47be973d75e15710aa8bd7 # v6.3.0
|
||||
with:
|
||||
version: v1.56.2
|
||||
only-new-issues: false
|
||||
|
||||
14
.github/workflows/releaser.yml
vendored
14
.github/workflows/releaser.yml
vendored
@@ -18,21 +18,25 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- name: Setup caches
|
||||
uses: ./.github/actions/setup-caches
|
||||
timeout-minutes: 5
|
||||
continue-on-error: true
|
||||
- uses: creekorful/goreportcard-action@1f35ced8cdac2cba28c9a2f2288a16aacfd507f9 # v1.0
|
||||
- uses: anchore/sbom-action/download-syft@b6a39da80722a2cb0ef5d197531764a89b5d48c3
|
||||
- uses: anchore/sbom-action/download-syft@79202aee38a39bd2039be442e58d731b63baf740
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0
|
||||
uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0
|
||||
uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean --timeout 90m --debug
|
||||
args: release --clean --timeout 90m
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
8
.github/workflows/scorecard.yml
vendored
8
.github/workflows/scorecard.yml
vendored
@@ -20,23 +20,23 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run analysis
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
|
||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
|
||||
publish_results: true
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
- name: Upload to code-scanning
|
||||
uses: github/codeql-action/upload-sarif@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
|
||||
uses: github/codeql-action/upload-sarif@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
@@ -36,8 +36,15 @@ release:
|
||||
**Full Changelog**: https://github.com/projectcapsule/{{ .ProjectName }}/compare/{{ .PreviousTag }}...{{ .Tag }}
|
||||
|
||||
**Docker Images**
|
||||
- `ghcr.io/projectcapsule/{{ .ProjectName }}:{{ .Tag }}`
|
||||
- `ghcr.io/projectcapsule/{{ .ProjectName }}:{{ .Version }}`
|
||||
- `ghcr.io/projectcapsule/{{ .ProjectName }}:latest`
|
||||
|
||||
**Helm Chart**
|
||||
View this release on [Artifact Hub](https://artifacthub.io/packages/helm/projectcapsule/capsule/{{ .Version }}) or use the OCI helm chart:
|
||||
|
||||
- `ghcr.io/projectcapsule/charts/{{ .ProjectName }}:{{ .Version }}`
|
||||
|
||||
[Review the Major Changes section first before upgrading to a new version](https://artifacthub.io/packages/helm/projectcapsule/capsule/{{ .Version }}#major-changes)
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
changelog:
|
||||
@@ -83,4 +90,4 @@ signs:
|
||||
- "--output-signature=${signature}"
|
||||
- "${artifact}"
|
||||
- "--yes"
|
||||
artifacts: all
|
||||
artifacts: all
|
||||
|
||||
52
.pre-commit-config.yaml
Normal file
52
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,52 @@
|
||||
repos:
|
||||
- repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
|
||||
rev: v9.20.0
|
||||
hooks:
|
||||
- id: commitlint
|
||||
stages: [commit-msg]
|
||||
additional_dependencies: ['@commitlint/config-conventional', 'commitlint-plugin-function-rules']
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.2.0
|
||||
hooks:
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-yaml
|
||||
- id: double-quote-string-fixer
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: run-helm-docs
|
||||
name: Execute helm-docs
|
||||
entry: make helm-docs
|
||||
language: system
|
||||
files: ^charts/
|
||||
- id: run-helm-schema
|
||||
name: Execute helm-schema
|
||||
entry: make helm-schema
|
||||
language: system
|
||||
files: ^charts/
|
||||
- id: run-helm-lint
|
||||
name: Execute helm-lint
|
||||
entry: make helm-lint
|
||||
language: system
|
||||
files: ^charts/
|
||||
- id: golangci-lint
|
||||
name: Execute golangci-lint
|
||||
entry: make golint
|
||||
language: system
|
||||
files: \.go$
|
||||
- repo: https://github.com/tekwizely/pre-commit-golang
|
||||
rev: v1.0.0-rc.1
|
||||
hooks:
|
||||
- id: go-vet
|
||||
- id: go-vet-mod
|
||||
- id: go-vet-pkg
|
||||
- id: go-vet-repo-mod
|
||||
- id: go-vet-repo-pkg
|
||||
- id: go-revive
|
||||
- id: go-revive-mod
|
||||
- id: go-revive-repo-mod
|
||||
- id: go-sec-mod
|
||||
- id: go-sec-pkg
|
||||
- id: go-sec-repo-mod
|
||||
- id: go-sec-repo-pkg
|
||||
10
ADOPTERS.md
10
ADOPTERS.md
@@ -7,8 +7,11 @@ This is a list of companies that have adopted Capsule, feel free to open a Pull-
|
||||
### [Bedag Informatik AG](https://www.bedag.ch/)
|
||||

|
||||
|
||||
### [EPAM Delivery Platform](https://epam.github.io/edp-install/)
|
||||

|
||||
### [Department of Defense](https://www.defense.gov/)
|
||||

|
||||
|
||||
### [KubeRocketCI](https://docs.kuberocketci.io/)
|
||||

|
||||
|
||||
### [Fastweb](https://www.fastweb.it/)
|
||||

|
||||
@@ -25,6 +28,9 @@ This is a list of companies that have adopted Capsule, feel free to open a Pull-
|
||||
### [Reevo](https://www.reevo.it/)
|
||||

|
||||
|
||||
### [Seeweb](https://seeweb.it/en)
|
||||

|
||||
|
||||
### [University of Torino](https://www.unito.it)
|
||||

|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ git clone https://hostname/YOUR-USERNAME/YOUR-REPOSITORY
|
||||
|
||||
2. **Create a branch:**
|
||||
|
||||
Create a new brach and navigate to the branch using this command.
|
||||
Create a new branch and navigate to it using this command.
|
||||
|
||||
```sh
|
||||
git checkout -b <new-branch>
|
||||
@@ -180,7 +180,7 @@ The semantics should indicate the change and it's impact. The general format for
|
||||
The following types are allowed for commits and pull requests:
|
||||
|
||||
* `chore`: housekeeping changes, no production code change
|
||||
* `ci`: changes to buillding process/workflows
|
||||
* `ci`: changes to building process/workflows
|
||||
* `docs`: changes to documentation
|
||||
* `feat`: new features
|
||||
* `fix`: bug fixes
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Build the manager binary
|
||||
FROM golang:1.20.10 as builder
|
||||
FROM golang:1.23.6 as builder
|
||||
|
||||
WORKDIR /workspace
|
||||
# Copy the Go Modules manifests
|
||||
|
||||
133
GOVERNANCE.md
Normal file
133
GOVERNANCE.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# Capsule Project Governance
|
||||
|
||||
The **Capsule** project is dedicated to creating a multi-tenancy and policy-based framework for Kubernetes. This governance explains how the project is run.
|
||||
|
||||
- [Values](#values)
|
||||
- [Maintainers](#maintainers)
|
||||
- [Becoming a Maintainer](#becoming-a-maintainer)
|
||||
- [Meetings](#meetings)
|
||||
- [CNCF Resources](#cncf-resources)
|
||||
- [Code of Conduct Enforcement](#code-of-conduct)
|
||||
- [Security Response Team](#security-response-team)
|
||||
- [Voting](#voting)
|
||||
- [Modifications](#modifying-this-charter)
|
||||
|
||||
## Values
|
||||
|
||||
The Capsule and its leadership embrace the following values:
|
||||
|
||||
* Openness: Communication and decision-making happens in the open and is discoverable for future
|
||||
reference. As much as possible, all discussions and work take place in public
|
||||
Slack channels and open repositories.
|
||||
|
||||
* Fairness: All stakeholders have the opportunity to provide feedback and submit
|
||||
contributions, which will be considered on their merits.
|
||||
|
||||
* Community over Product or Company: Sustaining and growing our community takes
|
||||
priority over shipping code or sponsors' organizational goals. Each
|
||||
contributor participates in the project as an individual.
|
||||
|
||||
* Community Before Individual Demand: As a community-driven open source project, we emphasize
|
||||
the importance of collaboration and contribution. Maintainers and contributors work together towards the project's growth, not to serve unilateral user demands. Users pretending features or enhancements for their sole benefit without contributing to the effort are not aligned with our community values.
|
||||
|
||||
* Inclusivity: We innovate through different perspectives and skill sets, which
|
||||
can only be accomplished in a welcoming and respectful environment.
|
||||
|
||||
* Participation: Responsibilities within the project are earned through
|
||||
participation, and there is a clear path up the contributor ladder into leadership
|
||||
positions.
|
||||
|
||||
## Maintainers
|
||||
|
||||
Capsule Maintainers have write access to the [project GitHub repository](https://github.com/orgs/projectcapsule). They can merge their own patches or patches from others. The current maintainers
|
||||
can be found in [MAINTAINERS.md](./MAINTAINERS.md). Maintainers collectively manage the project's
|
||||
resources and contributors.
|
||||
|
||||
This privilege is granted with some expectation of responsibility: maintainers
|
||||
are people who care about the Capsule project and want to help it grow and
|
||||
improve. A maintainer is not just someone who can make changes, but someone who
|
||||
has demonstrated their ability to collaborate with the team, get the most
|
||||
knowledgeable people to review code and docs.
|
||||
|
||||
A maintainer is a contributor to the project's success and a citizen helping
|
||||
the project succeed. The collective team of all Maintainers is known as the Maintainer Council, which
|
||||
is the governing body for the project.
|
||||
|
||||
### Becoming a Maintainer
|
||||
|
||||
To become a Maintainer you need to demonstrate the following:
|
||||
|
||||
* commitment to the project:
|
||||
* participate in discussions, contributions, code and documentation reviews,
|
||||
* perform reviews for non-trivial pull requests,
|
||||
* contribute non-trivial pull requests and have them merged,
|
||||
* ability to write quality code and/or documentation,
|
||||
* ability to collaborate with the team,
|
||||
* understanding of how the team works (policies, processes for testing and code review, etc),
|
||||
* understanding of the project's purpose, code base and coding and documentation style.
|
||||
|
||||
A new Maintainer must be proposed by an existing maintainer by sending a message to all the other existing Maintainers. A simple majority vote of existing Maintainers
|
||||
approves the application. Maintainers nominations will be evaluated without prejudice
|
||||
to employer or demographics.
|
||||
|
||||
Maintainers who are selected will be granted the necessary GitHub rights.
|
||||
|
||||
### Removing a Maintainer
|
||||
|
||||
Maintainers may resign at any time if they feel that they will not be able to
|
||||
continue fulfilling their project duties.
|
||||
|
||||
Maintainers may also be removed after being inactive, failure to fulfill their
|
||||
Maintainer responsibilities, violating the Code of Conduct, or other reasons.
|
||||
A Maintainer may be removed at any time by a 2/3 vote of the remaining maintainers.
|
||||
|
||||
Depending on the reason for removal, a Maintainer may be converted to Emeritus
|
||||
status. Emeritus Maintainers will still be consulted on some project matters,
|
||||
and can be rapidly returned to Maintainer status if their availability changes.
|
||||
|
||||
## Meetings
|
||||
|
||||
Time zones permitting, Maintainers are expected to participate in the public
|
||||
developer meeting and/or public discussions.
|
||||
|
||||
Maintainers will also have closed meetings in order to discuss security reports
|
||||
or Code of Conduct violations. Such meetings should be scheduled by any
|
||||
Maintainer on receipt of a security issue or CoC report. All current Maintainers
|
||||
must be invited to such closed meetings, except for any Maintainer who is
|
||||
accused of a CoC violation.
|
||||
|
||||
## CNCF Resources
|
||||
|
||||
Any Maintainer may suggest a request for CNCF resources. A simple majority of Maintainers
|
||||
approves the request. The Maintainers may also choose to delegate working with the CNCF to non-Maintainer community members, who will then be added to the [CNCF's Maintainer List](https://github.com/cncf/foundation/blob/main/project-maintainers.csv) for that purpose.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
[Code of Conduct](./CODE_OF_CONDUCT.md)
|
||||
violations by community members will be discussed and resolved in private Maintainer meetings. If a Maintainer is directly involved in the report, the Maintainers will instead designate two Maintainers to work with the CNCF Code of Conduct Committee in resolving it.
|
||||
|
||||
## Security Response Team
|
||||
|
||||
The Maintainers will appoint a Security Response Team to handle security reports.
|
||||
This committee may simply consist of the Maintainer Council themselves. If this
|
||||
responsibility is delegated, the Maintainers will appoint a team of at least two
|
||||
contributors to handle it. The Maintainers will review who is assigned to this
|
||||
at least once a year.
|
||||
|
||||
The Security Response Team is responsible for handling all reports of security
|
||||
holes and breaches according to the [security policy](TODO:Link to security.md).
|
||||
|
||||
## Voting
|
||||
|
||||
While most business in Capsule Project is conducted by "[lazy consensus](https://community.apache.org/committers/lazyConsensus.html)",
|
||||
periodically the Maintainers may need to vote on specific actions or changes.
|
||||
Any Maintainer may demand a vote be taken.
|
||||
|
||||
Most votes require a simple majority of all Maintainers to succeed, except where
|
||||
otherwise noted. Two-thirds majority votes mean at least two-thirds of all
|
||||
existing maintainers.
|
||||
|
||||
## Modifying this Charter
|
||||
|
||||
Changes to this Governance and its supporting documents may be approved by
|
||||
a 2/3 vote of the Maintainers.
|
||||
13
MAINTAINERS.md
Normal file
13
MAINTAINERS.md
Normal file
@@ -0,0 +1,13 @@
|
||||
The current Maintainers Group for the [TODO: Projectname] Project consists of:
|
||||
|
||||
| Name | Employer | Responsibilities |
|
||||
| ------------------------- | ----------- | ---------------- |
|
||||
| Adriano Pezzuto | Clastix | Maintainer |
|
||||
| Dario Tranchitella | Clastix | Maintainer |
|
||||
| Maksim Fedotov | Wargaming | Maintainer |
|
||||
| Oliver Bähler | Peak Scale | Maintainer |
|
||||
| Massimiliano Giovagnoli | Proximus | Maintainer |
|
||||
|
||||
This list must be kept in sync with the [CNCF Project Maintainers list](https://github.com/cncf/foundation/blob/master/project-maintainers.csv).
|
||||
|
||||
See [the project Governance](GOVERNANCE.md) for how maintainers are selected and replaced.
|
||||
162
Makefile
162
Makefile
@@ -1,6 +1,8 @@
|
||||
# Version
|
||||
GIT_HEAD_COMMIT ?= $(shell git rev-parse --short HEAD)
|
||||
VERSION ?= $(or $(shell git describe --abbrev=0 --tags --match "v*" 2>/dev/null),$(GIT_HEAD_COMMIT))
|
||||
GOOS ?= $(shell go env GOOS)
|
||||
GOARCH ?= $(shell go env GOARCH)
|
||||
|
||||
# Defaults
|
||||
REGISTRY ?= ghcr.io
|
||||
@@ -15,6 +17,10 @@ IMG_BASE ?= $(REPOSITORY)
|
||||
IMG ?= $(IMG_BASE):$(VERSION)
|
||||
CAPSULE_IMG ?= $(REGISTRY)/$(IMG_BASE)
|
||||
|
||||
## Tool Binaries
|
||||
KUBECTL ?= kubectl
|
||||
HELM ?= helm
|
||||
|
||||
# Options for 'bundle-build'
|
||||
ifneq ($(origin CHANNELS), undefined)
|
||||
BUNDLE_CHANNELS := --channels=$(CHANNELS)
|
||||
@@ -50,63 +56,38 @@ manager: generate golint
|
||||
run: generate manifests
|
||||
go run .
|
||||
|
||||
# Creates the single file to install Capsule without any external dependency
|
||||
installer: manifests kustomize
|
||||
cd config/manager && $(KUSTOMIZE) edit set image controller=${CAPSULE_IMG}
|
||||
$(KUSTOMIZE) build config/default > config/install.yaml
|
||||
|
||||
# Install CRDs into a cluster
|
||||
install: installer
|
||||
$(KUSTOMIZE) build config/crd | kubectl apply -f -
|
||||
|
||||
# Uninstall CRDs from a cluster
|
||||
uninstall: installer
|
||||
$(KUSTOMIZE) build config/crd | kubectl delete -f -
|
||||
|
||||
# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
|
||||
deploy: installer
|
||||
kubectl apply -f config/install.yaml
|
||||
|
||||
# Remove controller in the configured Kubernetes cluster in ~/.kube/config
|
||||
remove: installer
|
||||
kubectl delete -f config/install.yaml
|
||||
kubectl delete clusterroles.rbac.authorization.k8s.io capsule-namespace-deleter capsule-namespace-provisioner --ignore-not-found
|
||||
kubectl delete clusterrolebindings.rbac.authorization.k8s.io capsule-namespace-deleter capsule-namespace-provisioner --ignore-not-found
|
||||
|
||||
# Generate manifests e.g. CRD, RBAC etc.
|
||||
manifests: controller-gen
|
||||
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
|
||||
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=charts/capsule/crds
|
||||
|
||||
# Generate code
|
||||
generate: controller-gen
|
||||
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
|
||||
|
||||
apidoc: apidocs-gen
|
||||
$(APIDOCS_GEN) crdoc --resources config/crd/bases --output docs/content/general/crds-apis.md --template docs/template/reference-cr.tmpl
|
||||
|
||||
# Helm
|
||||
SRC_ROOT = $(shell git rev-parse --show-toplevel)
|
||||
|
||||
helm-controller-version:
|
||||
$(eval VERSION := $(shell grep 'appVersion:' charts/capsule/Chart.yaml | awk '{print "v"$$2}'))
|
||||
$(eval KO_TAGS := $(shell grep 'appVersion:' charts/capsule/Chart.yaml | awk '{print "v"$$2}'))
|
||||
|
||||
helm-docs: HELMDOCS_VERSION := v1.11.0
|
||||
helm-docs: docker
|
||||
@docker run -v "$(SRC_ROOT):/helm-docs" jnorwood/helm-docs:$(HELMDOCS_VERSION) --chart-search-root /helm-docs
|
||||
|
||||
helm-lint: CT_VERSION := v3.3.1
|
||||
helm-lint: docker
|
||||
@docker run -v "$(SRC_ROOT):/workdir" --entrypoint /bin/sh quay.io/helmpack/chart-testing:$(CT_VERSION) -c "cd /workdir; ct lint --config .github/configs/ct.yaml --lint-conf .github/configs/lintconf.yaml --all --debug"
|
||||
|
||||
helm-test: helm-controller-version kind ct ko-build-all
|
||||
@kind create cluster --wait=60s --name capsule-charts
|
||||
@kind load docker-image --name capsule-charts $(CAPSULE_IMG):$(VERSION)
|
||||
@kubectl create ns capsule-system
|
||||
@kubectl create -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.crds.yaml
|
||||
@kubectl create -f https://github.com/prometheus-operator/prometheus-operator/releases/download/v0.58.0/bundle.yaml
|
||||
helm-schema: helm-plugin-schema
|
||||
cd charts/capsule && $(HELM) schema
|
||||
|
||||
helm-test: kind ct ko-build-all
|
||||
@$(KIND) create cluster --wait=60s --name capsule-charts --image kindest/node:$${KIND_K8S_VERSION:-v1.27.0}
|
||||
@make helm-test-exec
|
||||
@$(KIND) delete cluster --name capsule-charts
|
||||
|
||||
helm-test-exec: kind
|
||||
@$(KIND) load docker-image --name capsule-charts $(CAPSULE_IMG):$(VERSION)
|
||||
@kubectl create ns capsule-system || true
|
||||
@kubectl apply --server-side=true -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.crds.yaml
|
||||
@kubectl apply --server-side=true -f https://github.com/prometheus-operator/prometheus-operator/releases/download/v0.58.0/bundle.yaml
|
||||
@ct install --config $(SRC_ROOT)/.github/configs/ct.yaml --namespace=capsule-system --all --debug
|
||||
@kind delete cluster --name capsule-charts
|
||||
|
||||
docker:
|
||||
@hash docker 2>/dev/null || {\
|
||||
@@ -115,7 +96,7 @@ docker:
|
||||
}
|
||||
|
||||
# Setup development env
|
||||
# Usage:
|
||||
# Usage:
|
||||
# LAPTOP_HOST_IP=<YOUR_LAPTOP_IP> make dev-setup
|
||||
# For example:
|
||||
# LAPTOP_HOST_IP=192.168.10.101 make dev-setup
|
||||
@@ -137,7 +118,7 @@ IP.1 = $(LAPTOP_HOST_IP)
|
||||
endef
|
||||
export TLS_CNF
|
||||
dev-setup:
|
||||
kubectl -n capsule-system scale deployment capsule-controller-manager --replicas=0
|
||||
kubectl -n capsule-system scale deployment capsule-controller-manager --replicas=0 || true
|
||||
mkdir -p /tmp/k8s-webhook-server/serving-certs
|
||||
echo "$${TLS_CNF}" > _tls.cnf
|
||||
openssl req -newkey rsa:4096 -days 3650 -nodes -x509 \
|
||||
@@ -146,43 +127,31 @@ dev-setup:
|
||||
-config _tls.cnf \
|
||||
-keyout /tmp/k8s-webhook-server/serving-certs/tls.key \
|
||||
-out /tmp/k8s-webhook-server/serving-certs/tls.crt
|
||||
rm -f _tls.cnf
|
||||
kubectl create secret tls capsule-tls -n capsule-system \
|
||||
--cert=/tmp/k8s-webhook-server/serving-certs/tls.crt\
|
||||
--key=/tmp/k8s-webhook-server/serving-certs/tls.key || true
|
||||
rm -f _tls.cnf
|
||||
export WEBHOOK_URL="https://$${LAPTOP_HOST_IP}:9443"; \
|
||||
export CA_BUNDLE=`openssl base64 -in /tmp/k8s-webhook-server/serving-certs/tls.crt | tr -d '\n'`; \
|
||||
kubectl patch MutatingWebhookConfiguration capsule-mutating-webhook-configuration \
|
||||
--type='json' -p="[\
|
||||
{'op': 'replace', 'path': '/webhooks/0/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/defaults\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/1/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/defaults\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/2/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/defaults\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/3/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/namespace-owner-reference\",'caBundle':\"$${CA_BUNDLE}\"}}\
|
||||
]" && \
|
||||
kubectl patch ValidatingWebhookConfiguration capsule-validating-webhook-configuration \
|
||||
--type='json' -p="[\
|
||||
{'op': 'replace', 'path': '/webhooks/0/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/cordoning\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/1/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/ingresses\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/2/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/namespaces\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/3/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/networkpolicies\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/4/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/nodes\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/5/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/pods\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/6/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/persistentvolumeclaims\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/7/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/services\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/8/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/tenantresource-objects\",'caBundle':\"$${CA_BUNDLE}\"}},\
|
||||
{'op': 'replace', 'path': '/webhooks/9/clientConfig', 'value':{'url':\"$${WEBHOOK_URL}/tenants\",'caBundle':\"$${CA_BUNDLE}\"}}\
|
||||
]" && \
|
||||
kubectl patch crd tenants.capsule.clastix.io \
|
||||
--type='json' -p="[\
|
||||
{'op': 'replace', 'path': '/spec/conversion/webhook/clientConfig', 'value':{'url': \"$${WEBHOOK_URL}\", 'caBundle': \"$${CA_BUNDLE}\"}}\
|
||||
]" && \
|
||||
kubectl patch crd capsuleconfigurations.capsule.clastix.io \
|
||||
--type='json' -p="[\
|
||||
{'op': 'replace', 'path': '/spec/conversion/webhook/clientConfig', 'value':{'url': \"$${WEBHOOK_URL}\", 'caBundle': \"$${CA_BUNDLE}\"}}\
|
||||
]";
|
||||
|
||||
helm upgrade \
|
||||
--dependency-update \
|
||||
--debug \
|
||||
--install \
|
||||
--namespace capsule-system \
|
||||
--create-namespace \
|
||||
--set 'crds.install=true' \
|
||||
--set 'crds.exclusive=true'\
|
||||
--set "webhooks.exclusive=true"\
|
||||
--set "webhooks.service.url=$${WEBHOOK_URL}" \
|
||||
--set "webhooks.service.caBundle=$${CA_BUNDLE}" \
|
||||
capsule \
|
||||
./charts/capsule
|
||||
|
||||
####################
|
||||
# -- Docker
|
||||
####################
|
||||
|
||||
KO_PLATFORM ?= linux/$(GOARCH)
|
||||
KOCACHE ?= /tmp/ko-cache
|
||||
KO_REGISTRY := ko.local
|
||||
KO_TAGS ?= "latest"
|
||||
@@ -202,9 +171,9 @@ LD_FLAGS := "-X main.Version=$(VERSION) \
|
||||
|
||||
.PHONY: ko-build-capsule
|
||||
ko-build-capsule: ko
|
||||
@echo Building Capsule $(KO_TAGS) >&2
|
||||
@echo Building Capsule $(KO_TAGS) for $(KO_PLATFORM) >&2
|
||||
@LD_FLAGS=$(LD_FLAGS) KOCACHE=$(KOCACHE) KO_DOCKER_REPO=$(CAPSULE_IMG) \
|
||||
$(KO) build ./ --bare --tags=$(KO_TAGS) --push=false --local
|
||||
$(KO) build ./ --bare --tags=$(KO_TAGS) --push=false --local --platform=$(KO_PLATFORM)
|
||||
|
||||
.PHONY: ko-build-all
|
||||
ko-build-all: ko-build-capsule
|
||||
@@ -227,27 +196,30 @@ ko-publish-capsule: ko-login ## Build and publish kyvernopre image (with ko)
|
||||
.PHONY: ko-publish-all
|
||||
ko-publish-all: ko-publish-capsule
|
||||
|
||||
|
||||
####################
|
||||
# -- Helm Plugins
|
||||
####################
|
||||
|
||||
HELM_SCHEMA_VERSION := ""
|
||||
helm-plugin-schema:
|
||||
$(HELM) plugin install https://github.com/losisin/helm-values-schema-json.git --version $(HELM_SCHEMA_VERSION) || true
|
||||
|
||||
####################
|
||||
# -- Binaries
|
||||
####################
|
||||
|
||||
CONTROLLER_GEN := $(shell pwd)/bin/controller-gen
|
||||
CONTROLLER_GEN_VERSION := v0.10.0
|
||||
CONTROLLER_GEN_VERSION := v0.16.1
|
||||
controller-gen: ## Download controller-gen locally if necessary.
|
||||
$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION))
|
||||
|
||||
APIDOCS_GEN := $(shell pwd)/bin/crdoc
|
||||
APIDOCS_GEN_VERSION := latest
|
||||
apidocs-gen: ## Download crdoc locally if necessary.
|
||||
$(call go-install-tool,$(APIDOCS_GEN),fybrik.io/crdoc@$(APIDOCS_GEN_VERSION))
|
||||
|
||||
GINKGO := $(shell pwd)/bin/ginkgo
|
||||
GINGKO_VERSION := v2.15.0
|
||||
ginkgo: ## Download ginkgo locally if necessary.
|
||||
$(call go-install-tool,$(GINKGO),github.com/onsi/ginkgo/v2/ginkgo@$(GINGKO_VERSION))
|
||||
$(call go-install-tool,$(GINKGO),github.com/onsi/ginkgo/v2/ginkgo)
|
||||
|
||||
CT := $(shell pwd)/bin/ct
|
||||
CT_VERSION := v3.7.1
|
||||
CT_VERSION := v3.10.1
|
||||
ct: ## Download ct locally if necessary.
|
||||
$(call go-install-tool,$(CT),github.com/helm/chart-testing/v3/ct@$(CT_VERSION))
|
||||
|
||||
@@ -315,17 +287,17 @@ golint: golangci-lint
|
||||
|
||||
# Running e2e tests in a KinD instance
|
||||
.PHONY: e2e
|
||||
e2e/%: ginkgo
|
||||
$(MAKE) e2e-build/$* && $(MAKE) e2e-exec && $(MAKE) e2e-destroy
|
||||
e2e: ginkgo
|
||||
$(MAKE) e2e-build && $(MAKE) e2e-exec && $(MAKE) e2e-destroy
|
||||
|
||||
e2e-build/%:
|
||||
kind create cluster --wait=60s --name capsule --image=kindest/node:$*
|
||||
make e2e-load-image
|
||||
make e2e-install
|
||||
e2e-build: kind
|
||||
$(KIND) create cluster --wait=60s --name capsule --image kindest/node:$${KIND_K8S_VERSION:-v1.27.0}
|
||||
$(MAKE) e2e-install
|
||||
|
||||
.PHONY: e2e-install
|
||||
e2e-install:
|
||||
e2e-install: e2e-load-image
|
||||
helm upgrade \
|
||||
--dependency-update \
|
||||
--debug \
|
||||
--install \
|
||||
--namespace capsule-system \
|
||||
@@ -335,23 +307,21 @@ e2e-install:
|
||||
--set "manager.image.tag=$(VERSION)" \
|
||||
--set 'manager.livenessProbe.failureThreshold=10' \
|
||||
--set 'manager.readinessProbe.failureThreshold=10' \
|
||||
--set 'podSecurityContext.seccompProfile=null' \
|
||||
capsule \
|
||||
./charts/capsule
|
||||
|
||||
.PHONY: e2e-load-image
|
||||
e2e-load-image: ko-build-all
|
||||
kind load docker-image --nodes capsule-control-plane --name capsule $(CAPSULE_IMG):$(VERSION)
|
||||
e2e-load-image: kind ko-build-all
|
||||
$(KIND) load docker-image --nodes capsule-control-plane --name capsule $(CAPSULE_IMG):$(VERSION)
|
||||
|
||||
.PHONY: e2e-exec
|
||||
e2e-exec: ginkgo
|
||||
$(GINKGO) -v -tags e2e ./e2e
|
||||
|
||||
.PHONY: e2e-destroy
|
||||
e2e-destroy:
|
||||
kind delete cluster --name capsule
|
||||
e2e-destroy: kind
|
||||
$(KIND) delete cluster --name capsule
|
||||
|
||||
SPELL_CHECKER = npx spellchecker-cli
|
||||
docs-lint:
|
||||
cd docs/content && $(SPELL_CHECKER) -f "*.md" "*/*.md" -d dictionary.txt
|
||||
|
||||
cd docs/content && $(SPELL_CHECKER) -f "*.md" "*/*.md" "!general/crds-apis.md" -d dictionary.txt
|
||||
|
||||
14
README.md
14
README.md
@@ -40,9 +40,9 @@ Kubernetes introduces the _Namespace_ object type to create logical partitions o
|
||||
|
||||
# Entering Capsule
|
||||
|
||||
Capsule takes a different approach. In a single cluster, the Capsule Controller aggregates multiple namespaces in a lightweight abstraction called _Tenant_, basically a grouping of Kubernetes Namespaces. Within each tenant, users are free to create their namespaces and share all the assigned resources.
|
||||
Capsule takes a different approach. In a single cluster, the Capsule Controller aggregates multiple namespaces in a lightweight abstraction called _Tenant_, basically a grouping of Kubernetes Namespaces. Within each tenant, users are free to create their namespaces and share all the assigned resources.
|
||||
|
||||
On the other side, the Capsule Policy Engine keeps the different tenants isolated from each other. _Network and Security Policies_, _Resource Quota_, _Limit Ranges_, _RBAC_, and other policies defined at the tenant level are automatically inherited by all the namespaces in the tenant. Then users are free to operate their tenants in autonomy, without the intervention of the cluster administrator.
|
||||
On the other side, the Capsule Policy Engine keeps the different tenants isolated from each other. _Network and Security Policies_, _Resource Quota_, _Limit Ranges_, _RBAC_, and other policies defined at the tenant level are automatically inherited by all the namespaces in the tenant. Then users are free to operate their tenants in autonomy, without the intervention of the cluster administrator.
|
||||
|
||||
# Features
|
||||
|
||||
@@ -76,7 +76,7 @@ Assign to tenants a dedicated set of compute, storage, and network resources and
|
||||
|
||||
# Documentation
|
||||
|
||||
Please, check the project [documentation](https://capsule.clastix.io) for the cool things you can do with Capsule.
|
||||
Please, check the project [documentation](https://projectcapsule.dev) for the cool things you can do with Capsule.
|
||||
|
||||
# Contributions
|
||||
|
||||
@@ -110,18 +110,14 @@ Please read the [code of conduct](CODE_OF_CONDUCT.md).
|
||||
|
||||
See the [ADOPTERS.md](ADOPTERS.md) file for a list of companies that are using Capsule.
|
||||
|
||||
# Governance
|
||||
# Project Governance
|
||||
|
||||
You can find how the Capsule project is governed [here](https://capsule.clastix.io/docs/contributing/governance).
|
||||
You can find how the Capsule project is governed [here](https://projectcapsule.dev/project/governance/).
|
||||
|
||||
## Maintainers
|
||||
|
||||
Please, refer to the maintainers file available [here](.github/maintainers.yaml).
|
||||
|
||||
## Release process
|
||||
|
||||
Please, refer to the [documentation page](https://capsule.clastix.io/docs/contributing/release).
|
||||
|
||||
### Changelog
|
||||
|
||||
Read how we log changes [here](CHANGELOG.md)
|
||||
|
||||
31
SECURITY.md
31
SECURITY.md
@@ -6,7 +6,6 @@ The Capsule community has adopted this security disclosures and response policy
|
||||
|
||||
For information regarding the security of this project please join our [slack channel](https://kubernetes.slack.com/archives/C03GETTJQRL).
|
||||
|
||||
|
||||
## Covered Repositories and Issues
|
||||
|
||||
When we say "a security vulnerability in capsule" we mean a security issue
|
||||
@@ -35,7 +34,7 @@ To report a security issue or vulnerability, [submit a private vulnerability rep
|
||||
Describe the issue in English, ideally with some example configuration or code which allows the issue to be reproduced. Explain why you believe this to be a security issue in capsule, if that's not obvious. should contain the following:
|
||||
|
||||
* description of the problem
|
||||
* precise and detailed steps (include screenshots)
|
||||
* precise and detailed steps (include screenshots)
|
||||
* the affected version(s). This may also include environment relevant versions.
|
||||
* any possible mitigations
|
||||
|
||||
@@ -55,19 +54,23 @@ Response times could be affected by weekends, holidays, breaks or time zone diff
|
||||
|
||||
## Verifing
|
||||
|
||||
To verify artifacts you need to have [cosign installed](https://github.com/sigstore/cosign#installation). This guide assumes you are using v2.x of cosign. All of the signatures are created using [keyless signing](https://docs.sigstore.dev/verifying/verify/#keyless-verification-using-openid-connect). We have a seperate repository for all the signatures for all the artifacts released under the projectcapsule - `ghcr.io/projectcapsule/signatures`. You can set the environment variable `COSIGN_REPOSITORY` to point to this repository. For example:
|
||||
To verify artifacts you need to have [cosign installed](https://github.com/sigstore/cosign#installation). This guide assumes you are using v2.x of cosign. All of the signatures are created using [keyless signing](https://docs.sigstore.dev/verifying/verify/#keyless-verification-using-openid-connect). You can set the environment variable `COSIGN_REPOSITORY` to point to this repository. For example:
|
||||
|
||||
export COSIGN_REPOSITORY=ghcr.io/projectcapsule/signatures
|
||||
# Docker Image
|
||||
export COSIGN_REPOSITORY=ghcr.io/projectcapsule/capsule
|
||||
|
||||
# Helm Chart
|
||||
export COSIGN_REPOSITORY=ghcr.io/projectcapsule/charts/capsule
|
||||
|
||||
To verify the signature of the docker image, run the following command. Replace `<release_tag>` with an [available release tag](https://github.com/projectcapsule/capsule/pkgs/container/capsule):
|
||||
|
||||
COSIGN_REPOSITORY=ghcr.io/projectcapsule/signatures cosign verify ghcr.io/projectcapsule/capsule:<release_tag> \
|
||||
COSIGN_REPOSITORY=ghcr.io/projectcapsule/charts/capsule cosign verify ghcr.io/projectcapsule/capsule:<release_tag> \
|
||||
--certificate-identity-regexp="https://github.com/projectcapsule/capsule/.github/workflows/docker-publish.yml@refs/tags/*" \
|
||||
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" | jq
|
||||
|
||||
To verify the signature of the helm image, run the following command. Replace `<release_tag>` with an [available release tag](https://github.com/projectcapsule/capsule/pkgs/container/charts%2Fcapsule):
|
||||
|
||||
COSIGN_REPOSITORY=ghcr.io/projectcapsule/signatures cosign verify ghcr.io/projectcapsule/charts/capsule:<release_tag> \
|
||||
COSIGN_REPOSITORY=ghcr.io/projectcapsule/charts/capsule cosign verify ghcr.io/projectcapsule/charts/capsule:<release_tag> \
|
||||
--certificate-identity-regexp="https://github.com/projectcapsule/capsule/.github/workflows/helm-publish.yml@refs/tags/*" \
|
||||
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" | jq
|
||||
|
||||
@@ -96,19 +99,23 @@ cosign verify-attestation --type slsaprovenance \
|
||||
|
||||
## Software Bill of Materials (SBOM)
|
||||
|
||||
An SBOM (Software Bill of Materials) in CycloneDX JSON format is published for each Kyverno release, including pre-releases. Like signatures, SBOMs are stored in a separate repository at `ghcr.io/projectcapsule/sbom`. You can set the environment variable `COSIGN_REPOSITORY` to point to this repository. For example:
|
||||
An SBOM (Software Bill of Materials) in CycloneDX JSON format is published for each release, including pre-releases. You can set the environment variable `COSIGN_REPOSITORY` to point to this repository. For example:
|
||||
|
||||
# Docker Image
|
||||
export COSIGN_REPOSITORY=ghcr.io/projectcapsule/capsule
|
||||
|
||||
# Helm Chart
|
||||
export COSIGN_REPOSITORY=ghcr.io/projectcapsule/charts/capsule
|
||||
|
||||
export COSIGN_REPOSITORY=ghcr.io/projectcapsule/sbom
|
||||
|
||||
To inspect the SBOM of the docker image, run the following command. Replace `<release_tag>` with an [available release tag](https://github.com/projectcapsule/capsule/pkgs/container/capsule):
|
||||
|
||||
|
||||
COSIGN_REPOSITORY=ghcr.io/projectcapsule/sbom cosign download sbom ghcr.io/projectcapsule/capsule:<release_tag>
|
||||
|
||||
COSIGN_REPOSITORY=ghcr.io/projectcapsule/capsule cosign download sbom ghcr.io/projectcapsule/capsule:<release_tag>
|
||||
|
||||
To inspect the SBOM of the helm image, run the following command. Replace `<release_tag>` with an [available release tag](https://github.com/projectcapsule/capsule/pkgs/container/charts%2Fcapsule):
|
||||
|
||||
COSIGN_REPOSITORY=ghcr.io/projectcapsule/sbom cosign download sbom ghcr.io/projectcapsule/charts/capsule:<release_tag>
|
||||
|
||||
COSIGN_REPOSITORY=ghcr.io/projectcapsule/charts/capsule cosign download sbom ghcr.io/projectcapsule/charts/capsule:<release_tag>
|
||||
|
||||
# Credits
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
@@ -4,9 +4,13 @@
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"sort"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
)
|
||||
|
||||
func (in *Tenant) IsFull() bool {
|
||||
@@ -36,3 +40,128 @@ func (in *Tenant) AssignNamespaces(namespaces []corev1.Namespace) {
|
||||
func (in *Tenant) GetOwnerProxySettings(name string, kind OwnerKind) []ProxySettings {
|
||||
return in.Spec.Owners.FindOwner(name, kind).ProxyOperations
|
||||
}
|
||||
|
||||
// GetClusterRolePermissions returns a map where the clusterRole is the key
|
||||
// and the value is a list of permission subjects (kind and name) that reference that role.
|
||||
// These mappings are gathered from the owners and additionalRolebindings spec.
|
||||
func (in *Tenant) GetSubjectsByClusterRoles(ignoreOwnerKind []OwnerKind) (rolePerms map[string][]rbacv1.Subject) {
|
||||
rolePerms = make(map[string][]rbacv1.Subject)
|
||||
|
||||
// Helper to add permissions for a given clusterRole
|
||||
addPermission := func(clusterRole string, permission rbacv1.Subject) {
|
||||
if _, exists := rolePerms[clusterRole]; !exists {
|
||||
rolePerms[clusterRole] = []rbacv1.Subject{}
|
||||
}
|
||||
|
||||
rolePerms[clusterRole] = append(rolePerms[clusterRole], permission)
|
||||
}
|
||||
|
||||
// Helper to check if a kind is in the ignoreOwnerKind list
|
||||
isIgnoredKind := func(kind string) bool {
|
||||
for _, ignored := range ignoreOwnerKind {
|
||||
if kind == ignored.String() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Process owners
|
||||
for _, owner := range in.Spec.Owners {
|
||||
if !isIgnoredKind(owner.Kind.String()) {
|
||||
for _, clusterRole := range owner.ClusterRoles {
|
||||
perm := rbacv1.Subject{
|
||||
Name: owner.Name,
|
||||
Kind: owner.Kind.String(),
|
||||
}
|
||||
addPermission(clusterRole, perm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process additional role bindings
|
||||
for _, role := range in.Spec.AdditionalRoleBindings {
|
||||
for _, subject := range role.Subjects {
|
||||
if !isIgnoredKind(subject.Kind) {
|
||||
perm := rbacv1.Subject{
|
||||
Name: subject.Name,
|
||||
Kind: subject.Kind,
|
||||
}
|
||||
addPermission(role.ClusterRoleName, perm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Get the permissions for a tenant ordered by groups and users.
|
||||
func (in *Tenant) GetClusterRolesBySubject(ignoreOwnerKind []OwnerKind) (maps map[string]map[string]api.TenantSubjectRoles) {
|
||||
maps = make(map[string]map[string]api.TenantSubjectRoles)
|
||||
|
||||
// Initialize a nested map for kind ("User", "Group") and name
|
||||
initNestedMap := func(kind string) {
|
||||
if _, exists := maps[kind]; !exists {
|
||||
maps[kind] = make(map[string]api.TenantSubjectRoles)
|
||||
}
|
||||
}
|
||||
// Helper to check if a kind is in the ignoreOwnerKind list
|
||||
isIgnoredKind := func(kind string) bool {
|
||||
for _, ignored := range ignoreOwnerKind {
|
||||
if kind == ignored.String() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Process owners
|
||||
for _, owner := range in.Spec.Owners {
|
||||
if !isIgnoredKind(owner.Kind.String()) {
|
||||
initNestedMap(owner.Kind.String())
|
||||
|
||||
if perm, exists := maps[owner.Kind.String()][owner.Name]; exists {
|
||||
// If the permission entry already exists, append cluster roles
|
||||
perm.ClusterRoles = append(perm.ClusterRoles, owner.ClusterRoles...)
|
||||
maps[owner.Kind.String()][owner.Name] = perm
|
||||
} else {
|
||||
// Create a new permission entry
|
||||
maps[owner.Kind.String()][owner.Name] = api.TenantSubjectRoles{
|
||||
ClusterRoles: owner.ClusterRoles,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process additional role bindings
|
||||
for _, role := range in.Spec.AdditionalRoleBindings {
|
||||
for _, subject := range role.Subjects {
|
||||
if !isIgnoredKind(subject.Kind) {
|
||||
initNestedMap(subject.Kind)
|
||||
|
||||
if perm, exists := maps[subject.Kind][subject.Name]; exists {
|
||||
// If the permission entry already exists, append cluster roles
|
||||
perm.ClusterRoles = append(perm.ClusterRoles, role.ClusterRoleName)
|
||||
maps[subject.Kind][subject.Name] = perm
|
||||
} else {
|
||||
// Create a new permission entry
|
||||
maps[subject.Kind][subject.Name] = api.TenantSubjectRoles{
|
||||
ClusterRoles: []string{role.ClusterRoleName},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove duplicates from cluster roles in both maps
|
||||
for kind, nameMap := range maps {
|
||||
for name, perm := range nameMap {
|
||||
perm.ClusterRoles = slices.Compact(perm.ClusterRoles)
|
||||
maps[kind][name] = perm
|
||||
}
|
||||
}
|
||||
|
||||
return maps
|
||||
}
|
||||
|
||||
192
api/v1beta2/tenant_func_test.go
Normal file
192
api/v1beta2/tenant_func_test.go
Normal file
@@ -0,0 +1,192 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
)
|
||||
|
||||
var tenant = &Tenant{
|
||||
Spec: TenantSpec{
|
||||
Owners: []OwnerSpec{
|
||||
{
|
||||
Kind: "User",
|
||||
Name: "user1",
|
||||
ClusterRoles: []string{"cluster-admin", "read-only"},
|
||||
},
|
||||
{
|
||||
Kind: "Group",
|
||||
Name: "group1",
|
||||
ClusterRoles: []string{"edit"},
|
||||
},
|
||||
{
|
||||
Kind: ServiceAccountOwner,
|
||||
Name: "service",
|
||||
ClusterRoles: []string{"read-only"},
|
||||
},
|
||||
},
|
||||
AdditionalRoleBindings: []api.AdditionalRoleBindingsSpec{
|
||||
{
|
||||
ClusterRoleName: "developer",
|
||||
Subjects: []rbacv1.Subject{
|
||||
{Kind: "User", Name: "user2"},
|
||||
{Kind: "Group", Name: "group1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
ClusterRoleName: "cluster-admin",
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: "User",
|
||||
Name: "user3",
|
||||
},
|
||||
{
|
||||
Kind: "Group",
|
||||
Name: "group1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ClusterRoleName: "deployer",
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "system:serviceaccount:argocd:argo-operator",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// TestGetClusterRolePermissions tests the GetClusterRolePermissions function
|
||||
func TestGetSubjectsByClusterRoles(t *testing.T) {
|
||||
expected := map[string][]rbacv1.Subject{
|
||||
"cluster-admin": {
|
||||
{Kind: "User", Name: "user1"},
|
||||
{Kind: "User", Name: "user3"},
|
||||
{Kind: "Group", Name: "group1"},
|
||||
},
|
||||
"read-only": {
|
||||
{Kind: "User", Name: "user1"},
|
||||
{Kind: "ServiceAccount", Name: "service"},
|
||||
},
|
||||
"edit": {
|
||||
{Kind: "Group", Name: "group1"},
|
||||
},
|
||||
"developer": {
|
||||
{Kind: "User", Name: "user2"},
|
||||
{Kind: "Group", Name: "group1"},
|
||||
},
|
||||
"deployer": {
|
||||
{Kind: "ServiceAccount", Name: "system:serviceaccount:argocd:argo-operator"},
|
||||
},
|
||||
}
|
||||
|
||||
// Call the function to test
|
||||
permissions := tenant.GetSubjectsByClusterRoles(nil)
|
||||
|
||||
if !reflect.DeepEqual(permissions, expected) {
|
||||
t.Errorf("Expected %v, but got %v", expected, permissions)
|
||||
}
|
||||
|
||||
// Ignore SubjectTypes (Ignores ServiceAccounts)
|
||||
ignored := tenant.GetSubjectsByClusterRoles([]OwnerKind{"ServiceAccount"})
|
||||
expectedIgnored := map[string][]rbacv1.Subject{
|
||||
"cluster-admin": {
|
||||
{Kind: "User", Name: "user1"},
|
||||
{Kind: "User", Name: "user3"},
|
||||
{Kind: "Group", Name: "group1"},
|
||||
},
|
||||
"read-only": {
|
||||
{Kind: "User", Name: "user1"},
|
||||
},
|
||||
"edit": {
|
||||
{Kind: "Group", Name: "group1"},
|
||||
},
|
||||
"developer": {
|
||||
{Kind: "User", Name: "user2"},
|
||||
{Kind: "Group", Name: "group1"},
|
||||
},
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(ignored, expectedIgnored) {
|
||||
t.Errorf("Expected %v, but got %v", expectedIgnored, ignored)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGetClusterRolesBySubject(t *testing.T) {
|
||||
|
||||
expected := map[string]map[string]api.TenantSubjectRoles{
|
||||
"User": {
|
||||
"user1": {
|
||||
ClusterRoles: []string{"cluster-admin", "read-only"},
|
||||
},
|
||||
"user2": {
|
||||
ClusterRoles: []string{"developer"},
|
||||
},
|
||||
"user3": {
|
||||
ClusterRoles: []string{"cluster-admin"},
|
||||
},
|
||||
},
|
||||
"Group": {
|
||||
"group1": {
|
||||
ClusterRoles: []string{"edit", "developer", "cluster-admin"},
|
||||
},
|
||||
},
|
||||
"ServiceAccount": {
|
||||
"service": {
|
||||
ClusterRoles: []string{"read-only"},
|
||||
},
|
||||
"system:serviceaccount:argocd:argo-operator": {
|
||||
ClusterRoles: []string{"deployer"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
permissions := tenant.GetClusterRolesBySubject(nil)
|
||||
if !reflect.DeepEqual(permissions, expected) {
|
||||
t.Errorf("Expected %v, but got %v", expected, permissions)
|
||||
}
|
||||
|
||||
delete(expected, "ServiceAccount")
|
||||
ignored := tenant.GetClusterRolesBySubject([]OwnerKind{"ServiceAccount"})
|
||||
|
||||
if !reflect.DeepEqual(ignored, expected) {
|
||||
t.Errorf("Expected %v, but got %v", expected, ignored)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to run tests
|
||||
func TestMain(t *testing.M) {
|
||||
t.Run()
|
||||
}
|
||||
|
||||
// permissionsEqual checks the equality of two TenantPermission structs.
|
||||
func permissionsEqual(a, b api.TenantSubjectRoles) bool {
|
||||
if a.Kind != b.Kind {
|
||||
return false
|
||||
}
|
||||
if len(a.ClusterRoles) != len(b.ClusterRoles) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Create a map to count occurrences of cluster roles
|
||||
counts := make(map[string]int)
|
||||
for _, role := range a.ClusterRoles {
|
||||
counts[role]++
|
||||
}
|
||||
for _, role := range b.ClusterRoles {
|
||||
counts[role]--
|
||||
if counts[role] < 0 {
|
||||
return false // More occurrences in b than in a
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -43,17 +43,28 @@ type TenantSpec struct {
|
||||
// Specifies the allowed RuntimeClasses assigned to the Tenant.
|
||||
// Capsule assures that all Pods resources created in the Tenant can use only one of the allowed RuntimeClasses.
|
||||
// Optional.
|
||||
RuntimeClasses *api.SelectorAllowedListSpec `json:"runtimeClasses,omitempty"`
|
||||
RuntimeClasses *api.DefaultAllowedListSpec `json:"runtimeClasses,omitempty"`
|
||||
// Specifies the allowed priorityClasses assigned to the Tenant.
|
||||
// Capsule assures that all Pods resources created in the Tenant can use only one of the allowed PriorityClasses.
|
||||
// A default value can be specified, and all the Pod resources created will inherit the declared class.
|
||||
// Optional.
|
||||
PriorityClasses *api.DefaultAllowedListSpec `json:"priorityClasses,omitempty"`
|
||||
// Toggling the Tenant resources cordoning, when enable resources cannot be deleted.
|
||||
//+kubebuilder:default:=false
|
||||
Cordoned bool `json:"cordoned,omitempty"`
|
||||
// Prevent accidental deletion of the Tenant.
|
||||
// When enabled, the deletion request will be declined.
|
||||
//+kubebuilder:default:=false
|
||||
PreventDeletion bool `json:"preventDeletion,omitempty"`
|
||||
// Use this if you want to disable/enable the Tenant name prefix to specific Tenants, overriding global forceTenantPrefix in CapsuleConfiguration.
|
||||
// When set to 'true', it enforces Namespaces created for this Tenant to be named with the Tenant name prefix,
|
||||
// separated by a dash (i.e. for Tenant 'foo', namespace names must be prefixed with 'foo-'),
|
||||
// this is useful to avoid Namespace name collision.
|
||||
// When set to 'false', it allows Namespaces created for this Tenant to be named anything.
|
||||
// Overrides CapsuleConfiguration global forceTenantPrefix for the Tenant only.
|
||||
// If unset, Tenant uses CapsuleConfiguration's forceTenantPrefix
|
||||
// Optional
|
||||
ForceTenantPrefix *bool `json:"forceTenantPrefix,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
@@ -756,7 +755,7 @@ func (in *TenantSpec) DeepCopyInto(out *TenantSpec) {
|
||||
}
|
||||
if in.RuntimeClasses != nil {
|
||||
in, out := &in.RuntimeClasses, &out.RuntimeClasses
|
||||
*out = new(api.SelectorAllowedListSpec)
|
||||
*out = new(api.DefaultAllowedListSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.PriorityClasses != nil {
|
||||
@@ -764,6 +763,11 @@ func (in *TenantSpec) DeepCopyInto(out *TenantSpec) {
|
||||
*out = new(api.DefaultAllowedListSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ForceTenantPrefix != nil {
|
||||
in, out := &in.ForceTenantPrefix, &out.ForceTenantPrefix
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TenantSpec.
|
||||
|
||||
4
charts/capsule/.schema.yaml
Normal file
4
charts/capsule/.schema.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
input:
|
||||
- values.yaml
|
||||
- ci/test-values.yaml
|
||||
- ci/proxy-values.yaml
|
||||
6
charts/capsule/Chart.lock
Normal file
6
charts/capsule/Chart.lock
Normal file
@@ -0,0 +1,6 @@
|
||||
dependencies:
|
||||
- name: capsule-proxy
|
||||
repository: oci://ghcr.io/projectcapsule/charts
|
||||
version: 0.9.0
|
||||
digest: sha256:cac4e476957f57f67ea501ea01e8439c74539b15891ff15337df6a80f484da27
|
||||
generated: "2025-01-11T02:25:45.377645646Z"
|
||||
@@ -4,6 +4,12 @@ description: A Helm chart to deploy the Capsule Operator for easily implementing
|
||||
managing, and maintaining mutitenancy and access control in Kubernetes.
|
||||
home: https://github.com/projectcapsule/capsule
|
||||
icon: https://github.com/projectcapsule/capsule/raw/main/assets/logo/capsule_small.png
|
||||
dependencies:
|
||||
- name: capsule-proxy
|
||||
version: 0.9.0
|
||||
repository: "oci://ghcr.io/projectcapsule/charts"
|
||||
condition: proxy.enabled
|
||||
alias: proxy
|
||||
keywords:
|
||||
- kubernetes
|
||||
- operator
|
||||
@@ -18,10 +24,9 @@ maintainers:
|
||||
name: capsule
|
||||
sources:
|
||||
- https://github.com/projectcapsule/capsule
|
||||
# The version is overwritten by the release workflow.
|
||||
# Note: The version is overwritten by the release workflow.
|
||||
version: 0.6.0
|
||||
# This is the version number of the application being deployed.
|
||||
# This version number should be incremented each time you make changes to the application.
|
||||
# Note: The version is overwritten by the release workflow.
|
||||
appVersion: 0.5.0
|
||||
annotations:
|
||||
artifacthub.io/operator: "true"
|
||||
@@ -33,9 +38,9 @@ annotations:
|
||||
email: cncf-capsule-maintainers@lists.cncf.io
|
||||
artifacthub.io/links: |
|
||||
- name: Documentation
|
||||
url: https://capsule.clastix.io/
|
||||
# artifacthub.io/changes: |
|
||||
# - kind: added
|
||||
# description: artifacthub annotations
|
||||
# - kind: changed
|
||||
# description: maintainers contact
|
||||
url: https://projectcapsule.dev/
|
||||
artifacthub.io/changes: |
|
||||
- kind: fixed
|
||||
description: added scope for mutating webhook configurations
|
||||
- kind: changed
|
||||
description: moved job configuration from jobs to global.jobs.kubectl
|
||||
|
||||
@@ -16,21 +16,39 @@ Use the Capsule Operator for easily implementing, managing, and maintaining mult
|
||||
|
||||
* A [`kubeconfig`](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) file accessing the Kubernetes cluster with cluster admin permissions.
|
||||
|
||||
## Quick Start
|
||||
## Major Changes
|
||||
|
||||
In the following sections you see actions which are required when you are upgrading to a specific version.
|
||||
|
||||
### Upgrading to 0.7.x
|
||||
|
||||
Introduces a new methode to manage all capsule CRDs and their lifecycle. We are no longer relying on the [native CRD hook with the Helm Chart](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations). The hook only allows to manage CRDs on install and uninstall but we can't deliver updates to the CRDs.
|
||||
When you newly install the chart we recommend to set `crds.install` to `true`. This will manage the CRDs with the Helm Chart. This behavior is the new default.
|
||||
|
||||
#### Changed Values
|
||||
|
||||
The following Values have changed key or Value:
|
||||
|
||||
* All values from previous releases under `webhooks` have moved to `webhooks.hooks`.
|
||||
* `mutatingWebhooksTimeoutSeconds` has moved to `webhooks.mutatingWebhooksTimeoutSeconds`
|
||||
* `validatingWebhooksTimeoutSeconds` has moved to `webhooks.validatingWebhooksTimeoutSeconds`
|
||||
|
||||
## Installation
|
||||
|
||||
The Capsule Operator requires it's CRDs to be installed before the operator itself. Since the Helm CRD lifecycle has limitations, we recommend to install the CRDs separately. Our chart supports the installation of crds via a dedicated Release.
|
||||
The Capsule Operator Chart can be used to instantly deploy the Capsule Operator on your Kubernetes cluster.
|
||||
|
||||
1. Add this repository:
|
||||
|
||||
$ helm repo add projectcapsule https://projectcapsule.github.io/charts
|
||||
|
||||
2. Install the Chart:
|
||||
2. Install Capsule:
|
||||
|
||||
$ helm install capsule projectcapsule/capsule -n capsule-system --create-namespace
|
||||
$ helm install capsule projectcapsule/capsule --version 0.7.0 -n capsule-system --create-namespace
|
||||
|
||||
or
|
||||
|
||||
$ helm install capsule oci://ghcr.io/projectcapsule/charts/capsule --version 0.4.6 -n capsule-system --create-namespace
|
||||
$ helm install capsule oci://ghcr.io/projectcapsule/charts/capsule --version 0.7.0 -n capsule-system --create-namespace
|
||||
|
||||
3. Show the status:
|
||||
|
||||
@@ -58,7 +76,7 @@ Specify your overrides file when you install the chart:
|
||||
|
||||
$ helm install capsule capsule-helm-chart --values myvalues.yaml -n capsule-system
|
||||
|
||||
The values in your overrides file `myvalues.yaml` will override their counterparts in the chart’s values.yaml file. Any values in `values.yaml` that weren’t overridden will keep their defaults.
|
||||
The values in your overrides file `myvalues.yaml` will override their counterparts in the chart's values.yaml file. Any values in `values.yaml` that weren’t overridden will keep their defaults.
|
||||
|
||||
If you only need to make minor customizations, you can specify them on the command line by using the `--set` option. For example:
|
||||
|
||||
@@ -66,36 +84,63 @@ If you only need to make minor customizations, you can specify them on the comma
|
||||
|
||||
Here the values you can override:
|
||||
|
||||
### CustomResourceDefinition Lifecycle
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| crds.annnotations | object | `{}` | Extra Annotations for CRDs |
|
||||
| crds.exclusive | bool | `false` | Only install the CRDs, no other primitives |
|
||||
| crds.install | bool | `true` | Install the CustomResourceDefinitions (This also manages the lifecycle of the CRDs for update operations) |
|
||||
| crds.labels | object | `{}` | Extra Labels for CRDs |
|
||||
|
||||
### Global Parameters
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| global.jobs.kubectl.affinity | object | `{}` | Set affinity rules |
|
||||
| global.jobs.kubectl.annotations | object | `{}` | Annotations to add to the certgen job. |
|
||||
| global.jobs.kubectl.backoffLimit | int | `4` | Backofflimit for jobs |
|
||||
| global.jobs.kubectl.image.pullPolicy | string | `"IfNotPresent"` | Set the image pull policy of the helm chart job |
|
||||
| global.jobs.kubectl.image.registry | string | `"docker.io"` | Set the image repository of the helm chart job |
|
||||
| global.jobs.kubectl.image.repository | string | `"clastix/kubectl"` | Set the image repository of the helm chart job |
|
||||
| global.jobs.kubectl.image.tag | string | `""` | Set the image tag of the helm chart job |
|
||||
| global.jobs.kubectl.imagePullSecrets | list | `[]` | ImagePullSecrets |
|
||||
| global.jobs.kubectl.nodeSelector | object | `{}` | Set the node selector |
|
||||
| global.jobs.kubectl.podSecurityContext | object | `{"seccompProfile":{"type":"RuntimeDefault"}}` | Security context for the job pods. |
|
||||
| global.jobs.kubectl.priorityClassName | string | `""` | Set a pod priorityClassName |
|
||||
| global.jobs.kubectl.resources | object | `{}` | Job resources |
|
||||
| global.jobs.kubectl.restartPolicy | string | `"Never"` | Set the restartPolicy |
|
||||
| global.jobs.kubectl.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsGroup":1002,"runAsNonRoot":true,"runAsUser":1002}` | Security context for the job containers. |
|
||||
| global.jobs.kubectl.tolerations | list | `[]` | Set list of tolerations |
|
||||
| global.jobs.kubectl.topologySpreadConstraints | list | `[]` | Set Topology Spread Constraints |
|
||||
| global.jobs.kubectl.ttlSecondsAfterFinished | int | `60` | Sets the ttl in seconds after a finished certgen job is deleted. Set to -1 to never delete. |
|
||||
|
||||
### General Parameters
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| affinity | object | `{}` | Set affinity rules for the Capsule pod |
|
||||
| certManager.additionalSANS | list | `[]` | Specify additional SANS to add to the certificate |
|
||||
| certManager.generateCertificates | bool | `false` | Specifies whether capsule webhooks certificates should be generated using cert-manager |
|
||||
| customAnnotations | object | `{}` | Additional annotations which will be added to all resources created by Capsule helm chart |
|
||||
| customLabels | object | `{}` | Additional labels which will be added to all resources created by Capsule helm chart |
|
||||
| imagePullSecrets | list | `[]` | Configuration for `imagePullSecrets` so that you can use a private images registry. |
|
||||
| jobs.image.pullPolicy | string | `"IfNotPresent"` | Set the image pull policy of the helm chart job |
|
||||
| jobs.image.registry | string | `"docker.io"` | Set the image repository of the helm chart job |
|
||||
| jobs.image.repository | string | `"clastix/kubectl"` | Set the image repository of the helm chart job |
|
||||
| jobs.image.tag | string | `""` | Set the image tag of the helm chart job |
|
||||
| mutatingWebhooksTimeoutSeconds | int | `30` | Timeout in seconds for mutating webhooks |
|
||||
| jobs | object | `{}` | Deprecated, use .global.jobs.kubectl instead |
|
||||
| nodeSelector | object | `{}` | Set the node selector for the Capsule pod |
|
||||
| podAnnotations | object | `{}` | Annotations to add to the capsule pod. |
|
||||
| podSecurityContext | object | `{"runAsGroup":1002,"runAsNonRoot":true,"runAsUser":1002,"seccompProfile":{"type":"RuntimeDefault"}}` | Set the securityContext for the Capsule pod |
|
||||
| podSecurityPolicy.enabled | bool | `false` | Specify if a Pod Security Policy must be created |
|
||||
| priorityClassName | string | `""` | Set the priority class name of the Capsule pod |
|
||||
| proxy.enabled | bool | `false` | Enable Installation of Capsule Proxy |
|
||||
| replicaCount | int | `1` | Set the replica count for capsule pod |
|
||||
| securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true}` | Set the securityContext for the Capsule container |
|
||||
| serviceAccount.annotations | object | `{}` | Annotations to add to the service account. |
|
||||
| serviceAccount.create | bool | `true` | Specifies whether a service account should be created. |
|
||||
| serviceAccount.name | string | `"capsule"` | The name of the service account to use. If not set and `serviceAccount.create=true`, a name is generated using the fullname template |
|
||||
| serviceAccount.name | string | `""` | The name of the service account to use. If not set and `serviceAccount.create=true`, a name is generated using the fullname template |
|
||||
| tls.create | bool | `true` | When cert-manager is disabled, Capsule will generate the TLS certificate for webhook and CRDs conversion. |
|
||||
| tls.enableController | bool | `true` | Start the Capsule controller that injects the CA into mutating and validating webhooks, and CRD as well. |
|
||||
| tls.name | string | `""` | Override name of the Capsule TLS Secret name when externally managed. |
|
||||
| tolerations | list | `[]` | Set list of tolerations for the Capsule pod |
|
||||
| topologySpreadConstraints | list | `[]` | Set topology spread constraints for the Capsule pod |
|
||||
| validatingWebhooksTimeoutSeconds | int | `30` | Timeout in seconds for validating webhooks |
|
||||
|
||||
### Manager Parameters
|
||||
|
||||
@@ -108,7 +153,8 @@ Here the values you can override:
|
||||
| manager.image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. |
|
||||
| manager.kind | string | `"Deployment"` | Set the controller deployment mode as `Deployment` or `DaemonSet`. |
|
||||
| manager.livenessProbe | object | `{"httpGet":{"path":"/healthz","port":10080}}` | Configure the liveness probe using Deployment probe spec |
|
||||
| manager.options.capsuleUserGroups | list | `["capsule.clastix.io"]` | Override the Capsule user groups |
|
||||
| manager.options.capsuleConfiguration | string | `"default"` | Change the default name of the capsule configuration name |
|
||||
| manager.options.capsuleUserGroups | list | `["projectcapsule.dev"]` | Override the Capsule user groups |
|
||||
| manager.options.forceTenantPrefix | bool | `false` | Boolean, enforces the Tenant owner, during Namespace creation, to name it using the selected Tenant name as prefix, separated by a dash |
|
||||
| manager.options.generateCertificates | bool | `true` | Specifies whether capsule webhooks certificates should be generated by capsule operator |
|
||||
| manager.options.logLevel | string | `"4"` | Set the log verbosity of the capsule with a value from 1 to 10 |
|
||||
@@ -118,10 +164,7 @@ Here the values you can override:
|
||||
| manager.rbac.existingClusterRoles | list | `[]` | Specifies further cluster roles to be added to the Capsule manager service account. |
|
||||
| manager.rbac.existingRoles | list | `[]` | Specifies further cluster roles to be added to the Capsule manager service account. |
|
||||
| manager.readinessProbe | object | `{"httpGet":{"path":"/readyz","port":10080}}` | Configure the readiness probe using Deployment probe spec |
|
||||
| manager.resources.limits.cpu | string | `"200m"` | |
|
||||
| manager.resources.limits.memory | string | `"128Mi"` | |
|
||||
| manager.resources.requests.cpu | string | `"200m"` | |
|
||||
| manager.resources.requests.memory | string | `"128Mi"` | |
|
||||
| manager.resources | object | `{}` | Set the resource requests/limits for the Capsule manager container |
|
||||
| manager.webhookPort | int | `9443` | Set an alternative to the default container port. Useful for use in some kubernetes clusters (such as GKE Private) with aggregator routing turned on, because pod ports have to be opened manually on the firewall side |
|
||||
|
||||
### ServiceMonitor Parameters
|
||||
@@ -139,42 +182,50 @@ Here the values you can override:
|
||||
| serviceMonitor.namespace | string | `""` | Install the ServiceMonitor into a different Namespace, as the monitoring stack one (default: the release one) |
|
||||
| serviceMonitor.targetLabels | list | `[]` | Set targetLabels for the serviceMonitor |
|
||||
|
||||
### Webhook Parameters
|
||||
### Webhooks Parameters
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| webhooks.cordoning.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.cordoning.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.cordoning.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.defaults.ingress.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.defaults.ingress.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.defaults.ingress.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.defaults.pods.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.defaults.pods.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.defaults.pods.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.defaults.pvc.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.defaults.pvc.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.defaults.pvc.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.ingresses.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.ingresses.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.ingresses.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.namespaceOwnerReference.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.namespaces.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.networkpolicies.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.networkpolicies.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.networkpolicies.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.nodes.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.persistentvolumeclaims.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.persistentvolumeclaims.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.persistentvolumeclaims.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.pods.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.pods.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.pods.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.services.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.services.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.services.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.tenantResourceObjects.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.tenants.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.exclusive | bool | `false` | When `crds.exclusive` is `true` the webhooks will be installed |
|
||||
| webhooks.hooks.cordoning.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.cordoning.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.cordoning.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.defaults.ingress.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.defaults.ingress.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.defaults.ingress.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.defaults.pods.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.defaults.pods.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.defaults.pods.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.defaults.pvc.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.defaults.pvc.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.defaults.pvc.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.ingresses.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.ingresses.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.ingresses.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.namespaceOwnerReference.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.namespaces.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.networkpolicies.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.networkpolicies.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.networkpolicies.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.nodes.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.persistentvolumeclaims.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.persistentvolumeclaims.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.persistentvolumeclaims.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.pods.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.pods.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.pods.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.services.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.services.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.services.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.tenantResourceObjects.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.tenants.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.mutatingWebhooksTimeoutSeconds | int | `30` | Timeout in seconds for mutating webhooks |
|
||||
| webhooks.service.caBundle | string | `""` | CABundle for the webhook service |
|
||||
| webhooks.service.name | string | `""` | Custom service name for the webhook service |
|
||||
| webhooks.service.namespace | string | `""` | Custom service namespace for the webhook service |
|
||||
| webhooks.service.port | string | `nil` | Custom service port for the webhook service |
|
||||
| webhooks.service.url | string | `""` | The URL where the capsule webhook services are running (Overwrites cluster scoped service definition) |
|
||||
| webhooks.validatingWebhooksTimeoutSeconds | int | `30` | Timeout in seconds for validating webhooks |
|
||||
|
||||
## Created resources
|
||||
|
||||
|
||||
@@ -16,21 +16,40 @@ Use the Capsule Operator for easily implementing, managing, and maintaining mult
|
||||
|
||||
* A [`kubeconfig`](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) file accessing the Kubernetes cluster with cluster admin permissions.
|
||||
|
||||
## Quick Start
|
||||
## Major Changes
|
||||
|
||||
In the following sections you see actions which are required when you are upgrading to a specific version.
|
||||
|
||||
### Upgrading to 0.7.x
|
||||
|
||||
Introduces a new methode to manage all capsule CRDs and their lifecycle. We are no longer relying on the [native CRD hook with the Helm Chart](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations). The hook only allows to manage CRDs on install and uninstall but we can't deliver updates to the CRDs.
|
||||
When you newly install the chart we recommend to set `crds.install` to `true`. This will manage the CRDs with the Helm Chart. This behavior is the new default.
|
||||
|
||||
#### Changed Values
|
||||
|
||||
The following Values have changed key or Value:
|
||||
|
||||
* All values from previous releases under `webhooks` have moved to `webhooks.hooks`.
|
||||
* `mutatingWebhooksTimeoutSeconds` has moved to `webhooks.mutatingWebhooksTimeoutSeconds`
|
||||
* `validatingWebhooksTimeoutSeconds` has moved to `webhooks.validatingWebhooksTimeoutSeconds`
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
The Capsule Operator requires it's CRDs to be installed before the operator itself. Since the Helm CRD lifecycle has limitations, we recommend to install the CRDs separately. Our chart supports the installation of crds via a dedicated Release.
|
||||
The Capsule Operator Chart can be used to instantly deploy the Capsule Operator on your Kubernetes cluster.
|
||||
|
||||
1. Add this repository:
|
||||
|
||||
$ helm repo add projectcapsule https://projectcapsule.github.io/charts
|
||||
|
||||
2. Install the Chart:
|
||||
2. Install Capsule:
|
||||
|
||||
$ helm install capsule projectcapsule/capsule -n capsule-system --create-namespace
|
||||
$ helm install capsule projectcapsule/capsule --version 0.7.0 -n capsule-system --create-namespace
|
||||
|
||||
or
|
||||
|
||||
$ helm install capsule oci://ghcr.io/projectcapsule/charts/capsule --version 0.4.6 -n capsule-system --create-namespace
|
||||
$ helm install capsule oci://ghcr.io/projectcapsule/charts/capsule --version 0.7.0 -n capsule-system --create-namespace
|
||||
|
||||
3. Show the status:
|
||||
|
||||
@@ -58,7 +77,7 @@ Specify your overrides file when you install the chart:
|
||||
|
||||
$ helm install capsule capsule-helm-chart --values myvalues.yaml -n capsule-system
|
||||
|
||||
The values in your overrides file `myvalues.yaml` will override their counterparts in the chart’s values.yaml file. Any values in `values.yaml` that weren’t overridden will keep their defaults.
|
||||
The values in your overrides file `myvalues.yaml` will override their counterparts in the chart's values.yaml file. Any values in `values.yaml` that weren’t overridden will keep their defaults.
|
||||
|
||||
If you only need to make minor customizations, you can specify them on the command line by using the `--set` option. For example:
|
||||
|
||||
@@ -66,13 +85,32 @@ If you only need to make minor customizations, you can specify them on the comma
|
||||
|
||||
Here the values you can override:
|
||||
|
||||
### CustomResourceDefinition Lifecycle
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
{{- range .Values }}
|
||||
{{- if (hasPrefix "crds" .Key) }}
|
||||
| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
### Global Parameters
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
{{- range .Values }}
|
||||
{{- if (hasPrefix "global" .Key) }}
|
||||
| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
### General Parameters
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
{{- range .Values }}
|
||||
{{- if not (or (hasPrefix "manager" .Key) (hasPrefix "serviceMonitor" .Key) (hasPrefix "webhook" .Key) (hasPrefix "capsule-proxy" .Key) ) }}
|
||||
{{- if not (or (hasPrefix "global" .Key) (hasPrefix "manager" .Key) (hasPrefix "crds" .Key) (hasPrefix "serviceMonitor" .Key) (hasPrefix "webhook" .Key) (hasPrefix "capsule-proxy" .Key) ) }}
|
||||
| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -97,7 +135,7 @@ Here the values you can override:
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
### Webhook Parameters
|
||||
### Webhooks Parameters
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
|
||||
7
charts/capsule/ci/proxy-values.yaml
Normal file
7
charts/capsule/ci/proxy-values.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
proxy:
|
||||
enabled: true
|
||||
manager:
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
@@ -1,16 +1,12 @@
|
||||
fullnameOverride: capsule
|
||||
manager:
|
||||
# Manager RBAC
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
rbac:
|
||||
create: true
|
||||
existingClusterRoles:
|
||||
- "view"
|
||||
existingRoles:
|
||||
- "some-role"
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
metadata:
|
||||
annotations:
|
||||
{{- if $.Values.certManager.generateCertificates }}
|
||||
cert-manager.io/inject-ca-from: {{ $.Release.Namespace }}/{{ include "capsule.fullname" $ }}-webhook-cert
|
||||
{{- end }}
|
||||
spec:
|
||||
conversion:
|
||||
strategy: Webhook
|
||||
webhook:
|
||||
clientConfig:
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/convert" "ctx" $) | nindent 8 }}
|
||||
conversionReviewVersions:
|
||||
- v1beta1
|
||||
- v1beta2
|
||||
@@ -0,0 +1,132 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.1
|
||||
name: capsuleconfigurations.capsule.clastix.io
|
||||
spec:
|
||||
group: capsule.clastix.io
|
||||
names:
|
||||
kind: CapsuleConfiguration
|
||||
listKind: CapsuleConfigurationList
|
||||
plural: capsuleconfigurations
|
||||
singular: capsuleconfiguration
|
||||
scope: Cluster
|
||||
versions:
|
||||
- name: v1beta2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: CapsuleConfiguration is the Schema for the Capsule configuration
|
||||
API.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: CapsuleConfigurationSpec defines the Capsule configuration.
|
||||
properties:
|
||||
enableTLSReconciler:
|
||||
default: true
|
||||
description: |-
|
||||
Toggles the TLS reconciler, the controller that is able to generate CA and certificates for the webhooks
|
||||
when not using an already provided CA and certificate, or when these are managed externally with Vault, or cert-manager.
|
||||
type: boolean
|
||||
forceTenantPrefix:
|
||||
default: false
|
||||
description: |-
|
||||
Enforces the Tenant owner, during Namespace creation, to name it using the selected Tenant name as prefix,
|
||||
separated by a dash. This is useful to avoid Namespace name collision in a public CaaS environment.
|
||||
type: boolean
|
||||
nodeMetadata:
|
||||
description: |-
|
||||
Allows to set the forbidden metadata for the worker nodes that could be patched by a Tenant.
|
||||
This applies only if the Tenant has an active NodeSelector, and the Owner have right to patch their nodes.
|
||||
properties:
|
||||
forbiddenAnnotations:
|
||||
description: Define the annotations that a Tenant Owner cannot
|
||||
set for their nodes.
|
||||
properties:
|
||||
denied:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
deniedRegex:
|
||||
type: string
|
||||
type: object
|
||||
forbiddenLabels:
|
||||
description: Define the labels that a Tenant Owner cannot set
|
||||
for their nodes.
|
||||
properties:
|
||||
denied:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
deniedRegex:
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- forbiddenAnnotations
|
||||
- forbiddenLabels
|
||||
type: object
|
||||
overrides:
|
||||
default:
|
||||
TLSSecretName: capsule-tls
|
||||
mutatingWebhookConfigurationName: capsule-mutating-webhook-configuration
|
||||
validatingWebhookConfigurationName: capsule-validating-webhook-configuration
|
||||
description: |-
|
||||
Allows to set different name rather than the canonical one for the Capsule configuration objects,
|
||||
such as webhook secret or configurations.
|
||||
properties:
|
||||
TLSSecretName:
|
||||
default: capsule-tls
|
||||
description: |-
|
||||
Defines the Secret name used for the webhook server.
|
||||
Must be in the same Namespace where the Capsule Deployment is deployed.
|
||||
type: string
|
||||
mutatingWebhookConfigurationName:
|
||||
default: capsule-mutating-webhook-configuration
|
||||
description: Name of the MutatingWebhookConfiguration which contains
|
||||
the dynamic admission controller paths and resources.
|
||||
type: string
|
||||
validatingWebhookConfigurationName:
|
||||
default: capsule-validating-webhook-configuration
|
||||
description: Name of the ValidatingWebhookConfiguration which
|
||||
contains the dynamic admission controller paths and resources.
|
||||
type: string
|
||||
required:
|
||||
- TLSSecretName
|
||||
- mutatingWebhookConfigurationName
|
||||
- validatingWebhookConfigurationName
|
||||
type: object
|
||||
protectedNamespaceRegex:
|
||||
description: Disallow creation of namespaces, whose name matches this
|
||||
regexp
|
||||
type: string
|
||||
userGroups:
|
||||
default:
|
||||
- capsule.clastix.io
|
||||
description: Names of the groups for Capsule users.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- enableTLSReconciler
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
@@ -0,0 +1,298 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.1
|
||||
name: globaltenantresources.capsule.clastix.io
|
||||
spec:
|
||||
group: capsule.clastix.io
|
||||
names:
|
||||
kind: GlobalTenantResource
|
||||
listKind: GlobalTenantResourceList
|
||||
plural: globaltenantresources
|
||||
singular: globaltenantresource
|
||||
scope: Cluster
|
||||
versions:
|
||||
- name: v1beta2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: GlobalTenantResource allows to propagate resource replications
|
||||
to a specific subset of Tenant resources.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: GlobalTenantResourceSpec defines the desired state of GlobalTenantResource.
|
||||
properties:
|
||||
pruningOnDelete:
|
||||
default: true
|
||||
description: |-
|
||||
When the replicated resource manifest is deleted, all the objects replicated so far will be automatically deleted.
|
||||
Disable this to keep replicated resources although the deletion of the replication manifest.
|
||||
type: boolean
|
||||
resources:
|
||||
description: Defines the rules to select targeting Namespace, along
|
||||
with the objects that must be replicated.
|
||||
items:
|
||||
properties:
|
||||
additionalMetadata:
|
||||
description: |-
|
||||
Besides the Capsule metadata required by TenantResource controller, defines additional metadata that must be
|
||||
added to the replicated resources.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
labels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: |-
|
||||
Defines the Namespace selector to select the Tenant Namespaces on which the resources must be propagated.
|
||||
In case of nil value, all the Tenant Namespaces are targeted.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespacedItems:
|
||||
description: List of the resources already existing in other
|
||||
Namespaces that must be replicated.
|
||||
items:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
selector:
|
||||
description: Label selector used to select the given resources
|
||||
in the given Namespace.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
required:
|
||||
- kind
|
||||
- namespace
|
||||
- selector
|
||||
type: object
|
||||
type: array
|
||||
rawItems:
|
||||
description: List of raw resources that must be replicated.
|
||||
items:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
resyncPeriod:
|
||||
default: 60s
|
||||
description: |-
|
||||
Define the period of time upon a second reconciliation must be invoked.
|
||||
Keep in mind that any change to the manifests will trigger a new reconciliation.
|
||||
type: string
|
||||
tenantSelector:
|
||||
description: Defines the Tenant selector used target the tenants on
|
||||
which resources must be propagated.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
required:
|
||||
- resources
|
||||
- resyncPeriod
|
||||
type: object
|
||||
status:
|
||||
description: GlobalTenantResourceStatus defines the observed state of
|
||||
GlobalTenantResource.
|
||||
properties:
|
||||
processedItems:
|
||||
description: List of the replicated resources for the given TenantResource.
|
||||
items:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
- namespace
|
||||
type: object
|
||||
type: array
|
||||
selectedTenants:
|
||||
description: List of Tenants addressed by the GlobalTenantResource.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- processedItems
|
||||
- selectedTenants
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
246
charts/capsule/crds/capsule.clastix.io_tenantresources.yaml
Normal file
246
charts/capsule/crds/capsule.clastix.io_tenantresources.yaml
Normal file
@@ -0,0 +1,246 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.1
|
||||
name: tenantresources.capsule.clastix.io
|
||||
spec:
|
||||
group: capsule.clastix.io
|
||||
names:
|
||||
kind: TenantResource
|
||||
listKind: TenantResourceList
|
||||
plural: tenantresources
|
||||
singular: tenantresource
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1beta2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: |-
|
||||
TenantResource allows a Tenant Owner, if enabled with proper RBAC, to propagate resources in its Namespace.
|
||||
The object must be deployed in a Tenant Namespace, and cannot reference object living in non-Tenant namespaces.
|
||||
For such cases, the GlobalTenantResource must be used.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: TenantResourceSpec defines the desired state of TenantResource.
|
||||
properties:
|
||||
pruningOnDelete:
|
||||
default: true
|
||||
description: |-
|
||||
When the replicated resource manifest is deleted, all the objects replicated so far will be automatically deleted.
|
||||
Disable this to keep replicated resources although the deletion of the replication manifest.
|
||||
type: boolean
|
||||
resources:
|
||||
description: Defines the rules to select targeting Namespace, along
|
||||
with the objects that must be replicated.
|
||||
items:
|
||||
properties:
|
||||
additionalMetadata:
|
||||
description: |-
|
||||
Besides the Capsule metadata required by TenantResource controller, defines additional metadata that must be
|
||||
added to the replicated resources.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
labels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: |-
|
||||
Defines the Namespace selector to select the Tenant Namespaces on which the resources must be propagated.
|
||||
In case of nil value, all the Tenant Namespaces are targeted.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespacedItems:
|
||||
description: List of the resources already existing in other
|
||||
Namespaces that must be replicated.
|
||||
items:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
selector:
|
||||
description: Label selector used to select the given resources
|
||||
in the given Namespace.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
required:
|
||||
- kind
|
||||
- namespace
|
||||
- selector
|
||||
type: object
|
||||
type: array
|
||||
rawItems:
|
||||
description: List of raw resources that must be replicated.
|
||||
items:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
resyncPeriod:
|
||||
default: 60s
|
||||
description: |-
|
||||
Define the period of time upon a second reconciliation must be invoked.
|
||||
Keep in mind that any change to the manifests will trigger a new reconciliation.
|
||||
type: string
|
||||
required:
|
||||
- resources
|
||||
- resyncPeriod
|
||||
type: object
|
||||
status:
|
||||
description: TenantResourceStatus defines the observed state of TenantResource.
|
||||
properties:
|
||||
processedItems:
|
||||
description: List of the replicated resources for the given TenantResource.
|
||||
items:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
- namespace
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- processedItems
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
14
charts/capsule/crds/capsule.clastix.io_tenants.patch
Normal file
14
charts/capsule/crds/capsule.clastix.io_tenants.patch
Normal file
@@ -0,0 +1,14 @@
|
||||
metadata:
|
||||
annotations:
|
||||
{{- if $.Values.certManager.generateCertificates }}
|
||||
cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "capsule.fullname" . }}-webhook-cert
|
||||
{{- end }}
|
||||
spec:
|
||||
conversion:
|
||||
strategy: Webhook
|
||||
webhook:
|
||||
clientConfig:
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/convert" "ctx" $) | nindent 8 }}
|
||||
conversionReviewVersions:
|
||||
- v1beta1
|
||||
- v1beta2
|
||||
2338
charts/capsule/crds/capsule.clastix.io_tenants.yaml
Normal file
2338
charts/capsule/crds/capsule.clastix.io_tenants.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,119 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.10.0
|
||||
name: capsuleconfigurations.capsule.clastix.io
|
||||
spec:
|
||||
conversion:
|
||||
strategy: Webhook
|
||||
webhook:
|
||||
clientConfig:
|
||||
service:
|
||||
name: capsule-webhook-service
|
||||
namespace: capsule-system
|
||||
path: /convert
|
||||
conversionReviewVersions:
|
||||
- v1beta1
|
||||
- v1beta2
|
||||
group: capsule.clastix.io
|
||||
names:
|
||||
kind: CapsuleConfiguration
|
||||
listKind: CapsuleConfigurationList
|
||||
plural: capsuleconfigurations
|
||||
singular: capsuleconfiguration
|
||||
scope: Cluster
|
||||
versions:
|
||||
- name: v1beta2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: CapsuleConfiguration is the Schema for the Capsule configuration API.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: CapsuleConfigurationSpec defines the Capsule configuration.
|
||||
properties:
|
||||
enableTLSReconciler:
|
||||
default: true
|
||||
description: Toggles the TLS reconciler, the controller that is able to generate CA and certificates for the webhooks when not using an already provided CA and certificate, or when these are managed externally with Vault, or cert-manager.
|
||||
type: boolean
|
||||
forceTenantPrefix:
|
||||
default: false
|
||||
description: Enforces the Tenant owner, during Namespace creation, to name it using the selected Tenant name as prefix, separated by a dash. This is useful to avoid Namespace name collision in a public CaaS environment.
|
||||
type: boolean
|
||||
nodeMetadata:
|
||||
description: Allows to set the forbidden metadata for the worker nodes that could be patched by a Tenant. This applies only if the Tenant has an active NodeSelector, and the Owner have right to patch their nodes.
|
||||
properties:
|
||||
forbiddenAnnotations:
|
||||
description: Define the annotations that a Tenant Owner cannot set for their nodes.
|
||||
properties:
|
||||
denied:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
deniedRegex:
|
||||
type: string
|
||||
type: object
|
||||
forbiddenLabels:
|
||||
description: Define the labels that a Tenant Owner cannot set for their nodes.
|
||||
properties:
|
||||
denied:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
deniedRegex:
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- forbiddenAnnotations
|
||||
- forbiddenLabels
|
||||
type: object
|
||||
overrides:
|
||||
default:
|
||||
TLSSecretName: capsule-tls
|
||||
mutatingWebhookConfigurationName: capsule-mutating-webhook-configuration
|
||||
validatingWebhookConfigurationName: capsule-validating-webhook-configuration
|
||||
description: Allows to set different name rather than the canonical one for the Capsule configuration objects, such as webhook secret or configurations.
|
||||
properties:
|
||||
TLSSecretName:
|
||||
default: capsule-tls
|
||||
description: Defines the Secret name used for the webhook server. Must be in the same Namespace where the Capsule Deployment is deployed.
|
||||
type: string
|
||||
mutatingWebhookConfigurationName:
|
||||
default: capsule-mutating-webhook-configuration
|
||||
description: Name of the MutatingWebhookConfiguration which contains the dynamic admission controller paths and resources.
|
||||
type: string
|
||||
validatingWebhookConfigurationName:
|
||||
default: capsule-validating-webhook-configuration
|
||||
description: Name of the ValidatingWebhookConfiguration which contains the dynamic admission controller paths and resources.
|
||||
type: string
|
||||
required:
|
||||
- TLSSecretName
|
||||
- mutatingWebhookConfigurationName
|
||||
- validatingWebhookConfigurationName
|
||||
type: object
|
||||
protectedNamespaceRegex:
|
||||
description: Disallow creation of namespaces, whose name matches this regexp
|
||||
type: string
|
||||
userGroups:
|
||||
default:
|
||||
- capsule.clastix.io
|
||||
description: Names of the groups for Capsule users.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- enableTLSReconciler
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
@@ -1,222 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.10.0
|
||||
creationTimestamp: null
|
||||
name: globaltenantresources.capsule.clastix.io
|
||||
spec:
|
||||
group: capsule.clastix.io
|
||||
names:
|
||||
kind: GlobalTenantResource
|
||||
listKind: GlobalTenantResourceList
|
||||
plural: globaltenantresources
|
||||
singular: globaltenantresource
|
||||
scope: Cluster
|
||||
versions:
|
||||
- name: v1beta2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: GlobalTenantResource allows to propagate resource replications to a specific subset of Tenant resources.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: GlobalTenantResourceSpec defines the desired state of GlobalTenantResource.
|
||||
properties:
|
||||
pruningOnDelete:
|
||||
default: true
|
||||
description: When the replicated resource manifest is deleted, all the objects replicated so far will be automatically deleted. Disable this to keep replicated resources although the deletion of the replication manifest.
|
||||
type: boolean
|
||||
resources:
|
||||
description: Defines the rules to select targeting Namespace, along with the objects that must be replicated.
|
||||
items:
|
||||
properties:
|
||||
additionalMetadata:
|
||||
description: Besides the Capsule metadata required by TenantResource controller, defines additional metadata that must be added to the replicated resources.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
labels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: Defines the Namespace selector to select the Tenant Namespaces on which the resources must be propagated. In case of nil value, all the Tenant Namespaces are targeted.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespacedItems:
|
||||
description: List of the resources already existing in other Namespaces that must be replicated.
|
||||
items:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
selector:
|
||||
description: Label selector used to select the given resources in the given Namespace.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
required:
|
||||
- kind
|
||||
- namespace
|
||||
- selector
|
||||
type: object
|
||||
type: array
|
||||
rawItems:
|
||||
description: List of raw resources that must be replicated.
|
||||
items:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
resyncPeriod:
|
||||
default: 60s
|
||||
description: Define the period of time upon a second reconciliation must be invoked. Keep in mind that any change to the manifests will trigger a new reconciliation.
|
||||
type: string
|
||||
tenantSelector:
|
||||
description: Defines the Tenant selector used target the tenants on which resources must be propagated.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
required:
|
||||
- resources
|
||||
- resyncPeriod
|
||||
type: object
|
||||
status:
|
||||
description: GlobalTenantResourceStatus defines the observed state of GlobalTenantResource.
|
||||
properties:
|
||||
processedItems:
|
||||
description: List of the replicated resources for the given TenantResource.
|
||||
items:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
- namespace
|
||||
type: object
|
||||
type: array
|
||||
selectedTenants:
|
||||
description: List of Tenants addressed by the GlobalTenantResource.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- processedItems
|
||||
- selectedTenants
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,185 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.10.0
|
||||
creationTimestamp: null
|
||||
name: tenantresources.capsule.clastix.io
|
||||
spec:
|
||||
group: capsule.clastix.io
|
||||
names:
|
||||
kind: TenantResource
|
||||
listKind: TenantResourceList
|
||||
plural: tenantresources
|
||||
singular: tenantresource
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1beta2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: TenantResource allows a Tenant Owner, if enabled with proper RBAC, to propagate resources in its Namespace. The object must be deployed in a Tenant Namespace, and cannot reference object living in non-Tenant namespaces. For such cases, the GlobalTenantResource must be used.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: TenantResourceSpec defines the desired state of TenantResource.
|
||||
properties:
|
||||
pruningOnDelete:
|
||||
default: true
|
||||
description: When the replicated resource manifest is deleted, all the objects replicated so far will be automatically deleted. Disable this to keep replicated resources although the deletion of the replication manifest.
|
||||
type: boolean
|
||||
resources:
|
||||
description: Defines the rules to select targeting Namespace, along with the objects that must be replicated.
|
||||
items:
|
||||
properties:
|
||||
additionalMetadata:
|
||||
description: Besides the Capsule metadata required by TenantResource controller, defines additional metadata that must be added to the replicated resources.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
labels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: Defines the Namespace selector to select the Tenant Namespaces on which the resources must be propagated. In case of nil value, all the Tenant Namespaces are targeted.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespacedItems:
|
||||
description: List of the resources already existing in other Namespaces that must be replicated.
|
||||
items:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
selector:
|
||||
description: Label selector used to select the given resources in the given Namespace.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
required:
|
||||
- kind
|
||||
- namespace
|
||||
- selector
|
||||
type: object
|
||||
type: array
|
||||
rawItems:
|
||||
description: List of raw resources that must be replicated.
|
||||
items:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
resyncPeriod:
|
||||
default: 60s
|
||||
description: Define the period of time upon a second reconciliation must be invoked. Keep in mind that any change to the manifests will trigger a new reconciliation.
|
||||
type: string
|
||||
required:
|
||||
- resources
|
||||
- resyncPeriod
|
||||
type: object
|
||||
status:
|
||||
description: TenantResourceStatus defines the observed state of TenantResource.
|
||||
properties:
|
||||
processedItems:
|
||||
description: List of the replicated resources for the given TenantResource.
|
||||
items:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
- namespace
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- processedItems
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
@@ -105,10 +105,12 @@ Determine the Kubernetes version to use for jobsFullyQualifiedDockerImage tag
|
||||
Create the jobs fully-qualified Docker image to use
|
||||
*/}}
|
||||
{{- define "capsule.jobsFullyQualifiedDockerImage" -}}
|
||||
{{- if .Values.jobs.image.tag }}
|
||||
{{- printf "%s/%s:%s" .Values.jobs.image.registry .Values.jobs.image.repository .Values.jobs.image.tag -}}
|
||||
{{- $Values := mergeOverwrite $.Values.global.jobs.kubectl $.Values.jobs -}}
|
||||
|
||||
{{- if $Values.image.tag }}
|
||||
{{- printf "%s/%s:%s" $Values.image.registry $Values.image.repository $Values.image.tag -}}
|
||||
{{- else }}
|
||||
{{- printf "%s/%s:%s" .Values.jobs.image.registry .Values.jobs.image.repository (include "capsule.jobsTagKubeVersion" .) -}}
|
||||
{{- printf "%s/%s:%s" $Values.image.registry $Values.image.repository (include "capsule.jobsTagKubeVersion" .) -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -125,3 +127,32 @@ Create the Capsule TLS Secret name to use
|
||||
{{- define "capsule.secretTlsName" -}}
|
||||
{{ default ( printf "%s-tls" ( include "capsule.fullname" . ) ) .Values.tls.name }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{/*
|
||||
Capsule Webhook service (Called with $.Path)
|
||||
|
||||
*/}}
|
||||
{{- define "capsule.webhooks.service" -}}
|
||||
{{- include "capsule.webhooks.cabundle" $.ctx | nindent 0 }}
|
||||
{{- if $.ctx.Values.webhooks.service.url }}
|
||||
url: {{ printf "%s/%s" (trimSuffix "/" $.ctx.Values.webhooks.service.url ) (trimPrefix "/" (required "Path is required for the function" $.path)) }}
|
||||
{{- else }}
|
||||
service:
|
||||
name: {{ default (printf "%s-webhook-service" (include "capsule.fullname" $.ctx)) $.ctx.Values.webhooks.service.name }}
|
||||
namespace: {{ default $.ctx.Release.Namespace $.ctx.Values.webhooks.service.namespace }}
|
||||
port: {{ default 443 $.ctx.Values.webhooks.service.port }}
|
||||
path: {{ required "Path is required for the function" $.path }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Capsule Webhook endpoint CA Bundle
|
||||
*/}}
|
||||
{{- define "capsule.webhooks.cabundle" -}}
|
||||
{{- if $.Values.webhooks.service.caBundle -}}
|
||||
caBundle: {{ $.Values.webhooks.service.caBundle -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{{- if .Values.certManager.generateCertificates }}
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
{{- if .Values.certManager.generateCertificates }}
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
@@ -26,6 +27,9 @@ spec:
|
||||
dnsNames:
|
||||
- {{ include "capsule.fullname" . }}-webhook-service.{{ .Release.Namespace }}.svc
|
||||
- {{ include "capsule.fullname" . }}-webhook-service.{{ .Release.Namespace }}.svc.cluster.local
|
||||
{{- range .Values.certManager.additionalSANS }}
|
||||
- {{ toYaml . }}
|
||||
{{- end }}
|
||||
issuerRef:
|
||||
kind: Issuer
|
||||
name: {{ include "capsule.fullname" . }}-webhook-selfsigned
|
||||
@@ -33,4 +37,5 @@ spec:
|
||||
subject:
|
||||
organizations:
|
||||
- clastix.io
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
{{- if or (not .Values.certManager.generateCertificates) (.Values.tls.create) }}
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
{{- if or (not .Values.certManager.generateCertificates) (.Values.tls.create) }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
{{- with .Values.customAnnotations }}
|
||||
{{- with .Values.customAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
name: {{ include "capsule.secretTlsName" . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
apiVersion: capsule.clastix.io/v1beta2
|
||||
kind: CapsuleConfiguration
|
||||
metadata:
|
||||
@@ -24,3 +25,5 @@ spec:
|
||||
nodeMetadata:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
17
charts/capsule/templates/crd-lifecycle/_helpers.tpl
Normal file
17
charts/capsule/templates/crd-lifecycle/_helpers.tpl
Normal file
@@ -0,0 +1,17 @@
|
||||
{{- define "capsule.crds.name" -}}
|
||||
{{- printf "%s-crds" (include "capsule.name" $) -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "capsule.crds.annotations" -}}
|
||||
"helm.sh/hook": "pre-install,pre-upgrade"
|
||||
{{- end }}
|
||||
|
||||
{{- define "capsule.crds.component" -}}
|
||||
crd-install-hook
|
||||
{{- end }}
|
||||
|
||||
{{- define "capsule.crds.regexReplace" -}}
|
||||
{{- printf "%s" ($ | base | trimSuffix ".yaml" | regexReplaceAll "[_.]" "-") -}}
|
||||
{{- end }}
|
||||
|
||||
|
||||
56
charts/capsule/templates/crd-lifecycle/crds.tpl
Normal file
56
charts/capsule/templates/crd-lifecycle/crds.tpl
Normal file
@@ -0,0 +1,56 @@
|
||||
{{/* CustomResources Lifecycle */}}
|
||||
{{- if $.Values.crds.install }}
|
||||
{{ range $path, $_ := .Files.Glob "crds/**.yaml" }}
|
||||
{{- with $ }}
|
||||
{{- $content := (tpl (.Files.Get $path) $) -}}
|
||||
{{- $p := (fromYaml $content) -}}
|
||||
{{- if $p.Error }}
|
||||
{{- fail (printf "found YAML error in file %s - %s - raw:\n\n%s" $path $p.Error $content) -}}
|
||||
{{- end -}}
|
||||
|
||||
|
||||
{{/* Add Common Lables */}}
|
||||
{{- $_ := set $p.metadata "labels" (mergeOverwrite (default dict (get $p.metadata "labels")) (default dict $.Values.crds.labels) (fromYaml (include "capsule.labels" $))) -}}
|
||||
|
||||
|
||||
{{/* Add Common Lables */}}
|
||||
{{- $_ := set $p.metadata "annotations" (mergeOverwrite (default dict (get $p.metadata "annotations")) (default dict $.Values.crds.annotations)) -}}
|
||||
|
||||
{{/* Add Keep annotation to CRDs */}}
|
||||
{{- if $.Values.crds.keep }}
|
||||
{{- $_ := set $p.metadata.annotations "helm.sh/resource-policy" "keep" -}}
|
||||
{{- end }}
|
||||
|
||||
{{/* Add Spec Patches for the CRD */}}
|
||||
{{- $patchFile := $path | replace ".yaml" ".patch" }}
|
||||
{{- $patchRawContent := (tpl (.Files.Get $patchFile) $) -}}
|
||||
{{- if $patchRawContent -}}
|
||||
{{- $patchContent := (fromYaml $patchRawContent) -}}
|
||||
{{- if $patchContent.Error }}
|
||||
{{- fail (printf "found YAML error in patch file %s - %s - raw:\n\n%s" $patchFile $patchContent.Error $patchRawContent) -}}
|
||||
{{- end -}}
|
||||
{{- $tmp := deepCopy $p | mergeOverwrite $patchContent -}}
|
||||
{{- $p = $tmp -}}
|
||||
{{- end -}}
|
||||
{{- if $p }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "capsule.crds.name" . }}-{{ $path | base | trimSuffix ".yaml" | regexFind "[^_]+$" }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-5"
|
||||
{{- include "capsule.crds.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.crds.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
data:
|
||||
content: |
|
||||
{{- printf "---\n%s" (toYaml $p) | nindent 4 }}
|
||||
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
101
charts/capsule/templates/crd-lifecycle/job.yaml
Normal file
101
charts/capsule/templates/crd-lifecycle/job.yaml
Normal file
@@ -0,0 +1,101 @@
|
||||
{{/* Backwards compatibility */}}
|
||||
{{- $Values := mergeOverwrite $.Values.global.jobs.kubectl $.Values.jobs -}}
|
||||
|
||||
{{- if .Values.crds.install }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ include "capsule.crds.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-1"
|
||||
{{- include "capsule.crds.annotations" . | nindent 4 }}
|
||||
{{- with $Values.annotations }}
|
||||
{{- . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.crds.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
spec:
|
||||
backoffLimit: {{ $Values.backoffLimit }}
|
||||
{{- if ge $Values.ttlSecondsAfterFinished 0.0 }}
|
||||
ttlSecondsAfterFinished: {{ $Values.ttlSecondsAfterFinished }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
name: "{{ include "capsule.crds.name" . }}"
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.crds.component" . | quote }}
|
||||
{{- include "capsule.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
restartPolicy: {{ $Values.restartPolicy }}
|
||||
{{- with $Values.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.priorityClassName }}
|
||||
priorityClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- with $Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "capsule.crds.name" . }}
|
||||
containers:
|
||||
- name: crds-hook
|
||||
image: {{ include "capsule.jobsFullyQualifiedDockerImage" . }}
|
||||
imagePullPolicy: {{ $Values.image.pullPolicy }}
|
||||
{{- with $Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -o errexit ; set -o xtrace ; set -o nounset
|
||||
|
||||
# piping stderr to stdout means kubectl's errors are surfaced
|
||||
# in the pod's logs.
|
||||
|
||||
kubectl apply --server-side=true --overwrite=true --force-conflicts=true -f /data/ 2>&1
|
||||
volumeMounts:
|
||||
{{- range $path, $_ := .Files.Glob "crds/**.yaml" }}
|
||||
- name: {{ $path | base | trimSuffix ".yaml" | regexFind "[^_]+$" }}
|
||||
mountPath: /data/{{ $path | base }}
|
||||
subPath: {{ $path | base }}
|
||||
{{- end }}
|
||||
{{- with $Values.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
{{ $currentScope := . }}
|
||||
{{- range $path, $_ := .Files.Glob "crds/**.yaml" }}
|
||||
{{- with $currentScope }}
|
||||
- name: {{ $path | base | trimSuffix ".yaml" | regexFind "[^_]+$" }}
|
||||
configMap:
|
||||
name: {{ include "capsule.crds.name" $ }}-{{ $path | base | trimSuffix ".yaml" | regexFind "[^_]+$" }}
|
||||
items:
|
||||
- key: content
|
||||
path: {{ $path | base }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
52
charts/capsule/templates/crd-lifecycle/rbac.yaml
Normal file
52
charts/capsule/templates/crd-lifecycle/rbac.yaml
Normal file
@@ -0,0 +1,52 @@
|
||||
{{- if .Values.crds.install }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "capsule.crds.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-3"
|
||||
{{- include "capsule.crds.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.crds.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- jobs
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- apiGroups:
|
||||
- apiextensions.k8s.io
|
||||
resources:
|
||||
- customresourcedefinitions
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "capsule.crds.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-2"
|
||||
{{- include "capsule.crds.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.crds.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "capsule.crds.name" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "capsule.crds.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
{{- end }}
|
||||
14
charts/capsule/templates/crd-lifecycle/serviceaccount.yaml
Normal file
14
charts/capsule/templates/crd-lifecycle/serviceaccount.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.crds.install }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "capsule.crds.name" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-4"
|
||||
{{- include "capsule.crds.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.crds.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -1,4 +1,5 @@
|
||||
{{- if eq .Values.manager.kind "DaemonSet" }}
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
{{- if eq .Values.manager.kind "DaemonSet" }}
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
@@ -63,7 +64,7 @@ spec:
|
||||
- --webhook-port={{ .Values.manager.webhookPort }}
|
||||
- --enable-leader-election
|
||||
- --zap-log-level={{ default 4 .Values.manager.options.logLevel }}
|
||||
- --configuration-name=default
|
||||
- --configuration-name={{ .Values.manager.options.capsuleConfiguration }}
|
||||
image: {{ include "capsule.managerFullyQualifiedDockerImage" . }}
|
||||
imagePullPolicy: {{ .Values.manager.image.pullPolicy }}
|
||||
env:
|
||||
@@ -90,4 +91,5 @@ spec:
|
||||
{{- toYaml .Values.manager.resources | nindent 12 }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{{- if eq .Values.manager.kind "Deployment" }}
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
{{- if eq .Values.manager.kind "Deployment" }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -64,7 +65,7 @@ spec:
|
||||
- --webhook-port={{ .Values.manager.webhookPort }}
|
||||
- --enable-leader-election
|
||||
- --zap-log-level={{ default 4 .Values.manager.options.logLevel }}
|
||||
- --configuration-name=default
|
||||
- --configuration-name={{ .Values.manager.options.capsuleConfiguration }}
|
||||
image: {{ include "capsule.managerFullyQualifiedDockerImage" . }}
|
||||
imagePullPolicy: {{ .Values.manager.image.pullPolicy }}
|
||||
env:
|
||||
@@ -91,4 +92,5 @@ spec:
|
||||
{{- toYaml .Values.manager.resources | nindent 12 }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
@@ -18,3 +19,4 @@ spec:
|
||||
{{- include "capsule.selectorLabels" . | nindent 4 }}
|
||||
sessionAffinity: None
|
||||
type: ClusterIP
|
||||
{{- end }}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{{- if or (not $.Values.crds.exclusive) ($.Values.webhooks.exclusive) }}
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: MutatingWebhookConfiguration
|
||||
metadata:
|
||||
@@ -12,19 +13,13 @@ metadata:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
webhooks:
|
||||
{{- with .Values.webhooks.defaults.pods }}
|
||||
{{- with .Values.webhooks.hooks.defaults.pods }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
{{- if not $.Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" $ }}-webhook-service
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
path: /defaults
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/defaults" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
name: pod.defaults.capsule.clastix.io
|
||||
name: pod.defaults.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -34,23 +29,19 @@ webhooks:
|
||||
- CREATE
|
||||
resources:
|
||||
- pods
|
||||
scope: "Namespaced"
|
||||
namespaceSelector:
|
||||
{{- toYaml .namespaceSelector | nindent 4}}
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ $.Values.webhooks.mutatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.defaults.pvc }}
|
||||
{{- with .Values.webhooks.hooks.defaults.pvc }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
{{- if not $.Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" $ }}-webhook-service
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
path: /defaults
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/defaults" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
name: storage.defaults.capsule.clastix.io
|
||||
name: storage.defaults.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -60,23 +51,19 @@ webhooks:
|
||||
- CREATE
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
scope: "Namespaced"
|
||||
namespaceSelector:
|
||||
{{- toYaml .namespaceSelector | nindent 4}}
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ $.Values.webhooks.mutatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.defaults.ingress }}
|
||||
{{- with .Values.webhooks.hooks.defaults.ingress }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
{{- if not $.Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" $ }}-webhook-service
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
path: /defaults
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/defaults" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
name: ingress.defaults.capsule.clastix.io
|
||||
name: ingress.defaults.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- networking.k8s.io
|
||||
@@ -88,25 +75,21 @@ webhooks:
|
||||
- UPDATE
|
||||
resources:
|
||||
- ingresses
|
||||
scope: "Namespaced"
|
||||
namespaceSelector:
|
||||
{{- toYaml .namespaceSelector | nindent 4}}
|
||||
sideEffects: None
|
||||
{{- end }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.mutatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.hooks.namespaceOwnerReference }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" . }}-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /namespace-owner-reference
|
||||
port: 443
|
||||
failurePolicy: {{ .Values.webhooks.namespaceOwnerReference.failurePolicy }}
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/namespace-owner-reference" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
matchPolicy: Equivalent
|
||||
name: owner.namespace.capsule.clastix.io
|
||||
name: owner.namespace.projectcapsule.dev
|
||||
namespaceSelector: {}
|
||||
objectSelector: {}
|
||||
reinvocationPolicy: Never
|
||||
@@ -122,4 +105,6 @@ webhooks:
|
||||
- namespaces
|
||||
scope: '*'
|
||||
sideEffects: NoneOnDryRun
|
||||
timeoutSeconds: {{ .Values.mutatingWebhooksTimeoutSeconds }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.mutatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
{{- if .Values.podSecurityPolicy.enabled }}
|
||||
kind: PodSecurityPolicy
|
||||
apiVersion: policy/v1beta1
|
||||
metadata:
|
||||
name: {{ include "capsule.fullname" . }}
|
||||
labels:
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
{{- with .Values.customAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
fsGroup:
|
||||
rule: RunAsAny
|
||||
hostPorts:
|
||||
- max: 0
|
||||
min: 0
|
||||
runAsUser:
|
||||
rule: RunAsAny
|
||||
seLinux:
|
||||
rule: RunAsAny
|
||||
supplementalGroups:
|
||||
rule: RunAsAny
|
||||
volumes:
|
||||
- secret
|
||||
---
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: {{ include "capsule.fullname" . }}-use-psp
|
||||
labels:
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- podsecuritypolicies
|
||||
resourceNames:
|
||||
- {{ include "capsule.fullname" . }}
|
||||
verbs:
|
||||
- use
|
||||
---
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: {{ include "capsule.fullname" . }}-use-psp
|
||||
labels:
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "capsule.fullname" . }}-use-psp
|
||||
subjects:
|
||||
- apiGroup: ""
|
||||
kind: ServiceAccount
|
||||
name: {{ include "capsule.serviceAccountName" . }}
|
||||
{{- end }}
|
||||
@@ -1,55 +0,0 @@
|
||||
{{- if .Values.tls.create }}
|
||||
{{- $cmd := printf "while [ -z $$(kubectl -n $NAMESPACE get secret %s -o jsonpath='{.data.tls\\\\.crt}') ];" (include "capsule.secretTlsName" .) -}}
|
||||
{{- $cmd = printf "%s do echo 'waiting Capsule to be up and running...' && sleep 5;" $cmd -}}
|
||||
{{- $cmd = printf "%s done" $cmd -}}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-waiting-certs"
|
||||
labels:
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
# This is what defines this resource as a hook. Without this line, the
|
||||
# job is considered part of the release.
|
||||
"helm.sh/hook": post-install
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": hook-succeeded
|
||||
{{- with .Values.customAnnotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}"
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name | quote }}
|
||||
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: post-install-job
|
||||
image: {{ include "capsule.jobsFullyQualifiedDockerImage" . }}
|
||||
imagePullPolicy: {{ .Values.jobs.image.pullPolicy }}
|
||||
command: ["sh", "-c", "{{ $cmd }}"]
|
||||
env:
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
serviceAccountName: {{ include "capsule.serviceAccountName" . }}
|
||||
{{- with .Values.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
12
charts/capsule/templates/post-install/_helpers.tpl
Normal file
12
charts/capsule/templates/post-install/_helpers.tpl
Normal file
@@ -0,0 +1,12 @@
|
||||
{{- define "capsule.post-install.name" -}}
|
||||
{{- printf "%s-post-install" (include "capsule.name" $) -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "capsule.post-install.annotations" -}}
|
||||
"helm.sh/hook": post-install
|
||||
{{- end }}
|
||||
|
||||
{{- define "capsule.post-install.component" -}}
|
||||
post-install-hook
|
||||
{{- end }}
|
||||
|
||||
84
charts/capsule/templates/post-install/job.yaml
Normal file
84
charts/capsule/templates/post-install/job.yaml
Normal file
@@ -0,0 +1,84 @@
|
||||
{{- $Values := mergeOverwrite $.Values.global.jobs.kubectl $.Values.jobs -}}
|
||||
|
||||
{{- if .Values.tls.create }}
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: "{{ include "capsule.post-install.name" . }}"
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.post-install.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook-weight": "-1"
|
||||
{{- include "capsule.post-install.annotations" . | nindent 4 }}
|
||||
{{- with $Values.annotations }}
|
||||
{{- . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
backoffLimit: {{ $Values.backoffLimit }}
|
||||
{{- if ge $Values.ttlSecondsAfterFinished 0.0 }}
|
||||
ttlSecondsAfterFinished: {{ $Values.ttlSecondsAfterFinished }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.post-install.component" . | quote }}
|
||||
{{- include "capsule.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
restartPolicy: {{ $Values.restartPolicy }}
|
||||
{{- with $Values.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.priorityClassName }}
|
||||
priorityClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- with $Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "capsule.post-install.name" . }}
|
||||
containers:
|
||||
- name: post-install
|
||||
image: {{ include "capsule.jobsFullyQualifiedDockerImage" . }}
|
||||
imagePullPolicy: {{ $Values.image.pullPolicy }}
|
||||
command:
|
||||
- "sh"
|
||||
- "-c"
|
||||
- |
|
||||
set -o errexit ; set -o nounset
|
||||
while [ -z $(kubectl -n $NAMESPACE get secret {{ include "capsule.secretTlsName" $ }} -o jsonpath='{.data.tls\.crt}') ]; do
|
||||
echo 'waiting Capsule to be up and running...' && sleep 5;
|
||||
done
|
||||
env:
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
{{- with $Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- with $Values.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
44
charts/capsule/templates/post-install/rbac.yaml
Normal file
44
charts/capsule/templates/post-install/rbac.yaml
Normal file
@@ -0,0 +1,44 @@
|
||||
{{- if .Values.tls.create }}
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ include "capsule.post-install.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-3"
|
||||
{{- include "capsule.post-install.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.post-install.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "capsule.post-install.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-2"
|
||||
{{- include "capsule.post-install.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.post-install.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ include "capsule.post-install.name" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "capsule.post-install.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
15
charts/capsule/templates/post-install/serviceaccount.yaml
Normal file
15
charts/capsule/templates/post-install/serviceaccount.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
{{- if .Values.tls.create }}
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "capsule.post-install.name" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook-weight": "-4"
|
||||
{{- include "capsule.post-install.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.post-install.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,56 +0,0 @@
|
||||
{{- $cmd := ""}}
|
||||
{{- if or (.Values.tls.create) (.Values.certManager.generateCertificates) }}
|
||||
{{- $cmd = printf "%s kubectl delete secret -n $NAMESPACE %s --ignore-not-found &&" $cmd (include "capsule.secretTlsName" .) -}}
|
||||
{{- end }}
|
||||
{{- $cmd = printf "%s kubectl delete clusterroles.rbac.authorization.k8s.io capsule-namespace-deleter capsule-namespace-provisioner --ignore-not-found &&" $cmd -}}
|
||||
{{- $cmd = printf "%s kubectl delete clusterrolebindings.rbac.authorization.k8s.io capsule-namespace-deleter capsule-namespace-provisioner --ignore-not-found" $cmd -}}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-rbac-cleaner"
|
||||
labels:
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
# This is what defines this resource as a hook. Without this line, the
|
||||
# job is considered part of the release.
|
||||
"helm.sh/hook": pre-delete
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": hook-succeeded
|
||||
{{- with .Values.customAnnotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}"
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name | quote }}
|
||||
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: pre-delete-job
|
||||
image: {{ include "capsule.jobsFullyQualifiedDockerImage" . }}
|
||||
imagePullPolicy: {{ .Values.jobs.image.pullPolicy }}
|
||||
command: [ "sh", "-c", "{{ $cmd }}"]
|
||||
env:
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
serviceAccountName: {{ include "capsule.serviceAccountName" . }}
|
||||
{{- with .Values.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
15
charts/capsule/templates/pre-delete/_helpers.tpl
Normal file
15
charts/capsule/templates/pre-delete/_helpers.tpl
Normal file
@@ -0,0 +1,15 @@
|
||||
{{- define "capsule.pre-delete.name" -}}
|
||||
{{- printf "%s-pre-delete" (include "capsule.name" $) -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "capsule.pre-delete.annotations" -}}
|
||||
"helm.sh/hook": pre-delete
|
||||
{{- with $.Values.jobs.annotations }}
|
||||
{{- . | toYaml | nindent 0 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "capsule.pre-delete.component" -}}
|
||||
pre-delete-hook
|
||||
{{- end }}
|
||||
|
||||
85
charts/capsule/templates/pre-delete/job.yaml
Normal file
85
charts/capsule/templates/pre-delete/job.yaml
Normal file
@@ -0,0 +1,85 @@
|
||||
{{- $Values := mergeOverwrite $.Values.global.jobs.kubectl $.Values.jobs -}}
|
||||
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: "{{ include "capsule.pre-delete.name" $ }}"
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.pre-delete.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook-weight": "-1"
|
||||
{{- include "capsule.pre-delete.annotations" . | nindent 4 }}
|
||||
{{- with $Values.annotations }}
|
||||
{{- . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
backoffLimit: {{ $Values.backoffLimit }}
|
||||
{{- if ge $Values.ttlSecondsAfterFinished 0.0 }}
|
||||
ttlSecondsAfterFinished: {{ $Values.ttlSecondsAfterFinished }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.pre-delete.component" . | quote }}
|
||||
{{- include "capsule.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
restartPolicy: {{ $Values.restartPolicy }}
|
||||
{{- with $Values.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $Values.priorityClassName }}
|
||||
priorityClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- with $Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "capsule.pre-delete.name" . }}
|
||||
containers:
|
||||
- name: pre-delete-job
|
||||
image: {{ include "capsule.jobsFullyQualifiedDockerImage" . }}
|
||||
imagePullPolicy: {{ $Values.image.pullPolicy }}
|
||||
command:
|
||||
- "/bin/sh"
|
||||
- "-c"
|
||||
- |
|
||||
set -o errexit ; set -o xtrace ; set -o nounset
|
||||
{{- if or (.Values.tls.create) (.Values.certManager.generateCertificates) }}
|
||||
kubectl delete secret -n $NAMESPACE {{ include "capsule.secretTlsName" $ }} --ignore-not-found
|
||||
{{- end }}
|
||||
kubectl delete clusterroles.rbac.authorization.k8s.io capsule-namespace-deleter capsule-namespace-provisioner --ignore-not-found
|
||||
kubectl delete clusterrolebindings.rbac.authorization.k8s.io capsule-namespace-deleter capsule-namespace-provisioner --ignore-not-found
|
||||
env:
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
{{- with $Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $Values.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
90
charts/capsule/templates/pre-delete/rbac.yaml
Normal file
90
charts/capsule/templates/pre-delete/rbac.yaml
Normal file
@@ -0,0 +1,90 @@
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "capsule.pre-delete.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-3"
|
||||
{{- include "capsule.pre-delete.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.pre-delete.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- rbac.authorization.k8s.io
|
||||
resourceNames:
|
||||
- capsule-namespace-deleter
|
||||
- capsule-namespace-provisioner
|
||||
resources:
|
||||
- clusterroles
|
||||
- clusterrolebindings
|
||||
verbs:
|
||||
- delete
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ include "capsule.pre-delete.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-3"
|
||||
{{- include "capsule.pre-delete.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.pre-delete.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- delete
|
||||
resourceNames:
|
||||
- {{ include "capsule.secretTlsName" $ }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "capsule.pre-delete.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-2"
|
||||
{{- include "capsule.pre-delete.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.pre-delete.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "capsule.pre-delete.name" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "capsule.pre-delete.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "capsule.pre-delete.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
annotations:
|
||||
# create hook dependencies in the right order
|
||||
"helm.sh/hook-weight": "-2"
|
||||
{{- include "capsule.pre-delete.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.pre-delete.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ include "capsule.pre-delete.name" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "capsule.pre-delete.name" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
{{- end }}
|
||||
14
charts/capsule/templates/pre-delete/serviceaccount.yaml
Normal file
14
charts/capsule/templates/pre-delete/serviceaccount.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "capsule.pre-delete.name" . }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook-weight": "-4"
|
||||
{{- include "capsule.pre-delete.annotations" . | nindent 4 }}
|
||||
labels:
|
||||
app.kubernetes.io/component: {{ include "capsule.pre-delete.component" . | quote }}
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -1,4 +1,5 @@
|
||||
{{- if $.Values.manager.rbac.create }}
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
{{- if $.Values.manager.rbac.create }}
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
@@ -18,8 +19,8 @@ subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "capsule.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
{{- range $_, $cr := $.Values.manager.rbac.existingClusterRoles }}
|
||||
{{- end }}
|
||||
{{- range $_, $cr := $.Values.manager.rbac.existingClusterRoles }}
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
@@ -60,4 +61,5 @@ subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "capsule.serviceAccountName" $ }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "capsule.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "capsule.labels" . | nindent 4 }}
|
||||
{{- if or (.Values.serviceAccount.annotations) (.Values.customAnnotations) }}
|
||||
{{- if or (.Values.serviceAccount.annotations) (.Values.customAnnotations) }}
|
||||
annotations:
|
||||
{{- include "capsule.serviceAccountAnnotations" . | nindent 4 }}
|
||||
{{- include "capsule.serviceAccountAnnotations" . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{{- if .Values.serviceMonitor.enabled }}
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
{{- if .Values.serviceMonitor.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
@@ -43,5 +44,6 @@ spec:
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{{- if or (not $.Values.crds.exclusive) ($.Values.webhooks.exclusive) }}
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
@@ -12,23 +13,17 @@ metadata:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
webhooks:
|
||||
{{- with .Values.webhooks.hooks.cordoning }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" . }}-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /cordoning
|
||||
port: 443
|
||||
failurePolicy: {{ .Values.webhooks.cordoning.failurePolicy }}
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/cordoning" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
matchPolicy: Equivalent
|
||||
name: cordoning.tenant.capsule.clastix.io
|
||||
name: cordoning.tenant.projectcapsule.dev
|
||||
namespaceSelector:
|
||||
{{- toYaml .Values.webhooks.cordoning.namespaceSelector | nindent 4}}
|
||||
{{- toYaml .namespaceSelector | nindent 4}}
|
||||
objectSelector: {}
|
||||
rules:
|
||||
- apiGroups:
|
||||
@@ -43,24 +38,19 @@ webhooks:
|
||||
- '*'
|
||||
scope: Namespaced
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ .Values.validatingWebhooksTimeoutSeconds }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.validatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.hooks.ingresses }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" . }}-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /ingresses
|
||||
port: 443
|
||||
failurePolicy: {{ .Values.webhooks.ingresses.failurePolicy }}
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/ingresses" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
matchPolicy: Equivalent
|
||||
name: ingress.capsule.clastix.io
|
||||
name: ingress.projectcapsule.dev
|
||||
namespaceSelector:
|
||||
{{- toYaml .Values.webhooks.ingresses.namespaceSelector | nindent 4}}
|
||||
{{- toYaml .namespaceSelector | nindent 4}}
|
||||
objectSelector: {}
|
||||
rules:
|
||||
- apiGroups:
|
||||
@@ -76,22 +66,17 @@ webhooks:
|
||||
- ingresses
|
||||
scope: Namespaced
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ .Values.validatingWebhooksTimeoutSeconds }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.validatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{ with .Values.webhooks.hooks.namespaces }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" . }}-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /namespaces
|
||||
port: 443
|
||||
failurePolicy: {{ .Values.webhooks.namespaces.failurePolicy }}
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/namespaces" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
matchPolicy: Equivalent
|
||||
name: namespaces.capsule.clastix.io
|
||||
name: namespaces.projectcapsule.dev
|
||||
namespaceSelector: {}
|
||||
objectSelector: {}
|
||||
rules:
|
||||
@@ -107,24 +92,19 @@ webhooks:
|
||||
- namespaces
|
||||
scope: '*'
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ .Values.validatingWebhooksTimeoutSeconds }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.validatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.hooks.networkpolicies }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" . }}-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /networkpolicies
|
||||
port: 443
|
||||
failurePolicy: {{ .Values.webhooks.networkpolicies.failurePolicy }}
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/networkpolicies" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
matchPolicy: Equivalent
|
||||
name: networkpolicies.capsule.clastix.io
|
||||
name: networkpolicies.projectcapsule.dev
|
||||
namespaceSelector:
|
||||
{{- toYaml .Values.webhooks.networkpolicies.namespaceSelector | nindent 4}}
|
||||
{{- toYaml .namespaceSelector | nindent 4}}
|
||||
objectSelector: {}
|
||||
rules:
|
||||
- apiGroups:
|
||||
@@ -138,21 +118,16 @@ webhooks:
|
||||
- networkpolicies
|
||||
scope: Namespaced
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ .Values.validatingWebhooksTimeoutSeconds }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.validatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.hooks.nodes }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" . }}-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /nodes
|
||||
port: 443
|
||||
failurePolicy: {{ .Values.webhooks.nodes.failurePolicy }}
|
||||
name: nodes.capsule.clastix.io
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/nodes" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
name: nodes.projectcapsule.dev
|
||||
matchPolicy: Exact
|
||||
namespaceSelector: {}
|
||||
objectSelector: {}
|
||||
@@ -166,24 +141,19 @@ webhooks:
|
||||
resources:
|
||||
- nodes
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ .Values.validatingWebhooksTimeoutSeconds }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.validatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.hooks.pods }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" . }}-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /pods
|
||||
port: 443
|
||||
failurePolicy: {{ .Values.webhooks.pods.failurePolicy }}
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/pods" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
matchPolicy: Exact
|
||||
name: pods.capsule.clastix.io
|
||||
name: pods.projectcapsule.dev
|
||||
namespaceSelector:
|
||||
{{- toYaml .Values.webhooks.pods.namespaceSelector | nindent 4}}
|
||||
{{- toYaml .namespaceSelector | nindent 4}}
|
||||
objectSelector: {}
|
||||
rules:
|
||||
- apiGroups:
|
||||
@@ -197,22 +167,18 @@ webhooks:
|
||||
- pods
|
||||
scope: Namespaced
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ .Values.validatingWebhooksTimeoutSeconds }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.validatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.hooks.persistentvolumeclaims }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" . }}-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /persistentvolumeclaims
|
||||
failurePolicy: {{ .Values.webhooks.persistentvolumeclaims.failurePolicy }}
|
||||
name: pvc.capsule.clastix.io
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/persistentvolumeclaims" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
name: pvc.projectcapsule.dev
|
||||
namespaceSelector:
|
||||
{{- toYaml .Values.webhooks.persistentvolumeclaims.namespaceSelector | nindent 4}}
|
||||
{{- toYaml .namespaceSelector | nindent 4}}
|
||||
objectSelector: {}
|
||||
rules:
|
||||
- apiGroups:
|
||||
@@ -225,24 +191,19 @@ webhooks:
|
||||
- persistentvolumeclaims
|
||||
scope: Namespaced
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ .Values.validatingWebhooksTimeoutSeconds }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.validatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.hooks.services }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" . }}-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /services
|
||||
port: 443
|
||||
failurePolicy: {{ .Values.webhooks.services.failurePolicy }}
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/services" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
matchPolicy: Exact
|
||||
name: services.capsule.clastix.io
|
||||
name: services.projectcapsule.dev
|
||||
namespaceSelector:
|
||||
{{- toYaml .Values.webhooks.services.namespaceSelector | nindent 4}}
|
||||
{{- toYaml .namespaceSelector | nindent 4}}
|
||||
objectSelector: {}
|
||||
rules:
|
||||
- apiGroups:
|
||||
@@ -256,19 +217,15 @@ webhooks:
|
||||
- services
|
||||
scope: Namespaced
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ .Values.validatingWebhooksTimeoutSeconds }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.validatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.hooks.tenantResourceObjects }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: capsule-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /tenantresource-objects
|
||||
failurePolicy: {{ .Values.webhooks.tenantResourceObjects.failurePolicy }}
|
||||
name: resource-objects.tenant.capsule.clastix.io
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/tenantresource-objects" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
name: resource-objects.tenant.projectcapsule.dev
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
@@ -289,21 +246,17 @@ webhooks:
|
||||
- '*'
|
||||
scope: Namespaced
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ $.Values.webhooks.validatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhooks.hooks.tenants }}
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
- v1beta1
|
||||
clientConfig:
|
||||
{{- if not .Values.certManager.generateCertificates }}
|
||||
caBundle: Cg==
|
||||
{{- end }}
|
||||
service:
|
||||
name: {{ include "capsule.fullname" . }}-webhook-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /tenants
|
||||
port: 443
|
||||
failurePolicy: {{ .Values.webhooks.tenants.failurePolicy }}
|
||||
{{- include "capsule.webhooks.service" (dict "path" "/tenants" "ctx" $) | nindent 4 }}
|
||||
failurePolicy: {{ .failurePolicy }}
|
||||
matchPolicy: Exact
|
||||
name: tenants.capsule.clastix.io
|
||||
name: tenants.projectcapsule.dev
|
||||
namespaceSelector: {}
|
||||
objectSelector: {}
|
||||
rules:
|
||||
@@ -319,4 +272,6 @@ webhooks:
|
||||
- tenants
|
||||
scope: '*'
|
||||
sideEffects: None
|
||||
timeoutSeconds: {{ .Values.validatingWebhooksTimeoutSeconds }}
|
||||
timeoutSeconds: {{ $.Values.webhooks.validatingWebhooksTimeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,3 +1,4 @@
|
||||
{{- if not $.Values.crds.exclusive }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
@@ -18,3 +19,4 @@ spec:
|
||||
{{- include "capsule.selectorLabels" . | nindent 4 }}
|
||||
sessionAffinity: None
|
||||
type: ClusterIP
|
||||
{{- end }}
|
||||
|
||||
794
charts/capsule/values.schema.json
Normal file
794
charts/capsule/values.schema.json
Normal file
@@ -0,0 +1,794 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"affinity": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"certManager": {
|
||||
"properties": {
|
||||
"additionalSANS": {
|
||||
"type": "array"
|
||||
},
|
||||
"generateCertificates": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"crds": {
|
||||
"properties": {
|
||||
"annnotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"exclusive": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"install": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"labels": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"customAnnotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"customLabels": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"fullnameOverride": {
|
||||
"type": "string"
|
||||
},
|
||||
"global": {
|
||||
"properties": {
|
||||
"jobs": {
|
||||
"properties": {
|
||||
"kubectl": {
|
||||
"properties": {
|
||||
"affinity": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"annotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"backoffLimit": {
|
||||
"type": "integer"
|
||||
},
|
||||
"image": {
|
||||
"properties": {
|
||||
"pullPolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"registry": {
|
||||
"type": "string"
|
||||
},
|
||||
"repository": {
|
||||
"type": "string"
|
||||
},
|
||||
"tag": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"imagePullSecrets": {
|
||||
"type": "array"
|
||||
},
|
||||
"nodeSelector": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"podSecurityContext": {
|
||||
"properties": {
|
||||
"seccompProfile": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"priorityClassName": {
|
||||
"type": "string"
|
||||
},
|
||||
"resources": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"restartPolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"securityContext": {
|
||||
"properties": {
|
||||
"allowPrivilegeEscalation": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"capabilities": {
|
||||
"properties": {
|
||||
"drop": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"readOnlyRootFilesystem": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"runAsGroup": {
|
||||
"type": "integer"
|
||||
},
|
||||
"runAsNonRoot": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"runAsUser": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"tolerations": {
|
||||
"type": "array"
|
||||
},
|
||||
"topologySpreadConstraints": {
|
||||
"type": "array"
|
||||
},
|
||||
"ttlSecondsAfterFinished": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"imagePullSecrets": {
|
||||
"type": "array"
|
||||
},
|
||||
"jobs": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"manager": {
|
||||
"properties": {
|
||||
"hostNetwork": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"image": {
|
||||
"properties": {
|
||||
"pullPolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"registry": {
|
||||
"type": "string"
|
||||
},
|
||||
"repository": {
|
||||
"type": "string"
|
||||
},
|
||||
"tag": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"kind": {
|
||||
"type": "string"
|
||||
},
|
||||
"livenessProbe": {
|
||||
"properties": {
|
||||
"httpGet": {
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"options": {
|
||||
"properties": {
|
||||
"capsuleConfiguration": {
|
||||
"type": "string"
|
||||
},
|
||||
"capsuleUserGroups": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"forceTenantPrefix": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"generateCertificates": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"logLevel": {
|
||||
"type": "string"
|
||||
},
|
||||
"nodeMetadata": {
|
||||
"properties": {
|
||||
"forbiddenAnnotations": {
|
||||
"properties": {
|
||||
"denied": {
|
||||
"type": "array"
|
||||
},
|
||||
"deniedRegex": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"forbiddenLabels": {
|
||||
"properties": {
|
||||
"denied": {
|
||||
"type": "array"
|
||||
},
|
||||
"deniedRegex": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"protectedNamespaceRegex": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"rbac": {
|
||||
"properties": {
|
||||
"create": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"existingClusterRoles": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"existingRoles": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"readinessProbe": {
|
||||
"properties": {
|
||||
"httpGet": {
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"resources": {
|
||||
"properties": {
|
||||
"requests": {
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"type": "string"
|
||||
},
|
||||
"memory": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"webhookPort": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"nodeSelector": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"podAnnotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"podSecurityContext": {
|
||||
"properties": {
|
||||
"runAsGroup": {
|
||||
"type": "integer"
|
||||
},
|
||||
"runAsNonRoot": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"runAsUser": {
|
||||
"type": "integer"
|
||||
},
|
||||
"seccompProfile": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"priorityClassName": {
|
||||
"type": "string"
|
||||
},
|
||||
"proxy": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"replicaCount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"securityContext": {
|
||||
"properties": {
|
||||
"allowPrivilegeEscalation": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"capabilities": {
|
||||
"properties": {
|
||||
"drop": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"readOnlyRootFilesystem": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"serviceAccount": {
|
||||
"properties": {
|
||||
"annotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"create": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"serviceMonitor": {
|
||||
"properties": {
|
||||
"annotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"endpoint": {
|
||||
"properties": {
|
||||
"interval": {
|
||||
"type": "string"
|
||||
},
|
||||
"metricRelabelings": {
|
||||
"type": "array"
|
||||
},
|
||||
"relabelings": {
|
||||
"type": "array"
|
||||
},
|
||||
"scrapeTimeout": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"labels": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"matchLabels": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"namespace": {
|
||||
"type": "string"
|
||||
},
|
||||
"targetLabels": {
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"tls": {
|
||||
"properties": {
|
||||
"create": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enableController": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"tolerations": {
|
||||
"type": "array"
|
||||
},
|
||||
"topologySpreadConstraints": {
|
||||
"type": "array"
|
||||
},
|
||||
"webhooks": {
|
||||
"properties": {
|
||||
"exclusive": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"hooks": {
|
||||
"properties": {
|
||||
"cordoning": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespaceSelector": {
|
||||
"properties": {
|
||||
"matchExpressions": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"defaults": {
|
||||
"properties": {
|
||||
"ingress": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespaceSelector": {
|
||||
"properties": {
|
||||
"matchExpressions": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"pods": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespaceSelector": {
|
||||
"properties": {
|
||||
"matchExpressions": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"pvc": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespaceSelector": {
|
||||
"properties": {
|
||||
"matchExpressions": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ingresses": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespaceSelector": {
|
||||
"properties": {
|
||||
"matchExpressions": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"namespaceOwnerReference": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"namespaces": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"networkpolicies": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespaceSelector": {
|
||||
"properties": {
|
||||
"matchExpressions": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"nodes": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"persistentvolumeclaims": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespaceSelector": {
|
||||
"properties": {
|
||||
"matchExpressions": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"pods": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespaceSelector": {
|
||||
"properties": {
|
||||
"matchExpressions": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"services": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespaceSelector": {
|
||||
"properties": {
|
||||
"matchExpressions": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"operator": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"tenantResourceObjects": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"tenants": {
|
||||
"properties": {
|
||||
"failurePolicy": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"mutatingWebhooksTimeoutSeconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"service": {
|
||||
"properties": {
|
||||
"caBundle": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespace": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "null"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"validatingWebhooksTimeoutSeconds": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
@@ -2,6 +2,66 @@
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
global:
|
||||
jobs:
|
||||
kubectl:
|
||||
image:
|
||||
# -- Set the image repository of the helm chart job
|
||||
registry: docker.io
|
||||
# -- Set the image repository of the helm chart job
|
||||
repository: clastix/kubectl
|
||||
# -- Set the image pull policy of the helm chart job
|
||||
pullPolicy: IfNotPresent
|
||||
# -- Set the image tag of the helm chart job
|
||||
tag: ""
|
||||
# -- ImagePullSecrets
|
||||
imagePullSecrets: []
|
||||
# -- Annotations to add to the certgen job.
|
||||
annotations: {}
|
||||
# -- Set the restartPolicy
|
||||
restartPolicy: Never
|
||||
# -- Sets the ttl in seconds after a finished certgen job is deleted. Set to -1 to never delete.
|
||||
ttlSecondsAfterFinished: 60
|
||||
# -- Security context for the job pods.
|
||||
podSecurityContext:
|
||||
seccompProfile:
|
||||
type: "RuntimeDefault"
|
||||
# -- Security context for the job containers.
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1002
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1002
|
||||
# -- Job resources
|
||||
resources: {}
|
||||
# -- Set the node selector
|
||||
nodeSelector: {}
|
||||
# -- Set list of tolerations
|
||||
tolerations: []
|
||||
# -- Set affinity rules
|
||||
affinity: {}
|
||||
# -- Set Topology Spread Constraints
|
||||
topologySpreadConstraints: []
|
||||
# -- Set a pod priorityClassName
|
||||
priorityClassName: ""
|
||||
# -- Backofflimit for jobs
|
||||
backoffLimit: 4
|
||||
|
||||
# Manage CRD Lifecycle
|
||||
crds:
|
||||
# -- Install the CustomResourceDefinitions (This also manages the lifecycle of the CRDs for update operations)
|
||||
install: true
|
||||
# -- Only install the CRDs, no other primitives
|
||||
exclusive: false
|
||||
# -- Extra Labels for CRDs
|
||||
labels: {}
|
||||
# -- Extra Annotations for CRDs
|
||||
annnotations: {}
|
||||
|
||||
# Secret Options
|
||||
tls:
|
||||
# -- Start the Capsule controller that injects the CA into mutating and validating webhooks, and CRD as well.
|
||||
@@ -11,6 +71,11 @@ tls:
|
||||
# -- Override name of the Capsule TLS Secret name when externally managed.
|
||||
name: ""
|
||||
|
||||
# Capsule Proxy
|
||||
proxy:
|
||||
# -- Enable Installation of Capsule Proxy
|
||||
enabled: false
|
||||
|
||||
# Manager Options
|
||||
manager:
|
||||
|
||||
@@ -54,12 +119,14 @@ manager:
|
||||
|
||||
# Additional Capsule Controller Options
|
||||
options:
|
||||
# -- Change the default name of the capsule configuration name
|
||||
capsuleConfiguration: default
|
||||
# -- Set the log verbosity of the capsule with a value from 1 to 10
|
||||
logLevel: '4'
|
||||
# -- Boolean, enforces the Tenant owner, during Namespace creation, to name it using the selected Tenant name as prefix, separated by a dash
|
||||
forceTenantPrefix: false
|
||||
# -- Override the Capsule user groups
|
||||
capsuleUserGroups: ["capsule.clastix.io"]
|
||||
capsuleUserGroups: ["projectcapsule.dev"]
|
||||
# -- If specified, disallows creation of namespaces matching the passed regexp
|
||||
protectedNamespaceRegex: ""
|
||||
# -- Specifies whether capsule webhooks certificates should be generated by capsule operator
|
||||
@@ -85,13 +152,8 @@ manager:
|
||||
path: /readyz
|
||||
port: 10080
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
# -- Set the resource requests/limits for the Capsule manager container
|
||||
resources: {}
|
||||
|
||||
# -- Configuration for `imagePullSecrets` so that you can use a private images registry.
|
||||
imagePullSecrets: []
|
||||
@@ -142,20 +204,8 @@ affinity: {}
|
||||
# -- Set topology spread constraints for the Capsule pod
|
||||
topologySpreadConstraints: []
|
||||
|
||||
podSecurityPolicy:
|
||||
# -- Specify if a Pod Security Policy must be created
|
||||
enabled: false
|
||||
|
||||
jobs:
|
||||
image:
|
||||
# -- Set the image repository of the helm chart job
|
||||
registry: docker.io
|
||||
# -- Set the image repository of the helm chart job
|
||||
repository: clastix/kubectl
|
||||
# -- Set the image pull policy of the helm chart job
|
||||
pullPolicy: IfNotPresent
|
||||
# -- Set the image tag of the helm chart job
|
||||
tag: ""
|
||||
# -- Deprecated, use .global.jobs.kubectl instead
|
||||
jobs: {}
|
||||
|
||||
# ServiceAccount
|
||||
serviceAccount:
|
||||
@@ -164,12 +214,13 @@ serviceAccount:
|
||||
# -- Annotations to add to the service account.
|
||||
annotations: {}
|
||||
# -- The name of the service account to use. If not set and `serviceAccount.create=true`, a name is generated using the fullname template
|
||||
name: "capsule"
|
||||
name: ""
|
||||
|
||||
certManager:
|
||||
# -- Specifies whether capsule webhooks certificates should be generated using cert-manager
|
||||
generateCertificates: false
|
||||
|
||||
# -- Specify additional SANS to add to the certificate
|
||||
additionalSANS: []
|
||||
# -- Additional labels which will be added to all resources created by Capsule helm chart
|
||||
customLabels: {}
|
||||
|
||||
@@ -178,60 +229,45 @@ customAnnotations: {}
|
||||
|
||||
# Webhooks configurations
|
||||
webhooks:
|
||||
namespaceOwnerReference:
|
||||
failurePolicy: Fail
|
||||
cordoning:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
ingresses:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
namespaces:
|
||||
failurePolicy: Fail
|
||||
networkpolicies:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
pods:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
persistentvolumeclaims:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
tenants:
|
||||
failurePolicy: Fail
|
||||
tenantResourceObjects:
|
||||
failurePolicy: Fail
|
||||
services:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
nodes:
|
||||
failurePolicy: Fail
|
||||
defaults:
|
||||
ingress:
|
||||
# -- When `crds.exclusive` is `true` the webhooks will be installed
|
||||
exclusive: false
|
||||
# -- Timeout in seconds for mutating webhooks
|
||||
mutatingWebhooksTimeoutSeconds: 30
|
||||
# -- Timeout in seconds for validating webhooks
|
||||
validatingWebhooksTimeoutSeconds: 30
|
||||
|
||||
# Configure custom webhook service
|
||||
service:
|
||||
# -- The URL where the capsule webhook services are running (Overwrites cluster scoped service definition)
|
||||
url: ""
|
||||
# -- CABundle for the webhook service
|
||||
caBundle: ""
|
||||
# -- Custom service name for the webhook service
|
||||
name: ""
|
||||
# -- Custom service namespace for the webhook service
|
||||
namespace: ""
|
||||
# -- Custom service port for the webhook service
|
||||
port:
|
||||
|
||||
# Hook Configuration
|
||||
hooks:
|
||||
namespaceOwnerReference:
|
||||
failurePolicy: Fail
|
||||
cordoning:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
pvc:
|
||||
ingresses:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
namespaces:
|
||||
failurePolicy: Fail
|
||||
networkpolicies:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
@@ -243,12 +279,43 @@ webhooks:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
|
||||
|
||||
# -- Timeout in seconds for mutating webhooks
|
||||
mutatingWebhooksTimeoutSeconds: 30
|
||||
# -- Timeout in seconds for validating webhooks
|
||||
validatingWebhooksTimeoutSeconds: 30
|
||||
persistentvolumeclaims:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
tenants:
|
||||
failurePolicy: Fail
|
||||
tenantResourceObjects:
|
||||
failurePolicy: Fail
|
||||
services:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
nodes:
|
||||
failurePolicy: Fail
|
||||
defaults:
|
||||
ingress:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
pvc:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
pods:
|
||||
failurePolicy: Fail
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: capsule.clastix.io/tenant
|
||||
operator: Exists
|
||||
|
||||
# ServiceMonitor
|
||||
serviceMonitor:
|
||||
|
||||
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.10.0
|
||||
creationTimestamp: null
|
||||
controller-gen.kubebuilder.io/version: v0.15.0
|
||||
name: capsuleconfigurations.capsule.clastix.io
|
||||
spec:
|
||||
group: capsule.clastix.io
|
||||
@@ -22,14 +21,19 @@ spec:
|
||||
API.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -38,23 +42,20 @@ spec:
|
||||
properties:
|
||||
enableTLSReconciler:
|
||||
default: true
|
||||
description: Toggles the TLS reconciler, the controller that is able
|
||||
to generate CA and certificates for the webhooks when not using
|
||||
an already provided CA and certificate, or when these are managed
|
||||
externally with Vault, or cert-manager.
|
||||
description: |-
|
||||
Toggles the TLS reconciler, the controller that is able to generate CA and certificates for the webhooks
|
||||
when not using an already provided CA and certificate, or when these are managed externally with Vault, or cert-manager.
|
||||
type: boolean
|
||||
forceTenantPrefix:
|
||||
default: false
|
||||
description: Enforces the Tenant owner, during Namespace creation,
|
||||
to name it using the selected Tenant name as prefix, separated by
|
||||
a dash. This is useful to avoid Namespace name collision in a public
|
||||
CaaS environment.
|
||||
description: |-
|
||||
Enforces the Tenant owner, during Namespace creation, to name it using the selected Tenant name as prefix,
|
||||
separated by a dash. This is useful to avoid Namespace name collision in a public CaaS environment.
|
||||
type: boolean
|
||||
nodeMetadata:
|
||||
description: Allows to set the forbidden metadata for the worker nodes
|
||||
that could be patched by a Tenant. This applies only if the Tenant
|
||||
has an active NodeSelector, and the Owner have right to patch their
|
||||
nodes.
|
||||
description: |-
|
||||
Allows to set the forbidden metadata for the worker nodes that could be patched by a Tenant.
|
||||
This applies only if the Tenant has an active NodeSelector, and the Owner have right to patch their nodes.
|
||||
properties:
|
||||
forbiddenAnnotations:
|
||||
description: Define the annotations that a Tenant Owner cannot
|
||||
@@ -87,15 +88,15 @@ spec:
|
||||
TLSSecretName: capsule-tls
|
||||
mutatingWebhookConfigurationName: capsule-mutating-webhook-configuration
|
||||
validatingWebhookConfigurationName: capsule-validating-webhook-configuration
|
||||
description: Allows to set different name rather than the canonical
|
||||
one for the Capsule configuration objects, such as webhook secret
|
||||
or configurations.
|
||||
description: |-
|
||||
Allows to set different name rather than the canonical one for the Capsule configuration objects,
|
||||
such as webhook secret or configurations.
|
||||
properties:
|
||||
TLSSecretName:
|
||||
default: capsule-tls
|
||||
description: Defines the Secret name used for the webhook server.
|
||||
Must be in the same Namespace where the Capsule Deployment is
|
||||
deployed.
|
||||
description: |-
|
||||
Defines the Secret name used for the webhook server.
|
||||
Must be in the same Namespace where the Capsule Deployment is deployed.
|
||||
type: string
|
||||
mutatingWebhookConfigurationName:
|
||||
default: capsule-mutating-webhook-configuration
|
||||
|
||||
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.10.0
|
||||
creationTimestamp: null
|
||||
controller-gen.kubebuilder.io/version: v0.15.0
|
||||
name: globaltenantresources.capsule.clastix.io
|
||||
spec:
|
||||
group: capsule.clastix.io
|
||||
@@ -22,14 +21,19 @@ spec:
|
||||
to a specific subset of Tenant resources.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -38,10 +42,9 @@ spec:
|
||||
properties:
|
||||
pruningOnDelete:
|
||||
default: true
|
||||
description: When the replicated resource manifest is deleted, all
|
||||
the objects replicated so far will be automatically deleted. Disable
|
||||
this to keep replicated resources although the deletion of the replication
|
||||
manifest.
|
||||
description: |-
|
||||
When the replicated resource manifest is deleted, all the objects replicated so far will be automatically deleted.
|
||||
Disable this to keep replicated resources although the deletion of the replication manifest.
|
||||
type: boolean
|
||||
resources:
|
||||
description: Defines the rules to select targeting Namespace, along
|
||||
@@ -49,9 +52,9 @@ spec:
|
||||
items:
|
||||
properties:
|
||||
additionalMetadata:
|
||||
description: Besides the Capsule metadata required by TenantResource
|
||||
controller, defines additional metadata that must be added
|
||||
to the replicated resources.
|
||||
description: |-
|
||||
Besides the Capsule metadata required by TenantResource controller, defines additional metadata that must be
|
||||
added to the replicated resources.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
@@ -63,49 +66,50 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: Defines the Namespace selector to select the Tenant
|
||||
Namespaces on which the resources must be propagated. In case
|
||||
of nil value, all the Tenant Namespaces are targeted.
|
||||
description: |-
|
||||
Defines the Namespace selector to select the Tenant Namespaces on which the resources must be propagated.
|
||||
In case of nil value, all the Tenant Namespaces are targeted.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
@@ -118,10 +122,14 @@ spec:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
selector:
|
||||
description: Label selector used to select the given resources
|
||||
@@ -131,8 +139,8 @@ spec:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
@@ -140,33 +148,33 @@ spec:
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In,
|
||||
NotIn, Exists and DoesNotExist.
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values
|
||||
array must be non-empty. If the operator is
|
||||
Exists or DoesNotExist, the values array must
|
||||
be empty. This array is replaced during a
|
||||
strategic merge patch.
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field
|
||||
is "key", the operator is "In", and the values array
|
||||
contains only "value". The requirements are ANDed.
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
@@ -187,9 +195,9 @@ spec:
|
||||
type: array
|
||||
resyncPeriod:
|
||||
default: 60s
|
||||
description: Define the period of time upon a second reconciliation
|
||||
must be invoked. Keep in mind that any change to the manifests will
|
||||
trigger a new reconciliation.
|
||||
description: |-
|
||||
Define the period of time upon a second reconciliation must be invoked.
|
||||
Keep in mind that any change to the manifests will trigger a new reconciliation.
|
||||
type: string
|
||||
tenantSelector:
|
||||
description: Defines the Tenant selector used target the tenants on
|
||||
@@ -199,41 +207,42 @@ spec:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that
|
||||
contains values, a key, and an operator that relates the key
|
||||
and values.
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to
|
||||
a set of values. Valid operators are In, NotIn, Exists
|
||||
and DoesNotExist.
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the
|
||||
operator is In or NotIn, the values array must be non-empty.
|
||||
If the operator is Exists or DoesNotExist, the values
|
||||
array must be empty. This array is replaced during a strategic
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single
|
||||
{key,value} in the matchLabels map is equivalent to an element
|
||||
of matchExpressions, whose key field is "key", the operator
|
||||
is "In", and the values array contains only "value". The requirements
|
||||
are ANDed.
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
@@ -253,13 +262,19 @@ spec:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
|
||||
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.10.0
|
||||
creationTimestamp: null
|
||||
controller-gen.kubebuilder.io/version: v0.15.0
|
||||
name: tenantresources.capsule.clastix.io
|
||||
spec:
|
||||
group: capsule.clastix.io
|
||||
@@ -18,20 +17,25 @@ spec:
|
||||
- name: v1beta2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: TenantResource allows a Tenant Owner, if enabled with proper
|
||||
RBAC, to propagate resources in its Namespace. The object must be deployed
|
||||
in a Tenant Namespace, and cannot reference object living in non-Tenant
|
||||
namespaces. For such cases, the GlobalTenantResource must be used.
|
||||
description: |-
|
||||
TenantResource allows a Tenant Owner, if enabled with proper RBAC, to propagate resources in its Namespace.
|
||||
The object must be deployed in a Tenant Namespace, and cannot reference object living in non-Tenant namespaces.
|
||||
For such cases, the GlobalTenantResource must be used.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -40,10 +44,9 @@ spec:
|
||||
properties:
|
||||
pruningOnDelete:
|
||||
default: true
|
||||
description: When the replicated resource manifest is deleted, all
|
||||
the objects replicated so far will be automatically deleted. Disable
|
||||
this to keep replicated resources although the deletion of the replication
|
||||
manifest.
|
||||
description: |-
|
||||
When the replicated resource manifest is deleted, all the objects replicated so far will be automatically deleted.
|
||||
Disable this to keep replicated resources although the deletion of the replication manifest.
|
||||
type: boolean
|
||||
resources:
|
||||
description: Defines the rules to select targeting Namespace, along
|
||||
@@ -51,9 +54,9 @@ spec:
|
||||
items:
|
||||
properties:
|
||||
additionalMetadata:
|
||||
description: Besides the Capsule metadata required by TenantResource
|
||||
controller, defines additional metadata that must be added
|
||||
to the replicated resources.
|
||||
description: |-
|
||||
Besides the Capsule metadata required by TenantResource controller, defines additional metadata that must be
|
||||
added to the replicated resources.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
@@ -65,49 +68,50 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: Defines the Namespace selector to select the Tenant
|
||||
Namespaces on which the resources must be propagated. In case
|
||||
of nil value, all the Tenant Namespaces are targeted.
|
||||
description: |-
|
||||
Defines the Namespace selector to select the Tenant Namespaces on which the resources must be propagated.
|
||||
In case of nil value, all the Tenant Namespaces are targeted.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
@@ -120,10 +124,14 @@ spec:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
selector:
|
||||
description: Label selector used to select the given resources
|
||||
@@ -133,8 +141,8 @@ spec:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
@@ -142,33 +150,33 @@ spec:
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In,
|
||||
NotIn, Exists and DoesNotExist.
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values
|
||||
array must be non-empty. If the operator is
|
||||
Exists or DoesNotExist, the values array must
|
||||
be empty. This array is replaced during a
|
||||
strategic merge patch.
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field
|
||||
is "key", the operator is "In", and the values array
|
||||
contains only "value". The requirements are ANDed.
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
@@ -189,9 +197,9 @@ spec:
|
||||
type: array
|
||||
resyncPeriod:
|
||||
default: 60s
|
||||
description: Define the period of time upon a second reconciliation
|
||||
must be invoked. Keep in mind that any change to the manifests will
|
||||
trigger a new reconciliation.
|
||||
description: |-
|
||||
Define the period of time upon a second reconciliation must be invoked.
|
||||
Keep in mind that any change to the manifests will trigger a new reconciliation.
|
||||
type: string
|
||||
required:
|
||||
- resources
|
||||
@@ -208,13 +216,19 @@ spec:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2617
config/install.yaml
2617
config/install.yaml
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,6 @@
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: MutatingWebhookConfiguration
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: mutating-webhook-configuration
|
||||
webhooks:
|
||||
- admissionReviewVersions:
|
||||
@@ -13,45 +12,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /defaults
|
||||
failurePolicy: Fail
|
||||
name: pod.defaults.capsule.clastix.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
apiVersions:
|
||||
- v1
|
||||
operations:
|
||||
- CREATE
|
||||
resources:
|
||||
- pods
|
||||
sideEffects: None
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /defaults
|
||||
failurePolicy: Fail
|
||||
name: storage.defaults.capsule.clastix.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
apiVersions:
|
||||
- v1
|
||||
operations:
|
||||
- CREATE
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
sideEffects: None
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /defaults
|
||||
failurePolicy: Fail
|
||||
name: ingress.defaults.capsule.clastix.io
|
||||
name: ingress.defaults.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- networking.k8s.io
|
||||
@@ -72,7 +33,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /namespace-owner-reference
|
||||
failurePolicy: Fail
|
||||
name: owner.namespace.capsule.clastix.io
|
||||
name: owner.namespace.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -84,11 +45,48 @@ webhooks:
|
||||
resources:
|
||||
- namespaces
|
||||
sideEffects: None
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /defaults
|
||||
failurePolicy: Fail
|
||||
name: pod.defaults.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
apiVersions:
|
||||
- v1
|
||||
operations:
|
||||
- CREATE
|
||||
resources:
|
||||
- pods
|
||||
sideEffects: None
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /defaults
|
||||
failurePolicy: Fail
|
||||
name: storage.defaults.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
apiVersions:
|
||||
- v1
|
||||
operations:
|
||||
- CREATE
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
sideEffects: None
|
||||
---
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: validating-webhook-configuration
|
||||
webhooks:
|
||||
- admissionReviewVersions:
|
||||
@@ -99,7 +97,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /cordoning
|
||||
failurePolicy: Fail
|
||||
name: cordoning.tenant.capsule.clastix.io
|
||||
name: cordoning.tenant.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- '*'
|
||||
@@ -120,7 +118,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /ingresses
|
||||
failurePolicy: Fail
|
||||
name: ingress.capsule.clastix.io
|
||||
name: ingress.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- networking.k8s.io
|
||||
@@ -142,7 +140,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /namespaces
|
||||
failurePolicy: Fail
|
||||
name: namespaces.capsule.clastix.io
|
||||
name: namespaces.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -163,7 +161,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /networkpolicies
|
||||
failurePolicy: Fail
|
||||
name: networkpolicies.capsule.clastix.io
|
||||
name: networkpolicies.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- networking.k8s.io
|
||||
@@ -183,7 +181,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /nodes
|
||||
failurePolicy: Fail
|
||||
name: nodes.capsule.clastix.io
|
||||
name: nodes.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -202,7 +200,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /pods
|
||||
failurePolicy: Fail
|
||||
name: pods.capsule.clastix.io
|
||||
name: pods.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -222,7 +220,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /persistentvolumeclaims
|
||||
failurePolicy: Fail
|
||||
name: pvc.capsule.clastix.io
|
||||
name: pvc.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -233,6 +231,26 @@ webhooks:
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
sideEffects: None
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /tenantresource-objects
|
||||
failurePolicy: Fail
|
||||
name: resource-objects.tenant.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- '*'
|
||||
apiVersions:
|
||||
- '*'
|
||||
operations:
|
||||
- UPDATE
|
||||
- DELETE
|
||||
resources:
|
||||
- '*'
|
||||
sideEffects: None
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
@@ -241,7 +259,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /services
|
||||
failurePolicy: Fail
|
||||
name: services.capsule.clastix.io
|
||||
name: services.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -253,26 +271,6 @@ webhooks:
|
||||
resources:
|
||||
- services
|
||||
sideEffects: None
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /tenantresource-objects
|
||||
failurePolicy: Fail
|
||||
name: resource-objects.tenant.capsule.clastix.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- '*'
|
||||
apiVersions:
|
||||
- '*'
|
||||
operations:
|
||||
- UPDATE
|
||||
- DELETE
|
||||
resources:
|
||||
- '*'
|
||||
sideEffects: None
|
||||
- admissionReviewVersions:
|
||||
- v1
|
||||
clientConfig:
|
||||
@@ -281,7 +279,7 @@ webhooks:
|
||||
namespace: system
|
||||
path: /tenants
|
||||
failurePolicy: Fail
|
||||
name: tenants.capsule.clastix.io
|
||||
name: tenants.projectcapsule.dev
|
||||
rules:
|
||||
- apiGroups:
|
||||
- capsule.clastix.io
|
||||
|
||||
@@ -5,10 +5,10 @@ package rbac
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -39,24 +39,23 @@ func (r *Manager) SetupWithManager(ctx context.Context, mgr ctrl.Manager, config
|
||||
For(&rbacv1.ClusterRole{}, namesPredicate).
|
||||
Complete(r)
|
||||
if crErr != nil {
|
||||
err = multierror.Append(err, crErr)
|
||||
err = errors.Join(err, crErr)
|
||||
}
|
||||
|
||||
crbErr := ctrl.NewControllerManagedBy(mgr).
|
||||
For(&rbacv1.ClusterRoleBinding{}, namesPredicate).
|
||||
Watches(&capsulev1beta2.CapsuleConfiguration{}, handler.Funcs{
|
||||
UpdateFunc: func(ctx context.Context, updateEvent event.UpdateEvent, limitingInterface workqueue.RateLimitingInterface) {
|
||||
UpdateFunc: func(ctx context.Context, updateEvent event.TypedUpdateEvent[client.Object], limitingInterface workqueue.TypedRateLimitingInterface[reconcile.Request]) {
|
||||
if updateEvent.ObjectNew.GetName() == configurationName {
|
||||
if crbErr := r.EnsureClusterRoleBindings(ctx); crbErr != nil {
|
||||
r.Log.Error(err, "cannot update ClusterRoleBinding upon CapsuleConfiguration update")
|
||||
}
|
||||
}
|
||||
},
|
||||
}).
|
||||
Complete(r)
|
||||
}).Complete(r)
|
||||
|
||||
if crbErr != nil {
|
||||
err = multierror.Append(err, crbErr)
|
||||
err = errors.Join(err, crbErr)
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
@@ -5,9 +5,9 @@ package resources
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
gherrors "github.com/pkg/errors"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@@ -75,14 +75,15 @@ func (r *Global) SetupWithManager(mgr ctrl.Manager) error {
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
//nolint:dupl
|
||||
func (r *Global) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
|
||||
var err error
|
||||
|
||||
log := ctrllog.FromContext(ctx)
|
||||
|
||||
log.Info("start processing")
|
||||
// Retrieving the GlobalTenantResource
|
||||
tntResource := &capsulev1beta2.GlobalTenantResource{}
|
||||
if err := r.client.Get(ctx, request.NamespacedName, tntResource); err != nil {
|
||||
if err = r.client.Get(ctx, request.NamespacedName, tntResource); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
log.Info("Request object not found, could have been deleted after reconcile request")
|
||||
|
||||
@@ -94,13 +95,13 @@ func (r *Global) Reconcile(ctx context.Context, request reconcile.Request) (reco
|
||||
|
||||
patchHelper, err := patch.NewHelper(tntResource, r.client)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, errors.Wrap(err, "failed to init patch helper")
|
||||
return reconcile.Result{}, gherrors.Wrap(err, "failed to init patch helper")
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if e := patchHelper.Patch(ctx, tntResource); e != nil {
|
||||
if err == nil {
|
||||
err = errors.Wrap(e, "failed to patch GlobalTenantResource")
|
||||
err = gherrors.Wrap(e, "failed to patch GlobalTenantResource")
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -143,7 +144,6 @@ func (r *Global) reconcileNormal(ctx context.Context, tntResource *capsulev1beta
|
||||
// upon replication and pruning, this will be updated in the status of the resource.
|
||||
tntSet := sets.NewString()
|
||||
|
||||
err = new(multierror.Error)
|
||||
// A TenantResource is made of several Resource sections, each one with specific options:
|
||||
// the Status can be updated only in case of no errors across all of them to guarantee a valid and coherent status.
|
||||
processedItems := sets.NewString()
|
||||
@@ -163,14 +163,14 @@ func (r *Global) reconcileNormal(ctx context.Context, tntResource *capsulev1beta
|
||||
if sectionErr != nil {
|
||||
// Upon a process error storing the last error occurred and continuing to iterate,
|
||||
// avoid to block the whole processing.
|
||||
err = multierror.Append(err, sectionErr)
|
||||
err = errors.Join(err, sectionErr)
|
||||
} else {
|
||||
processedItems.Insert(items...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err.(*multierror.Error).ErrorOrNil() != nil { //nolint:errorlint,forcetypeassert
|
||||
if err != nil {
|
||||
log.Error(err, "unable to replicate the requested resources")
|
||||
|
||||
return reconcile.Result{}, err
|
||||
|
||||
@@ -5,9 +5,9 @@ package resources
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
gherrors "github.com/pkg/errors"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
@@ -37,7 +37,6 @@ func (r *Namespaced) SetupWithManager(mgr ctrl.Manager) error {
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
//nolint:dupl
|
||||
func (r *Namespaced) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
|
||||
log := ctrllog.FromContext(ctx)
|
||||
|
||||
@@ -56,13 +55,13 @@ func (r *Namespaced) Reconcile(ctx context.Context, request reconcile.Request) (
|
||||
|
||||
patchHelper, err := patch.NewHelper(tntResource, r.client)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, errors.Wrap(err, "failed to init patch helper")
|
||||
return reconcile.Result{}, gherrors.Wrap(err, "failed to init patch helper")
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if e := patchHelper.Patch(ctx, tntResource); e != nil {
|
||||
if err == nil {
|
||||
err = errors.Wrap(e, "failed to patch TenantResource")
|
||||
err = gherrors.Wrap(e, "failed to patch TenantResource")
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -103,7 +102,6 @@ func (r *Namespaced) reconcileNormal(ctx context.Context, tntResource *capsulev1
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
err := new(multierror.Error)
|
||||
// A TenantResource is made of several Resource sections, each one with specific options:
|
||||
// the Status can be updated only in case of no errors across all of them to guarantee a valid and coherent status.
|
||||
processedItems := sets.NewString()
|
||||
@@ -115,18 +113,21 @@ func (r *Namespaced) reconcileNormal(ctx context.Context, tntResource *capsulev1
|
||||
return reconcile.Result{}, labelErr
|
||||
}
|
||||
|
||||
// new empty error
|
||||
var err error
|
||||
|
||||
for index, resource := range tntResource.Spec.Resources {
|
||||
items, sectionErr := r.processor.HandleSection(ctx, tl.Items[0], false, tenantLabel, index, resource)
|
||||
if sectionErr != nil {
|
||||
// Upon a process error storing the last error occurred and continuing to iterate,
|
||||
// avoid to block the whole processing.
|
||||
err = multierror.Append(err, sectionErr)
|
||||
err = errors.Join(err, sectionErr)
|
||||
} else {
|
||||
processedItems.Insert(items...)
|
||||
}
|
||||
}
|
||||
|
||||
if err.ErrorOrNil() != nil {
|
||||
if err != nil {
|
||||
log.Error(err, "unable to replicate the requested resources")
|
||||
|
||||
return reconcile.Result{}, err
|
||||
|
||||
@@ -5,9 +5,10 @@ package resources
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/valyala/fasttemplate"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierr "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -78,6 +79,7 @@ func (r *Processor) HandlePruning(ctx context.Context, current, desired sets.Set
|
||||
return updateStatus
|
||||
}
|
||||
|
||||
//nolint:gocognit
|
||||
func (r *Processor) HandleSection(ctx context.Context, tnt capsulev1beta2.Tenant, allowCrossNamespaceSelection bool, tenantLabel string, resourceIndex int, spec capsulev1beta2.ResourceSpec) ([]string, error) {
|
||||
log := ctrllog.FromContext(ctx)
|
||||
|
||||
@@ -124,14 +126,13 @@ func (r *Processor) HandleSection(ctx context.Context, tnt capsulev1beta2.Tenant
|
||||
|
||||
objLabels[Label] = fmt.Sprintf("%d", resourceIndex)
|
||||
objLabels[tenantLabel] = tnt.GetName()
|
||||
|
||||
// processed will contain the sets of resources replicated, both for the raw and the Namespaced ones:
|
||||
// these are required to perform a final pruning once the replication has been occurred.
|
||||
processed := sets.NewString()
|
||||
|
||||
tntNamespaces := sets.NewString(tnt.Status.Namespaces...)
|
||||
|
||||
syncErr := new(multierror.Error)
|
||||
var syncErr error
|
||||
|
||||
codecFactory := serializer.NewCodecFactory(r.client.Scheme())
|
||||
|
||||
@@ -153,7 +154,7 @@ func (r *Processor) HandleSection(ctx context.Context, tnt capsulev1beta2.Tenant
|
||||
if selectorErr != nil {
|
||||
log.Error(selectorErr, "cannot create Selector for namespacedItem", keysAndValues...)
|
||||
|
||||
syncErr = multierror.Append(syncErr, selectorErr)
|
||||
syncErr = errors.Join(syncErr, selectorErr)
|
||||
|
||||
continue
|
||||
}
|
||||
@@ -164,27 +165,38 @@ func (r *Processor) HandleSection(ctx context.Context, tnt capsulev1beta2.Tenant
|
||||
if clientErr := r.client.List(ctx, &objs, client.InNamespace(item.Namespace), client.MatchingLabelsSelector{Selector: itemSelector}); clientErr != nil {
|
||||
log.Error(clientErr, "cannot retrieve object for namespacedItem", keysAndValues...)
|
||||
|
||||
syncErr = multierror.Append(syncErr, clientErr)
|
||||
syncErr = errors.Join(syncErr, clientErr)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
multiErr := new(multierror.Group)
|
||||
var wg sync.WaitGroup
|
||||
|
||||
errorsChan := make(chan error, len(objs.Items))
|
||||
// processedRaw is used to avoid concurrent map writes during iteration of namespaced items:
|
||||
// the objects will be then added to processed variable if the resulting string is not empty,
|
||||
// meaning it has been processed correctly.
|
||||
processedRaw := make([]string, len(objs.Items))
|
||||
// Iterating over all the retrieved objects from the resource spec to get replicated in all the selected Namespaces:
|
||||
// in case of error during the create or update function, this will be appended to the list of errors.
|
||||
for _, o := range objs.Items {
|
||||
for i, o := range objs.Items {
|
||||
obj := o
|
||||
obj.SetNamespace(ns.Name)
|
||||
obj.SetOwnerReferences(nil)
|
||||
|
||||
multiErr.Go(func() error {
|
||||
wg.Add(1)
|
||||
|
||||
go func(index int, obj unstructured.Unstructured) {
|
||||
defer wg.Done()
|
||||
|
||||
kv := keysAndValues
|
||||
kv = append(kv, "resource", fmt.Sprintf("%s/%s", obj.GetNamespace(), obj.GetNamespace()))
|
||||
|
||||
if opErr := r.createOrUpdate(ctx, &obj, objLabels, objAnnotations); opErr != nil {
|
||||
log.Error(opErr, "unable to sync namespacedItems", kv...)
|
||||
errorsChan <- opErr
|
||||
|
||||
return opErr
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("resource has been replicated", kv...)
|
||||
@@ -195,14 +207,25 @@ func (r *Processor) HandleSection(ctx context.Context, tnt capsulev1beta2.Tenant
|
||||
replicatedItem.Namespace = ns.Name
|
||||
replicatedItem.APIVersion = obj.GetAPIVersion()
|
||||
|
||||
processed.Insert(replicatedItem.String())
|
||||
|
||||
return nil
|
||||
})
|
||||
processedRaw[index] = replicatedItem.String()
|
||||
}(i, obj)
|
||||
}
|
||||
|
||||
if objsErr := multiErr.Wait(); objsErr != nil {
|
||||
syncErr = multierror.Append(syncErr, objsErr)
|
||||
wg.Wait()
|
||||
close(errorsChan)
|
||||
|
||||
for err := range errorsChan {
|
||||
if err != nil {
|
||||
syncErr = errors.Join(syncErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range processedRaw {
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
processed.Insert(p)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +244,7 @@ func (r *Processor) HandleSection(ctx context.Context, tnt capsulev1beta2.Tenant
|
||||
if _, _, decodeErr := codecFactory.UniversalDeserializer().Decode([]byte(tmplString), nil, &obj); decodeErr != nil {
|
||||
log.Error(decodeErr, "unable to deserialize rawItem", keysAndValues...)
|
||||
|
||||
syncErr = multierror.Append(syncErr, decodeErr)
|
||||
syncErr = errors.Join(syncErr, decodeErr)
|
||||
|
||||
continue
|
||||
}
|
||||
@@ -232,7 +255,7 @@ func (r *Processor) HandleSection(ctx context.Context, tnt capsulev1beta2.Tenant
|
||||
log.Info("unable to sync rawItem", keysAndValues...)
|
||||
// In case of error processing an item in one of any selected Namespaces, storing it to report it lately
|
||||
// to the upper call to ensure a partial sync that will be fixed by a subsequent reconciliation.
|
||||
syncErr = multierror.Append(syncErr, rawErr)
|
||||
syncErr = errors.Join(syncErr, rawErr)
|
||||
} else {
|
||||
log.Info("resource has been replicated", keysAndValues...)
|
||||
|
||||
@@ -247,7 +270,7 @@ func (r *Processor) HandleSection(ctx context.Context, tnt capsulev1beta2.Tenant
|
||||
}
|
||||
}
|
||||
|
||||
return processed.List(), syncErr.ErrorOrNil()
|
||||
return processed.List(), syncErr
|
||||
}
|
||||
|
||||
// createOrUpdate replicates the provided unstructured object to all the provided Namespaces:
|
||||
|
||||
@@ -16,9 +16,11 @@ import (
|
||||
"k8s.io/client-go/util/retry"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
|
||||
capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
|
||||
"github.com/projectcapsule/capsule/pkg/metrics"
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
@@ -31,11 +33,11 @@ type Manager struct {
|
||||
func (r *Manager) SetupWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
For(&capsulev1beta2.Tenant{}).
|
||||
Owns(&corev1.Namespace{}).
|
||||
Owns(&networkingv1.NetworkPolicy{}).
|
||||
Owns(&corev1.LimitRange{}).
|
||||
Owns(&corev1.ResourceQuota{}).
|
||||
Owns(&rbacv1.RoleBinding{}).
|
||||
Watches(&corev1.Namespace{}, handler.EnqueueRequestForOwner(mgr.GetScheme(), mgr.GetRESTMapper(), &capsulev1beta2.Tenant{})).
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
@@ -48,6 +50,10 @@ func (r Manager) Reconcile(ctx context.Context, request ctrl.Request) (result ct
|
||||
if apierrors.IsNotFound(err) {
|
||||
r.Log.Info("Request object not found, could have been deleted after reconcile request")
|
||||
|
||||
// If tenant was deleted or cannot be found, clean up metrics
|
||||
metrics.TenantResourceUsage.DeletePartialMatch(map[string]string{"tenant": request.Name})
|
||||
metrics.TenantResourceLimit.DeletePartialMatch(map[string]string{"tenant": request.Name})
|
||||
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
"github.com/projectcapsule/capsule/pkg/metrics"
|
||||
"github.com/projectcapsule/capsule/pkg/utils"
|
||||
)
|
||||
|
||||
@@ -51,6 +52,18 @@ func (r *Manager) syncResourceQuotas(ctx context.Context, tenant *capsulev1beta2
|
||||
if typeLabel, err = utils.GetTypeLabel(&corev1.ResourceQuota{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove prior metrics, to avoid cleaning up for metrics of deleted ResourceQuotas
|
||||
metrics.TenantResourceUsage.DeletePartialMatch(map[string]string{"tenant": tenant.Name})
|
||||
metrics.TenantResourceLimit.DeletePartialMatch(map[string]string{"tenant": tenant.Name})
|
||||
|
||||
// Expose the namespace quota and usage as metrics for the tenant
|
||||
metrics.TenantResourceUsage.WithLabelValues(tenant.Name, "namespaces", "").Set(float64(tenant.Status.Size))
|
||||
|
||||
if tenant.Spec.NamespaceOptions != nil && tenant.Spec.NamespaceOptions.Quota != nil {
|
||||
metrics.TenantResourceLimit.WithLabelValues(tenant.Name, "namespaces", "").Set(float64(*tenant.Spec.NamespaceOptions.Quota))
|
||||
}
|
||||
|
||||
//nolint:nestif
|
||||
if tenant.Spec.ResourceQuota.Scope == api.ResourceQuotaScopeTenant {
|
||||
group := new(errgroup.Group)
|
||||
@@ -102,6 +115,19 @@ func (r *Manager) syncResourceQuotas(ctx context.Context, tenant *capsulev1beta2
|
||||
|
||||
r.Log.Info("Computed " + name.String() + " quota for the whole Tenant is " + quantity.String())
|
||||
|
||||
// Expose usage and limit metrics for the resource (name) of the ResourceQuota (index)
|
||||
metrics.TenantResourceUsage.WithLabelValues(
|
||||
tenant.Name,
|
||||
name.String(),
|
||||
strconv.Itoa(index),
|
||||
).Set(float64(quantity.MilliValue()) / 1000)
|
||||
|
||||
metrics.TenantResourceLimit.WithLabelValues(
|
||||
tenant.Name,
|
||||
name.String(),
|
||||
strconv.Itoa(index),
|
||||
).Set(float64(hardQuota.MilliValue()) / 1000)
|
||||
|
||||
switch quantity.Cmp(resourceQuota.Hard[name]) {
|
||||
case 0:
|
||||
// The Tenant is matching exactly the Quota:
|
||||
@@ -130,7 +156,15 @@ func (r *Manager) syncResourceQuotas(ctx context.Context, tenant *capsulev1beta2
|
||||
list.Items[item].Spec.Hard = map[corev1.ResourceName]resource.Quantity{}
|
||||
}
|
||||
|
||||
list.Items[item].Spec.Hard[name] = resourceQuota.Hard[name]
|
||||
// Effectively this subtracts the usage from all other namespaces in the tenant from the desired tenant hard quota.
|
||||
// Thus we can determine, how much is left in this resourcequota (item) for the current resource (name).
|
||||
// We use this remaining quota at the tenant level, to update the hard quota for the current namespace.
|
||||
|
||||
newHard := hardQuota // start off with desired tenant wide hard quota
|
||||
newHard.Sub(quantity) // subtract tenant wide usage
|
||||
newHard.Add(list.Items[item].Status.Used[name]) // add back usage in current ns
|
||||
|
||||
list.Items[item].Spec.Hard[name] = newHard
|
||||
|
||||
for k := range list.Items[item].Spec.Hard {
|
||||
if !toKeep.Has(k) {
|
||||
|
||||
@@ -218,3 +218,7 @@ v2
|
||||
webhook
|
||||
webhooks
|
||||
wontfix
|
||||
Quickstart
|
||||
FluxCD
|
||||
addon
|
||||
kustomize-controller
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,20 +6,7 @@ Thanks for giving Capsule a try.
|
||||
|
||||
Make sure you have access to a Kubernetes cluster as administrator.
|
||||
|
||||
There are two ways to install Capsule:
|
||||
|
||||
* Use the [single YAML file installer](https://raw.githubusercontent.com/clastix/capsule/master/config/install.yaml)
|
||||
* Use the [Capsule Helm Chart](https://github.com/projectcapsule/capsule/blob/master/charts/capsule/README.md)
|
||||
|
||||
### Install with the single YAML file installer
|
||||
|
||||
Ensure you have `kubectl` installed in your `PATH`. Clone this repository and move to the repo folder:
|
||||
|
||||
```
|
||||
$ kubectl apply -f https://raw.githubusercontent.com/clastix/capsule/master/config/install.yaml
|
||||
```
|
||||
|
||||
It will install the Capsule controller in a dedicated namespace `capsule-system`.
|
||||
You can use the [Capsule Helm Chart](https://github.com/projectcapsule/capsule/blob/master/charts/capsule/README.md) to install Capsule.
|
||||
|
||||
### Install with Helm Chart
|
||||
|
||||
|
||||
@@ -2104,7 +2104,7 @@ spec:
|
||||
uid: 1b3aa814-3b0c-4912-9bd9-112820da38fe
|
||||
```
|
||||
|
||||
Once the `PeristentVolume` become available again, it can be referenced by any `PersistentVolumeClaim` in the `atreides` Tenant Namespace resources.
|
||||
Once the `PersistentVolume` become available again, it can be referenced by any `PersistentVolumeClaim` in the `atreides` Tenant Namespace resources.
|
||||
|
||||
If another Tenant, like `harkonnen`, tries to use it, it will get an error:
|
||||
|
||||
|
||||
@@ -1,6 +1,135 @@
|
||||
# Multi-tenancy the GitOps way
|
||||
|
||||
This guide is intended to cover how to use Flux v2 with [multi-tenancy lockdown features](https://fluxcd.io/docs/installation/#multi-tenancy-lockdown) with Capsule and Capsule Proxy together, to enable a Namespace-as-a-Service the GitOps-way.
|
||||
This document will guide you to manage Tenant resources the GitOps way with Flux configured with the [multi-tenancy lockdown](https://fluxcd.io/docs/installation/#multi-tenancy-lockdown).
|
||||
|
||||
The proposed approach consists on making Flux to reconcile Tenant resources as Tenant Owners, while still providing Namespace as a Service to Tenants.
|
||||
|
||||
This means that Tenants can operate and declare multiple Namespaces in their own Git repositories while not escaping the policies enforced by Capsule.
|
||||
|
||||
## Quickstart
|
||||
|
||||
### Install
|
||||
|
||||
In order to make it work you can install the FluxCD addon via Helm:
|
||||
|
||||
```shell
|
||||
helm install -n capsule-system capsule-addon-fluxcd \
|
||||
oci://ghcr.io/projectcapsule/charts/capsule-addon-fluxcd
|
||||
```
|
||||
|
||||
### Configure Tenants
|
||||
|
||||
> The audience for this part is the **platform administrator** user persona.
|
||||
|
||||
In order to make Flux controllers reconcile Tenant resources impersonating a Tenant Owner, a Tenant Owner as Service Account is required.
|
||||
|
||||
To be recognized by the addon that will automate the required configurations, the `ServiceAccount` needs the `capsule.addon.fluxcd/enabled=true` annotation.
|
||||
|
||||
Assuming a configured *oil* `Tenant`, the following Tenant Owner `ServiceAccount` must be declared:
|
||||
|
||||
```yml
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: oil-system
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: gitops-reconciler
|
||||
namespace: oil-system
|
||||
annotations:
|
||||
capsule.addon.fluxcd/enabled: "true"
|
||||
```
|
||||
|
||||
set it as a valid *oil* `Tenant` owner, and made Capsule recognize its `Group`:
|
||||
|
||||
```yml
|
||||
---
|
||||
apiVersion: capsule.clastix.io/v1beta2
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: oil
|
||||
spec:
|
||||
additionalRoleBindings:
|
||||
- clusterRoleName: cluster-admin
|
||||
subjects:
|
||||
- name: gitops-reconciler
|
||||
kind: ServiceAccount
|
||||
namespace: oil-system
|
||||
owners:
|
||||
- name: system:serviceaccount:oil-system:gitops-reconciler
|
||||
kind: ServiceAccount
|
||||
---
|
||||
apiVersion: capsule.clastix.io/v1beta2
|
||||
kind: CapsuleConfiguration
|
||||
metadata:
|
||||
name: default
|
||||
spec:
|
||||
userGroups:
|
||||
- capsule.clastix.io
|
||||
- system:serviceaccounts:oil-system
|
||||
```
|
||||
|
||||
The addon will automate:
|
||||
* RBAC configuration for the `Tenant` owner `ServiceAccount`
|
||||
* `Tenant` owner `ServiceAccount` token generation
|
||||
* `Tenant` owner `kubeconfig` needed to send Flux reconciliation requests through the Capsule proxy
|
||||
* `Tenant` `kubeconfig` distribution across all Tenant `Namespace`s.
|
||||
|
||||
The last automation is needed so that the `kubeconfig` can be set on `Kustomization`s/`HelmRelease`s across all `Tenant`'s `Namespace`s.
|
||||
|
||||
More details on this are available in the deep-dive section.
|
||||
|
||||
### How to use
|
||||
|
||||
> The audience for this part is the **platform administrator** user persona.
|
||||
|
||||
Consider a `Tenant` named *oil* that has a dedicated Git repository that contains oil's configurations.
|
||||
|
||||
You as a platform administrator want to provide to the *oil* `Tenant` a Namespace-as-a-Service with a GitOps experience, allowing the tenant to version the configurations in a Git repository.
|
||||
|
||||
You, as Tenant owner, can configure Flux [reconciliation](https://fluxcd.io/flux/concepts/#reconciliation) resources to be applied as Tenant owner:
|
||||
|
||||
```yml
|
||||
---
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: oil-apps
|
||||
namespace: oil-system
|
||||
spec:
|
||||
serviceAccountName: gitops-reconciler
|
||||
kubeConfig:
|
||||
secretRef:
|
||||
name: gitops-reconciler-kubeconfig
|
||||
key: kubeconfig
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: oil
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: oil
|
||||
namespace: oil-system
|
||||
spec:
|
||||
url: https://github.com/oil/oil-apps
|
||||
```
|
||||
|
||||
Let's analyze the setup field by field:
|
||||
- the `GitRepository` and the `Kustomization` are in a Tenant system `Namespace`
|
||||
- the `Kustomization` refers to a `ServiceAccount` to be impersonated when reconciling the resources the `Kustomization` refers to: this ServiceAccount is an *oil* **Tenant owner**
|
||||
- the `Kustomization` refers also to a `kubeConfig` to be used when reconciling the resources the `Kustomization` refers to: this is needed to make requests through the **Capsule proxy** in order to operate on cluster-wide resources as a Tenant
|
||||
|
||||
The *oil* tenant can also declare new `Namespace`s thanks to the segregation provided by Capsule.
|
||||
|
||||
> Note: it can be avoided to explicitly set the service account name when it's set as default Service Account name at Flux's [kustomize-controller level](https://fluxcd.io/flux/installation/configuration/multitenancy/#how-to-configure-flux-multi-tenancy) via the `default-service-account` flag.
|
||||
|
||||
More information are available in the [addon repository](https://github.com/projectcapsule/capsule-addon-fluxcd).
|
||||
|
||||
## Deep dive
|
||||
|
||||
### Flux and multi-tenancy
|
||||
|
||||
@@ -50,7 +179,7 @@ What if we would like to provide tenants the ability to manage also their own sp
|
||||
|
||||

|
||||
|
||||
## The ingredients of the recipe
|
||||
## Manual setup
|
||||
|
||||
> Legenda:
|
||||
> - Privileged space: group of Namespaces which are not part of any Tenant.
|
||||
|
||||
@@ -70,7 +70,7 @@ When onboarding tenants, the administrator needs to create the following, in ord
|
||||
|
||||
#### Create the Tenant Member Project Role
|
||||
|
||||
A custom `Project Role` is needed to allow Tenant users, with minimun set of privileges and create and delete `Namespace`s.
|
||||
A custom `Project Role` is needed to allow Tenant users, with minimum set of privileges and create and delete `Namespace`s.
|
||||
|
||||
Create a Project Role named *Tenant Member* that inherits the privileges from the following Roles:
|
||||
- *read-only*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user