mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-03-17 09:00:31 +00:00
Compare commits
345 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67b5c3e880 | ||
|
|
1f4fcce977 | ||
|
|
100454d303 | ||
|
|
074eb40734 | ||
|
|
1336ebe9c3 | ||
|
|
13d37b28be | ||
|
|
ca9323518f | ||
|
|
e1f47feade | ||
|
|
24543aa13a | ||
|
|
73cc0917ee | ||
|
|
06614c9d86 | ||
|
|
b3bfead6a0 | ||
|
|
1b415d4931 | ||
|
|
0ab0135977 | ||
|
|
b22adc424f | ||
|
|
a31259ad9b | ||
|
|
13208208d6 | ||
|
|
dda7393c3f | ||
|
|
c7dbb44aaf | ||
|
|
1e3b62bf83 | ||
|
|
30168db4fa | ||
|
|
9d6d68c519 | ||
|
|
3bac2b6f0e | ||
|
|
cdca11f0b9 | ||
|
|
10eeecc6a3 | ||
|
|
e234200d1c | ||
|
|
bdcae3af42 | ||
|
|
698c3d5e3d | ||
|
|
135af0cba5 | ||
|
|
0df9e58313 | ||
|
|
cb0d06c322 | ||
|
|
3c0545f2a6 | ||
|
|
951f7f9918 | ||
|
|
61e2144d15 | ||
|
|
4f329a9c95 | ||
|
|
f1038911e2 | ||
|
|
9481b8ff80 | ||
|
|
5a15324108 | ||
|
|
4f7ae03241 | ||
|
|
2b92dac4cd | ||
|
|
f408a79b2d | ||
|
|
4e07b95155 | ||
|
|
49f0ae0826 | ||
|
|
406d285742 | ||
|
|
4be16d5ba5 | ||
|
|
90b3434b17 | ||
|
|
1ab4eb677b | ||
|
|
797deaf48f | ||
|
|
ccc0feec0a | ||
|
|
020c0ef8f6 | ||
|
|
90049844f3 | ||
|
|
1ce9dca14c | ||
|
|
255c71e9bd | ||
|
|
30408c9036 | ||
|
|
643b7390d1 | ||
|
|
6bbcede4b2 | ||
|
|
46d519d1f4 | ||
|
|
ebfa654b69 | ||
|
|
34cadd42d2 | ||
|
|
134780f149 | ||
|
|
42354761ea | ||
|
|
838cc5f969 | ||
|
|
0b9db34735 | ||
|
|
eb121a91f2 | ||
|
|
91b4266573 | ||
|
|
6501745fc4 | ||
|
|
c33d8a5b34 | ||
|
|
95d471d40f | ||
|
|
444a468a66 | ||
|
|
04a846ad4e | ||
|
|
e4d7f72d17 | ||
|
|
db709d56f7 | ||
|
|
4a6fd78f61 | ||
|
|
b0c76344a0 | ||
|
|
76f29e620c | ||
|
|
e8e9c8b6ad | ||
|
|
c7d8fc555d | ||
|
|
eaa85aba7d | ||
|
|
df6bb2f7dc | ||
|
|
3682283352 | ||
|
|
13575af1d8 | ||
|
|
703c7b9a10 | ||
|
|
6048754840 | ||
|
|
ee2eac9010 | ||
|
|
2fb2c79107 | ||
|
|
359dbf55cb | ||
|
|
99bfc88f06 | ||
|
|
e4f426b979 | ||
|
|
387aa91d07 | ||
|
|
288f08e735 | ||
|
|
972ddcee44 | ||
|
|
c8377d51f1 | ||
|
|
d3b435c353 | ||
|
|
fe2cc4c8f7 | ||
|
|
78c9b285c1 | ||
|
|
0a65b106ad | ||
|
|
373df97629 | ||
|
|
ceaa272d44 | ||
|
|
3c267c9362 | ||
|
|
2113f793c0 | ||
|
|
de41fcb6f2 | ||
|
|
82eea46952 | ||
|
|
c0cfa86497 | ||
|
|
a6f38583b3 | ||
|
|
5c3b014059 | ||
|
|
c7237f802b | ||
|
|
f143abc481 | ||
|
|
4b3a813f27 | ||
|
|
77de23d73b | ||
|
|
02d13889e9 | ||
|
|
a60ebfac5e | ||
|
|
7d0a4c58fd | ||
|
|
e1699a90b1 | ||
|
|
4e4a0c10bb | ||
|
|
0565c5ee85 | ||
|
|
8bb1cad898 | ||
|
|
06850f4ccb | ||
|
|
9130cad7d6 | ||
|
|
2c0348195b | ||
|
|
e14c030db0 | ||
|
|
dc4b9049b3 | ||
|
|
452afd0807 | ||
|
|
fdba17099c | ||
|
|
cc6bd2c05d | ||
|
|
b44e8ecb44 | ||
|
|
e6fcfaf6f6 | ||
|
|
f85b61860e | ||
|
|
dea9b1604f | ||
|
|
2a45647293 | ||
|
|
063e02b3a8 | ||
|
|
8e9b8adac9 | ||
|
|
eb52eba944 | ||
|
|
63c92f8e6c | ||
|
|
2d3851f409 | ||
|
|
035fcc0362 | ||
|
|
9d1f70229b | ||
|
|
2ea70e30c4 | ||
|
|
5d30a1301c | ||
|
|
61a5422559 | ||
|
|
3c5874a37a | ||
|
|
47720bdacb | ||
|
|
0d559d6031 | ||
|
|
28542e907d | ||
|
|
5aec7e5e24 | ||
|
|
9a36fba438 | ||
|
|
85e6d00f2f | ||
|
|
5ca926c255 | ||
|
|
d15ef08576 | ||
|
|
4f11a1e6e2 | ||
|
|
b739e4816c | ||
|
|
d93279bceb | ||
|
|
e286dc94a7 | ||
|
|
5a32195091 | ||
|
|
7495eba74f | ||
|
|
bb3b7fee48 | ||
|
|
e2af0dc493 | ||
|
|
535c0e127d | ||
|
|
2f70e92df8 | ||
|
|
73746ad885 | ||
|
|
a6b3895756 | ||
|
|
72012c19e6 | ||
|
|
a440a59435 | ||
|
|
6fcc9de3b1 | ||
|
|
f5a621174a | ||
|
|
76016fba71 | ||
|
|
c9af3fcad1 | ||
|
|
d3c79538e0 | ||
|
|
9127bdb66a | ||
|
|
45a46d7337 | ||
|
|
f5c7cffb82 | ||
|
|
e52539bed6 | ||
|
|
9bd7bbf274 | ||
|
|
2e6c26c982 | ||
|
|
cbc1fea680 | ||
|
|
a1d89711b0 | ||
|
|
7b985fcb6e | ||
|
|
a783bd69fa | ||
|
|
35f11679b1 | ||
|
|
063788c8af | ||
|
|
4be73f2d52 | ||
|
|
bd53884e23 | ||
|
|
4eca6ca5b1 | ||
|
|
93ed1c7171 | ||
|
|
97a4dccc42 | ||
|
|
0ef6733d67 | ||
|
|
80538d6344 | ||
|
|
8e0b5b9413 | ||
|
|
14679921d0 | ||
|
|
4b2c86be65 | ||
|
|
72c0cd0199 | ||
|
|
3ef3e1f137 | ||
|
|
a55154ea56 | ||
|
|
8df833116c | ||
|
|
cfdd812d21 | ||
|
|
aaca9ca1b6 | ||
|
|
b630aa7671 | ||
|
|
2cb6100d24 | ||
|
|
6f8563f7e8 | ||
|
|
c51e4cac9a | ||
|
|
08331211d1 | ||
|
|
075f3a8385 | ||
|
|
c20272c8b9 | ||
|
|
e7640ec584 | ||
|
|
360d0dc48b | ||
|
|
e808118b43 | ||
|
|
b7a2072b0f | ||
|
|
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 |
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -9,7 +9,7 @@ assignees: ''
|
||||
|
||||
<!--
|
||||
Thanks for taking time reporting a Capsule bug!
|
||||
|
||||
|
||||
-->
|
||||
|
||||
# Bug description
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -32,4 +32,4 @@ How would the new interaction with Capsule look like? E.g.
|
||||
Feel free to add a diagram if that helps explain things.
|
||||
|
||||
# Expected behavior
|
||||
A clear and concise description of what you expect to happen.
|
||||
A clear and concise description of what you expect to happen.
|
||||
|
||||
2
.github/actions/exists/action.yaml
vendored
2
.github/actions/exists/action.yaml
vendored
@@ -18,4 +18,4 @@ runs:
|
||||
- shell: bash
|
||||
id: check
|
||||
run: |
|
||||
echo "result=${{ inputs.value != '' }}" >> $GITHUB_OUTPUT
|
||||
echo "result=${{ inputs.value != '' }}" >> $GITHUB_OUTPUT
|
||||
|
||||
6
.github/actions/setup-caches/action.yaml
vendored
6
.github/actions/setup-caches/action.yaml
vendored
@@ -9,12 +9,12 @@ inputs:
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d # v3.2.2
|
||||
- uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
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@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
if: ${{ inputs.build-cache-key }}
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-build-cache-${{ inputs.build-cache-key }}-${{ hashFiles('**/go.sum') }}-${{ hashFiles('Makefile') }}
|
||||
key: ${{ runner.os }}-build-cache-${{ inputs.build-cache-key }}-${{ hashFiles('**/go.sum') }}-${{ hashFiles('Makefile') }}
|
||||
|
||||
2
.github/configs/ct.yaml
vendored
2
.github/configs/ct.yaml
vendored
@@ -4,7 +4,7 @@ chart-dirs:
|
||||
- charts
|
||||
chart-repos:
|
||||
- capsule=https://projectcapsule.github.io/charts/
|
||||
helm-extra-args: "--timeout 600s"
|
||||
helm-extra-args: "--timeout 600s"
|
||||
validate-chart-schema: false
|
||||
validate-maintainers: false
|
||||
validate-yaml: true
|
||||
|
||||
16
.github/configs/lintconf.yaml
vendored
16
.github/configs/lintconf.yaml
vendored
@@ -1,6 +1,18 @@
|
||||
|
||||
---
|
||||
ignore:
|
||||
- config/
|
||||
- charts/*/templates/
|
||||
- charts/**/templates/
|
||||
rules:
|
||||
truthy:
|
||||
level: warning
|
||||
allowed-values:
|
||||
- "true"
|
||||
- "false"
|
||||
- "on"
|
||||
- "off"
|
||||
|
||||
check-keys: false
|
||||
braces:
|
||||
min-spaces-inside: 0
|
||||
max-spaces-inside: 0
|
||||
@@ -39,5 +51,3 @@ rules:
|
||||
new-lines:
|
||||
type: unix
|
||||
trailing-spaces: enable
|
||||
truthy:
|
||||
level: warning
|
||||
|
||||
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)"
|
||||
8
.github/maintainers.yaml
vendored
8
.github/maintainers.yaml
vendored
@@ -1,3 +1,4 @@
|
||||
maintainers:
|
||||
- name: Adriano Pezzuto
|
||||
github: https://github.com/bsctl
|
||||
company: Clastix
|
||||
@@ -21,9 +22,16 @@
|
||||
company: Peak Scale
|
||||
projects:
|
||||
- https://github.com/projectcapsule/capsule
|
||||
- https://github.com/projectcapsule/capsule-proxy
|
||||
- name: Massimiliano Giovagnoli
|
||||
github: https://github.com/maxgio92
|
||||
company: Proximus
|
||||
projects:
|
||||
- https://github.com/projectcapsule/capsule
|
||||
- https://github.com/projectcapsule/capsule-proxy
|
||||
- name: Hristo Hristov
|
||||
github: https://github.com/Svarrogh1337
|
||||
company: Vaerolabs
|
||||
projects:
|
||||
- https://github.com/projectcapsule/capsule
|
||||
- https://github.com/projectcapsule/capsule-proxy
|
||||
|
||||
11
.github/workflows/check-actions.yml
vendored
11
.github/workflows/check-actions.yml
vendored
@@ -3,7 +3,8 @@ permissions: {}
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
branches:
|
||||
- "*"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -14,11 +15,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Ensure SHA pinned actions
|
||||
uses: zgosalvez/github-actions-ensure-sha-pinned-actions@74606c30450304eee8660aae751818321754feb1 # v3.0.9
|
||||
uses: zgosalvez/github-actions-ensure-sha-pinned-actions@fc87bb5b5a97953d987372e74478de634726b3e5 # v3.0.25
|
||||
with:
|
||||
# slsa-github-generator requires using a semver tag for reusable workflows.
|
||||
# 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
|
||||
allowlist: |
|
||||
slsa-framework/slsa-github-generator
|
||||
slsa-framework/slsa-github-generator
|
||||
|
||||
15
.github/workflows/check-commit.yml
vendored
15
.github/workflows/check-commit.yml
vendored
@@ -3,21 +3,20 @@ permissions: {}
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
branches:
|
||||
- "*"
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
branches:
|
||||
- "*"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
commit_lint:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: wagoid/commitlint-github-action@7f0a61df502599e1f1f50880aaa7ec1e2c0592f2 #v6.0.1
|
||||
with:
|
||||
firstParent: true
|
||||
- uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6.2.1
|
||||
|
||||
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@cfb60706e18bc85e8aec535e3c577abe8f70378e
|
||||
- uses: amannn/action-semantic-pull-request@a46a7c8dc4bb34503174eba2f2f7ef80dffc8ed7
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
|
||||
38
.github/workflows/codecov.yml
vendored
38
.github/workflows/codecov.yml
vendored
@@ -1,38 +0,0 @@
|
||||
name: Codecov
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
codecov:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Setup caches
|
||||
uses: ./.github/actions/setup-caches
|
||||
timeout-minutes: 5
|
||||
continue-on-error: true
|
||||
with:
|
||||
build-cache-key: codecov
|
||||
- name: Check secret
|
||||
id: checksecret
|
||||
uses: ./.github/actions/exists
|
||||
with:
|
||||
value: ${{ secrets.CODECOV_TOKEN }}
|
||||
- name: Generate Code Coverage Report
|
||||
if: steps.checksecret.outputs.result == 'true'
|
||||
run: make test
|
||||
- name: Upload Report to Codecov
|
||||
if: steps.checksecret.outputs.result == 'true'
|
||||
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
|
||||
with:
|
||||
file: ./coverage.out
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
||||
86
.github/workflows/coverage.yml
vendored
Normal file
86
.github/workflows/coverage.yml
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
name: Coverage
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
branches:
|
||||
- "main"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
compliance:
|
||||
name: "License Compliance"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout Code"
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Check secret
|
||||
id: checksecret
|
||||
uses: ./.github/actions/exists
|
||||
with:
|
||||
value: ${{ secrets.FOSSA_API_KEY }}
|
||||
- name: "Run FOSSA Scan"
|
||||
if: steps.checksecret.outputs.result == 'true'
|
||||
uses: fossas/fossa-action@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # v1.7.0
|
||||
with:
|
||||
api-key: ${{ secrets.FOSSA_API_KEY }}
|
||||
- name: "Run FOSSA Test"
|
||||
if: steps.checksecret.outputs.result == 'true'
|
||||
uses: fossas/fossa-action@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # v1.7.0
|
||||
with:
|
||||
api-key: ${{ secrets.FOSSA_API_KEY }}
|
||||
run-tests: true
|
||||
sast:
|
||||
name: "SAST"
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
GO111MODULE: on
|
||||
permissions:
|
||||
security-events: write
|
||||
actions: read
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- name: Run Gosec Security Scanner
|
||||
uses: securego/gosec@c9453023c4e81ebdb6dde29e22d9cd5e2285fb16 # v2.22.8
|
||||
with:
|
||||
args: '-no-fail -fmt sarif -out gosec.sarif ./...'
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@233052189b8c862bfaf875fb02c115f54d2b9286
|
||||
with:
|
||||
sarif_file: gosec.sarif
|
||||
unit_tests:
|
||||
name: "Unit tests"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- name: Unit Test
|
||||
run: make test
|
||||
- name: Check secret
|
||||
id: checksecret
|
||||
uses: ./.github/actions/exists
|
||||
with:
|
||||
value: ${{ secrets.CODECOV_TOKEN }}
|
||||
- name: Upload Report to Codecov
|
||||
if: ${{ steps.checksecret.outputs.result == 'true' }}
|
||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
slug: projectcapsule/capsule
|
||||
files: ./coverage.out
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
||||
31
.github/workflows/diff.yml
vendored
31
.github/workflows/diff.yml
vendored
@@ -1,31 +0,0 @@
|
||||
name: Diff checks
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
diff:
|
||||
name: diff
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
|
||||
with:
|
||||
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
|
||||
- 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
|
||||
run: test -z "$(git diff 2> /dev/null)"
|
||||
45
.github/workflows/docker-build.yml
vendored
Normal file
45
.github/workflows/docker-build.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
name: Build images
|
||||
permissions: {}
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "*"
|
||||
paths:
|
||||
- '.github/workflows/docker-*.yml'
|
||||
- 'api/**'
|
||||
- 'controllers/**'
|
||||
- 'pkg/**'
|
||||
- 'e2e/*'
|
||||
- '.ko.yaml'
|
||||
- 'go.*'
|
||||
- 'main.go'
|
||||
- 'Makefile'
|
||||
|
||||
jobs:
|
||||
build-images:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
actions: read
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: ko build
|
||||
run: VERSION=${{ github.sha }} make ko-build-all
|
||||
- name: Trivy Scan Image
|
||||
uses: aquasecurity/trivy-action@dc5a429b52fcf669ce959baa2c2dd26090d2a6c4 # 0.32.0
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
ignore-unfixed: true
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
env:
|
||||
# Trivy is returning TOOMANYREQUESTS
|
||||
# See: https://github.com/aquasecurity/trivy-action/issues/389#issuecomment-2385416577
|
||||
TRIVY_DB_REPOSITORY: 'public.ecr.aws/aquasecurity/trivy-db:2'
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@233052189b8c862bfaf875fb02c115f54d2b9286
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
20
.github/workflows/docker-publish.yml
vendored
20
.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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- 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@7c2007bcb556501da015201bcba5aa14069b74e2 # v0.23.0
|
||||
uses: aquasecurity/trivy-action@dc5a429b52fcf669ce959baa2c2dd26090d2a6c4 # 0.32.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@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0
|
||||
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
|
||||
- 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,9 +49,9 @@ 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
|
||||
main-path: ./
|
||||
sbom-repository: ghcr.io/${{ github.repository_owner }}/capsule
|
||||
signature-repository: ghcr.io/${{ github.repository_owner }}/capsule
|
||||
main-path: ./cmd/
|
||||
env:
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
generate-capsule-provenance:
|
||||
@@ -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@v2.0.0
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.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 }}
|
||||
|
||||
12
.github/workflows/docs-lint.yml
vendored
12
.github/workflows/docs-lint.yml
vendored
@@ -3,12 +3,14 @@ permissions: {}
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
branches:
|
||||
- "*"
|
||||
paths:
|
||||
- '.github/workflows/docs-lint.yml'
|
||||
- 'docs/content/**'
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
branches:
|
||||
- "*"
|
||||
paths:
|
||||
- '.github/workflows/docs-lint.yml'
|
||||
- 'docs/content/**'
|
||||
@@ -22,10 +24,10 @@ jobs:
|
||||
name: Spell Check
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- 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
|
||||
- run: make docs-lint
|
||||
|
||||
49
.github/workflows/e2e.yml
vendored
49
.github/workflows/e2e.yml
vendored
@@ -2,20 +2,9 @@ name: e2e
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
paths:
|
||||
- '.github/workflows/e2e.yml'
|
||||
- 'api/**'
|
||||
- 'controllers/**'
|
||||
- 'pkg/**'
|
||||
- 'e2e/*'
|
||||
- 'Dockerfile'
|
||||
- 'go.*'
|
||||
- 'main.go'
|
||||
- 'Makefile'
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
branches:
|
||||
- "*"
|
||||
paths:
|
||||
- '.github/workflows/e2e.yml'
|
||||
- 'api/**'
|
||||
@@ -32,26 +21,28 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
kind:
|
||||
name: Kubernetes
|
||||
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
|
||||
e2e:
|
||||
name: E2E Testing
|
||||
runs-on:
|
||||
labels: ubuntu-latest-8-cores
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
|
||||
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- uses: engineerd/setup-kind@aa272fe2a7309878ffc2a81c56cfe3ef108ae7d0 # v0.5.0
|
||||
with:
|
||||
skipClusterCreation: true
|
||||
version: v0.14.0
|
||||
- uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v3
|
||||
- uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 # v4
|
||||
with:
|
||||
version: v3.14.2
|
||||
- name: e2e testing
|
||||
run: make e2e/${{ matrix.k8s-version }}
|
||||
- name: unit tracing
|
||||
run: sudo make trace-unit
|
||||
- name: e2e tracing
|
||||
run: sudo make trace-e2e
|
||||
- name: build seccomp profile
|
||||
run: make seccomp
|
||||
- name: upload artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: capsule-seccomp
|
||||
path: capsule-seccomp.json
|
||||
|
||||
35
.github/workflows/fossa.yml
vendored
35
.github/workflows/fossa.yml
vendored
@@ -1,35 +0,0 @@
|
||||
name: FOSSA
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
fossa-scan:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: "Checkout Code"
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Check secret
|
||||
id: checksecret
|
||||
uses: ./.github/actions/exists
|
||||
with:
|
||||
value: ${{ secrets.FOSSA_API_KEY }}
|
||||
- name: "Run FOSSA Scan"
|
||||
if: steps.checksecret.outputs.result == 'true'
|
||||
uses: fossas/fossa-action@47ef11b1e1e3812e88dae436ccbd2d0cbd1adab0 # v1.3.3
|
||||
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
|
||||
with:
|
||||
api-key: ${{ secrets.FOSSA_API_KEY }}
|
||||
run-tests: true
|
||||
33
.github/workflows/gosec.yml
vendored
33
.github/workflows/gosec.yml
vendored
@@ -1,33 +0,0 @@
|
||||
name: CI gosec
|
||||
permissions:
|
||||
actions: read
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
GO111MODULE: on
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- name: Run Gosec Security Scanner
|
||||
uses: securego/gosec@6fbd381238e97e1d1f3358f0d6d65de78dcf9245 # v2.20.0
|
||||
with:
|
||||
args: '-no-fail -fmt sarif -out gosec.sarif ./...'
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@c4fb451437765abf5018c6fbf22cce1a7da1e5cc
|
||||
with:
|
||||
sarif_file: gosec.sarif
|
||||
|
||||
17
.github/workflows/helm-publish.yml
vendored
17
.github/workflows/helm-publish.yml
vendored
@@ -1,5 +1,6 @@
|
||||
name: Publish charts
|
||||
permissions: read-all
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
@@ -13,9 +14,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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: "Extract Version"
|
||||
id: extract_version
|
||||
run: |
|
||||
@@ -36,7 +37,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
|
||||
@@ -44,8 +45,8 @@ jobs:
|
||||
outputs:
|
||||
chart-digest: ${{ steps.helm_publish.outputs.digest }}
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
|
||||
- name: "Extract Version"
|
||||
id: extract_version
|
||||
run: |
|
||||
@@ -54,7 +55,7 @@ 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
|
||||
@@ -65,14 +66,14 @@ jobs:
|
||||
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@v2.0.0
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
|
||||
with:
|
||||
image: ghcr.io/${{ github.repository_owner }}/charts/capsule
|
||||
digest: "${{ needs.publish-helm-oci.outputs.chart-digest }}"
|
||||
|
||||
56
.github/workflows/helm-test.yml
vendored
56
.github/workflows/helm-test.yml
vendored
@@ -3,34 +3,43 @@ permissions: {}
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
branches:
|
||||
- "main"
|
||||
paths:
|
||||
- '.github/configs/**'
|
||||
- '.github/workflows/helm-*.yml'
|
||||
- 'charts/**'
|
||||
- 'Makefile'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-20.04
|
||||
linter-artifacthub:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: artifacthub/ah
|
||||
options: --user root
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Run ah lint
|
||||
working-directory: ./charts/
|
||||
run: ah lint
|
||||
lint:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v3
|
||||
- uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 # v4
|
||||
- name: Linting Chart
|
||||
run: helm lint ./charts/capsule
|
||||
- name: Setup Chart Linting
|
||||
id: lint
|
||||
uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 # v2.6.1
|
||||
- name: Run chart-testing (list-changed)
|
||||
id: list-changed
|
||||
run: |
|
||||
changed=$(ct list-changed --config ./.github/configs/ct.yaml)
|
||||
if [[ -n "$changed" ]]; then
|
||||
echo "::set-output name=changed::true"
|
||||
fi
|
||||
|
||||
- name: Run chart-testing (lint)
|
||||
run: ct lint --debug --config ./.github/configs/ct.yaml --lint-conf ./.github/configs/lintconf.yaml
|
||||
run: make helm-lint
|
||||
|
||||
- name: Run docs-testing (helm-docs)
|
||||
id: helm-docs
|
||||
run: |
|
||||
@@ -42,7 +51,16 @@ jobs:
|
||||
else
|
||||
echo -e '\033[0;32mDocumentation up to date\033[0m ✔'
|
||||
fi
|
||||
|
||||
- name: Run schema-testing (helm-schema)
|
||||
id: helm-schema
|
||||
run: |
|
||||
make helm-schema
|
||||
if [[ $(git diff --stat) != '' ]]; then
|
||||
echo -e '\033[0;31mSchema outdated! (Run make helm-schema locally and commit)\033[0m ❌'
|
||||
git diff --color
|
||||
exit 1
|
||||
else
|
||||
echo -e '\033[0;32mSchema up to date\033[0m ✔'
|
||||
fi
|
||||
- name: Run chart-testing (install)
|
||||
run: make helm-test
|
||||
if: steps.list-changed.outputs.changed == 'true'
|
||||
run: HELM_KIND_CONFIG="./hack/kind-cluster.yml" make helm-test
|
||||
|
||||
50
.github/workflows/lint.yml
vendored
50
.github/workflows/lint.yml
vendored
@@ -1,28 +1,52 @@
|
||||
name: Linting
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
branches:
|
||||
- "*"
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
|
||||
branches:
|
||||
- "*"
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
manifests:
|
||||
name: diff
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- name: Generate manifests
|
||||
run: |
|
||||
make manifests
|
||||
if [[ $(git diff --stat) != '' ]]; then
|
||||
echo -e '\033[0;31mManifests outdated! (Run make manifests locally and commit)\033[0m ❌'
|
||||
git diff --color
|
||||
exit 1
|
||||
else
|
||||
echo -e '\033[0;32mDocumentation up to date\033[0m ✔'
|
||||
fi
|
||||
yamllint:
|
||||
name: yamllint
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Install yamllint
|
||||
run: pip install yamllint
|
||||
- name: Lint YAML files
|
||||
run: yamllint -c=.github/configs/lintconf.yaml .
|
||||
golangci:
|
||||
name: lint
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/golangci-lint-action@a4f60bb28d35aeee14e6880718e0c85ff1882e64 # v6.0.1
|
||||
with:
|
||||
version: v1.56.2
|
||||
only-new-issues: false
|
||||
args: --timeout 5m --config .golangci.yml
|
||||
run: make golint
|
||||
|
||||
51
.github/workflows/releaser.yml
vendored
51
.github/workflows/releaser.yml
vendored
@@ -11,26 +11,69 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
seccomp-generation:
|
||||
name: Seccomp Generation
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# differently from the e2e workflow
|
||||
# we don't need all the versions of kubernetes
|
||||
# to generate the seccomp profile.
|
||||
k8s-version:
|
||||
- "v1.30.0"
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 # v4
|
||||
with:
|
||||
version: v3.14.2
|
||||
- name: unit tracing
|
||||
run: sudo make trace-unit
|
||||
- name: e2e tracing
|
||||
run: sudo KIND_K8S_VERSION=${{ matrix.k8s-version }} make trace-e2e
|
||||
- name: build seccomp profile
|
||||
run: make seccomp
|
||||
- name: upload artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: capsule-seccomp
|
||||
path: capsule-seccomp.json
|
||||
|
||||
create-release:
|
||||
needs: seccomp-generation
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.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@e8d2a6937ecead383dfe75190d104edd1f9c5751
|
||||
- uses: anchore/sbom-action/download-syft@da167eac915b4e86f08b264dbdbc867b61be6f0c
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0
|
||||
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
|
||||
- name: download artifact
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||
with:
|
||||
name: capsule-seccomp
|
||||
path: ./capsule-seccomp.json
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0
|
||||
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean --timeout 90m
|
||||
|
||||
10
.github/workflows/scorecard.yml
vendored
10
.github/workflows/scorecard.yml
vendored
@@ -20,23 +20,23 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run analysis
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
||||
uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
|
||||
publish_results: true
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
- name: Upload to code-scanning
|
||||
uses: github/codeql-action/upload-sarif@c4fb451437765abf5018c6fbf22cce1a7da1e5cc # v2.13.4
|
||||
uses: github/codeql-action/upload-sarif@df559355d593797519d70b90fc8edd5db049e7a2 # v3.29.9
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
sarif_file: results.sarif
|
||||
|
||||
26
.github/workflows/stale.yml
vendored
Normal file
26
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Stale-Bot
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *' # Run every day at midnight
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
contents: write # only for delete-branch option
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Close stale pull requests
|
||||
uses: actions/stale@8f717f0dfca33b78d3c933452e42558e4456c8e7
|
||||
with:
|
||||
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.'
|
||||
stale-pr-message: 'This pull request has been marked as stale because it has been inactive for more than 30 days. Please update this pull request or it will be automatically closed in 30 days.'
|
||||
days-before-issue-stale: 60
|
||||
days-before-pr-stale: 30
|
||||
days-before-issue-close: 30
|
||||
days-before-pr-close: 30
|
||||
stale-pr-label: stale
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,6 +7,7 @@
|
||||
*.dylib
|
||||
bin
|
||||
dist/
|
||||
config/
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
@@ -31,3 +32,4 @@ dist/
|
||||
.DS_Store
|
||||
*.tgz
|
||||
kind.yaml
|
||||
capsule-seccomp.json
|
||||
|
||||
90
.golangci.yaml
Normal file
90
.golangci.yaml
Normal file
@@ -0,0 +1,90 @@
|
||||
version: "2"
|
||||
run:
|
||||
tests: false
|
||||
allow-parallel-runners: true
|
||||
linters:
|
||||
default: all
|
||||
disable:
|
||||
- depguard
|
||||
- err113
|
||||
- exhaustruct
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- ireturn
|
||||
- lll
|
||||
- mnd
|
||||
- nilnil
|
||||
- nonamedreturns
|
||||
- paralleltest
|
||||
- perfsprint
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- unparam
|
||||
- varnamelen
|
||||
- wrapcheck
|
||||
- interfacebloat
|
||||
- noinlineerr
|
||||
- revive
|
||||
settings:
|
||||
cyclop:
|
||||
max-complexity: 27
|
||||
dupl:
|
||||
threshold: 100
|
||||
gocognit:
|
||||
min-complexity: 50
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 2
|
||||
goheader:
|
||||
template: |-
|
||||
Copyright 2020-2025 Project Capsule Authors
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
inamedparam:
|
||||
skip-single-param: true
|
||||
nakedret:
|
||||
max-func-lines: 50
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- zz_.*\.go$
|
||||
- .+\.generated.go
|
||||
- .+_test.go
|
||||
- .+_test_.+.go
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
rules:
|
||||
- path: pkg/meta/
|
||||
linters:
|
||||
- dupl
|
||||
formatters:
|
||||
enable:
|
||||
- gci
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goimports
|
||||
settings:
|
||||
gci:
|
||||
sections:
|
||||
- standard
|
||||
- default
|
||||
- prefix(github.com/projectcapsule/capsule)
|
||||
gofumpt:
|
||||
module-path: github.com/projectcapsule/capsule
|
||||
extra-rules: false
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- zz_.*\.go$
|
||||
- .+\.generated.go
|
||||
- .+_test.go
|
||||
- .+_test_.+.go
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
@@ -1,72 +0,0 @@
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
dupl:
|
||||
threshold: 100
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 2
|
||||
cyclop:
|
||||
max-complexity: 27
|
||||
gocognit:
|
||||
min-complexity: 50
|
||||
gci:
|
||||
sections:
|
||||
- standard
|
||||
- default
|
||||
- prefix(github.com/projectcapsule/capsule)
|
||||
goheader:
|
||||
template: |-
|
||||
Copyright 2020-2023 Project Capsule Authors.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
gofumpt:
|
||||
module-path: github.com/projectcapsule/capsule
|
||||
extra-rules: false
|
||||
inamedparam:
|
||||
# Skips check for interface methods with only a single parameter.
|
||||
# Default: false
|
||||
skip-single-param: true
|
||||
nakedret:
|
||||
# Make an issue if func has more lines of code than this setting, and it has naked returns.
|
||||
max-func-lines: 50
|
||||
linters:
|
||||
enable-all: true
|
||||
disable:
|
||||
- depguard
|
||||
- perfsprint
|
||||
- funlen
|
||||
- gochecknoinits
|
||||
- lll
|
||||
- exhaustivestruct
|
||||
- maligned
|
||||
- interfacer
|
||||
- scopelint
|
||||
- golint
|
||||
- gochecknoglobals
|
||||
- goerr113
|
||||
- gomnd
|
||||
- paralleltest
|
||||
- ireturn
|
||||
- testpackage
|
||||
- varnamelen
|
||||
- wrapcheck
|
||||
- exhaustruct
|
||||
- varcheck
|
||||
- structcheck
|
||||
- nosnakecase
|
||||
- deadcode
|
||||
- ifshort
|
||||
- nonamedreturns
|
||||
|
||||
service:
|
||||
golangci-lint-version: 1.56.x
|
||||
|
||||
run:
|
||||
timeout: 3m
|
||||
go: '1.21'
|
||||
skip-files:
|
||||
- "zz_.*\\.go$"
|
||||
- ".+\\.generated.go"
|
||||
- ".+_test.go"
|
||||
- ".+_test_.+.go"
|
||||
@@ -8,7 +8,8 @@ before:
|
||||
gomod:
|
||||
proxy: false
|
||||
builds:
|
||||
- main: .
|
||||
- id: "{{ .ProjectName }}"
|
||||
main: ./cmd/
|
||||
binary: "{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}"
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
@@ -28,13 +29,31 @@ builds:
|
||||
-X main.GitDirty={{ .Date }}
|
||||
-X main.BuildTime={{ .Date }}
|
||||
-X main.GitRepo={{ .ProjectName }}
|
||||
# - id: "{{ .ProjectName }}-wasm"
|
||||
# main: ./cmd/
|
||||
# binary: "{{ .ProjectName }}.wasm"
|
||||
# env:
|
||||
# - CGO_ENABLED=0
|
||||
# goos:
|
||||
# - js
|
||||
# goarch:
|
||||
# - wasm
|
||||
# flags:
|
||||
# - -trimpath
|
||||
# mod_timestamp: '{{ .CommitTimestamp }}'
|
||||
# ldflags:
|
||||
# - >-
|
||||
# -X main.Version={{ .Tag }}
|
||||
# -X main.GitCommit={{ .Commit }}
|
||||
# -X main.GitTag={{ .Tag }}
|
||||
# -X main.GitDirty={{ .Date }}
|
||||
# -X main.BuildTime={{ .Date }}
|
||||
# -X main.GitRepo={{ .ProjectName }}
|
||||
release:
|
||||
prerelease: auto
|
||||
footer: |
|
||||
Thanks to all the contributors!
|
||||
|
||||
**Full Changelog**: https://github.com/projectcapsule/{{ .ProjectName }}/compare/{{ .PreviousTag }}...{{ .Tag }}
|
||||
|
||||
|
||||
**Docker Images**
|
||||
- `ghcr.io/projectcapsule/{{ .ProjectName }}:{{ .Version }}`
|
||||
- `ghcr.io/projectcapsule/{{ .ProjectName }}:latest`
|
||||
@@ -45,6 +64,21 @@ release:
|
||||
- `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)
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Kubernetes compatibility**
|
||||
>
|
||||
> Note that the Capsule project offers support only for the latest minor version of Kubernetes.
|
||||
> Backwards compatibility with older versions of Kubernetes and OpenShift is [offered by vendors](https://projectcapsule.dev/support/).
|
||||
>
|
||||
> | Kubernetes version | Minimum required |
|
||||
> |--------------------|------------------|
|
||||
> | `v1.33` | `>= 1.33.0` |
|
||||
|
||||
|
||||
Thanks to all the contributors! 🚀 🦄
|
||||
extra_files:
|
||||
- glob: ./capsule-seccomp.json
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
changelog:
|
||||
@@ -61,26 +95,27 @@ changelog:
|
||||
- Merge branch
|
||||
groups:
|
||||
# https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional
|
||||
- title: '🛠 Dependency updates'
|
||||
regexp: '^.*?(feat|fix)\(deps\)!?:.+$'
|
||||
order: 300
|
||||
- title: '✨ New Features'
|
||||
regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$'
|
||||
order: 100
|
||||
- title: '🐛 Bug fixes'
|
||||
regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$'
|
||||
order: 200
|
||||
- title: '📖 Documentation updates'
|
||||
regexp: ^.*?docs(\([[:word:]]+\))??!?:.+$
|
||||
order: 400
|
||||
- title: '🛡️ Security updates'
|
||||
regexp: ^.*?(sec)(\([[:word:]]+\))??!?:.+$
|
||||
order: 500
|
||||
- title: '🚀 Build process updates'
|
||||
regexp: ^.*?(build|ci)(\([[:word:]]+\))??!?:.+$
|
||||
order: 600
|
||||
- title: '📦 Other work'
|
||||
order: 9999
|
||||
- title: '🛠 Dependency updates'
|
||||
regexp: '^fix\(deps\):|^feat\(deps\):'
|
||||
order: 300
|
||||
- title: '✨ New Features'
|
||||
regexp: '^feat(\([^)]*\))?:'
|
||||
order: 100
|
||||
- title: '🐛 Bug fixes'
|
||||
regexp: '^fix(\([^)]*\))?:'
|
||||
order: 200
|
||||
- title: '📖 Documentation updates'
|
||||
regexp: '^docs(\([^)]*\))?:'
|
||||
order: 400
|
||||
- title: '🛡️ Security updates'
|
||||
regexp: '^sec(\([^)]*\))?:'
|
||||
order: 500
|
||||
- title: '🚀 Build process updates'
|
||||
regexp: '^(build|ci)(\([^)]*\))?:'
|
||||
order: 600
|
||||
- title: '📦 Other work'
|
||||
regexp: '^chore(\([^)]*\))?:|^chore:'
|
||||
order: 9999
|
||||
sboms:
|
||||
- artifacts: archive
|
||||
signs:
|
||||
|
||||
4
.ko.yaml
4
.ko.yaml
@@ -4,6 +4,6 @@ defaultPlatforms:
|
||||
- linux/arm
|
||||
builds:
|
||||
- id: capsule
|
||||
main: ./
|
||||
main: ./cmd/
|
||||
ldflags:
|
||||
- '{{ if index .Env "LD_FLAGS" }}{{ .Env.LD_FLAGS }}{{ end }}'
|
||||
- '{{ if index .Env "LD_FLAGS" }}{{ .Env.LD_FLAGS }}{{ end }}'
|
||||
|
||||
14
.nwa-config
Normal file
14
.nwa-config
Normal file
@@ -0,0 +1,14 @@
|
||||
nwa:
|
||||
cmd: "update"
|
||||
holder: "Project Capsule Authors"
|
||||
year: "2020-2025"
|
||||
spdxids: "Apache-2.0"
|
||||
path:
|
||||
- "pkg/**/*.go"
|
||||
- "cmd/**/*.go"
|
||||
- "api/**/*.go"
|
||||
- "controllers/**/*.go"
|
||||
- "main.go"
|
||||
mute: false
|
||||
verbose: true
|
||||
fuzzy: true
|
||||
46
.pre-commit-config.yaml
Normal file
46
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
repos:
|
||||
- repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
|
||||
rev: v9.22.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: v6.0.0
|
||||
hooks:
|
||||
- id: check-executables-have-shebangs
|
||||
- id: double-quote-string-fixer
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/adrienverge/yamllint
|
||||
rev: v1.37.1
|
||||
hooks:
|
||||
- id: yamllint
|
||||
args: [-c=.github/configs/lintconf.yaml]
|
||||
- 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$
|
||||
- id: go-test
|
||||
name: Execute go test
|
||||
entry: make test
|
||||
language: system
|
||||
files: \.go$
|
||||
15
ADOPTERS.md
15
ADOPTERS.md
@@ -2,13 +2,18 @@
|
||||
|
||||
This is a list of companies that have adopted Capsule, feel free to open a Pull-Request to get yours listed.
|
||||
|
||||
[See all on the website](https://projectcapsule.dev/adopters/)
|
||||
|
||||
## Adopters list (alphabetically)
|
||||
|
||||
### [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 +30,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)
|
||||

|
||||
|
||||
@@ -33,3 +41,6 @@ This is a list of companies that have adopted Capsule, feel free to open a Pull-
|
||||
|
||||
### [Wargaming.net](https://www.wargaming.net/)
|
||||

|
||||
|
||||
### [Enreach](https://www.enreach.com/)
|
||||

|
||||
|
||||
@@ -7,4 +7,4 @@ See the [Releases](https://github.com/projectcapsule/capsule/releases)
|
||||
|
||||
## Helm Chart
|
||||
|
||||
For the helm chart, a dedicated changelog is created based on the chart's annotations ([See](./DEVELOPMENT.md#helm-changelog)).
|
||||
For the helm chart, a dedicated changelog is created based on the chart's annotations ([See](./DEVELOPMENT.md#helm-changelog)).
|
||||
|
||||
@@ -45,7 +45,7 @@ Prereleases are marked as `-rc.x` (release candidate) and may refere to any type
|
||||
|
||||
The pull request title is checked according to the described [semantics](#semantics) (pull requests don't require a scope). However pull requests are currently not used to generate the changelog. Check if your pull requests body meets the following criteria:
|
||||
|
||||
- reference a previously opened issue: https://docs.github.com/en/github/writing-on-github/autolinked-references-and-urls#issues-and-pull-requests
|
||||
- reference a previously opened issue: https://docs.github.com/en/github/writing-on-github/autolinked-references-and-urls#issues-and-pull-requests
|
||||
- splitting changes into several and documented small commits
|
||||
- limit the git subject to 50 characters and write as the continuation of the
|
||||
sentence "If applied, this commit will ..."
|
||||
@@ -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>
|
||||
@@ -104,7 +104,7 @@ To reorganise your commits, do the following (or use your way of doing it):
|
||||
|
||||
|
||||
1. Pull upstream changes
|
||||
|
||||
|
||||
```bash
|
||||
git remote add upstream git@github.com:projectcapsule/capsule.git
|
||||
git pull upstream main
|
||||
@@ -180,10 +180,9 @@ 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
|
||||
* `test`: test related changes
|
||||
* `sec`: security related changes
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@ Capsule maintainers must follow these guidelines when consuming third-party pack
|
||||
|
||||
When adding a new third-party package to Capsule, maintainers must follow these steps:
|
||||
|
||||
1. Evaluate the need for the package. Is it necessary for the functionality of Capsule?
|
||||
2. Research the package. Is it well-maintained? Does it have a good reputation?
|
||||
3. Choose a version of the package. Use the latest version whenever possible.
|
||||
4. Pin the package to the specific version in the Capsule codebase.
|
||||
1. Evaluate the need for the package. Is it necessary for the functionality of Capsule?
|
||||
2. Research the package. Is it well-maintained? Does it have a good reputation?
|
||||
3. Choose a version of the package. Use the latest version whenever possible.
|
||||
4. Pin the package to the specific version in the Capsule codebase.
|
||||
5. Update the Capsule documentation to reflect the new dependency.
|
||||
|
||||
## Archive/Deprecation
|
||||
|
||||
@@ -60,7 +60,7 @@ To achieve that, there are some necessary steps we need to walk through, which h
|
||||
|
||||
So the TL;DR answer is:
|
||||
|
||||
**Make sure a *KinD* cluster is running on your laptop, and then run `make dev-setup` to setup the dev environment.**. This is not done in the `make dev-setup` setup.
|
||||
**Make sure a *KinD* cluster is running on your laptop, and then run `make dev-setup` to setup the dev environment.**. This is not done in the `make dev-setup` setup.
|
||||
|
||||
```bash
|
||||
# If you haven't installed or run `make deploy` before, do it first
|
||||
@@ -222,12 +222,12 @@ time="2023-10-23T13:45:08Z" level=info msg="Found Chart directories [charts/caps
|
||||
time="2023-10-23T13:45:08Z" level=info msg="Generating README Documentation for chart /helm-docs/charts/capsule"
|
||||
```
|
||||
|
||||
This will update the documentation for the chart in the `README.md` file.
|
||||
This will update the documentation for the chart in the `README.md` file.
|
||||
|
||||
### Helm Changelog
|
||||
### Helm Changelog
|
||||
|
||||
The `version` of the chart does not require a bump, since it's driven by our release process. The `appVersion` of the chart is the version of the Capsule project. This is the version that should be bumped when a new Capsule version is released. This will be done by the maintainers.
|
||||
|
||||
To create the proper changelog for the helm chart, all changes which affect the helm chart must be documented as chart annotation. See all the available [chart annotations](https://artifacthub.io/docs/topics/annotations/helm/).
|
||||
|
||||
This annotation can be provided using two different formats: using a plain list of strings with the description of the change or using a list of objects with some extra structured information (see example below). Please feel free to use the one that better suits your needs. The UI experience will be slightly different depending on the choice. When using the list of objects option the valid supported kinds are `added`, `changed`, `deprecated`, `removed`, `fixed` and `security`.
|
||||
This annotation can be provided using two different formats: using a plain list of strings with the description of the change or using a list of objects with some extra structured information (see example below). Please feel free to use the one that better suits your needs. The UI experience will be slightly different depending on the choice. When using the list of objects option the valid supported kinds are `added`, `changed`, `deprecated`, `removed`, `fixed` and `security`.
|
||||
|
||||
40
Dockerfile
40
Dockerfile
@@ -1,40 +0,0 @@
|
||||
# Build the manager binary
|
||||
FROM golang:1.20.10 as builder
|
||||
|
||||
WORKDIR /workspace
|
||||
# Copy the Go Modules manifests
|
||||
COPY go.mod go.mod
|
||||
COPY go.sum go.sum
|
||||
# cache deps before building and copying source so that we don't need to re-download as much
|
||||
# and so that source changes don't invalidate our downloaded layer
|
||||
RUN go mod download
|
||||
|
||||
ARG TARGETARCH
|
||||
ARG GIT_HEAD_COMMIT
|
||||
ARG GIT_TAG_COMMIT
|
||||
ARG GIT_LAST_TAG
|
||||
ARG GIT_MODIFIED
|
||||
ARG GIT_REPO
|
||||
ARG BUILD_DATE
|
||||
|
||||
# Copy the go source
|
||||
COPY main.go main.go
|
||||
COPY version.go version.go
|
||||
COPY api/ api/
|
||||
COPY controllers/ controllers/
|
||||
COPY pkg/ pkg/
|
||||
|
||||
# Build
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH GO111MODULE=on go build \
|
||||
-gcflags "-N -l" \
|
||||
-ldflags "-X main.GitRepo=$GIT_REPO -X main.GitTag=$GIT_LAST_TAG -X main.GitCommit=$GIT_HEAD_COMMIT -X main.GitDirty=$GIT_MODIFIED -X main.BuildTime=$BUILD_DATE" \
|
||||
-o manager
|
||||
|
||||
# Use distroless as minimal base image to package the manager binary
|
||||
# Refer to https://github.com/GoogleContainerTools/distroless for more details
|
||||
FROM gcr.io/distroless/static:nonroot
|
||||
WORKDIR /
|
||||
COPY --from=builder /workspace/manager .
|
||||
USER nonroot:nonroot
|
||||
|
||||
ENTRYPOINT ["/manager"]
|
||||
17
Dockerfile.tracing
Normal file
17
Dockerfile.tracing
Normal file
@@ -0,0 +1,17 @@
|
||||
# Target Binary
|
||||
ARG TARGET_IMAGE
|
||||
FROM ${TARGET_IMAGE} AS target
|
||||
|
||||
# Inject Harpoon Image
|
||||
FROM ghcr.io/alegrey91/harpoon:latest
|
||||
WORKDIR /
|
||||
COPY --from=target /ko-app/cmd ./manager
|
||||
RUN chmod +x ./harpoon
|
||||
ENTRYPOINT ["/harpoon", \
|
||||
"capture", \
|
||||
"-f", "main.main", \
|
||||
"-E", "NAMESPACE=capsule-system", \
|
||||
"-i", "2", \
|
||||
"-c", "-e", \
|
||||
"-S", "-D", "/tmp/results/", \
|
||||
"--", "/manager"]
|
||||
@@ -77,7 +77,7 @@ Maintainers who are selected will be granted the necessary GitHub rights.
|
||||
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
|
||||
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.
|
||||
|
||||
@@ -88,7 +88,7 @@ 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.
|
||||
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
|
||||
@@ -110,7 +110,7 @@ violations by community members will be discussed and resolved in private Mainta
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
@@ -119,15 +119,15 @@ 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)",
|
||||
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
|
||||
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.
|
||||
Changes to this Governance and its supporting documents may be approved by
|
||||
a 2/3 vote of the Maintainers.
|
||||
|
||||
@@ -6,8 +6,9 @@ The current Maintainers Group for the [TODO: Projectname] Project consists of:
|
||||
| Dario Tranchitella | Clastix | Maintainer |
|
||||
| Maksim Fedotov | Wargaming | Maintainer |
|
||||
| Oliver Bähler | Peak Scale | Maintainer |
|
||||
| Hristo Hristov | Vaerolabs | 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.
|
||||
See [the project Governance](GOVERNANCE.md) for how maintainers are selected and replaced.
|
||||
|
||||
328
Makefile
328
Makefile
@@ -16,6 +16,14 @@ BUILD_DATE ?= $(shell git log -1 --format="%at" | xargs -I{} sh -c 'if [ "$
|
||||
IMG_BASE ?= $(REPOSITORY)
|
||||
IMG ?= $(IMG_BASE):$(VERSION)
|
||||
CAPSULE_IMG ?= $(REGISTRY)/$(IMG_BASE)
|
||||
CLUSTER_NAME ?= capsule
|
||||
|
||||
## Kubernetes Version Support
|
||||
KUBERNETES_SUPPORTED_VERSION ?= "v1.33.0"
|
||||
|
||||
## Tool Binaries
|
||||
KUBECTL ?= kubectl
|
||||
HELM ?= helm
|
||||
|
||||
# Options for 'bundle-build'
|
||||
ifneq ($(origin CHANNELS), undefined)
|
||||
@@ -38,7 +46,7 @@ all: manager
|
||||
# Run tests
|
||||
.PHONY: test
|
||||
test: test-clean generate manifests test-clean
|
||||
@GO111MODULE=on go test -v ./... -coverprofile coverage.out
|
||||
@GO111MODULE=on go test -v $(shell go list ./... | grep -v "e2e") -coverprofile coverage.out
|
||||
|
||||
.PHONY: test-clean
|
||||
test-clean: ## Clean tests cache
|
||||
@@ -53,43 +61,53 @@ run: generate manifests
|
||||
go run .
|
||||
|
||||
# Generate manifests e.g. CRD, RBAC etc.
|
||||
manifests: controller-gen
|
||||
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=charts/capsule/crds
|
||||
manifests: generate
|
||||
$(CONTROLLER_GEN) crd paths="./..." output:crd:artifacts:config=charts/capsule/crds
|
||||
|
||||
# Generate code
|
||||
generate: controller-gen
|
||||
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
|
||||
|
||||
|
||||
# Generate License Header
|
||||
license-headers: nwa
|
||||
$(NWA) config
|
||||
|
||||
# Helm
|
||||
SRC_ROOT = $(shell git rev-parse --show-toplevel)
|
||||
|
||||
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-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-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-docs: helm-doc
|
||||
$(HELM_DOCS) --chart-search-root ./charts
|
||||
|
||||
helm-test: kind ct ko-build-all
|
||||
@kind create cluster --wait=60s --name capsule-charts
|
||||
helm-lint: ct
|
||||
@$(CT) lint --config .github/configs/ct.yaml --validate-yaml=false --all --debug
|
||||
|
||||
helm-schema: helm-plugin-schema
|
||||
cd charts/capsule && $(HELM) schema --use-helm-docs
|
||||
|
||||
helm-test: HELM_KIND_CONFIG ?= ""
|
||||
helm-test: kind
|
||||
@mkdir -p /tmp/results || true
|
||||
@$(KIND) create cluster --wait=60s --name capsule-charts --image kindest/node:$(KUBERNETES_SUPPORTED_VERSION) --config $(HELM_KIND_CONFIG)
|
||||
@make helm-test-exec
|
||||
@kind delete cluster --name capsule-charts
|
||||
@$(KIND) delete cluster --name capsule-charts
|
||||
|
||||
helm-test-exec:
|
||||
@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
|
||||
|
||||
docker:
|
||||
@hash docker 2>/dev/null || {\
|
||||
echo "You need docker" &&\
|
||||
exit 1;\
|
||||
}
|
||||
helm-test-exec: ct helm-controller-version ko-build-all
|
||||
$(MAKE) docker-build-capsule-trace
|
||||
$(MAKE) e2e-load-image CLUSTER_NAME=capsule-charts IMAGE=$(CAPSULE_IMG) VERSION=v0.0.0
|
||||
$(MAKE) e2e-load-image CLUSTER_NAME=capsule-charts IMAGE=$(CAPSULE_IMG) VERSION=tracing
|
||||
@$(KUBECTL) create ns capsule-system || true
|
||||
@$(KUBECTL) apply --force-conflicts --server-side=true -f https://github.com/grafana/grafana-operator/releases/download/v5.18.0/crds.yaml
|
||||
@$(KUBECTL) apply --force-conflicts --server-side=true -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.crds.yaml
|
||||
@$(KUBECTL) apply --force-conflicts --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
|
||||
|
||||
# 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
|
||||
@@ -111,7 +129,6 @@ IP.1 = $(LAPTOP_HOST_IP)
|
||||
endef
|
||||
export TLS_CNF
|
||||
dev-setup:
|
||||
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 \
|
||||
@@ -120,10 +137,13 @@ 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'`; \
|
||||
helm upgrade \
|
||||
$(HELM) upgrade \
|
||||
--dependency-update \
|
||||
--debug \
|
||||
--install \
|
||||
@@ -136,6 +156,7 @@ dev-setup:
|
||||
--set "webhooks.service.caBundle=$${CA_BUNDLE}" \
|
||||
capsule \
|
||||
./charts/capsule
|
||||
$(KUBECTL) -n capsule-system scale deployment capsule-controller-manager --replicas=0 || true
|
||||
|
||||
####################
|
||||
# -- Docker
|
||||
@@ -163,11 +184,19 @@ LD_FLAGS := "-X main.Version=$(VERSION) \
|
||||
ko-build-capsule: ko
|
||||
@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 --platform=$(KO_PLATFORM)
|
||||
$(KO) build ./cmd/ --bare --tags=$(KO_TAGS) --push=false --local --platform=$(KO_PLATFORM)
|
||||
|
||||
.PHONY: ko-build-all
|
||||
ko-build-all: ko-build-capsule
|
||||
|
||||
.PHONY: docker-build-capsule-trace
|
||||
docker-build-capsule-trace: ko-build-capsule
|
||||
@docker build \
|
||||
--no-cache \
|
||||
--build-arg TARGET_IMAGE=$(CAPSULE_IMG):$(VERSION) \
|
||||
-t $(CAPSULE_IMG):tracing \
|
||||
-f Dockerfile.tracing .
|
||||
|
||||
# Docker Image Publish
|
||||
# ------------------
|
||||
|
||||
@@ -181,104 +210,46 @@ ko-login: ko
|
||||
.PHONY: ko-publish-capsule
|
||||
ko-publish-capsule: ko-login ## Build and publish kyvernopre image (with ko)
|
||||
@LD_FLAGS=$(LD_FLAGS) KOCACHE=$(KOCACHE) KO_DOCKER_REPO=$(CAPSULE_IMG) \
|
||||
$(KO) build ./ --bare --tags=$(KO_TAGS)
|
||||
$(KO) build ./cmd/ --bare --tags=$(KO_TAGS)
|
||||
|
||||
.PHONY: ko-publish-all
|
||||
ko-publish-all: ko-publish-capsule
|
||||
|
||||
####################
|
||||
# -- Binaries
|
||||
####################
|
||||
|
||||
CONTROLLER_GEN := $(shell pwd)/bin/controller-gen
|
||||
CONTROLLER_GEN_VERSION := v0.15.0
|
||||
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))
|
||||
|
||||
GINKGO := $(shell pwd)/bin/ginkgo
|
||||
GINGKO_VERSION := v2.17.2
|
||||
ginkgo: ## Download ginkgo locally if necessary.
|
||||
$(call go-install-tool,$(GINKGO),github.com/onsi/ginkgo/v2/ginkgo@$(GINGKO_VERSION))
|
||||
|
||||
CT := $(shell pwd)/bin/ct
|
||||
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))
|
||||
|
||||
KIND := $(shell pwd)/bin/kind
|
||||
KIND_VERSION := v0.17.0
|
||||
kind: ## Download kind locally if necessary.
|
||||
$(call go-install-tool,$(KIND),sigs.k8s.io/kind/cmd/kind@$(KIND_VERSION))
|
||||
|
||||
KUSTOMIZE := $(shell pwd)/bin/kustomize
|
||||
KUSTOMIZE_VERSION := 3.8.7
|
||||
kustomize: ## Download kustomize locally if necessary.
|
||||
$(call install-kustomize,$(KUSTOMIZE),$(KUSTOMIZE_VERSION))
|
||||
|
||||
KO = $(shell pwd)/bin/ko
|
||||
KO_VERSION = v0.14.1
|
||||
ko:
|
||||
$(call go-install-tool,$(KO),github.com/google/ko@$(KO_VERSION))
|
||||
|
||||
####################
|
||||
# -- Helpers
|
||||
####################
|
||||
pull-upstream:
|
||||
git remote add upstream https://github.com/capsuleproject/capsule.git
|
||||
git fetch --all && git pull upstream
|
||||
|
||||
define install-kustomize
|
||||
@[ -f $(1) ] || { \
|
||||
set -e ;\
|
||||
echo "Installing v$(2)" ;\
|
||||
cd bin ;\
|
||||
wget "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" ;\
|
||||
bash ./install_kustomize.sh $(2) ;\
|
||||
}
|
||||
endef
|
||||
|
||||
# go-install-tool will 'go install' any package $2 and install it to $1.
|
||||
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||
define go-install-tool
|
||||
@[ -f $(1) ] || { \
|
||||
set -e ;\
|
||||
GOBIN=$(PROJECT_DIR)/bin go install $(2) ;\
|
||||
}
|
||||
endef
|
||||
|
||||
# Generate bundle manifests and metadata, then validate generated files.
|
||||
bundle: manifests
|
||||
operator-sdk generate kustomize manifests -q
|
||||
kustomize build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS)
|
||||
operator-sdk bundle validate ./bundle
|
||||
|
||||
# Sorting imports
|
||||
.PHONY: goimports
|
||||
goimports:
|
||||
goimports -w -l -local "github.com/projectcapsule/capsule" .
|
||||
|
||||
GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint
|
||||
GOLANGCI_LINT_VERSION = v1.56.2
|
||||
golangci-lint: ## Download golangci-lint locally if necessary.
|
||||
$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION))
|
||||
|
||||
# Linting code as PR is expecting
|
||||
.PHONY: golint
|
||||
golint: golangci-lint
|
||||
$(GOLANGCI_LINT) run -c .golangci.yml
|
||||
$(GOLANGCI_LINT) run -c .golangci.yaml --verbose
|
||||
|
||||
.PHONY: golint-fix
|
||||
golint-fix: golangci-lint
|
||||
$(GOLANGCI_LINT) run -c .golangci.yaml --verbose --fix
|
||||
|
||||
|
||||
# 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-install
|
||||
API_GW := none
|
||||
API_GW_VERSION := v1.3.0
|
||||
API_GW_LOOKUP := kubernetes-sigs/gateway-api/
|
||||
e2e-install-deps:
|
||||
@$(KUBECTL) apply --force-conflicts --server-side=true -f https://github.com/$(API_GW_LOOKUP)/releases/download/$(API_GW_VERSION)/standard-install.yaml
|
||||
|
||||
e2e-build: kind
|
||||
$(KIND) create cluster --wait=60s --name $(CLUSTER_NAME) --image kindest/node:$(KUBERNETES_SUPPORTED_VERSION)
|
||||
$(MAKE) e2e-install-deps
|
||||
$(MAKE) e2e-install
|
||||
|
||||
.PHONY: e2e-install
|
||||
e2e-install: e2e-load-image
|
||||
helm upgrade \
|
||||
e2e-install: ko-build-all
|
||||
$(MAKE) e2e-load-image CLUSTER_NAME=$(CLUSTER_NAME) IMAGE=$(CAPSULE_IMG) VERSION=$(VERSION)
|
||||
$(HELM) upgrade \
|
||||
--dependency-update \
|
||||
--debug \
|
||||
--install \
|
||||
@@ -292,19 +263,152 @@ e2e-install: e2e-load-image
|
||||
capsule \
|
||||
./charts/capsule
|
||||
|
||||
.PHONY: trace-install
|
||||
trace-install:
|
||||
helm upgrade \
|
||||
--dependency-update \
|
||||
--debug \
|
||||
--install \
|
||||
--namespace capsule-system \
|
||||
--create-namespace \
|
||||
--set 'manager.resources=null'\
|
||||
--set 'manager.livenessProbe.failureThreshold=10' \
|
||||
--set 'manager.readinessProbe.failureThreshold=10' \
|
||||
--values charts/capsule/ci/tracing-values.yaml \
|
||||
capsule \
|
||||
./charts/capsule
|
||||
|
||||
.PHONY: trace-e2e
|
||||
trace-e2e: kind
|
||||
$(MAKE) docker-build-capsule-trace
|
||||
$(KIND) create cluster --wait=60s --image kindest/node:$(KUBERNETES_SUPPORTED_VERSION) --config hack/kind-cluster.yml
|
||||
$(MAKE) e2e-load-image CLUSTER_NAME=capsule-tracing IMAGE=$(CAPSULE_IMG) VERSION=tracing
|
||||
$(MAKE) trace-install
|
||||
$(MAKE) e2e-install-deps
|
||||
$(MAKE) e2e-exec
|
||||
$(KIND) delete cluster --name capsule-tracing
|
||||
|
||||
.PHONY: trace-unit
|
||||
trace-unit: harpoon
|
||||
$(HARPOON) analyze -e .git/ -e assets/ -e charts/ -e config/ -e docs/ -e e2e/ -e hack/ --directory /tmp/artifacts/ --save
|
||||
$(HARPOON) hunt -D /tmp/results -F harpoon-report.yml --include-cmd-stdout --save
|
||||
|
||||
.PHONY: seccomp
|
||||
seccomp:
|
||||
$(HARPOON) build --add-syscall-sets=dynamic,docker -D /tmp/results --name capsule-seccomp.json --save
|
||||
|
||||
.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
|
||||
$(KIND) load docker-image $(IMAGE):$(VERSION) --name $(CLUSTER_NAME)
|
||||
|
||||
.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" "!general/crds-apis.md" -d dictionary.txt
|
||||
|
||||
####################
|
||||
# -- Helpers
|
||||
####################
|
||||
pull-upstream:
|
||||
git remote add upstream https://github.com/capsuleproject/capsule.git
|
||||
git fetch --all && git pull upstream
|
||||
|
||||
## Location to install dependencies to
|
||||
LOCALBIN ?= $(shell pwd)/bin
|
||||
$(LOCALBIN):
|
||||
mkdir -p $(LOCALBIN)
|
||||
|
||||
####################
|
||||
# -- 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
|
||||
|
||||
HELM_DOCS := $(LOCALBIN)/helm-docs
|
||||
HELM_DOCS_VERSION := v1.14.1
|
||||
HELM_DOCS_LOOKUP := norwoodj/helm-docs
|
||||
helm-doc:
|
||||
@test -s $(HELM_DOCS) || \
|
||||
$(call go-install-tool,$(HELM_DOCS),github.com/$(HELM_DOCS_LOOKUP)/cmd/helm-docs@$(HELM_DOCS_VERSION))
|
||||
|
||||
####################
|
||||
# -- Tools
|
||||
####################
|
||||
CONTROLLER_GEN := $(LOCALBIN)/controller-gen
|
||||
CONTROLLER_GEN_VERSION ?= v0.18.0
|
||||
CONTROLLER_GEN_LOOKUP := kubernetes-sigs/controller-tools
|
||||
controller-gen:
|
||||
@test -s $(CONTROLLER_GEN) && $(CONTROLLER_GEN) --version | grep -q $(CONTROLLER_GEN_VERSION) || \
|
||||
$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION))
|
||||
|
||||
GINKGO := $(LOCALBIN)/ginkgo
|
||||
ginkgo:
|
||||
$(call go-install-tool,$(GINKGO),github.com/onsi/ginkgo/v2/ginkgo)
|
||||
|
||||
CT := $(LOCALBIN)/ct
|
||||
CT_VERSION := v3.13.0
|
||||
CT_LOOKUP := helm/chart-testing
|
||||
ct:
|
||||
@test -s $(CT) && $(CT) version | grep -q $(CT_VERSION) || \
|
||||
$(call go-install-tool,$(CT),github.com/$(CT_LOOKUP)/v3/ct@$(CT_VERSION))
|
||||
|
||||
KIND := $(LOCALBIN)/kind
|
||||
KIND_VERSION := v0.29.0
|
||||
KIND_LOOKUP := kubernetes-sigs/kind
|
||||
kind:
|
||||
@test -s $(KIND) && $(KIND) --version | grep -q $(KIND_VERSION) || \
|
||||
$(call go-install-tool,$(KIND),sigs.k8s.io/kind/cmd/kind@$(KIND_VERSION))
|
||||
|
||||
KO := $(LOCALBIN)/ko
|
||||
KO_VERSION := v0.18.0
|
||||
KO_LOOKUP := google/ko
|
||||
ko:
|
||||
@test -s $(KO) && $(KO) -h | grep -q $(KO_VERSION) || \
|
||||
$(call go-install-tool,$(KO),github.com/$(KO_LOOKUP)@$(KO_VERSION))
|
||||
|
||||
NWA := $(LOCALBIN)/nwa
|
||||
NWA_VERSION := v0.7.5
|
||||
NWA_LOOKUP := B1NARY-GR0UP/nwa
|
||||
nwa:
|
||||
@test -s $(NWA) && $(NWA) -h | grep -q $(NWA_VERSION) || \
|
||||
$(call go-install-tool,$(NWA),github.com/$(NWA_LOOKUP)@$(NWA_VERSION))
|
||||
|
||||
GOLANGCI_LINT := $(LOCALBIN)/golangci-lint
|
||||
GOLANGCI_LINT_VERSION := v2.4.0
|
||||
GOLANGCI_LINT_LOOKUP := golangci/golangci-lint
|
||||
golangci-lint: ## Download golangci-lint locally if necessary.
|
||||
@test -s $(GOLANGCI_LINT) && $(GOLANGCI_LINT) -h | grep -q $(GOLANGCI_LINT_VERSION) || \
|
||||
$(call go-install-tool,$(GOLANGCI_LINT),github.com/$(GOLANGCI_LINT_LOOKUP)/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION))
|
||||
|
||||
APIDOCS_GEN := $(LOCALBIN)/crdoc
|
||||
APIDOCS_GEN_VERSION := v0.6.4
|
||||
APIDOCS_GEN_LOOKUP := fybrik/crdoc
|
||||
apidocs-gen: ## Download crdoc locally if necessary.
|
||||
@test -s $(APIDOCS_GEN) && $(APIDOCS_GEN) --version | grep -q $(APIDOCS_GEN_VERSION) || \
|
||||
$(call go-install-tool,$(APIDOCS_GEN),fybrik.io/crdoc@$(APIDOCS_GEN_VERSION))
|
||||
|
||||
HARPOON := $(LOCALBIN)/harpoon
|
||||
HARPOON_VERSION := v0.10.2
|
||||
HARPOON_LOOKUP := alegrey91/harpoon
|
||||
harpoon:
|
||||
@mkdir $(LOCALBIN)
|
||||
@curl -s https://raw.githubusercontent.com/alegrey91/harpoon/main/install | \
|
||||
sudo bash -s -- --install-version $(HARPOON_VERSION) --install-dir $(LOCALBIN)
|
||||
|
||||
# go-install-tool will 'go install' any package $2 and install it to $1.
|
||||
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||
define go-install-tool
|
||||
[ -f $(1) ] || { \
|
||||
set -e ;\
|
||||
GOBIN=$(LOCALBIN) go install $(2) ;\
|
||||
}
|
||||
endef
|
||||
|
||||
22
PROJECT
22
PROJECT
@@ -1,6 +1,10 @@
|
||||
# Code generated by tool. DO NOT EDIT.
|
||||
# This file is used to track the info used to scaffold your project
|
||||
# and allow the plugins properly work.
|
||||
# More info: https://book.kubebuilder.io/reference/project-config.html
|
||||
domain: clastix.io
|
||||
layout:
|
||||
- go.kubebuilder.io/v3
|
||||
- go.kubebuilder.io/v4
|
||||
plugins:
|
||||
manifests.sdk.operatorframework.io/v2: {}
|
||||
scorecard.sdk.operatorframework.io/v2: {}
|
||||
@@ -44,4 +48,20 @@ resources:
|
||||
kind: GlobalTenantResource
|
||||
path: github.com/projectcapsule/capsule/api/v1beta2
|
||||
version: v1beta2
|
||||
- api:
|
||||
crdVersion: v1
|
||||
domain: clastix.io
|
||||
group: capsule
|
||||
kind: ResourcePool
|
||||
path: github.com/projectcapsule/capsule/api/v1beta2
|
||||
version: v1beta2
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: clastix.io
|
||||
group: capsule
|
||||
kind: ResourcePoolClaim
|
||||
path: github.com/projectcapsule/capsule/api/v1beta2
|
||||
version: v1beta2
|
||||
version: "3"
|
||||
|
||||
48
README.md
48
README.md
@@ -23,7 +23,7 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/logo/capsule_medium.png" />
|
||||
<img src="assets/logo/capsule.svg" height=560 />
|
||||
</p>
|
||||
|
||||
---
|
||||
@@ -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,30 +76,12 @@ 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
|
||||
|
||||
Capsule is Open Source with Apache 2 license and any contribution is welcome.
|
||||
|
||||
## Chart Development
|
||||
|
||||
### Chart Linting
|
||||
|
||||
The chart is linted with [ct](https://github.com/helm/chart-testing). You can run the linter locally with this command:
|
||||
|
||||
```
|
||||
make helm-lint
|
||||
```
|
||||
|
||||
### Chart Documentation
|
||||
|
||||
The documentation for each chart is done with [helm-docs](https://github.com/norwoodj/helm-docs). This way we can ensure that values are consistent with the chart documentation. Run this anytime you make changes to a `values.yaml` file:
|
||||
|
||||
```
|
||||
make helm-docs
|
||||
```
|
||||
|
||||
## Community meeting
|
||||
|
||||
Join the community, share and learn from it. You can find all the resources to how to contribute code and docs, connect with people in the [community repository](https://github.com/projectcapsule/capsule-community).
|
||||
@@ -110,17 +92,19 @@ 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).
|
||||
Please refer to the maintainers file available [here](.github/maintainers.yaml).
|
||||
|
||||
## Release process
|
||||
## CLOMonitor
|
||||
|
||||
Please, refer to the [documentation page](https://capsule.clastix.io/docs/contributing/release).
|
||||
CLOMonitor is a tool that periodically checks open source project repositories to verify they meet certain project health best practices.
|
||||
|
||||
[](https://clomonitor.io/projects/cncf/capsule)
|
||||
|
||||
### Changelog
|
||||
|
||||
@@ -128,22 +112,22 @@ Read how we log changes [here](CHANGELOG.md)
|
||||
|
||||
### Software Bill of Materials
|
||||
|
||||
All OCI release artifacts include a Software Bill of Materials (SBOM) in CycloneDX JSON format. More information on this is available [here](SECURITY.md#software-bill-of-materials-sbom)
|
||||
All OCI release artifacts include a Software Bill of Materials (SBOM) in CycloneDX JSON format. More information about this is available [here](SECURITY.md#software-bill-of-materials-sbom)
|
||||
|
||||
# FAQ
|
||||
|
||||
- Q. How to pronounce Capsule?
|
||||
- Q. How do you pronounce Capsule?
|
||||
|
||||
A. It should be pronounced as `/ˈkæpsjuːl/`.
|
||||
|
||||
- Q. Is it production grade?
|
||||
|
||||
A. Although under frequent development and improvements, Capsule is ready to be used in production environments as currently, people are using it in public and private deployments. Check out the [release](https://github.com/projectcapsule/capsule/releases) page for a detailed list of available versions.
|
||||
A. Although under frequent development and improvement, Capsule is ready to be used in production environments as currently, people are using it in public and private deployments. Check out the [release](https://github.com/projectcapsule/capsule/releases) page for a detailed list of available versions.
|
||||
|
||||
- Q. Does it work with my Kubernetes XYZ distribution?
|
||||
|
||||
A. We tested Capsule with vanilla Kubernetes 1.16+ on private environments and public clouds. We expect it to work smoothly on any other Kubernetes distribution. Please, let us know if you find it doesn't.
|
||||
A. We tested Capsule with vanilla Kubernetes 1.16+ on private environments and public clouds. We expect it to work smoothly on any other Kubernetes distribution. Please let us know if you find it doesn't.
|
||||
|
||||
- Q. Do you provide commercial support?
|
||||
|
||||
A. Yes, we're available to help and provide commercial support. [Clastix](https://clastix.io) is the company behind Capsule. Please, contact us for a quote.
|
||||
A. Yes, we're available to help and provide commercial support. [Clastix](https://clastix.io) is the company behind Capsule. Please, contact us for a quote.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Roadmap
|
||||
|
||||
future features and fixes are planned with [release milestones on GitHub](https://github.com/projectcapsule/capsule/milestones?direction=asc&sort=due_date&state=open). You can influence the roadmap by opening issues or joining our community meetings.
|
||||
future features and fixes are planned with [release milestones on GitHub](https://github.com/projectcapsule/capsule/milestones?direction=asc&sort=due_date&state=open). You can influence the roadmap by opening issues or joining our community meetings.
|
||||
|
||||
@@ -57,4 +57,3 @@ security-contacts:
|
||||
- type: email
|
||||
value: cncf-capsule-maintainers@lists.cncf.io
|
||||
primary: true
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ Capsule was accepted as a CNCF sandbox project in December 2022.
|
||||
It's the Operator which provides all the multi-tenant capabilities offered by Capsule.
|
||||
It's made of two internal components, such as the webhooks server (known as _policy engine_), and the _tenant controller_.
|
||||
|
||||
**Capsule Tenant Controller**
|
||||
**Capsule Tenant Controller**
|
||||
|
||||
The controller is responsible for managing the tenants by reconciling the required objects at the Namespace level, such as _Network Policy_, _LimitRange_, _ResourceQuota_, _Role Binding_, as well as labelling the Namespace objects belonging to a Tenant according to their desired metadata.
|
||||
It is responsible for binding Namespaces to the selected Tenant, and managing their lifecycle.
|
||||
@@ -90,10 +90,10 @@ Furthermore, the manager can replicate objects thanks to the **Tenant Resource**
|
||||
|
||||
The replicated resources are dynamically created, and replicated by Capsule itself, as well as preserving the deletion of these objects by the Tenant owner.
|
||||
|
||||
**Capsule Tenant Controller (Policy Engine)**
|
||||
**Capsule Tenant Controller (Policy Engine)**
|
||||
|
||||
Policies are defined on a Tenant basis: therefore the policy engine is enforcing these policies on the tenants's Namespaces and their children's resources.
|
||||
The Policy Engine is currently not a dedicated component, but a part of the Capsule Tenant Controller.
|
||||
The Policy Engine is currently not a dedicated component, but a part of the Capsule Tenant Controller.
|
||||
|
||||
The webhook server, also known as the policy engine, interpolates the Tenant rules and takes full advantage of the dynamic admission controllers offered by Kubernetes itself (such as `ValidatingWebhookConfiguration` and `MutatingWebhookConfiguration`).
|
||||
Thanks to the _policy engine_ the cluster administrators can enforce specific rules such as preventing _Pod_ objects from untrusted registries to run or preventing the creation of _PersistentVolumeClaim_ resources using a non-allowed _StorageClass_, etc.
|
||||
@@ -152,7 +152,7 @@ This is a further abstraction from having cluster defaults (eg. default `Storage
|
||||
|
||||
**General**
|
||||
|
||||
* **Control Plane**: Capsule can't mimic for each tenant a feeling of a dedicated control plane.
|
||||
* **Control Plane**: Capsule can't mimic for each tenant a feeling of a dedicated control plane.
|
||||
|
||||
* **Custom Resource Definitions**: Capsule doesn't want to provide virtual cluster capabilities and it's sticking to the native Kubernetes user experience and design; rather, its focus is to provide a governance solution by focusing on resource optimization and security lockdown.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package v1beta1 contains API Schema definitions for the capsule v1beta1 API group
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
@@ -65,7 +65,8 @@ func (in *Tenant) Hub() {}
|
||||
type TenantList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Tenant `json:"items"`
|
||||
|
||||
Items []Tenant `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
@@ -14,6 +14,9 @@ type CapsuleConfigurationSpec struct {
|
||||
// Names of the groups for Capsule users.
|
||||
// +kubebuilder:default={capsule.clastix.io}
|
||||
UserGroups []string `json:"userGroups,omitempty"`
|
||||
// Define groups which when found in the request of a user will be ignored by the Capsule
|
||||
// this might be useful if you have one group where all the users are in, but you want to separate administrators from normal users with additional groups.
|
||||
IgnoreUserWithGroups []string `json:"ignoreUserWithGroups,omitempty"`
|
||||
// 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.
|
||||
// +kubebuilder:default=false
|
||||
@@ -71,7 +74,8 @@ type CapsuleConfiguration struct {
|
||||
type CapsuleConfigurationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []CapsuleConfiguration `json:"items"`
|
||||
|
||||
Items []CapsuleConfiguration `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
12
api/v1beta2/gateway_options.go
Normal file
12
api/v1beta2/gateway_options.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
)
|
||||
|
||||
type GatewayOptions struct {
|
||||
AllowedClasses *api.SelectionListWithDefaultSpec `json:"allowedClasses,omitempty"`
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package v1beta2 contains API Schema definitions for the capsule v1beta2 API group
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
@@ -13,6 +13,8 @@ type NamespaceOptions struct {
|
||||
Quota *int32 `json:"quota,omitempty"`
|
||||
// Specifies additional labels and annotations the Capsule operator places on any Namespace resource in the Tenant. Optional.
|
||||
AdditionalMetadata *api.AdditionalMetadataSpec `json:"additionalMetadata,omitempty"`
|
||||
// Specifies additional labels and annotations the Capsule operator places on any Namespace resource in the Tenant via a list. Optional.
|
||||
AdditionalMetadataList []api.AdditionalMetadataSelectorSpec `json:"additionalMetadataList,omitempty"`
|
||||
// Define the labels that a Tenant Owner cannot set for their Namespace resources.
|
||||
ForbiddenLabels api.ForbiddenListSpec `json:"forbiddenLabels,omitempty"`
|
||||
// Define the annotations that a Tenant Owner cannot set for their Namespace resources.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
276
api/v1beta2/resourcepool_func.go
Normal file
276
api/v1beta2/resourcepool_func.go
Normal file
@@ -0,0 +1,276 @@
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
)
|
||||
|
||||
func (r *ResourcePool) AssignNamespaces(namespaces []corev1.Namespace) {
|
||||
var l []string
|
||||
|
||||
for _, ns := range namespaces {
|
||||
if ns.Status.Phase == corev1.NamespaceActive && ns.DeletionTimestamp == nil {
|
||||
l = append(l, ns.GetName())
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(l)
|
||||
|
||||
r.Status.NamespaceSize = uint(len(l))
|
||||
r.Status.Namespaces = l
|
||||
}
|
||||
|
||||
func (r *ResourcePool) AssignClaims() {
|
||||
var size uint
|
||||
|
||||
for _, claims := range r.Status.Claims {
|
||||
for range claims {
|
||||
size++
|
||||
}
|
||||
}
|
||||
|
||||
r.Status.ClaimSize = size
|
||||
}
|
||||
|
||||
func (r *ResourcePool) GetClaimFromStatus(cl *ResourcePoolClaim) *ResourcePoolClaimsItem {
|
||||
ns := cl.Namespace
|
||||
|
||||
claims := r.Status.Claims[ns]
|
||||
if claims == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, claim := range claims {
|
||||
if claim.UID == cl.UID {
|
||||
return claim
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ResourcePool) AddClaimToStatus(claim *ResourcePoolClaim) {
|
||||
ns := claim.Namespace
|
||||
|
||||
if r.Status.Claims == nil {
|
||||
r.Status.Claims = ResourcePoolNamespaceClaimsStatus{}
|
||||
}
|
||||
|
||||
if r.Status.Allocation.Claimed == nil {
|
||||
r.Status.Allocation.Claimed = corev1.ResourceList{}
|
||||
}
|
||||
|
||||
claims := r.Status.Claims[ns]
|
||||
if claims == nil {
|
||||
claims = ResourcePoolClaimsList{}
|
||||
}
|
||||
|
||||
scl := &ResourcePoolClaimsItem{
|
||||
StatusNameUID: api.StatusNameUID{
|
||||
UID: claim.UID,
|
||||
Name: api.Name(claim.Name),
|
||||
},
|
||||
Claims: claim.Spec.ResourceClaims,
|
||||
}
|
||||
|
||||
// Try to update existing entry if UID matches
|
||||
exists := false
|
||||
|
||||
for i, cl := range claims {
|
||||
if cl.UID == claim.UID {
|
||||
claims[i] = scl
|
||||
|
||||
exists = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !exists {
|
||||
claims = append(claims, scl)
|
||||
}
|
||||
|
||||
r.Status.Claims[ns] = claims
|
||||
|
||||
r.CalculateClaimedResources()
|
||||
}
|
||||
|
||||
func (r *ResourcePool) RemoveClaimFromStatus(claim *ResourcePoolClaim) {
|
||||
newClaims := ResourcePoolClaimsList{}
|
||||
|
||||
claims, ok := r.Status.Claims[claim.Namespace]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
for _, cl := range claims {
|
||||
if cl.UID != claim.UID {
|
||||
newClaims = append(newClaims, cl)
|
||||
}
|
||||
}
|
||||
|
||||
r.Status.Claims[claim.Namespace] = newClaims
|
||||
|
||||
if len(newClaims) == 0 {
|
||||
delete(r.Status.Claims, claim.Namespace)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ResourcePool) CalculateClaimedResources() {
|
||||
usage := corev1.ResourceList{}
|
||||
|
||||
for res := range r.Status.Allocation.Hard {
|
||||
usage[res] = resource.MustParse("0")
|
||||
}
|
||||
|
||||
for _, claims := range r.Status.Claims {
|
||||
for _, claim := range claims {
|
||||
for resourceName, qt := range claim.Claims {
|
||||
amount, exists := usage[resourceName]
|
||||
if !exists {
|
||||
amount = resource.MustParse("0")
|
||||
}
|
||||
|
||||
amount.Add(qt)
|
||||
usage[resourceName] = amount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r.Status.Allocation.Claimed = usage
|
||||
|
||||
r.CalculateAvailableResources()
|
||||
}
|
||||
|
||||
func (r *ResourcePool) CalculateAvailableResources() {
|
||||
available := corev1.ResourceList{}
|
||||
|
||||
for res, qt := range r.Status.Allocation.Hard {
|
||||
amount, exists := r.Status.Allocation.Claimed[res]
|
||||
if exists {
|
||||
qt.Sub(amount)
|
||||
}
|
||||
|
||||
available[res] = qt
|
||||
}
|
||||
|
||||
r.Status.Allocation.Available = available
|
||||
}
|
||||
|
||||
func (r *ResourcePool) CanClaimFromPool(claim corev1.ResourceList) []error {
|
||||
claimable := r.GetAvailableClaimableResources()
|
||||
errs := []error{}
|
||||
|
||||
for resourceName, req := range claim {
|
||||
available, exists := claimable[resourceName]
|
||||
if !exists || available.IsZero() || available.Cmp(req) < 0 {
|
||||
errs = append(errs, errors.New("not enough resources"+string(resourceName)+"available"))
|
||||
}
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func (r *ResourcePool) GetAvailableClaimableResources() corev1.ResourceList {
|
||||
hard := r.Status.Allocation.Hard.DeepCopy()
|
||||
|
||||
for resourceName, qt := range hard {
|
||||
claimed, exists := r.Status.Allocation.Claimed[resourceName]
|
||||
if !exists {
|
||||
claimed = resource.MustParse("0")
|
||||
}
|
||||
|
||||
qt.Sub(claimed)
|
||||
|
||||
hard[resourceName] = qt
|
||||
}
|
||||
|
||||
return hard
|
||||
}
|
||||
|
||||
// Gets the Hard specification for the resourcequotas
|
||||
// This takes into account the default resources being used. However they don't count towards the claim usage
|
||||
// This can be changed in the future, the default is not calculated as usage because this might interrupt the namespace management
|
||||
// As we would need to verify if a new namespace with it's defaults still has place in the Pool. Same with attempting to join existing namespaces.
|
||||
func (r *ResourcePool) GetResourceQuotaHardResources(namespace string) corev1.ResourceList {
|
||||
_, claimed := r.GetNamespaceClaims(namespace)
|
||||
|
||||
for resourceName, amount := range claimed {
|
||||
if amount.IsZero() {
|
||||
delete(claimed, resourceName)
|
||||
}
|
||||
}
|
||||
|
||||
// Only Consider Default, when enabled
|
||||
for resourceName, amount := range r.Spec.Defaults {
|
||||
usedValue := claimed[resourceName]
|
||||
usedValue.Add(amount)
|
||||
|
||||
claimed[resourceName] = usedValue
|
||||
}
|
||||
|
||||
return claimed
|
||||
}
|
||||
|
||||
// Gets the total amount of claimed resources for a namespace.
|
||||
func (r *ResourcePool) GetNamespaceClaims(namespace string) (claims map[string]*ResourcePoolClaimsItem, claimedResources corev1.ResourceList) {
|
||||
claimedResources = corev1.ResourceList{}
|
||||
claims = map[string]*ResourcePoolClaimsItem{}
|
||||
|
||||
// First, check if quota exists in the status
|
||||
for ns, cl := range r.Status.Claims {
|
||||
if ns != namespace {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, claim := range cl {
|
||||
for resourceName, claimed := range claim.Claims {
|
||||
usedValue, usedExists := claimedResources[resourceName]
|
||||
if !usedExists {
|
||||
usedValue = resource.MustParse("0") // Default to zero if no used value is found
|
||||
}
|
||||
|
||||
// Combine with claim
|
||||
usedValue.Add(claimed)
|
||||
claimedResources[resourceName] = usedValue
|
||||
}
|
||||
|
||||
claims[string(claim.UID)] = claim
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate usage for each namespace.
|
||||
func (r *ResourcePool) GetClaimedByNamespaceClaims() (claims map[string]corev1.ResourceList) {
|
||||
claims = map[string]corev1.ResourceList{}
|
||||
|
||||
// First, check if quota exists in the status
|
||||
for ns, cl := range r.Status.Claims {
|
||||
claims[ns] = corev1.ResourceList{}
|
||||
nsScope := claims[ns]
|
||||
|
||||
for _, claim := range cl {
|
||||
for resourceName, claimed := range claim.Claims {
|
||||
usedValue, usedExists := nsScope[resourceName]
|
||||
if !usedExists {
|
||||
usedValue = resource.MustParse("0")
|
||||
}
|
||||
|
||||
usedValue.Add(claimed)
|
||||
nsScope[resourceName] = usedValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
295
api/v1beta2/resourcepool_func_test.go
Normal file
295
api/v1beta2/resourcepool_func_test.go
Normal file
@@ -0,0 +1,295 @@
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
"github.com/projectcapsule/capsule/pkg/meta"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetClaimFromStatus(t *testing.T) {
|
||||
ns := "test-namespace"
|
||||
testUID := types.UID("test-uid")
|
||||
otherUID := types.UID("wrong-uid")
|
||||
|
||||
claim := &ResourcePoolClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "claim-a",
|
||||
Namespace: ns,
|
||||
UID: testUID,
|
||||
},
|
||||
}
|
||||
|
||||
pool := &ResourcePool{
|
||||
Status: ResourcePoolStatus{
|
||||
Claims: ResourcePoolNamespaceClaimsStatus{
|
||||
ns: {
|
||||
&ResourcePoolClaimsItem{
|
||||
StatusNameUID: api.StatusNameUID{
|
||||
UID: testUID,
|
||||
},
|
||||
Claims: corev1.ResourceList{
|
||||
corev1.ResourceCPU: resource.MustParse("500m"),
|
||||
corev1.ResourceMemory: resource.MustParse("256Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
t.Run("returns matching claim", func(t *testing.T) {
|
||||
found := pool.GetClaimFromStatus(claim)
|
||||
assert.NotNil(t, found)
|
||||
assert.Equal(t, testUID, found.UID)
|
||||
})
|
||||
|
||||
t.Run("returns nil if UID doesn't match", func(t *testing.T) {
|
||||
claimWrongUID := *claim
|
||||
claimWrongUID.UID = otherUID
|
||||
|
||||
found := pool.GetClaimFromStatus(&claimWrongUID)
|
||||
assert.Nil(t, found)
|
||||
})
|
||||
|
||||
t.Run("returns nil if namespace has no claims", func(t *testing.T) {
|
||||
claimWrongNS := *claim
|
||||
claimWrongNS.Namespace = "other-ns"
|
||||
|
||||
found := pool.GetClaimFromStatus(&claimWrongNS)
|
||||
assert.Nil(t, found)
|
||||
})
|
||||
}
|
||||
|
||||
func makeResourceList(cpu, memory string) corev1.ResourceList {
|
||||
return corev1.ResourceList{
|
||||
corev1.ResourceLimitsCPU: resource.MustParse(cpu),
|
||||
corev1.ResourceLimitsMemory: resource.MustParse(memory),
|
||||
}
|
||||
}
|
||||
|
||||
func makeClaim(name, ns string, uid types.UID, res corev1.ResourceList) *ResourcePoolClaim {
|
||||
return &ResourcePoolClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns,
|
||||
UID: uid,
|
||||
},
|
||||
Spec: ResourcePoolClaimSpec{
|
||||
ResourceClaims: res,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestAssignNamespaces(t *testing.T) {
|
||||
pool := &ResourcePool{}
|
||||
|
||||
namespaces := []corev1.Namespace{
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: "active-ns"}, Status: corev1.NamespaceStatus{Phase: corev1.NamespaceActive}},
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: "terminating-ns", DeletionTimestamp: &metav1.Time{}}, Status: corev1.NamespaceStatus{Phase: corev1.NamespaceTerminating}},
|
||||
}
|
||||
|
||||
pool.AssignNamespaces(namespaces)
|
||||
|
||||
assert.Equal(t, uint(1), pool.Status.NamespaceSize)
|
||||
assert.Equal(t, []string{"active-ns"}, pool.Status.Namespaces)
|
||||
}
|
||||
|
||||
func TestAssignClaims(t *testing.T) {
|
||||
pool := &ResourcePool{
|
||||
Status: ResourcePoolStatus{
|
||||
Claims: ResourcePoolNamespaceClaimsStatus{
|
||||
"ns": {
|
||||
&ResourcePoolClaimsItem{},
|
||||
&ResourcePoolClaimsItem{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
pool.AssignClaims()
|
||||
|
||||
assert.Equal(t, uint(2), pool.Status.ClaimSize)
|
||||
}
|
||||
|
||||
func TestAddRemoveClaimToStatus(t *testing.T) {
|
||||
pool := &ResourcePool{}
|
||||
|
||||
claim := makeClaim("claim-1", "ns", "uid-1", makeResourceList("1", "1Gi"))
|
||||
pool.AddClaimToStatus(claim)
|
||||
|
||||
stored := pool.GetClaimFromStatus(claim)
|
||||
assert.NotNil(t, stored)
|
||||
assert.Equal(t, api.Name("claim-1"), stored.Name)
|
||||
|
||||
pool.RemoveClaimFromStatus(claim)
|
||||
assert.Nil(t, pool.GetClaimFromStatus(claim))
|
||||
}
|
||||
|
||||
func TestCalculateResources(t *testing.T) {
|
||||
pool := &ResourcePool{
|
||||
Status: ResourcePoolStatus{
|
||||
Allocation: ResourcePoolQuotaStatus{
|
||||
Hard: corev1.ResourceList{
|
||||
corev1.ResourceLimitsCPU: resource.MustParse("2"),
|
||||
},
|
||||
},
|
||||
Claims: ResourcePoolNamespaceClaimsStatus{
|
||||
"ns": {
|
||||
&ResourcePoolClaimsItem{
|
||||
Claims: corev1.ResourceList{
|
||||
corev1.ResourceLimitsCPU: resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
pool.CalculateClaimedResources()
|
||||
|
||||
actualClaimed := pool.Status.Allocation.Claimed[corev1.ResourceLimitsCPU]
|
||||
actualAvailable := pool.Status.Allocation.Available[corev1.ResourceLimitsCPU]
|
||||
|
||||
assert.Equal(t, 0, (&actualClaimed).Cmp(resource.MustParse("1")))
|
||||
assert.Equal(t, 0, (&actualAvailable).Cmp(resource.MustParse("1")))
|
||||
}
|
||||
|
||||
func TestCanClaimFromPool(t *testing.T) {
|
||||
pool := &ResourcePool{
|
||||
Status: ResourcePoolStatus{
|
||||
Allocation: ResourcePoolQuotaStatus{
|
||||
Hard: corev1.ResourceList{
|
||||
corev1.ResourceLimitsMemory: resource.MustParse("1Gi"),
|
||||
},
|
||||
Claimed: corev1.ResourceList{
|
||||
corev1.ResourceLimitsMemory: resource.MustParse("512Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
errs := pool.CanClaimFromPool(corev1.ResourceList{
|
||||
corev1.ResourceLimitsMemory: resource.MustParse("1Gi"),
|
||||
})
|
||||
assert.Len(t, errs, 1)
|
||||
|
||||
errs = pool.CanClaimFromPool(corev1.ResourceList{
|
||||
corev1.ResourceLimitsMemory: resource.MustParse("500Mi"),
|
||||
})
|
||||
assert.Len(t, errs, 0)
|
||||
}
|
||||
|
||||
func TestGetResourceQuotaHardResources(t *testing.T) {
|
||||
pool := &ResourcePool{
|
||||
Spec: ResourcePoolSpec{
|
||||
Defaults: corev1.ResourceList{
|
||||
corev1.ResourceLimitsCPU: resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
Status: ResourcePoolStatus{
|
||||
Claims: ResourcePoolNamespaceClaimsStatus{
|
||||
"ns": {
|
||||
&ResourcePoolClaimsItem{
|
||||
Claims: corev1.ResourceList{
|
||||
corev1.ResourceLimitsCPU: resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
res := pool.GetResourceQuotaHardResources("ns")
|
||||
actual := res[corev1.ResourceLimitsCPU]
|
||||
assert.Equal(t, 0, (&actual).Cmp(resource.MustParse("2")))
|
||||
}
|
||||
|
||||
func TestGetNamespaceClaims(t *testing.T) {
|
||||
pool := &ResourcePool{
|
||||
Status: ResourcePoolStatus{
|
||||
Claims: ResourcePoolNamespaceClaimsStatus{
|
||||
"ns": {
|
||||
&ResourcePoolClaimsItem{
|
||||
StatusNameUID: api.StatusNameUID{UID: "uid1"},
|
||||
Claims: corev1.ResourceList{
|
||||
corev1.ResourceLimitsCPU: resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
claims, res := pool.GetNamespaceClaims("ns")
|
||||
assert.Contains(t, claims, "uid1")
|
||||
actual := res[corev1.ResourceLimitsCPU]
|
||||
assert.Equal(t, 0, (&actual).Cmp(resource.MustParse("1")))
|
||||
}
|
||||
|
||||
func TestGetClaimedByNamespaceClaims(t *testing.T) {
|
||||
pool := &ResourcePool{
|
||||
Status: ResourcePoolStatus{
|
||||
Claims: ResourcePoolNamespaceClaimsStatus{
|
||||
"ns1": {
|
||||
&ResourcePoolClaimsItem{
|
||||
Claims: makeResourceList("1", "1Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := pool.GetClaimedByNamespaceClaims()
|
||||
actualCPU := result["ns1"][corev1.ResourceLimitsCPU]
|
||||
actualMem := result["ns1"][corev1.ResourceLimitsMemory]
|
||||
|
||||
assert.Equal(t, 0, (&actualCPU).Cmp(resource.MustParse("1")))
|
||||
assert.Equal(t, 0, (&actualMem).Cmp(resource.MustParse("1Gi")))
|
||||
}
|
||||
|
||||
func TestIsBoundToResourcePool_2(t *testing.T) {
|
||||
t.Run("bound to resource pool (Assigned=True)", func(t *testing.T) {
|
||||
claim := &ResourcePoolClaim{
|
||||
Status: ResourcePoolClaimStatus{
|
||||
Condition: metav1.Condition{
|
||||
Type: meta.BoundCondition,
|
||||
Status: metav1.ConditionTrue,
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, true, claim.IsBoundToResourcePool())
|
||||
})
|
||||
|
||||
t.Run("not bound - wrong condition type", func(t *testing.T) {
|
||||
claim := &ResourcePoolClaim{
|
||||
Status: ResourcePoolClaimStatus{
|
||||
Condition: metav1.Condition{
|
||||
Type: "Other",
|
||||
Status: metav1.ConditionTrue,
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, false, claim.IsBoundToResourcePool())
|
||||
})
|
||||
|
||||
t.Run("not bound - condition not true", func(t *testing.T) {
|
||||
claim := &ResourcePoolClaim{
|
||||
Status: ResourcePoolClaimStatus{
|
||||
Condition: metav1.Condition{
|
||||
Type: meta.BoundCondition,
|
||||
Status: metav1.ConditionFalse,
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, false, claim.IsBoundToResourcePool())
|
||||
})
|
||||
}
|
||||
65
api/v1beta2/resourcepool_status.go
Normal file
65
api/v1beta2/resourcepool_status.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
)
|
||||
|
||||
// GlobalResourceQuotaStatus defines the observed state of GlobalResourceQuota.
|
||||
type ResourcePoolStatus struct {
|
||||
// How many namespaces are considered
|
||||
// +kubebuilder:default=0
|
||||
NamespaceSize uint `json:"namespaceCount,omitempty"`
|
||||
// Amount of claims
|
||||
// +kubebuilder:default=0
|
||||
ClaimSize uint `json:"claimCount,omitempty"`
|
||||
// Namespaces which are considered for claims
|
||||
Namespaces []string `json:"namespaces,omitempty"`
|
||||
// Tracks the quotas for the Resource.
|
||||
Claims ResourcePoolNamespaceClaimsStatus `json:"claims,omitempty"`
|
||||
// Tracks the Usage from Claimed against what has been granted from the pool
|
||||
Allocation ResourcePoolQuotaStatus `json:"allocation,omitempty"`
|
||||
// Exhaustions from claims associated with the pool
|
||||
Exhaustions map[string]api.PoolExhaustionResource `json:"exhaustions,omitempty"`
|
||||
}
|
||||
|
||||
type ResourcePoolNamespaceClaimsStatus map[string]ResourcePoolClaimsList
|
||||
|
||||
type ResourcePoolQuotaStatus struct {
|
||||
// Hard is the set of enforced hard limits for each named resource.
|
||||
// More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/
|
||||
// +optional
|
||||
Hard corev1.ResourceList `json:"hard,omitempty" protobuf:"bytes,1,rep,name=hard,casttype=ResourceList,castkey=ResourceName"`
|
||||
// Used is the current observed total usage of the resource in the namespace.
|
||||
// +optional
|
||||
Claimed corev1.ResourceList `json:"used,omitempty" protobuf:"bytes,2,rep,name=used,casttype=ResourceList,castkey=ResourceName"`
|
||||
// Used to track the usage of the resource in the pool (diff hard - claimed). May be used for further automation
|
||||
// +optional
|
||||
Available corev1.ResourceList `json:"available,omitempty" protobuf:"bytes,2,rep,name=available,casttype=ResourceList,castkey=ResourceName"`
|
||||
}
|
||||
|
||||
type ResourcePoolClaimsList []*ResourcePoolClaimsItem
|
||||
|
||||
func (r *ResourcePoolClaimsList) GetClaimByUID(uid types.UID) *ResourcePoolClaimsItem {
|
||||
for _, claim := range *r {
|
||||
if claim.UID == uid {
|
||||
return claim
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResourceQuotaClaimStatus defines the observed state of ResourceQuotaClaim.
|
||||
type ResourcePoolClaimsItem struct {
|
||||
// Reference to the GlobalQuota being claimed from
|
||||
api.StatusNameUID `json:",inline"`
|
||||
|
||||
// Claimed resources
|
||||
Claims corev1.ResourceList `json:"claims,omitempty"`
|
||||
}
|
||||
77
api/v1beta2/resourcepool_types.go
Normal file
77
api/v1beta2/resourcepool_types.go
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
)
|
||||
|
||||
// ResourcePoolSpec.
|
||||
type ResourcePoolSpec struct {
|
||||
// Selector to match the namespaces that should be managed by the GlobalResourceQuota
|
||||
Selectors []api.NamespaceSelector `json:"selectors,omitempty"`
|
||||
// Define the resourcequota served by this resourcepool.
|
||||
Quota corev1.ResourceQuotaSpec `json:"quota"`
|
||||
// The Defaults given for each namespace, the default is not counted towards the total allocation
|
||||
// When you use claims it's recommended to provision Defaults as the prevent the scheduling of any resources
|
||||
Defaults corev1.ResourceList `json:"defaults,omitempty"`
|
||||
// Additional Configuration
|
||||
//+kubebuilder:default:={}
|
||||
Config ResourcePoolSpecConfiguration `json:"config,omitempty"`
|
||||
}
|
||||
|
||||
type ResourcePoolSpecConfiguration struct {
|
||||
// With this option all resources which can be allocated are set to 0 for the resourcequota defaults.
|
||||
// +kubebuilder:default=false
|
||||
DefaultsAssignZero *bool `json:"defaultsZero,omitempty"`
|
||||
// Claims are queued whenever they are allocated to a pool. A pool tries to allocate claims in order based on their
|
||||
// creation date. But no matter their creation time, if a claim is requesting too much resources it's put into the queue
|
||||
// but if a lower priority claim still has enough space in the available resources, it will be able to claim them. Eventough
|
||||
// it's priority was lower
|
||||
// Enabling this option respects to Order. Meaning the Creationtimestamp matters and if a resource is put into the queue, no
|
||||
// other claim can claim the same resources with lower priority.
|
||||
// +kubebuilder:default=false
|
||||
OrderedQueue *bool `json:"orderedQueue,omitempty"`
|
||||
// When a resourcepool is deleted, the resourceclaims bound to it are disassociated from the resourcepool but not deleted.
|
||||
// By Enabling this option, the resourceclaims will be deleted when the resourcepool is deleted, if they are in bound state.
|
||||
// +kubebuilder:default=false
|
||||
DeleteBoundResources *bool `json:"deleteBoundResources,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:scope=Cluster,shortName=quotapool
|
||||
// +kubebuilder:printcolumn:name="Claims",type="integer",JSONPath=".status.claimCount",description="The total amount of Claims bound"
|
||||
// +kubebuilder:printcolumn:name="Namespaces",type="integer",JSONPath=".status.namespaceCount",description="The total amount of Namespaces considered"
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Age"
|
||||
|
||||
// Resourcepools allows you to define a set of resources as known from ResoureQuotas. The Resourcepools are defined at cluster-scope an should
|
||||
// be administrated by cluster-administrators. However they create an interface, where cluster-administrators can define
|
||||
// from which namespaces resources from a Resourcepool can be claimed. The claiming is done via a namespaced CRD called ResourcePoolClaim. Then
|
||||
// it's up the group of users within these namespaces, to manage the resources they consume per namespace. Each Resourcepool provisions a ResourceQuotainto all the selected namespaces. Then essentially the ResourcePoolClaims, when they can be assigned to the ResourcePool stack resources on top of that
|
||||
// ResourceQuota based on the namspace, where the ResourcePoolClaim was made from.
|
||||
type ResourcePool struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ResourcePoolSpec `json:"spec,omitempty"`
|
||||
Status ResourcePoolStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ResourcePoolList contains a list of ResourcePool.
|
||||
type ResourcePoolList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []ResourcePool `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&ResourcePool{}, &ResourcePoolList{})
|
||||
}
|
||||
20
api/v1beta2/resourcepoolclaim_func.go
Normal file
20
api/v1beta2/resourcepoolclaim_func.go
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/meta"
|
||||
)
|
||||
|
||||
// Indicate the claim is bound to a resource pool.
|
||||
func (r *ResourcePoolClaim) IsBoundToResourcePool() bool {
|
||||
if r.Status.Condition.Type == meta.BoundCondition &&
|
||||
r.Status.Condition.Status == metav1.ConditionTrue {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
71
api/v1beta2/resourcepoolclaim_func_test.go
Normal file
71
api/v1beta2/resourcepoolclaim_func_test.go
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/meta"
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestIsBoundToResourcePool(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
claim ResourcePoolClaim
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "bound to resource pool (Assigned=True)",
|
||||
claim: ResourcePoolClaim{
|
||||
Status: ResourcePoolClaimStatus{
|
||||
Condition: metav1.Condition{
|
||||
Type: meta.BoundCondition,
|
||||
Status: metav1.ConditionTrue,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "not bound - wrong condition type",
|
||||
claim: ResourcePoolClaim{
|
||||
Status: ResourcePoolClaimStatus{
|
||||
Condition: metav1.Condition{
|
||||
Type: "SomethingElse",
|
||||
Status: metav1.ConditionTrue,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "not bound - status not true",
|
||||
claim: ResourcePoolClaim{
|
||||
Status: ResourcePoolClaimStatus{
|
||||
Condition: metav1.Condition{
|
||||
Type: meta.BoundCondition,
|
||||
Status: metav1.ConditionFalse,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "not bound - empty condition",
|
||||
claim: ResourcePoolClaim{
|
||||
Status: ResourcePoolClaimStatus{},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual := tt.claim.IsBoundToResourcePool()
|
||||
assert.Equal(t, tt.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
59
api/v1beta2/resourcepoolclaim_types.go
Normal file
59
api/v1beta2/resourcepoolclaim_types.go
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
)
|
||||
|
||||
type ResourcePoolClaimSpec struct {
|
||||
// If there's the possability to claim from multiple global Quotas
|
||||
// You must be specific about which one you want to claim resources from
|
||||
// Once bound to a ResourcePool, this field is immutable
|
||||
Pool string `json:"pool"`
|
||||
// Amount which should be claimed for the resourcequota
|
||||
ResourceClaims corev1.ResourceList `json:"claim"`
|
||||
}
|
||||
|
||||
// ResourceQuotaClaimStatus defines the observed state of ResourceQuotaClaim.
|
||||
type ResourcePoolClaimStatus struct {
|
||||
// Reference to the GlobalQuota being claimed from
|
||||
Pool api.StatusNameUID `json:"pool,omitempty"`
|
||||
// Condtion for this resource claim
|
||||
Condition metav1.Condition `json:"condition,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="Pool",type="string",JSONPath=".status.pool.name",description="The ResourcePool being claimed from"
|
||||
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.condition.type",description="Status for claim"
|
||||
// +kubebuilder:printcolumn:name="Reason",type="string",JSONPath=".status.condition.reason",description="Reason for status"
|
||||
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.condition.message",description="Condition Message"
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
|
||||
|
||||
// ResourcePoolClaim is the Schema for the resourcepoolclaims API.
|
||||
type ResourcePoolClaim struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ResourcePoolClaimSpec `json:"spec,omitempty"`
|
||||
Status ResourcePoolClaimStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ResourceQuotaClaimList contains a list of ResourceQuotaClaim.
|
||||
type ResourcePoolClaimList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []ResourcePoolClaim `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&ResourcePoolClaim{}, &ResourcePoolClaimList{})
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
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-2025 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
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
@@ -43,12 +43,14 @@ 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"`
|
||||
// Specifies options for the GatewayClass resources.
|
||||
GatewayOptions GatewayOptions `json:"gatewayOptions,omitempty"`
|
||||
// Toggling the Tenant resources cordoning, when enable resources cannot be deleted.
|
||||
//+kubebuilder:default:=false
|
||||
Cordoned bool `json:"cordoned,omitempty"`
|
||||
@@ -56,6 +58,15 @@ type TenantSpec struct {
|
||||
// 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
|
||||
@@ -91,7 +102,8 @@ func (in *Tenant) GetNamespaces() (res []string) {
|
||||
type TenantList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Tenant `json:"items"`
|
||||
|
||||
Items []Tenant `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
@@ -10,9 +10,10 @@ import (
|
||||
|
||||
// GlobalTenantResourceSpec defines the desired state of GlobalTenantResource.
|
||||
type GlobalTenantResourceSpec struct {
|
||||
// Defines the Tenant selector used target the tenants on which resources must be propagated.
|
||||
TenantSelector metav1.LabelSelector `json:"tenantSelector,omitempty"`
|
||||
TenantResourceSpec `json:",inline"`
|
||||
|
||||
// Defines the Tenant selector used target the tenants on which resources must be propagated.
|
||||
TenantSelector metav1.LabelSelector `json:"tenantSelector,omitempty"`
|
||||
}
|
||||
|
||||
// GlobalTenantResourceStatus defines the observed state of GlobalTenantResource.
|
||||
@@ -54,7 +55,8 @@ type GlobalTenantResource struct {
|
||||
type GlobalTenantResourceList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []GlobalTenantResource `json:"items"`
|
||||
|
||||
Items []GlobalTenantResource `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
@@ -69,7 +69,8 @@ type TenantResource struct {
|
||||
type TenantResourceList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []TenantResource `json:"items"`
|
||||
|
||||
Items []TenantResource `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
@@ -23,6 +23,7 @@ type ObjectReferenceAbstract struct {
|
||||
|
||||
type ObjectReferenceStatus struct {
|
||||
ObjectReferenceAbstract `json:",inline"`
|
||||
|
||||
// Name of the referent.
|
||||
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
Name string `json:"name"`
|
||||
@@ -30,6 +31,7 @@ type ObjectReferenceStatus struct {
|
||||
|
||||
type ObjectReference struct {
|
||||
ObjectReferenceAbstract `json:",inline"`
|
||||
|
||||
// Label selector used to select the given resources in the given Namespace.
|
||||
Selector metav1.LabelSelector `json:"selector"`
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ package v1beta2
|
||||
|
||||
import (
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -121,6 +122,11 @@ func (in *CapsuleConfigurationSpec) DeepCopyInto(out *CapsuleConfigurationSpec)
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.IgnoreUserWithGroups != nil {
|
||||
in, out := &in.IgnoreUserWithGroups, &out.IgnoreUserWithGroups
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.CapsuleResources = in.CapsuleResources
|
||||
if in.NodeMetadata != nil {
|
||||
in, out := &in.NodeMetadata, &out.NodeMetadata
|
||||
@@ -154,6 +160,26 @@ func (in *CapsuleResources) DeepCopy() *CapsuleResources {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GatewayOptions) DeepCopyInto(out *GatewayOptions) {
|
||||
*out = *in
|
||||
if in.AllowedClasses != nil {
|
||||
in, out := &in.AllowedClasses, &out.AllowedClasses
|
||||
*out = new(api.SelectionListWithDefaultSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayOptions.
|
||||
func (in *GatewayOptions) DeepCopy() *GatewayOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(GatewayOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GlobalTenantResource) DeepCopyInto(out *GlobalTenantResource) {
|
||||
*out = *in
|
||||
@@ -216,8 +242,8 @@ func (in *GlobalTenantResourceList) DeepCopyObject() runtime.Object {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GlobalTenantResourceSpec) DeepCopyInto(out *GlobalTenantResourceSpec) {
|
||||
*out = *in
|
||||
in.TenantSelector.DeepCopyInto(&out.TenantSelector)
|
||||
in.TenantResourceSpec.DeepCopyInto(&out.TenantResourceSpec)
|
||||
in.TenantSelector.DeepCopyInto(&out.TenantSelector)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalTenantResourceSpec.
|
||||
@@ -293,6 +319,13 @@ func (in *NamespaceOptions) DeepCopyInto(out *NamespaceOptions) {
|
||||
*out = new(api.AdditionalMetadataSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.AdditionalMetadataList != nil {
|
||||
in, out := &in.AdditionalMetadataList, &out.AdditionalMetadataList
|
||||
*out = make([]api.AdditionalMetadataSelectorSpec, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
in.ForbiddenLabels.DeepCopyInto(&out.ForbiddenLabels)
|
||||
in.ForbiddenAnnotations.DeepCopyInto(&out.ForbiddenAnnotations)
|
||||
}
|
||||
@@ -490,6 +523,394 @@ func (in *RawExtension) DeepCopy() *RawExtension {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePool) DeepCopyInto(out *ResourcePool) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePool.
|
||||
func (in *ResourcePool) DeepCopy() *ResourcePool {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePool)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ResourcePool) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePoolClaim) DeepCopyInto(out *ResourcePoolClaim) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolClaim.
|
||||
func (in *ResourcePoolClaim) DeepCopy() *ResourcePoolClaim {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolClaim)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ResourcePoolClaim) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePoolClaimList) DeepCopyInto(out *ResourcePoolClaimList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ResourcePoolClaim, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolClaimList.
|
||||
func (in *ResourcePoolClaimList) DeepCopy() *ResourcePoolClaimList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolClaimList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ResourcePoolClaimList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePoolClaimSpec) DeepCopyInto(out *ResourcePoolClaimSpec) {
|
||||
*out = *in
|
||||
if in.ResourceClaims != nil {
|
||||
in, out := &in.ResourceClaims, &out.ResourceClaims
|
||||
*out = make(corev1.ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolClaimSpec.
|
||||
func (in *ResourcePoolClaimSpec) DeepCopy() *ResourcePoolClaimSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolClaimSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePoolClaimStatus) DeepCopyInto(out *ResourcePoolClaimStatus) {
|
||||
*out = *in
|
||||
out.Pool = in.Pool
|
||||
in.Condition.DeepCopyInto(&out.Condition)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolClaimStatus.
|
||||
func (in *ResourcePoolClaimStatus) DeepCopy() *ResourcePoolClaimStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolClaimStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePoolClaimsItem) DeepCopyInto(out *ResourcePoolClaimsItem) {
|
||||
*out = *in
|
||||
out.StatusNameUID = in.StatusNameUID
|
||||
if in.Claims != nil {
|
||||
in, out := &in.Claims, &out.Claims
|
||||
*out = make(corev1.ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolClaimsItem.
|
||||
func (in *ResourcePoolClaimsItem) DeepCopy() *ResourcePoolClaimsItem {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolClaimsItem)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ResourcePoolClaimsList) DeepCopyInto(out *ResourcePoolClaimsList) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(ResourcePoolClaimsList, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(ResourcePoolClaimsItem)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolClaimsList.
|
||||
func (in ResourcePoolClaimsList) DeepCopy() ResourcePoolClaimsList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolClaimsList)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePoolList) DeepCopyInto(out *ResourcePoolList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ResourcePool, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolList.
|
||||
func (in *ResourcePoolList) DeepCopy() *ResourcePoolList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ResourcePoolList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ResourcePoolNamespaceClaimsStatus) DeepCopyInto(out *ResourcePoolNamespaceClaimsStatus) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(ResourcePoolNamespaceClaimsStatus, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []*ResourcePoolClaimsItem
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
inVal := (*in)[key]
|
||||
in, out := &inVal, &outVal
|
||||
*out = make(ResourcePoolClaimsList, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(ResourcePoolClaimsItem)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolNamespaceClaimsStatus.
|
||||
func (in ResourcePoolNamespaceClaimsStatus) DeepCopy() ResourcePoolNamespaceClaimsStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolNamespaceClaimsStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePoolQuotaStatus) DeepCopyInto(out *ResourcePoolQuotaStatus) {
|
||||
*out = *in
|
||||
if in.Hard != nil {
|
||||
in, out := &in.Hard, &out.Hard
|
||||
*out = make(corev1.ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.Claimed != nil {
|
||||
in, out := &in.Claimed, &out.Claimed
|
||||
*out = make(corev1.ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.Available != nil {
|
||||
in, out := &in.Available, &out.Available
|
||||
*out = make(corev1.ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolQuotaStatus.
|
||||
func (in *ResourcePoolQuotaStatus) DeepCopy() *ResourcePoolQuotaStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolQuotaStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePoolSpec) DeepCopyInto(out *ResourcePoolSpec) {
|
||||
*out = *in
|
||||
if in.Selectors != nil {
|
||||
in, out := &in.Selectors, &out.Selectors
|
||||
*out = make([]api.NamespaceSelector, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
in.Quota.DeepCopyInto(&out.Quota)
|
||||
if in.Defaults != nil {
|
||||
in, out := &in.Defaults, &out.Defaults
|
||||
*out = make(corev1.ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
in.Config.DeepCopyInto(&out.Config)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolSpec.
|
||||
func (in *ResourcePoolSpec) DeepCopy() *ResourcePoolSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePoolSpecConfiguration) DeepCopyInto(out *ResourcePoolSpecConfiguration) {
|
||||
*out = *in
|
||||
if in.DefaultsAssignZero != nil {
|
||||
in, out := &in.DefaultsAssignZero, &out.DefaultsAssignZero
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.OrderedQueue != nil {
|
||||
in, out := &in.OrderedQueue, &out.OrderedQueue
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.DeleteBoundResources != nil {
|
||||
in, out := &in.DeleteBoundResources, &out.DeleteBoundResources
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolSpecConfiguration.
|
||||
func (in *ResourcePoolSpecConfiguration) DeepCopy() *ResourcePoolSpecConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolSpecConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourcePoolStatus) DeepCopyInto(out *ResourcePoolStatus) {
|
||||
*out = *in
|
||||
if in.Namespaces != nil {
|
||||
in, out := &in.Namespaces, &out.Namespaces
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Claims != nil {
|
||||
in, out := &in.Claims, &out.Claims
|
||||
*out = make(ResourcePoolNamespaceClaimsStatus, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []*ResourcePoolClaimsItem
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
inVal := (*in)[key]
|
||||
in, out := &inVal, &outVal
|
||||
*out = make(ResourcePoolClaimsList, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(ResourcePoolClaimsItem)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
in.Allocation.DeepCopyInto(&out.Allocation)
|
||||
if in.Exhaustions != nil {
|
||||
in, out := &in.Exhaustions, &out.Exhaustions
|
||||
*out = make(map[string]api.PoolExhaustionResource, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolStatus.
|
||||
func (in *ResourcePoolStatus) DeepCopy() *ResourcePoolStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourcePoolStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceSpec) DeepCopyInto(out *ResourceSpec) {
|
||||
*out = *in
|
||||
@@ -755,7 +1176,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 {
|
||||
@@ -763,6 +1184,12 @@ func (in *TenantSpec) DeepCopyInto(out *TenantSpec) {
|
||||
*out = new(api.DefaultAllowedListSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.GatewayOptions.DeepCopyInto(&out.GatewayOptions)
|
||||
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.
|
||||
|
||||
@@ -1,101 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Livello_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 595.28 841.89" style="enable-background:new 0 0 595.28 841.89;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#274872;}
|
||||
.st1{fill:#314A70;}
|
||||
.st2{fill:#5783AB;}
|
||||
.st3{fill:#EAECEC;}
|
||||
</style>
|
||||
<path class="st0" d="M243.53,178.65c-0.06-4.5-0.37-9.02,0-13.49c0.1-1.22,2.13-3.09,3.45-3.25c6.99-0.88,14.03-1.47,21.07-1.8
|
||||
c2.43-0.12,3.48-1.05,4.29-3.12c2-5.14,4.08-10.25,6.32-15.29c0.86-1.93,0.56-2.83-1.2-4.09c-4.42-3.15-4.97-8.41-1.6-12.08
|
||||
c3.7-4.04,8.88-4.09,12.65-0.12c3.5,3.68,3.07,8.88-1.39,12.08c-1.93,1.39-2.08,2.44-1.22,4.44c2.19,5.06,3.96,10.31,6.33,15.27
|
||||
c0.65,1.37,2.73,2.73,4.28,2.89c7.57,0.77,15.19,1.17,22.79,1.64c2.69,0.16,4.13,1.28,4.21,4.15c0.1,3.95,0.43,7.89,0.66,11.84
|
||||
c-1.51,0.05-3.03,0.22-4.53,0.13c-12.54-0.76-37.47-2.65-37.47-2.65S254.81,177.52,243.53,178.65z"/>
|
||||
<g>
|
||||
<path class="st1" d="M73.32,483.91c-5.2-2.69-9.26-6.43-12.18-11.22c-2.92-4.78-4.38-10.21-4.38-16.28c0-6.07,1.46-11.5,4.38-16.28
|
||||
c2.92-4.78,6.98-8.52,12.18-11.22c5.2-2.69,11.06-4.04,17.59-4.04c6.45,0,12.09,1.35,16.91,4.04c4.82,2.7,8.33,6.55,10.53,11.56
|
||||
l-13.78,7.4c-3.19-5.62-7.78-8.43-13.78-8.43c-4.63,0-8.47,1.52-11.5,4.55c-3.04,3.04-4.55,7.17-4.55,12.41
|
||||
c0,5.24,1.52,9.38,4.55,12.41c3.04,3.04,6.87,4.55,11.5,4.55c6.07,0,10.66-2.81,13.78-8.43l13.78,7.52
|
||||
c-2.2,4.86-5.71,8.65-10.53,11.39c-4.82,2.73-10.46,4.1-16.91,4.1C84.38,487.95,78.52,486.6,73.32,483.91z"/>
|
||||
<path class="st1" d="M175.17,431.64c5.08,4.52,7.63,11.33,7.63,20.44v34.96h-16.62v-7.63c-3.34,5.69-9.56,8.54-18.67,8.54
|
||||
c-4.71,0-8.79-0.8-12.24-2.39c-3.46-1.59-6.09-3.79-7.91-6.6c-1.82-2.81-2.73-6-2.73-9.56c0-5.69,2.14-10.17,6.43-13.44
|
||||
c4.29-3.26,10.91-4.9,19.87-4.9h14.12c0-3.87-1.18-6.85-3.53-8.94c-2.35-2.09-5.88-3.13-10.59-3.13c-3.26,0-6.47,0.51-9.62,1.54
|
||||
c-3.15,1.03-5.83,2.41-8.03,4.16l-6.38-12.41c3.34-2.35,7.34-4.17,12.01-5.47c4.67-1.29,9.47-1.94,14.4-1.94
|
||||
C162.8,424.87,170.08,427.13,175.17,431.64z M160.03,473.89c2.35-1.4,4.02-3.47,5.01-6.21v-6.26h-12.18
|
||||
c-7.29,0-10.93,2.39-10.93,7.17c0,2.28,0.89,4.08,2.68,5.41c1.78,1.33,4.23,1.99,7.34,1.99
|
||||
C154.98,475.99,157.67,475.29,160.03,473.89z"/>
|
||||
<path class="st1" d="M250.6,428.8c4.67,2.62,8.33,6.3,10.99,11.04c2.66,4.75,3.99,10.27,3.99,16.57s-1.33,11.82-3.99,16.57
|
||||
c-2.66,4.75-6.32,8.43-10.99,11.04s-9.85,3.93-15.54,3.93c-7.82,0-13.97-2.47-18.45-7.4v28.58h-17.76v-83.35h16.97v7.06
|
||||
c4.4-5.31,10.82-7.97,19.24-7.97C240.76,424.87,245.94,426.18,250.6,428.8z M243.2,468.76c2.92-3.07,4.38-7.19,4.38-12.35
|
||||
s-1.46-9.28-4.38-12.35c-2.92-3.07-6.66-4.61-11.22-4.61s-8.29,1.54-11.22,4.61c-2.92,3.07-4.38,7.19-4.38,12.35
|
||||
s1.46,9.28,4.38,12.35c2.92,3.07,6.66,4.61,11.22,4.61S240.28,471.84,243.2,468.76z"/>
|
||||
<path class="st1" d="M283.11,486.07c-4.86-1.25-8.73-2.83-11.61-4.73l5.92-12.75c2.73,1.75,6.03,3.17,9.91,4.27
|
||||
c3.87,1.1,7.67,1.65,11.39,1.65c7.51,0,11.27-1.86,11.27-5.58c0-1.75-1.03-3-3.07-3.76c-2.05-0.76-5.2-1.4-9.45-1.94
|
||||
c-5.01-0.76-9.15-1.63-12.41-2.62c-3.26-0.99-6.09-2.73-8.48-5.24s-3.59-6.07-3.59-10.7c0-3.87,1.12-7.3,3.36-10.3
|
||||
c2.24-3,5.5-5.33,9.79-7c4.29-1.67,9.35-2.5,15.2-2.5c4.33,0,8.63,0.48,12.92,1.42c4.29,0.95,7.84,2.26,10.65,3.93l-5.92,12.64
|
||||
c-5.39-3.04-11.27-4.55-17.65-4.55c-3.8,0-6.64,0.53-8.54,1.59c-1.9,1.06-2.85,2.43-2.85,4.1c0,1.9,1.02,3.23,3.07,3.99
|
||||
c2.05,0.76,5.31,1.48,9.79,2.16c5.01,0.84,9.11,1.73,12.3,2.68c3.19,0.95,5.96,2.68,8.31,5.18c2.35,2.5,3.53,6,3.53,10.48
|
||||
c0,3.8-1.14,7.17-3.42,10.13c-2.28,2.96-5.6,5.26-9.96,6.89c-4.37,1.63-9.55,2.45-15.54,2.45
|
||||
C292.94,487.95,287.97,487.32,283.11,486.07z"/>
|
||||
<path class="st1" d="M399.59,425.78v61.26h-16.85v-7.29c-2.35,2.66-5.16,4.69-8.43,6.09c-3.26,1.4-6.79,2.11-10.59,2.11
|
||||
c-8.05,0-14.42-2.31-19.13-6.95c-4.71-4.63-7.06-11.5-7.06-20.61v-34.61h17.76v32c0,9.87,4.14,14.8,12.41,14.8
|
||||
c4.25,0,7.67-1.38,10.25-4.16c2.58-2.77,3.87-6.89,3.87-12.35v-30.29H399.59z"/>
|
||||
<path class="st1" d="M416.1,402.55h17.76v84.49H416.1V402.55z"/>
|
||||
<path class="st1" d="M510.04,461.42H463.7c0.83,3.8,2.81,6.79,5.92,9c3.11,2.2,6.98,3.3,11.61,3.3c3.19,0,6.01-0.47,8.48-1.42
|
||||
c2.47-0.95,4.76-2.45,6.89-4.5l9.45,10.25c-5.77,6.6-14.2,9.91-25.28,9.91c-6.91,0-13.02-1.35-18.33-4.04
|
||||
c-5.31-2.69-9.41-6.43-12.3-11.22c-2.89-4.78-4.33-10.21-4.33-16.28c0-6,1.42-11.4,4.27-16.23c2.85-4.82,6.76-8.58,11.73-11.27
|
||||
c4.97-2.69,10.53-4.04,16.68-4.04c6,0,11.42,1.29,16.28,3.87c4.86,2.58,8.67,6.28,11.44,11.1c2.77,4.82,4.16,10.42,4.16,16.79
|
||||
C510.38,456.86,510.27,458.46,510.04,461.42z M468.48,441.72c-2.73,2.28-4.4,5.39-5.01,9.34h30.17c-0.61-3.87-2.28-6.96-5.01-9.28
|
||||
c-2.73-2.31-6.07-3.47-10.02-3.47C474.59,438.3,471.21,439.44,468.48,441.72z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M144.97,316.25c2.88-4.14,5.7-8.31,8.68-12.38c0.84-1.14,2.13-1.94,3.22-2.9c8.67,2.77,17.24,5.98,26.06,8.18
|
||||
c7.28,1.81,7.49,1.33,11.08-5.55c9.52-18.28,18.99-36.58,28.42-54.91c3.55-6.9,7.04-13.85,10.34-20.87c1.87-3.99,1-5.28-3.27-5.1
|
||||
c-5.07,0.21-10.13,0.68-15.19,1.04c1.72-2.35,3.24-4.87,5.2-7.01c4.47-4.88,9.14-9.57,13.74-14.34c1.84-0.03,3.68,0.02,5.52-0.1
|
||||
c14.62-1.03,29.24-2.1,43.86-3.16c-0.08,0.84-0.24,1.68-0.24,2.52c0.01,48.41,0.03,96.83,0.05,145.24
|
||||
c-15.73,0.85-30.48,0.97-47.48-0.65c-16.01-1.04-30.66-3.54-46.6-5.49c-13.64-1.67-26.85-5.2-39.21-11.4
|
||||
c-4.77-2.4-5.86-5.41-4.24-10.45C145.16,318.1,144.96,317.14,144.97,316.25z"/>
|
||||
<path class="st3" d="M282.42,346.9c-0.02-48.41-0.04-96.83-0.05-145.24c0-0.84,0.05-1.64,0.04-2.48
|
||||
c5.63,0.1,11.47-0.06,17.08,0.32c11.35,0.78,22.67,1.83,34.01,2.77c2.69,3.09,5.47,6.1,8.05,9.28c3.38,4.17,6.61,8.47,9.9,12.71
|
||||
c-6.04-0.52-12.07-1.2-18.13-1.49c-4.12-0.2-4.91,1.24-3.08,4.81c9.87,19.27,19.73,38.54,29.65,57.78
|
||||
c4.02,7.79,8.22,15.49,12.24,23.29c1.46,2.83,3.6,3.9,6.61,3.17c11.52-2.81,23.03-5.68,34.54-8.52c1.8,3.04,3.52,6.13,5.42,9.1
|
||||
c0.89,1.39,2.13,2.56,3.21,3.83c0,0.56-0.19,1.22,0.04,1.66c3.28,6.31-0.16,9.95-5.82,12.53c-14.18,6.44-29.11,9.85-44.52,11.41
|
||||
c-12.89,1.31-25.79,2.51-38.68,3.77c-6.24,0.61-12.47,1.45-18.72,1.79c-4.58,0.24-9.2-0.17-13.81-0.3
|
||||
c-5.95-0.04-11.9-0.08-17.85-0.12L282.42,346.9z"/>
|
||||
<path class="st2" d="M413.28,303.3c-11.51,2.84-23.02,5.71-34.54,8.52c-3.01,0.74-5.15-0.34-6.61-3.17
|
||||
c-4.02-7.79-8.22-15.49-12.24-23.29c-9.92-19.24-19.79-38.51-29.65-57.78c-1.83-3.57-1.04-5.01,3.08-4.81
|
||||
c6.05,0.29,12.09,0.97,18.13,1.49c1.89,0.4,2.54,0.15,5.06,3.74c17.1,24.41,37.01,47.73,54.85,71.62
|
||||
C412.17,300.72,412.64,302.07,413.28,303.3z"/>
|
||||
<path class="st3" d="M155.06,302.38c11.51,2.84,22.26,5.47,33.78,8.28c3.01,0.74,5.15-0.34,6.61-3.17
|
||||
c4.02-7.79,8.22-15.49,12.24-23.29c9.92-19.24,17.3-37.26,26.37-56.7c1.83-3.57,0.68-4.95-3.44-4.75
|
||||
c-6.05,0.29-10.08,0.42-16.13,0.94c-2.11,1.25-2.46,1.66-3.84,3.47c-18.01,23.75-35.83,47.64-53.67,71.53
|
||||
C156.18,299.79,155.7,301.14,155.06,302.38z"/>
|
||||
<path class="st0" d="M421.92,316.24c0,0.56-0.19,1.22,0.04,1.66c3.28,6.31-0.16,9.95-5.82,12.53
|
||||
c-14.18,6.44-29.11,9.85-44.52,11.41c-12.89,1.31-25.79,2.51-38.68,3.77c-6.24,0.61-12.94,1.22-18.94,1.29
|
||||
c-4.59,0.05-8.98,0.32-13.59,0.2c-5.95-0.04-11.9-0.08-17.85-0.12c0,0-0.12-0.08-0.12-0.08c-15.36,0.35-28.73,0.35-46.17-1.19
|
||||
c-15.98-1.41-31.97-2.99-47.91-4.95c-13.64-1.67-26.85-5.2-39.21-11.4c-4.77-2.4-5.86-5.41-4.24-10.45
|
||||
c0.26-0.81,0.06-1.77,0.07-2.66c-6.55,2.47-11.33,6.45-12.86,13.75c-1.74,8.28,0.69,15.31,5.77,21.67
|
||||
c1.43,1.79,2.4,3.22,0.07,5.22c-0.71,0.61-0.81,3.27-0.15,3.89c6.36,6.04,13.89,10.11,22.37,12.36c2.35,0.62,4.12,0.02,4.62-2.85
|
||||
c0.11-0.64,1.63-1.63,2.27-1.49c8.66,1.96,17.26,4.13,25.91,6.14c1.98,0.46,2.73,1,1.52,3.01c-1.45,2.4-0.41,3.92,2,4.93
|
||||
c8.64,3.63,17.82,3.98,26.97,4.34c2.18,0.08,4.54-0.9,3.51-3.88c-1.11-3.22,0.45-3.2,2.83-2.99c8.57,0.73,17.14,1.44,25.72,1.95
|
||||
c3.13,0.19,3.98,1.04,2.41,3.98c-1.6,2.98-0.26,4.76,2.9,4.77c14.82,0.08,29.65,0.17,44.46-0.08c4.59-0.08,5.1-1.29,3.36-5.63
|
||||
c-0.84-2.1-0.97-2.87,1.76-3.02c9.16-0.52,18.32-1.21,27.45-2.12c2.5-0.25,3.06,0.34,2.55,2.56c-0.53,2.31,0.05,4.05,2.72,4.11
|
||||
c9.52,0.21,18.91-0.53,27.82-4.34c1.95-0.83,3.09-2.06,1.71-4.23c-1.72-2.71-0.09-3.15,2.17-3.67c8.24-1.87,16.46-3.83,24.64-5.93
|
||||
c1.82-0.47,3-0.77,3.21,1.6c0.26,2.99,2.1,3.32,4.53,2.61c8.11-2.36,15.55-5.98,21.6-11.99c0.69-0.69,1.03-2.99,0.55-3.39
|
||||
c-3.18-2.71-1.41-4.64,0.51-6.95C437.87,340.92,439.33,322.67,421.92,316.24z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st3" d="M324.35,192.94c-6.72-0.27-13.4-0.35-20.23-0.52c-7.13-0.17-18.9-0.51-18.9-0.51s-1.27,0.04-2.44,0
|
||||
c0,0-0.63-0.01-0.63,0.18c-0.01-5.67,0.01-11.83,0-17.5c12.58,0.95,24.65,1.94,37.19,2.72c1.5,0.09,3.29-0.07,4.8-0.12
|
||||
C324.19,182.43,324.33,187.69,324.35,192.94z"/>
|
||||
<path class="st2" d="M243.35,193.45c6.72-0.27,10.02-0.35,16.86-0.52c7.13-0.17,18.9-0.51,18.9-0.51s1.27,0.04,2.44,0
|
||||
c0,0,0.63-0.53,0.63-0.34c0.01-5.67-0.01-11.83,0-17.5c-12.58,0.95-21.28,1.94-33.82,2.72c-1.5,0.09-3.29-0.07-4.8-0.12
|
||||
C243.51,182.43,243.38,188.21,243.35,193.45z"/>
|
||||
<path class="st0" d="M327.57,193.15c-1.31-0.1-2.62-0.17-3.93-0.26c-13.33-0.32-26.66-0.63-39.99-0.95v0c-0.03,0-0.06,0-0.1,0
|
||||
c-0.03,0-0.06,0-0.1,0v0c-13.33,0.32-26.66,0.63-39.99,0.95c-1.31,0.08-2.62,0.15-3.93,0.26c-6.26,0.5-6.88,1.16-6.73,7.17
|
||||
c0.02,0.7,0.18,1.39,0.27,2.09c1.91-0.03,3.82,0.02,5.72-0.1c14.92-1.02,28.65-2.07,43.57-3.11c14.92,1.04,31.01,2.1,45.93,3.11
|
||||
c1.9,0.13,3.81,0.07,5.72,0.1c0.09-0.7,0.25-1.39,0.27-2.09C334.45,194.31,333.82,193.65,327.57,193.15z"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" id="Livello_1" x="0" y="0" version="1.1" viewBox="36.76 68.993 493.611 493.611">
|
||||
<style>.st0{fill:#274872}.st2{fill:#5783ab}.st3{fill:#eaecec}</style>
|
||||
<path d="M243.53 178.65c-.06-4.5-.37-9.02 0-13.49.1-1.22 2.13-3.09 3.45-3.25 6.99-.88 14.03-1.47 21.07-1.8 2.43-.12 3.48-1.05 4.29-3.12 2-5.14 4.08-10.25 6.32-15.29.86-1.93.56-2.83-1.2-4.09-4.42-3.15-4.97-8.41-1.6-12.08 3.7-4.04 8.88-4.09 12.65-.12 3.5 3.68 3.07 8.88-1.39 12.08-1.93 1.39-2.08 2.44-1.22 4.44 2.19 5.06 3.96 10.31 6.33 15.27.65 1.37 2.73 2.73 4.28 2.89 7.57.77 15.19 1.17 22.79 1.64 2.69.16 4.13 1.28 4.21 4.15.1 3.95.43 7.89.66 11.84-1.51.05-3.03.22-4.53.13-12.54-.76-37.47-2.65-37.47-2.65s-27.36 2.32-38.64 3.45z" class="st0"/>
|
||||
<path fill="#314a70" d="M73.32 483.91c-5.2-2.69-9.26-6.43-12.18-11.22-2.92-4.78-4.38-10.21-4.38-16.28s1.46-11.5 4.38-16.28c2.92-4.78 6.98-8.52 12.18-11.22 5.2-2.69 11.06-4.04 17.59-4.04 6.45 0 12.09 1.35 16.91 4.04 4.82 2.7 8.33 6.55 10.53 11.56l-13.78 7.4c-3.19-5.62-7.78-8.43-13.78-8.43-4.63 0-8.47 1.52-11.5 4.55-3.04 3.04-4.55 7.17-4.55 12.41s1.52 9.38 4.55 12.41c3.04 3.04 6.87 4.55 11.5 4.55 6.07 0 10.66-2.81 13.78-8.43l13.78 7.52c-2.2 4.86-5.71 8.65-10.53 11.39-4.82 2.73-10.46 4.1-16.91 4.1-6.53.01-12.39-1.34-17.59-4.03zm101.85-52.27c5.08 4.52 7.63 11.33 7.63 20.44v34.96h-16.62v-7.63c-3.34 5.69-9.56 8.54-18.67 8.54-4.71 0-8.79-.8-12.24-2.39-3.46-1.59-6.09-3.79-7.91-6.6-1.82-2.81-2.73-6-2.73-9.56 0-5.69 2.14-10.17 6.43-13.44 4.29-3.26 10.91-4.9 19.87-4.9h14.12c0-3.87-1.18-6.85-3.53-8.94-2.35-2.09-5.88-3.13-10.59-3.13-3.26 0-6.47.51-9.62 1.54-3.15 1.03-5.83 2.41-8.03 4.16l-6.38-12.41c3.34-2.35 7.34-4.17 12.01-5.47 4.67-1.29 9.47-1.94 14.4-1.94 9.49 0 16.77 2.26 21.86 6.77zm-15.14 42.25c2.35-1.4 4.02-3.47 5.01-6.21v-6.26h-12.18c-7.29 0-10.93 2.39-10.93 7.17 0 2.28.89 4.08 2.68 5.41 1.78 1.33 4.23 1.99 7.34 1.99 3.03 0 5.72-.7 8.08-2.1zm90.57-45.09c4.67 2.62 8.33 6.3 10.99 11.04 2.66 4.75 3.99 10.27 3.99 16.57s-1.33 11.82-3.99 16.57-6.32 8.43-10.99 11.04-9.85 3.93-15.54 3.93c-7.82 0-13.97-2.47-18.45-7.4v28.58h-17.76v-83.35h16.97v7.06c4.4-5.31 10.82-7.97 19.24-7.97 5.7 0 10.88 1.31 15.54 3.93zm-7.4 39.96c2.92-3.07 4.38-7.19 4.38-12.35s-1.46-9.28-4.38-12.35c-2.92-3.07-6.66-4.61-11.22-4.61s-8.29 1.54-11.22 4.61c-2.92 3.07-4.38 7.19-4.38 12.35s1.46 9.28 4.38 12.35c2.92 3.07 6.66 4.61 11.22 4.61s8.3-1.53 11.22-4.61zm39.91 17.31c-4.86-1.25-8.73-2.83-11.61-4.73l5.92-12.75c2.73 1.75 6.03 3.17 9.91 4.27 3.87 1.1 7.67 1.65 11.39 1.65 7.51 0 11.27-1.86 11.27-5.58 0-1.75-1.03-3-3.07-3.76-2.05-.76-5.2-1.4-9.45-1.94-5.01-.76-9.15-1.63-12.41-2.62-3.26-.99-6.09-2.73-8.48-5.24s-3.59-6.07-3.59-10.7c0-3.87 1.12-7.3 3.36-10.3 2.24-3 5.5-5.33 9.79-7 4.29-1.67 9.35-2.5 15.2-2.5 4.33 0 8.63.48 12.92 1.42 4.29.95 7.84 2.26 10.65 3.93l-5.92 12.64c-5.39-3.04-11.27-4.55-17.65-4.55-3.8 0-6.64.53-8.54 1.59-1.9 1.06-2.85 2.43-2.85 4.1 0 1.9 1.02 3.23 3.07 3.99 2.05.76 5.31 1.48 9.79 2.16 5.01.84 9.11 1.73 12.3 2.68 3.19.95 5.96 2.68 8.31 5.18 2.35 2.5 3.53 6 3.53 10.48 0 3.8-1.14 7.17-3.42 10.13-2.28 2.96-5.6 5.26-9.96 6.89-4.37 1.63-9.55 2.45-15.54 2.45-5.09-.01-10.06-.64-14.92-1.89zm116.48-60.29v61.26h-16.85v-7.29a23.4 23.4 0 0 1-8.43 6.09c-3.26 1.4-6.79 2.11-10.59 2.11-8.05 0-14.42-2.31-19.13-6.95-4.71-4.63-7.06-11.5-7.06-20.61v-34.61h17.76v32c0 9.87 4.14 14.8 12.41 14.8 4.25 0 7.67-1.38 10.25-4.16 2.58-2.77 3.87-6.89 3.87-12.35v-30.29h17.77zm16.51-23.23h17.76v84.49H416.1v-84.49zm93.94 58.87H463.7c.83 3.8 2.81 6.79 5.92 9 3.11 2.2 6.98 3.3 11.61 3.3 3.19 0 6.01-.47 8.48-1.42 2.47-.95 4.76-2.45 6.89-4.5l9.45 10.25c-5.77 6.6-14.2 9.91-25.28 9.91-6.91 0-13.02-1.35-18.33-4.04-5.31-2.69-9.41-6.43-12.3-11.22-2.89-4.78-4.33-10.21-4.33-16.28 0-6 1.42-11.4 4.27-16.23 2.85-4.82 6.76-8.58 11.73-11.27 4.97-2.69 10.53-4.04 16.68-4.04 6 0 11.42 1.29 16.28 3.87 4.86 2.58 8.67 6.28 11.44 11.1 2.77 4.82 4.16 10.42 4.16 16.79.01.22-.1 1.82-.33 4.78zm-41.56-19.7c-2.73 2.28-4.4 5.39-5.01 9.34h30.17c-.61-3.87-2.28-6.96-5.01-9.28-2.73-2.31-6.07-3.47-10.02-3.47-4.02-.01-7.4 1.13-10.13 3.41z"/>
|
||||
<path d="M144.97 316.25c2.88-4.14 5.7-8.31 8.68-12.38.84-1.14 2.13-1.94 3.22-2.9 8.67 2.77 17.24 5.98 26.06 8.18 7.28 1.81 7.49 1.33 11.08-5.55 9.52-18.28 18.99-36.58 28.42-54.91 3.55-6.9 7.04-13.85 10.34-20.87 1.87-3.99 1-5.28-3.27-5.1-5.07.21-10.13.68-15.19 1.04 1.72-2.35 3.24-4.87 5.2-7.01 4.47-4.88 9.14-9.57 13.74-14.34 1.84-.03 3.68.02 5.52-.1 14.62-1.03 29.24-2.1 43.86-3.16-.08.84-.24 1.68-.24 2.52.01 48.41.03 96.83.05 145.24-15.73.85-30.48.97-47.48-.65-16.01-1.04-30.66-3.54-46.6-5.49-13.64-1.67-26.85-5.2-39.21-11.4-4.77-2.4-5.86-5.41-4.24-10.45.25-.82.05-1.78.06-2.67z" class="st2"/>
|
||||
<path d="M282.42 346.9c-.02-48.41-.04-96.83-.05-145.24 0-.84.05-1.64.04-2.48 5.63.1 11.47-.06 17.08.32 11.35.78 22.67 1.83 34.01 2.77 2.69 3.09 5.47 6.1 8.05 9.28 3.38 4.17 6.61 8.47 9.9 12.71-6.04-.52-12.07-1.2-18.13-1.49-4.12-.2-4.91 1.24-3.08 4.81 9.87 19.27 19.73 38.54 29.65 57.78 4.02 7.79 8.22 15.49 12.24 23.29 1.46 2.83 3.6 3.9 6.61 3.17 11.52-2.81 23.03-5.68 34.54-8.52 1.8 3.04 3.52 6.13 5.42 9.1.89 1.39 2.13 2.56 3.21 3.83 0 .56-.19 1.22.04 1.66 3.28 6.31-.16 9.95-5.82 12.53-14.18 6.44-29.11 9.85-44.52 11.41-12.89 1.31-25.79 2.51-38.68 3.77-6.24.61-12.47 1.45-18.72 1.79-4.58.24-9.2-.17-13.81-.3l-17.85-.12-.13-.07z" class="st3"/>
|
||||
<path d="M413.28 303.3c-11.51 2.84-23.02 5.71-34.54 8.52-3.01.74-5.15-.34-6.61-3.17-4.02-7.79-8.22-15.49-12.24-23.29-9.92-19.24-19.79-38.51-29.65-57.78-1.83-3.57-1.04-5.01 3.08-4.81 6.05.29 12.09.97 18.13 1.49 1.89.4 2.54.15 5.06 3.74 17.1 24.41 37.01 47.73 54.85 71.62.81 1.1 1.28 2.45 1.92 3.68z" class="st2"/>
|
||||
<path d="M155.06 302.38c11.51 2.84 22.26 5.47 33.78 8.28 3.01.74 5.15-.34 6.61-3.17 4.02-7.79 8.22-15.49 12.24-23.29 9.92-19.24 17.3-37.26 26.37-56.7 1.83-3.57.68-4.95-3.44-4.75-6.05.29-10.08.42-16.13.94-2.11 1.25-2.46 1.66-3.84 3.47-18.01 23.75-35.83 47.64-53.67 71.53-.8 1.1-1.28 2.45-1.92 3.69z" class="st3"/>
|
||||
<path d="M421.92 316.24c0 .56-.19 1.22.04 1.66 3.28 6.31-.16 9.95-5.82 12.53-14.18 6.44-29.11 9.85-44.52 11.41-12.89 1.31-25.79 2.51-38.68 3.77-6.24.61-12.94 1.22-18.94 1.29-4.59.05-8.98.32-13.59.2l-17.85-.12-.12-.08c-15.36.35-28.73.35-46.17-1.19-15.98-1.41-31.97-2.99-47.91-4.95-13.64-1.67-26.85-5.2-39.21-11.4-4.77-2.4-5.86-5.41-4.24-10.45.26-.81.06-1.77.07-2.66-6.55 2.47-11.33 6.45-12.86 13.75-1.74 8.28.69 15.31 5.77 21.67 1.43 1.79 2.4 3.22.07 5.22-.71.61-.81 3.27-.15 3.89 6.36 6.04 13.89 10.11 22.37 12.36 2.35.62 4.12.02 4.62-2.85.11-.64 1.63-1.63 2.27-1.49 8.66 1.96 17.26 4.13 25.91 6.14 1.98.46 2.73 1 1.52 3.01-1.45 2.4-.41 3.92 2 4.93 8.64 3.63 17.82 3.98 26.97 4.34 2.18.08 4.54-.9 3.51-3.88-1.11-3.22.45-3.2 2.83-2.99 8.57.73 17.14 1.44 25.72 1.95 3.13.19 3.98 1.04 2.41 3.98-1.6 2.98-.26 4.76 2.9 4.77 14.82.08 29.65.17 44.46-.08 4.59-.08 5.1-1.29 3.36-5.63-.84-2.1-.97-2.87 1.76-3.02 9.16-.52 18.32-1.21 27.45-2.12 2.5-.25 3.06.34 2.55 2.56-.53 2.31.05 4.05 2.72 4.11 9.52.21 18.91-.53 27.82-4.34 1.95-.83 3.09-2.06 1.71-4.23-1.72-2.71-.09-3.15 2.17-3.67 8.24-1.87 16.46-3.83 24.64-5.93 1.82-.47 3-.77 3.21 1.6.26 2.99 2.1 3.32 4.53 2.61 8.11-2.36 15.55-5.98 21.6-11.99.69-.69 1.03-2.99.55-3.39-3.18-2.71-1.41-4.64.51-6.95 7.99-9.66 9.45-27.91-7.96-34.34z" class="st0"/>
|
||||
<path d="M324.35 192.94c-6.72-.27-13.4-.35-20.23-.52-7.13-.17-18.9-.51-18.9-.51s-1.27.04-2.44 0c0 0-.63-.01-.63.18-.01-5.67.01-11.83 0-17.5 12.58.95 24.65 1.94 37.19 2.72 1.5.09 3.29-.07 4.8-.12.05 5.24.19 10.5.21 15.75z" class="st3"/>
|
||||
<path d="M243.35 193.45c6.72-.27 10.02-.35 16.86-.52 7.13-.17 18.9-.51 18.9-.51s1.27.04 2.44 0c0 0 .63-.53.63-.34.01-5.67-.01-11.83 0-17.5-12.58.95-21.28 1.94-33.82 2.72-1.5.09-3.29-.07-4.8-.12-.05 5.25-.18 11.03-.21 16.27z" class="st2"/>
|
||||
<path d="M327.57 193.15c-1.31-.1-2.62-.17-3.93-.26-13.33-.32-26.66-.63-39.99-.95h-.2c-13.33.32-26.66.63-39.99.95-1.31.08-2.62.15-3.93.26-6.26.5-6.88 1.16-6.73 7.17.02.7.18 1.39.27 2.09 1.91-.03 3.82.02 5.72-.1 14.92-1.02 28.65-2.07 43.57-3.11 14.92 1.04 31.01 2.1 45.93 3.11 1.9.13 3.81.07 5.72.1.09-.7.25-1.39.27-2.09.17-6.01-.46-6.67-6.71-7.17z" class="st0"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 7.9 KiB |
@@ -22,3 +22,4 @@
|
||||
*.tmproj
|
||||
.vscode/
|
||||
README.md.gotmpl
|
||||
artifacthub-repo.yml
|
||||
|
||||
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
|
||||
@@ -1,6 +1,6 @@
|
||||
dependencies:
|
||||
- name: capsule-proxy
|
||||
repository: oci://ghcr.io/projectcapsule/charts
|
||||
version: 0.6.0
|
||||
digest: sha256:4cf05b352f1c38a821081cc01ac5f2a84ed7d68514a5b98e63edba5ab1c7b19e
|
||||
generated: "2024-03-05T17:09:58.383699+01:00"
|
||||
version: 0.9.9
|
||||
digest: sha256:01938e6682c7788e1f6bb38cb97969ac524ffdc1ae824b59acdc7119938ac23c
|
||||
generated: "2025-07-22T22:24:44.398030885Z"
|
||||
|
||||
@@ -6,7 +6,7 @@ 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.6.0
|
||||
version: 0.9.9
|
||||
repository: "oci://ghcr.io/projectcapsule/charts"
|
||||
condition: proxy.enabled
|
||||
alias: proxy
|
||||
@@ -25,9 +25,9 @@ name: capsule
|
||||
sources:
|
||||
- https://github.com/projectcapsule/capsule
|
||||
# Note: The version is overwritten by the release workflow.
|
||||
version: 0.6.0
|
||||
version: 0.0.0
|
||||
# Note: The version is overwritten by the release workflow.
|
||||
appVersion: 0.5.0
|
||||
appVersion: 0.0.0
|
||||
annotations:
|
||||
artifacthub.io/operator: "true"
|
||||
artifacthub.io/prerelease: "false"
|
||||
@@ -41,6 +41,4 @@ annotations:
|
||||
url: https://projectcapsule.dev/
|
||||
artifacthub.io/changes: |
|
||||
- kind: added
|
||||
description: bundled crd lifecycle
|
||||
- kind: changed
|
||||
description: removed PodSecurityPolicy support
|
||||
description: added toggles for podSecurityContexts and securityContexts
|
||||
|
||||
@@ -35,6 +35,8 @@ The following Values have changed key or Value:
|
||||
|
||||
## Installation
|
||||
|
||||
**When using OCI we recommend our dedicated [OCI Repository](https://artifacthub.io/packages/helm/capsule/capsule) for this chart**
|
||||
|
||||
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.
|
||||
|
||||
@@ -93,37 +95,51 @@ Here the values you can override:
|
||||
| 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 | `{"enabled":true,"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"]},"enabled":true,"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.affinity | object | `{}` | Set affinity rules |
|
||||
| jobs.annotations | object | `{"helm.sh/hook-delete-policy":"before-hook-creation,hook-succeeded"}` | Annotations to add to the certgen job. |
|
||||
| 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 |
|
||||
| jobs.nodeSelector | object | `{}` | Set the node selector |
|
||||
| jobs.podSecurityContext | object | `{"seccompProfile":{"type":"RuntimeDefault"}}` | Security context for the job pods. |
|
||||
| jobs.priorityClassName | string | `""` | Set a pod priorityClassName |
|
||||
| jobs.resources | object | `{}` | Job resources |
|
||||
| jobs.restartPolicy | string | `"Never"` | Set the restartPolicy |
|
||||
| jobs.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsGroup":1002,"runAsNonRoot":true,"runAsUser":1002}` | Security context for the job containers. |
|
||||
| jobs.tolerations | list | `[]` | Set list of tolerations |
|
||||
| jobs.topologySpreadConstraints | list | `[]` | Set Topology Spread Constraints |
|
||||
| jobs.ttlSecondsAfterFinished | int | `60` | Sets the ttl in seconds after a finished certgen job is deleted. Set to -1 to never delete. |
|
||||
| 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 |
|
||||
| podSecurityContext | object | `{"enabled":true,"runAsGroup":1002,"runAsNonRoot":true,"runAsUser":1002,"seccompProfile":{"type":"RuntimeDefault"}}` | Set the securityContext for the Capsule pod |
|
||||
| ports | list | `[]` | Set additional ports for the deployment |
|
||||
| priorityClassName | string | `""` | Set the priority class name of the Capsule pod |
|
||||
| proxy.enabled | bool | `false` | Enable Installation of Capsule Proxy |
|
||||
| rbac.resourcepoolclaims.create | bool | `false` | |
|
||||
| rbac.resourcepoolclaims.labels."rbac.authorization.k8s.io/aggregate-to-admin" | string | `"true"` | |
|
||||
| rbac.resources.create | bool | `false` | |
|
||||
| rbac.resources.labels."rbac.authorization.k8s.io/aggregate-to-admin" | string | `"true"` | |
|
||||
| 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 |
|
||||
| securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"enabled":true,"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 | `""` | The name of the service account to use. If not set and `serviceAccount.create=true`, a name is generated using the fullname template |
|
||||
@@ -138,6 +154,7 @@ Here the values you can override:
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| manager.hostNetwork | bool | `false` | Specifies if the container should be started in hostNetwork mode. Required for use in some managed kubernetes clusters (such as AWS EKS) with custom CNI (such as calico), because control-plane managed by AWS cannot communicate with pods' IP CIDR and admission webhooks are not working |
|
||||
| manager.hostPID | bool | `false` | Specifies if the container should be started in hostPID mode. |
|
||||
| manager.image.pullPolicy | string | `"IfNotPresent"` | Set the image pull policy. |
|
||||
| manager.image.registry | string | `"ghcr.io"` | Set the image registry of capsule. |
|
||||
| manager.image.repository | string | `"projectcapsule/capsule"` | Set the image repository of capsule. |
|
||||
@@ -156,22 +173,34 @@ Here the values you can override:
|
||||
| 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 | object | `{}` | Set the resource requests/limits for the Capsule manager container |
|
||||
| manager.securityContext | object | `{}` | Set the securityContext for the Capsule container |
|
||||
| manager.volumeMounts | list | `[]` | Set the additional volumeMounts needed for the Capsule manager container |
|
||||
| manager.volumes | list | `[]` | Set the additional volumes needed 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
|
||||
### Monitoring Parameters
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| serviceMonitor.annotations | object | `{}` | Assign additional Annotations |
|
||||
| serviceMonitor.enabled | bool | `false` | Enable ServiceMonitor |
|
||||
| serviceMonitor.endpoint.interval | string | `"15s"` | Set the scrape interval for the endpoint of the serviceMonitor |
|
||||
| serviceMonitor.endpoint.metricRelabelings | list | `[]` | Set metricRelabelings for the endpoint of the serviceMonitor |
|
||||
| serviceMonitor.endpoint.relabelings | list | `[]` | Set relabelings for the endpoint of the serviceMonitor |
|
||||
| serviceMonitor.endpoint.scrapeTimeout | string | `""` | Set the scrape timeout for the endpoint of the serviceMonitor |
|
||||
| serviceMonitor.labels | object | `{}` | Assign additional labels according to Prometheus' serviceMonitorSelector matching labels |
|
||||
| serviceMonitor.matchLabels | object | `{}` | Change matching labels |
|
||||
| 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 |
|
||||
| monitoring.dashboards.annotations | object | `{}` | Annotations for dashboard configmaps |
|
||||
| monitoring.dashboards.enabled | bool | `false` | Enable Dashboards to be deployed |
|
||||
| monitoring.dashboards.labels | object | `{}` | Labels for dashboard configmaps |
|
||||
| monitoring.dashboards.namespace | string | `""` | Custom namespace for dashboard configmaps |
|
||||
| monitoring.dashboards.operator.allowCrossNamespaceImport | bool | `true` | Allow the Operator to match this resource with Grafanas outside the current namespace |
|
||||
| monitoring.dashboards.operator.enabled | bool | `true` | Enable Operator Resources (GrafanaDashboard) |
|
||||
| monitoring.dashboards.operator.folder | string | `""` | folder assignment for dashboard |
|
||||
| monitoring.dashboards.operator.instanceSelector | object | `{}` | Selects Grafana instances for import |
|
||||
| monitoring.dashboards.operator.resyncPeriod | string | `"10m"` | How often the resource is synced, defaults to 10m0s if not set |
|
||||
| monitoring.serviceMonitor.annotations | object | `{}` | Assign additional Annotations |
|
||||
| monitoring.serviceMonitor.enabled | bool | `false` | Enable ServiceMonitor |
|
||||
| monitoring.serviceMonitor.endpoint.interval | string | `"15s"` | Set the scrape interval for the endpoint of the serviceMonitor |
|
||||
| monitoring.serviceMonitor.endpoint.metricRelabelings | list | `[]` | Set metricRelabelings for the endpoint of the serviceMonitor |
|
||||
| monitoring.serviceMonitor.endpoint.relabelings | list | `[]` | Set relabelings for the endpoint of the serviceMonitor |
|
||||
| monitoring.serviceMonitor.endpoint.scrapeTimeout | string | `""` | Set the scrape timeout for the endpoint of the serviceMonitor |
|
||||
| monitoring.serviceMonitor.labels | object | `{}` | Assign additional labels according to Prometheus' serviceMonitorSelector matching labels |
|
||||
| monitoring.serviceMonitor.matchLabels | object | `{}` | Change matching labels |
|
||||
| monitoring.serviceMonitor.namespace | string | `""` | Install the ServiceMonitor into a different Namespace, as the monitoring stack one (default: the release one) |
|
||||
| monitoring.serviceMonitor.targetLabels | list | `[]` | Set targetLabels for the serviceMonitor |
|
||||
|
||||
### Webhooks Parameters
|
||||
|
||||
@@ -181,6 +210,12 @@ Here the values you can override:
|
||||
| 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.cordoning.namespaceSelector.matchExpressions[1].key | string | `"projectcapsule.dev/cordoned"` | |
|
||||
| webhooks.hooks.cordoning.namespaceSelector.matchExpressions[1].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.customresources.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.customresources.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.customresources.namespaceSelector.matchExpressions[0].operator | string | `"Exists"` | |
|
||||
| webhooks.hooks.customresources.objectSelector | object | `{}` | |
|
||||
| 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"` | |
|
||||
@@ -190,9 +225,16 @@ Here the values you can override:
|
||||
| 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.gateways.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.gateways.namespaceSelector.matchExpressions[0].key | string | `"capsule.clastix.io/tenant"` | |
|
||||
| webhooks.hooks.gateways.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.namespace.mutation.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.namespace.mutation.namespaceSelector | object | `{}` | |
|
||||
| webhooks.hooks.namespace.mutation.objectSelector | object | `{}` | |
|
||||
| webhooks.hooks.namespace.validation.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.namespaceOwnerReference.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.namespaces.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.networkpolicies.failurePolicy | string | `"Fail"` | |
|
||||
@@ -205,6 +247,16 @@ Here the values you can override:
|
||||
| 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.resourcepools.claims.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.resourcepools.claims.matchPolicy | string | `"Equivalent"` | |
|
||||
| webhooks.hooks.resourcepools.claims.namespaceSelector | object | `{}` | |
|
||||
| webhooks.hooks.resourcepools.claims.objectSelector | object | `{}` | |
|
||||
| webhooks.hooks.resourcepools.claims.reinvocationPolicy | string | `"Never"` | |
|
||||
| webhooks.hooks.resourcepools.pools.failurePolicy | string | `"Fail"` | |
|
||||
| webhooks.hooks.resourcepools.pools.matchPolicy | string | `"Equivalent"` | |
|
||||
| webhooks.hooks.resourcepools.pools.namespaceSelector | object | `{}` | |
|
||||
| webhooks.hooks.resourcepools.pools.objectSelector | object | `{}` | |
|
||||
| webhooks.hooks.resourcepools.pools.reinvocationPolicy | string | `"Never"` | |
|
||||
| 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"` | |
|
||||
|
||||
@@ -16,7 +16,7 @@ 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.
|
||||
|
||||
## Major Changes
|
||||
## Major Changes
|
||||
|
||||
In the following sections you see actions which are required when you are upgrading to a specific version.
|
||||
|
||||
@@ -25,7 +25,7 @@ In the following sections you see actions which are required when you are upgrad
|
||||
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
|
||||
#### Changed Values
|
||||
|
||||
The following Values have changed key or Value:
|
||||
|
||||
@@ -36,6 +36,8 @@ The following Values have changed key or Value:
|
||||
|
||||
## Installation
|
||||
|
||||
**When using OCI we recommend our dedicated [OCI Repository](https://artifacthub.io/packages/helm/capsule/capsule) for this chart**
|
||||
|
||||
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.
|
||||
|
||||
@@ -95,13 +97,22 @@ Here the values you can override:
|
||||
{{- 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 "crds" .Key) (hasPrefix "serviceMonitor" .Key) (hasPrefix "webhook" .Key) (hasPrefix "capsule-proxy" .Key) ) }}
|
||||
{{- if not (or (hasPrefix "global" .Key) (hasPrefix "manager" .Key) (hasPrefix "crds" .Key) (hasPrefix "monitoring" .Key) (hasPrefix "webhook" .Key) (hasPrefix "capsule-proxy" .Key) ) }}
|
||||
| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -116,12 +127,12 @@ Here the values you can override:
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
### ServiceMonitor Parameters
|
||||
### Monitoring Parameters
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
{{- range .Values }}
|
||||
{{- if hasPrefix "serviceMonitor" .Key }}
|
||||
{{- if hasPrefix "monitoring" .Key }}
|
||||
| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
4
charts/capsule/artifacthub-repo.yml
Normal file
4
charts/capsule/artifacthub-repo.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
repositoryID: 783775bb-96c2-4915-8c7d-ba4a1118323c
|
||||
owners:
|
||||
- name: capsule-maintainers
|
||||
email: cncf-capsule-maintainers@lists.cncf.io
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user