mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-01-14 09:43:13 +00:00
Compare commits
396 Commits
poc/sessio
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
174b3026c7 | ||
|
|
e009d22900 | ||
|
|
4b7fbc144e | ||
|
|
98621c76b5 | ||
|
|
6d8aed7f40 | ||
|
|
3031a070d1 | ||
|
|
ff71d7e768 | ||
|
|
a82e32057a | ||
|
|
d99563c85c | ||
|
|
54d530784d | ||
|
|
44509d016e | ||
|
|
3c4c272607 | ||
|
|
cbce243d57 | ||
|
|
b04ae898ca | ||
|
|
bc88faa50d | ||
|
|
f703d096d6 | ||
|
|
9d1c65c3e6 | ||
|
|
10444fb9a3 | ||
|
|
ebfd7d0600 | ||
|
|
b2747a0ebe | ||
|
|
e824e74fcc | ||
|
|
2394960a89 | ||
|
|
1a5a1eefe4 | ||
|
|
1350fb71f0 | ||
|
|
ca7d53ba0a | ||
|
|
0a5bc94c6e | ||
|
|
ca3c669230 | ||
|
|
5218c20c76 | ||
|
|
cba4e2a2e8 | ||
|
|
4b77a46a6f | ||
|
|
db1e85c412 | ||
|
|
a4fdce1077 | ||
|
|
f2c1eda663 | ||
|
|
fd05cbb4b1 | ||
|
|
22c63919af | ||
|
|
70cb9b64b9 | ||
|
|
3447e28fee | ||
|
|
05db85cb2d | ||
|
|
2cfa610249 | ||
|
|
fa5f75464d | ||
|
|
718b970bc2 | ||
|
|
9be6bb0b94 | ||
|
|
6e87caaa6a | ||
|
|
270594cdb1 | ||
|
|
b1b4bbaa4a | ||
|
|
9aa3f7496a | ||
|
|
7f14ac7863 | ||
|
|
f001df3978 | ||
|
|
2f68041c88 | ||
|
|
513f1cf7d9 | ||
|
|
d68761e144 | ||
|
|
92172ca150 | ||
|
|
c6d8539b8a | ||
|
|
70c3c62021 | ||
|
|
1623b2c46e | ||
|
|
adc0dba8e5 | ||
|
|
6de6d17429 | ||
|
|
c51fde6c5a | ||
|
|
cf63d782d4 | ||
|
|
577797d569 | ||
|
|
e427a5202e | ||
|
|
44893e6b0d | ||
|
|
7090fb7038 | ||
|
|
892ffead6c | ||
|
|
9bbdf59828 | ||
|
|
bf416d59c8 | ||
|
|
95e4ec9d88 | ||
|
|
097f3ec5fe | ||
|
|
301c717d17 | ||
|
|
e20c5beb47 | ||
|
|
f96b17abbf | ||
|
|
71295c619d | ||
|
|
bf2b28a755 | ||
|
|
62dd4ab758 | ||
|
|
ff38d82745 | ||
|
|
47e1f7e465 | ||
|
|
4fe8167f60 | ||
|
|
8f583447ca | ||
|
|
9c1cc8db50 | ||
|
|
089e8cf740 | ||
|
|
a038aeb8f0 | ||
|
|
088f88bdc0 | ||
|
|
3a02eec765 | ||
|
|
1c1b3b7f2e | ||
|
|
b387a2cae9 | ||
|
|
af8d7335fd | ||
|
|
07ed9e95cd | ||
|
|
8d56e06f1c | ||
|
|
17cb4c2ee5 | ||
|
|
cd3f55c019 | ||
|
|
cf700382fe | ||
|
|
da26da1bd5 | ||
|
|
679a40b847 | ||
|
|
6d8ad5f7a9 | ||
|
|
3c28171525 | ||
|
|
83696fd023 | ||
|
|
cc4a148c70 | ||
|
|
52622d5e4c | ||
|
|
64e5e20010 | ||
|
|
2a83d00373 | ||
|
|
fdfe2a3c9f | ||
|
|
04f0c559db | ||
|
|
9a97e20c40 | ||
|
|
9e742d2d84 | ||
|
|
4c134a410d | ||
|
|
cd431c2a8e | ||
|
|
96ef1b75a7 | ||
|
|
63d56f3abb | ||
|
|
de273ea68a | ||
|
|
b4758c8e4f | ||
|
|
5258bd542c | ||
|
|
0656a2dde9 | ||
|
|
9d681f2745 | ||
|
|
d57005c42a | ||
|
|
6de6bcd81a | ||
|
|
d1a14413fb | ||
|
|
c8a7c10793 | ||
|
|
fa0c63fc40 | ||
|
|
d8a439acc3 | ||
|
|
1254f730f2 | ||
|
|
69281a4620 | ||
|
|
02f7ad2fff | ||
|
|
2e3e0eed8e | ||
|
|
72cea70967 | ||
|
|
1428444c24 | ||
|
|
7276a1df53 | ||
|
|
33c68e2e7d | ||
|
|
0986c90678 | ||
|
|
986ebe0063 | ||
|
|
9b24ecad19 | ||
|
|
2e4f719419 | ||
|
|
f45e0aeb3d | ||
|
|
e743beac53 | ||
|
|
b294c7657a | ||
|
|
524989e16b | ||
|
|
a6b2905c3a | ||
|
|
aa2bdcb8dd | ||
|
|
a315cc4977 | ||
|
|
b8e7a64afe | ||
|
|
b50da60c84 | ||
|
|
dfc4c38259 | ||
|
|
dce1f5b208 | ||
|
|
c600cf7949 | ||
|
|
32a29da86c | ||
|
|
9ac9930650 | ||
|
|
1f01c394f3 | ||
|
|
a41ca92b8e | ||
|
|
f75eef16b4 | ||
|
|
2e801dc275 | ||
|
|
b8b460f98a | ||
|
|
39588c3bb4 | ||
|
|
79035bc2b6 | ||
|
|
85c94116ce | ||
|
|
7e8ea9f1fb | ||
|
|
a0e38fe8c1 | ||
|
|
f9c3d932c1 | ||
|
|
861c501ea8 | ||
|
|
e129a569ba | ||
|
|
fd42da225d | ||
|
|
b139a458fd | ||
|
|
68a2df41ed | ||
|
|
2cbdd60022 | ||
|
|
0e12f90749 | ||
|
|
7e132a5dcd | ||
|
|
910326f1ea | ||
|
|
6057b0c912 | ||
|
|
2845829fb4 | ||
|
|
653b6d5b0d | ||
|
|
7ef58a9132 | ||
|
|
cf98c69c0d | ||
|
|
62f6d8516b | ||
|
|
604ecc583c | ||
|
|
a010794873 | ||
|
|
c7462bf1f6 | ||
|
|
b396d12456 | ||
|
|
695ea3a165 | ||
|
|
d625ada06a | ||
|
|
0f48620d9c | ||
|
|
c2496aab6b | ||
|
|
00734d143e | ||
|
|
d90b3c23ef | ||
|
|
035dbffd28 | ||
|
|
e3710289e5 | ||
|
|
99b67b89ac | ||
|
|
e374841857 | ||
|
|
9f2336476f | ||
|
|
63b560d740 | ||
|
|
f54834cbee | ||
|
|
749633e43c | ||
|
|
308c76cd69 | ||
|
|
fc9a261b77 | ||
|
|
d2d860bd3b | ||
|
|
9cb3638354 | ||
|
|
6133276555 | ||
|
|
a7a3016ae5 | ||
|
|
dd0dcad8c4 | ||
|
|
ed8c9448de | ||
|
|
5e80fb26f0 | ||
|
|
292855332c | ||
|
|
68b0dd83f2 | ||
|
|
611fc61c12 | ||
|
|
2cd4a2c730 | ||
|
|
3e89915a98 | ||
|
|
f4aaee8bd7 | ||
|
|
d56413a289 | ||
|
|
27b629af3a | ||
|
|
1a3cb65fa4 | ||
|
|
4b3eb0e6ec | ||
|
|
f89b13bc62 | ||
|
|
8b7fec5049 | ||
|
|
3a6573f89e | ||
|
|
4e04f5b606 | ||
|
|
39a86e7d52 | ||
|
|
8cfc1c08ec | ||
|
|
c90637398d | ||
|
|
737aabb620 | ||
|
|
0e930b3d63 | ||
|
|
876f626e7d | ||
|
|
0dc704be9c | ||
|
|
e437832698 | ||
|
|
274ca4cb73 | ||
|
|
a99ff646a0 | ||
|
|
02eb26f135 | ||
|
|
e90f19f8ab | ||
|
|
00c2c5cf6e | ||
|
|
3386774f5f | ||
|
|
7e4330be93 | ||
|
|
f5b3e6da93 | ||
|
|
5c39374915 | ||
|
|
4fdb931141 | ||
|
|
3a02854192 | ||
|
|
63c071d6ea | ||
|
|
6dc96f4224 | ||
|
|
aa8f8f7fda | ||
|
|
f5167bb279 | ||
|
|
b84eafc173 | ||
|
|
50ed1b0cf9 | ||
|
|
1d873be184 | ||
|
|
5a0d6eddb1 | ||
|
|
31b45525ce | ||
|
|
430c73b903 | ||
|
|
cc1befbc57 | ||
|
|
68a0ad4112 | ||
|
|
9aca187559 | ||
|
|
d0fb9f3637 | ||
|
|
51d1bc32e8 | ||
|
|
e9b9dd6fa3 | ||
|
|
7e43aa4e12 | ||
|
|
de509db7be | ||
|
|
69c6676d8f | ||
|
|
2ab11dccfc | ||
|
|
d64b4677b9 | ||
|
|
f040f098dc | ||
|
|
abe3391cce | ||
|
|
6ae27c87f6 | ||
|
|
3d2446d235 | ||
|
|
4f01b3157f | ||
|
|
14e728aa0d | ||
|
|
4a266a44db | ||
|
|
900db0d3a3 | ||
|
|
8b95b141b2 | ||
|
|
5a9f2f3181 | ||
|
|
4f43f01e55 | ||
|
|
7221be5a8a | ||
|
|
83ab099b84 | ||
|
|
5f79860c8c | ||
|
|
e4f7b5d181 | ||
|
|
9619a0f226 | ||
|
|
23f414c384 | ||
|
|
4872be0a84 | ||
|
|
691307a269 | ||
|
|
6d846ad2a9 | ||
|
|
ff24c757b7 | ||
|
|
ee4663aa19 | ||
|
|
119c591500 | ||
|
|
275412e902 | ||
|
|
fe75ebe4b2 | ||
|
|
fabb80cf19 | ||
|
|
7577f20c61 | ||
|
|
f441714f93 | ||
|
|
2c9547e6a4 | ||
|
|
3bf3ed03f5 | ||
|
|
c279253e20 | ||
|
|
fa9ddf48d5 | ||
|
|
b8a9c4d1e5 | ||
|
|
b4365c100f | ||
|
|
ef4b0c9cff | ||
|
|
b625b4a076 | ||
|
|
acbe9ce23d | ||
|
|
90c95866d1 | ||
|
|
57fc177266 | ||
|
|
0366f4087f | ||
|
|
3f6d287b44 | ||
|
|
36aa701b56 | ||
|
|
fc5a776645 | ||
|
|
c2b4390bfa | ||
|
|
b371389c27 | ||
|
|
87640ca54a | ||
|
|
8322b03d63 | ||
|
|
594c3580f2 | ||
|
|
0d80c492f1 | ||
|
|
1a29cca1ca | ||
|
|
b54191f29f | ||
|
|
422e4e4785 | ||
|
|
4187cc1f61 | ||
|
|
ede9e45211 | ||
|
|
a36550d94b | ||
|
|
7c3870f3fa | ||
|
|
7ca2796774 | ||
|
|
170cc3bba4 | ||
|
|
1980912ebe | ||
|
|
1571859d67 | ||
|
|
eb4c20a6aa | ||
|
|
1154139b91 | ||
|
|
28e22d7dd2 | ||
|
|
9cfbbb541a | ||
|
|
21bce1cb92 | ||
|
|
fe045343ee | ||
|
|
df017f9267 | ||
|
|
ae5aad178d | ||
|
|
032160a85e | ||
|
|
ecd23e86ce | ||
|
|
51ae782135 | ||
|
|
54b35c30da | ||
|
|
dfe04c5a58 | ||
|
|
4423d472da | ||
|
|
c803a182be | ||
|
|
bc73505e35 | ||
|
|
0a28c818ad | ||
|
|
ce2dcbdbb3 | ||
|
|
1ebe2fcd1a | ||
|
|
c7e9ee1c61 | ||
|
|
51c86795af | ||
|
|
8dffd60f0b | ||
|
|
6bf9b64778 | ||
|
|
26ec7fa346 | ||
|
|
60bd118a9c | ||
|
|
b69507f7f3 | ||
|
|
7d59df0f86 | ||
|
|
9c0272382f | ||
|
|
2de8d9f0f3 | ||
|
|
d0905c02dd | ||
|
|
51fc86f950 | ||
|
|
76bda12760 | ||
|
|
a84b76e56a | ||
|
|
c2018717b6 | ||
|
|
f388513145 | ||
|
|
c16ebe1707 | ||
|
|
b54365c199 | ||
|
|
51d1cc7a96 | ||
|
|
c06141c871 | ||
|
|
eab3fde3af | ||
|
|
de7781b7f9 | ||
|
|
611de03e01 | ||
|
|
de722332b1 | ||
|
|
438ca437ec | ||
|
|
e21e1326b7 | ||
|
|
37e12b4024 | ||
|
|
e126ee5495 | ||
|
|
a308f3f22a | ||
|
|
c5f4cce3ae | ||
|
|
ced8686d11 | ||
|
|
76f6b725b8 | ||
|
|
f9e1dd4bec | ||
|
|
f4f393e5de | ||
|
|
2db5dda266 | ||
|
|
8cf9c59957 | ||
|
|
088556193d | ||
|
|
18d3ab3d15 | ||
|
|
dc6faa33bb | ||
|
|
0d22ae2c1a | ||
|
|
362d982906 | ||
|
|
1006dd9379 | ||
|
|
369316556a | ||
|
|
cf4b29de4b | ||
|
|
09ca7920ea | ||
|
|
9994e033b2 | ||
|
|
dd56f2b47f | ||
|
|
4df043a91c | ||
|
|
d020de4b3d | ||
|
|
dd42f35db0 | ||
|
|
a67af9455b | ||
|
|
d729c82f84 | ||
|
|
44e218194b | ||
|
|
bf1e37f149 | ||
|
|
aee56c388f | ||
|
|
fd5a10bee7 | ||
|
|
b20e890f15 | ||
|
|
4f9530eec7 | ||
|
|
615b60bd37 | ||
|
|
e61afcd109 | ||
|
|
6ac5446940 | ||
|
|
0706681180 | ||
|
|
e44d70b41d | ||
|
|
4bf810cb8f | ||
|
|
c791db4c52 |
16
.github/ISSUE_TEMPLATE/release_checklist.md
vendored
16
.github/ISSUE_TEMPLATE/release_checklist.md
vendored
@@ -11,21 +11,23 @@ assignees: ''
|
||||
|
||||
# Release checklist
|
||||
|
||||
- [ ] Ensure that Pinniped's dependencies have been upgraded, to the extent desired by the team (refer to the diff output from the latest run of the [all-golang-deps-updated](https://ci.pinniped.dev/teams/main/pipelines/security-scan/jobs/all-golang-deps-updated/) CI job)
|
||||
- [ ] Ensure that Pinniped's dependencies have been upgraded, to the extent desired by the team (refer to the diff output from the latest run of the [all-golang-deps-updated](https://ci.pinniped.broadcom.net/teams/main/pipelines/security-scan/jobs/all-golang-deps-updated/) CI job)
|
||||
- [ ] If you are updating golang in Pinniped, be sure to update golang in CI as well. Do a search-and-replace to update the version number everywhere in the pinniped `ci` branch.
|
||||
- [ ] If the Fosite library is being updated and the format of the content of the Supervisor's storage Secrets are changed, or if any change to our own code changes the format of the content of the Supervisor's session storage Secrets, then be sure to update the `accessTokenStorageVersion`, `authorizeCodeStorageVersion`, `oidcStorageVersion`, `pkceStorageVersion`, `refreshTokenStorageVersion`, variables in files such as `internal/fositestorage/accesstoken/accesstoken.go`. Failing tests should signal the need to update these values.
|
||||
- [ ] For go.mod direct dependencies that are v2 or above, such as `github.com/google/go-github/vXX`, check to see if there is a new major version available.
|
||||
- [ ] Evaluate all `replace` directives in the `go.mod` file. Are they up to date versions? Can any `replace` directives be removed?
|
||||
- [ ] Ensure that Pinniped's codegen is up-to-date with the latest Kubernetes releases by making sure this [file](https://github.com/vmware-tanzu/pinniped/blob/main/hack/lib/kube-versions.txt) is updated compared to the latest releases listed [here for active branches](https://kubernetes.io/releases/) and [here for non-active branches](https://kubernetes.io/releases/patch-releases/#non-active-branch-history)
|
||||
- [ ] For go.mod direct dependencies that are v2 or above, such as `github.com/google/go-github/vXX`, check to see if there is a new major version available. Try using `hack/update-go-mod/update-majors.sh`.
|
||||
- [ ] Evaluate all `replace` directives in the `go.mod` file. Are those versions up-to-date? Can any `replace` directives be removed?
|
||||
- [ ] Evaluate all overrides in the `hack/update-go-mod/overrides.conf` file. Are those versions up-to-date? Can those overrides be removed?
|
||||
- [ ] Ensure that Pinniped's codegen is up-to-date with the latest Kubernetes releases by making sure this [file](https://github.com/vmware/pinniped/blob/main/hack/lib/kube-versions.txt) is updated compared to the latest releases listed [here for active branches](https://kubernetes.io/releases/) and [here for non-active branches](https://kubernetes.io/releases/patch-releases/#non-active-branch-history)
|
||||
- [ ] Ensure that the `k8s-code-generator` CI job definitions are up-to-date with the latest Go, K8s, and `controller-gen` versions
|
||||
- [ ] All relevant feature and docs PRs are merged
|
||||
- [ ] The [main pipeline](https://ci.pinniped.dev/teams/main/pipelines/main) is green, up to and including the `ready-to-release` job. Check that the expected git commit has passed the `ready-to-release` job.
|
||||
- [ ] The [main pipeline](https://ci.pinniped.broadcom.net/teams/main/pipelines/main) is green, up to and including the `ready-to-release` job. Check that the expected git commit has passed the `ready-to-release` job.
|
||||
- [ ] Manually trigger the jobs `run-int-misc`, `run-int-cloud-providers`, and `run-int-k8s-versions` in the main pipeline to run other pre-release tests. Depending on the number of Concourse workers, you may need to run these one at a time.
|
||||
- [ ] Optional: a blog post for the release is written and submitted as a PR but not merged yet
|
||||
- [ ] All merged user stories are accepted (manually tested)
|
||||
- [ ] Only after all stories are accepted, manually trigger the `release` job to create a draft GitHub release
|
||||
- [ ] Manually edit the draft release notes on the [GitHub release](https://github.com/vmware-tanzu/pinniped/releases) to describe the contents of the release, using the format which was automatically added to the draft release
|
||||
- [ ] Manually edit the draft release notes on the [GitHub release](https://github.com/vmware/pinniped/releases) to describe the contents of the release, using the format which was automatically added to the draft release
|
||||
- [ ] Publish (i.e. make public) the draft release
|
||||
- [ ] After making the release public, the jobs in the [main pipeline](https://ci.pinniped.dev/teams/main/pipelines/main) beyond the release job should auto-trigger, so check to make sure that they passed
|
||||
- [ ] After making the release public, the jobs in the [main pipeline](https://ci.pinniped.broadcom.net/teams/main/pipelines/main) beyond the release job should auto-trigger, so check to make sure that they passed
|
||||
- [ ] Edit the blog post's date to make it match the actual release date, and merge the blog post PR to make it live on the website
|
||||
- [ ] Publicize the release via tweets, etc.
|
||||
- [ ] Close this issue
|
||||
|
||||
6
.github/dependabot.yml
vendored
6
.github/dependabot.yml
vendored
@@ -71,12 +71,6 @@ updates:
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/go-lint-runner/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/integration-test-runner/"
|
||||
open-pull-requests-limit: 100
|
||||
|
||||
277
.golangci.yaml
277
.golangci.yaml
@@ -1,24 +1,14 @@
|
||||
# https://golangci-lint.run/usage/configuration/
|
||||
run:
|
||||
timeout: 1m
|
||||
|
||||
version: "2"
|
||||
linters:
|
||||
disable-all: true
|
||||
default: none
|
||||
enable:
|
||||
# default linters
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- typecheck
|
||||
- unused
|
||||
|
||||
# additional linters for this project (we should disable these if they get annoying).
|
||||
- asciicheck
|
||||
- bodyclose
|
||||
# - depguard
|
||||
- copyloopvar
|
||||
- dogsled
|
||||
- errcheck
|
||||
- exhaustive
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
@@ -27,136 +17,151 @@ linters:
|
||||
- gocyclo
|
||||
- godot
|
||||
- goheader
|
||||
- goimports
|
||||
- revive
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- govet
|
||||
- importas
|
||||
- ineffassign
|
||||
- intrange
|
||||
- makezero
|
||||
- misspell
|
||||
- nakedret
|
||||
- nestif
|
||||
- noctx
|
||||
- nolintlint
|
||||
- prealloc
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- sqlclosecheck
|
||||
- unconvert
|
||||
- whitespace
|
||||
- copyloopvar
|
||||
- intrange
|
||||
# - fatcontext Starting in go@1.23.1 and golangci-lint@1.61.0 this gave a lot of false positives
|
||||
# - canonicalheader Can't do this one since it alerts on valid headers such as X-XSS-Protection
|
||||
- spancheck
|
||||
- importas
|
||||
- makezero
|
||||
- prealloc
|
||||
- gofmt
|
||||
|
||||
issues:
|
||||
exclude-dirs:
|
||||
- generated
|
||||
exclude-rules:
|
||||
# exclude tests from some rules for things that are useful in a testing context.
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- revive
|
||||
- path: internal/testutil/
|
||||
linters:
|
||||
- revive
|
||||
|
||||
linters-settings:
|
||||
funlen:
|
||||
lines: 150
|
||||
statements: 50
|
||||
goheader:
|
||||
values:
|
||||
regexp:
|
||||
# YYYY or YYYY-YYYY
|
||||
YEARS: \d\d\d\d(-\d\d\d\d)?
|
||||
template: |-
|
||||
Copyright {{YEARS}} the Pinniped contributors. All Rights Reserved.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
goimports:
|
||||
local-prefixes: go.pinniped.dev
|
||||
revive:
|
||||
max-open-files: 2048
|
||||
- sqlclosecheck
|
||||
- staticcheck
|
||||
- unconvert
|
||||
- unused
|
||||
- whitespace
|
||||
settings:
|
||||
funlen:
|
||||
lines: 150
|
||||
statements: 50
|
||||
goheader:
|
||||
values:
|
||||
regexp:
|
||||
# YYYY or YYYY-YYYY
|
||||
YEARS: \d\d\d\d(-\d\d\d\d)?
|
||||
template: |-
|
||||
Copyright {{YEARS}} the Pinniped contributors. All Rights Reserved.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
importas:
|
||||
alias:
|
||||
- pkg: k8s.io/apimachinery/pkg/util/errors
|
||||
alias: utilerrors
|
||||
- pkg: k8s.io/apimachinery/pkg/api/errors
|
||||
alias: apierrors
|
||||
- pkg: k8s.io/apimachinery/pkg/apis/meta/v1
|
||||
alias: metav1
|
||||
- pkg: k8s.io/api/core/v1
|
||||
alias: corev1
|
||||
- pkg: github.com/coreos/go-oidc/v3/oidc
|
||||
alias: coreosoidc
|
||||
- pkg: github.com/ory/fosite/handler/oauth2
|
||||
alias: fositeoauth2
|
||||
- pkg: github.com/ory/fosite/token/jwt
|
||||
alias: fositejwt
|
||||
- pkg: github.com/go-jose/go-jose/v4/jwt
|
||||
alias: josejwt
|
||||
- pkg: github.com/go-jose/go-jose/v3
|
||||
alias: oldjosev3
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1
|
||||
alias: authenticationv1alpha1
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/clientsecret/v1alpha1
|
||||
alias: clientsecretv1alpha1
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1
|
||||
alias: supervisorconfigv1alpha1
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1
|
||||
alias: conciergeconfigv1alpha1
|
||||
- pkg: go.pinniped.dev/generated/latest/client/concierge/clientset/versioned
|
||||
alias: conciergeclientset
|
||||
- pkg: go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/scheme
|
||||
alias: conciergeclientsetscheme
|
||||
- pkg: go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake
|
||||
alias: conciergefake
|
||||
- pkg: go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned
|
||||
alias: supervisorclientset
|
||||
- pkg: go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/scheme
|
||||
alias: supervisorclientsetscheme
|
||||
- pkg: go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake
|
||||
alias: supervisorfake
|
||||
- pkg: k8s.io/client-go/kubernetes/fake
|
||||
alias: kubefake
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1
|
||||
alias: idpv1alpha1
|
||||
- pkg: go.pinniped.dev/generated/latest/client/concierge/informers/externalversions
|
||||
alias: conciergeinformers
|
||||
- pkg: go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions
|
||||
alias: supervisorinformers
|
||||
- pkg: go.pinniped.dev/internal/concierge/scheme
|
||||
alias: conciergescheme
|
||||
no-unaliased: true # All packages explicitly listed above must be aliased
|
||||
no-extra-aliases: false # Allow other aliases than the ones explicitly listed above
|
||||
revive:
|
||||
max-open-files: 2048
|
||||
rules:
|
||||
# Allow unused params that start with underscore. It can be nice to keep unused param names when implementing
|
||||
# an interface sometimes, to help readers understand why it is unused in that particular implementation.
|
||||
- name: unused-parameter
|
||||
arguments:
|
||||
- allowRegex: ^_
|
||||
spancheck:
|
||||
# https://golangci-lint.run/usage/linters/#spancheck
|
||||
checks:
|
||||
- end
|
||||
- record-error
|
||||
- set-status
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
rules:
|
||||
- name: unused-parameter
|
||||
arguments:
|
||||
# Allow unused params that start with underscore. It can be nice to keep unused param names when implementing
|
||||
# an interface sometimes, to help readers understand why it is unused in that particular implementation.
|
||||
- allowRegex: "^_"
|
||||
spancheck:
|
||||
# https://golangci-lint.run/usage/linters/#spancheck
|
||||
checks:
|
||||
- end
|
||||
- record-error
|
||||
- set-status
|
||||
importas:
|
||||
no-unaliased: true # All packages explicitly listed below must be aliased
|
||||
no-extra-aliases: false # Allow other aliases than the ones explicitly listed below
|
||||
alias:
|
||||
# k8s.io/apimachinery
|
||||
- pkg: k8s.io/apimachinery/pkg/util/errors
|
||||
alias: utilerrors
|
||||
- pkg: k8s.io/apimachinery/pkg/api/errors
|
||||
alias: apierrors
|
||||
- pkg: k8s.io/apimachinery/pkg/apis/meta/v1
|
||||
alias: metav1
|
||||
# k8s.io
|
||||
- pkg: k8s.io/api/core/v1
|
||||
alias: corev1
|
||||
# OAuth2/OIDC/Fosite/JOSE
|
||||
- pkg: github.com/coreos/go-oidc/v3/oidc
|
||||
alias: coreosoidc
|
||||
- pkg: github.com/ory/fosite/handler/oauth2
|
||||
alias: fositeoauth2
|
||||
- pkg: github.com/ory/fosite/token/jwt
|
||||
alias: fositejwt
|
||||
- pkg: github.com/go-jose/go-jose/v4/jwt
|
||||
alias: josejwt
|
||||
- pkg: github.com/go-jose/go-jose/v3
|
||||
alias: oldjosev3
|
||||
# Generated Pinniped
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1
|
||||
alias: authenticationv1alpha1
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/clientsecret/v1alpha1
|
||||
alias: clientsecretv1alpha1
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1
|
||||
alias: supervisorconfigv1alpha1
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1
|
||||
alias: conciergeconfigv1alpha1
|
||||
- pkg: go.pinniped.dev/generated/latest/client/concierge/clientset/versioned
|
||||
alias: conciergeclientset
|
||||
- pkg: go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/scheme
|
||||
alias: conciergeclientsetscheme
|
||||
- pkg: go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake
|
||||
alias: conciergefake
|
||||
- pkg: go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned
|
||||
alias: supervisorclientset
|
||||
- pkg: go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/scheme
|
||||
alias: supervisorclientsetscheme
|
||||
- pkg: go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake
|
||||
alias: supervisorfake
|
||||
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1
|
||||
alias: idpv1alpha1
|
||||
- pkg: go.pinniped.dev/generated/latest/client/concierge/informers/externalversions
|
||||
alias: conciergeinformers
|
||||
- pkg: go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions
|
||||
alias: supervisorinformers
|
||||
# Pinniped internal
|
||||
- pkg: go.pinniped.dev/internal/concierge/scheme
|
||||
alias: conciergescheme
|
||||
gofmt:
|
||||
# Simplify code: gofmt with `-s` option.
|
||||
# Default: true
|
||||
simplify: false
|
||||
# Apply the rewrite rules to the source before reformatting.
|
||||
# https://pkg.go.dev/cmd/gofmt
|
||||
# Default: []
|
||||
rewrite-rules:
|
||||
- pattern: 'interface{}'
|
||||
replacement: 'any'
|
||||
- pattern: 'a[b:len(a)]'
|
||||
replacement: 'a[b:]'
|
||||
# exclude tests from some rules for things that are useful in a testing context.
|
||||
- linters:
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- revive
|
||||
path: _test\.go
|
||||
- linters:
|
||||
- revive
|
||||
path: internal/testutil/
|
||||
paths:
|
||||
- generated
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
settings:
|
||||
gofmt:
|
||||
# Simplify code: gofmt with `-s` option.
|
||||
# Default: true
|
||||
simplify: false
|
||||
# Apply the rewrite rules to the source before reformatting.
|
||||
# https://pkg.go.dev/cmd/gofmt
|
||||
# Default: []
|
||||
rewrite-rules:
|
||||
- pattern: interface{}
|
||||
replacement: any
|
||||
- pattern: a[b:len(a)]
|
||||
replacement: a[b:]
|
||||
goimports:
|
||||
local-prefixes:
|
||||
- go.pinniped.dev
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- generated
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
|
||||
@@ -30,5 +30,5 @@ TMC uses Pinniped to provide a uniform authentication experience across all atta
|
||||
## Adding your organization to the list of adopters
|
||||
|
||||
If you are using Pinniped and would like to be included in the list of Pinniped Adopters, add an SVG version of your logo that is less than 150 KB to
|
||||
the [img directory](https://github.com/vmware-tanzu/pinniped/tree/main/site/themes/pinniped/static/img) in this repo and submit a pull request with your change including 1-2 sentences describing how your organization is using Pinniped. Name the image file something that
|
||||
the [img directory](https://github.com/vmware/pinniped/tree/main/site/themes/pinniped/static/img) in this repo and submit a pull request with your change including 1-2 sentences describing how your organization is using Pinniped. Name the image file something that
|
||||
reflects your company (e.g., if your company is called Acme, name the image acme.svg). Please feel free to send us a message in [#pinniped](https://kubernetes.slack.com/archives/C01BW364RJA) with any questions you may have.
|
||||
|
||||
@@ -20,26 +20,26 @@ The near-term and mid-term roadmap for the work planned for the project [maintai
|
||||
## Discussion
|
||||
|
||||
Got a question, comment, or idea? Please don't hesitate to reach out
|
||||
via GitHub [Discussions](https://github.com/vmware-tanzu/pinniped/discussions),
|
||||
GitHub [Issues](https://github.com/vmware-tanzu/pinniped/issues),
|
||||
via GitHub [Discussions](https://github.com/vmware/pinniped/discussions),
|
||||
GitHub [Issues](https://github.com/vmware/pinniped/issues),
|
||||
or in the Kubernetes Slack Workspace within the [#pinniped channel](https://go.pinniped.dev/community/slack).
|
||||
Join our [Google Group](https://go.pinniped.dev/community/group) to receive updates and meeting invitations.
|
||||
|
||||
## Issues
|
||||
|
||||
Need an idea for a project to get started contributing? Take a look at the open
|
||||
[issues](https://github.com/vmware-tanzu/pinniped/issues).
|
||||
[issues](https://github.com/vmware/pinniped/issues).
|
||||
Also check to see if any open issues are labeled with
|
||||
["good first issue"](https://github.com/vmware-tanzu/pinniped/labels/good%20first%20issue)
|
||||
or ["help wanted"](https://github.com/vmware-tanzu/pinniped/labels/help%20wanted).
|
||||
["good first issue"](https://github.com/vmware/pinniped/labels/good%20first%20issue)
|
||||
or ["help wanted"](https://github.com/vmware/pinniped/labels/help%20wanted).
|
||||
|
||||
### Bugs
|
||||
|
||||
To file a bug report, please first open an
|
||||
[issue](https://github.com/vmware-tanzu/pinniped/issues/new?template=bug_report.md). The project team
|
||||
[issue](https://github.com/vmware/pinniped/issues/new?template=bug_report.md). The project team
|
||||
will work with you on your bug report.
|
||||
|
||||
Once the bug has been validated, a [pull request](https://github.com/vmware-tanzu/pinniped/compare)
|
||||
Once the bug has been validated, a [pull request](https://github.com/vmware/pinniped/compare)
|
||||
can be opened to fix the bug.
|
||||
|
||||
For specifics on what to include in your bug report, please follow the
|
||||
@@ -48,11 +48,11 @@ guidelines in the issue and pull request templates.
|
||||
### Features
|
||||
|
||||
To suggest a feature, please first open an
|
||||
[issue](https://github.com/vmware-tanzu/pinniped/issues/new?template=feature-proposal.md)
|
||||
and tag it with `proposal`, or create a new [Discussion](https://github.com/vmware-tanzu/pinniped/discussions).
|
||||
[issue](https://github.com/vmware/pinniped/issues/new?template=feature-proposal.md)
|
||||
and tag it with `proposal`, or create a new [Discussion](https://github.com/vmware/pinniped/discussions).
|
||||
The project [maintainers](MAINTAINERS.md) will work with you on your feature request.
|
||||
|
||||
Once the feature request has been validated, a [pull request](https://github.com/vmware-tanzu/pinniped/compare)
|
||||
Once the feature request has been validated, a [pull request](https://github.com/vmware/pinniped/compare)
|
||||
can be opened to implement the feature.
|
||||
|
||||
For specifics on what to include in your feature request, please follow the
|
||||
@@ -127,7 +127,7 @@ go build -o pinniped ./cmd/pinniped
|
||||
On macOS, these tools can be installed with [Homebrew](https://brew.sh/) (assuming you have Chrome installed already):
|
||||
|
||||
```bash
|
||||
brew install kind vmware-tanzu/carvel/ytt vmware-tanzu/carvel/kapp kubectl nmap && brew cask install docker
|
||||
brew install kind carvel-dev/carvel/ytt carvel-dev/carvel/kapp kubectl nmap && brew cask install docker
|
||||
```
|
||||
|
||||
1. Create a kind cluster, compile, create container images, and install Pinniped and supporting test dependencies using:
|
||||
@@ -144,7 +144,7 @@ go build -o pinniped ./cmd/pinniped
|
||||
|
||||
To run specific integration tests, add the `-run` flag to the above command to specify a regexp for the test names.
|
||||
Use a leading `/` on the regexp because the Pinniped integration tests are automatically nested under several parent tests
|
||||
(see [integration/main_test.go](https://github.com/vmware-tanzu/pinniped/blob/main/test/integration/main_test.go)).
|
||||
(see [integration/main_test.go](https://github.com/vmware/pinniped/blob/main/test/integration/main_test.go)).
|
||||
For example, to run an integration test called `TestE2E`, add `-run /TestE2E` to the command shown above.
|
||||
|
||||
1. After making production code changes, recompile, redeploy, and run tests again by repeating the same
|
||||
@@ -177,17 +177,20 @@ Each run of `hack/prepare-for-integration-tests.sh` can result in different valu
|
||||
|
||||
### Observing Tests on the Continuous Integration Environment
|
||||
|
||||
[CI](https://ci.pinniped.dev/teams/main/pipelines/pull-requests)
|
||||
will not be triggered on a pull request until the pull request is reviewed and
|
||||
CI will not be triggered on a pull request until the pull request is reviewed and
|
||||
approved for CI by a project [maintainer](MAINTAINERS.md). Once CI is triggered,
|
||||
the progress and results will appear on the Github page for that
|
||||
[pull request](https://github.com/vmware-tanzu/pinniped/pulls) as checks. Links
|
||||
[pull request](https://github.com/vmware/pinniped/pulls) as checks. Links
|
||||
will appear to view the details of each check.
|
||||
|
||||
Starting in mid-2025, Pinniped's CI system is no longer externally visible due to corporate policies.
|
||||
Please contact the maintainers for help with your PR if you encounter any CI failures.
|
||||
They will be happy to share CI logs with you directly for your PR.
|
||||
|
||||
## CI
|
||||
|
||||
Pinniped's CI configuration and code is in the [`ci`](https://github.com/vmware-tanzu/pinniped/tree/ci)
|
||||
branch of this repo. The CI results are visible to the public at https://ci.pinniped.dev.
|
||||
Pinniped's CI configuration and code is in the [`ci`](https://github.com/vmware/pinniped/tree/ci)
|
||||
branch of this repo.
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
15
Dockerfile
15
Dockerfile
@@ -1,13 +1,13 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ARG BUILD_IMAGE=golang:1.23.3@sha256:73f06be4578c9987ce560087e2e2ea6485fb605e3910542cadd8fa09fc5f3e31
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea
|
||||
ARG BUILD_IMAGE=golang:1.25.5@sha256:6cc2338c038bc20f96ab32848da2b5c0641bb9bb5363f2c33e9b7c8838f9a208
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:2b7c93f6d6648c11f0e80a48558c8f77885eb0445213b8e69a6a0d7c89fc6ae4
|
||||
|
||||
# Prepare to cross-compile by always running the build stage in the build platform, not the target platform.
|
||||
FROM --platform=$BUILDPLATFORM $BUILD_IMAGE as build-env
|
||||
FROM --platform=$BUILDPLATFORM $BUILD_IMAGE AS build-env
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
@@ -21,6 +21,9 @@ ENV KUBE_GIT_VERSION=$KUBE_GIT_VERSION
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
||||
# If provided, must be a comma-separated list of Go build tags.
|
||||
ARG ADDITIONAL_BUILD_TAGS
|
||||
|
||||
# Build the statically linked (CGO_ENABLED=0) binary.
|
||||
# Mount source, build cache, and module cache for performance reasons.
|
||||
# See https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/
|
||||
@@ -29,8 +32,8 @@ RUN \
|
||||
--mount=type=cache,target=/cache/gocache \
|
||||
--mount=type=cache,target=/cache/gomodcache \
|
||||
export GOCACHE=/cache/gocache GOMODCACHE=/cache/gomodcache CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH && \
|
||||
go build -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -s" -o /usr/local/bin/pinniped-concierge-kube-cert-agent ./cmd/pinniped-concierge-kube-cert-agent/... && \
|
||||
go build -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -s" -o /usr/local/bin/pinniped-server ./cmd/pinniped-server/... && \
|
||||
go build -tags $ADDITIONAL_BUILD_TAGS -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -s" -o /usr/local/bin/pinniped-concierge-kube-cert-agent ./cmd/pinniped-concierge-kube-cert-agent/... && \
|
||||
go build -tags $ADDITIONAL_BUILD_TAGS -v -trimpath -ldflags "$(hack/get-ldflags.sh) -w -s" -o /usr/local/bin/pinniped-server ./cmd/pinniped-server/... && \
|
||||
ln -s /usr/local/bin/pinniped-server /usr/local/bin/pinniped-concierge && \
|
||||
ln -s /usr/local/bin/pinniped-server /usr/local/bin/pinniped-supervisor && \
|
||||
ln -s /usr/local/bin/pinniped-server /usr/local/bin/local-user-authenticator
|
||||
|
||||
@@ -11,7 +11,7 @@ all members should work together to achieve this goal.
|
||||
# Code of Conduct
|
||||
|
||||
The Pinniped community abides by this
|
||||
[code of conduct](https://github.com/vmware-tanzu/pinniped/blob/main/CODE_OF_CONDUCT.md).
|
||||
[code of conduct](https://github.com/vmware/pinniped/blob/main/CODE_OF_CONDUCT.md).
|
||||
|
||||
# Community Roles
|
||||
|
||||
@@ -29,7 +29,7 @@ notifying one of the maintainers.
|
||||
|
||||
**Note:** If a maintainer leaves their employer they are still considered a maintainer of Pinniped, unless they
|
||||
voluntarily resign. Employment is not taken into consideration when determining maintainer eligibility unless the
|
||||
company itself violates our [Code of Conduct](https://github.com/vmware-tanzu/pinniped/blob/main/CODE_OF_CONDUCT.md).
|
||||
company itself violates our [Code of Conduct](https://github.com/vmware/pinniped/blob/main/CODE_OF_CONDUCT.md).
|
||||
|
||||
# Decision Making
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ Care to kick the tires? It's easy to [install and try Pinniped](https://pinniped
|
||||
## Discussion
|
||||
|
||||
Got a question, comment, or idea? Please don't hesitate to reach out
|
||||
via GitHub [Discussions](https://github.com/vmware-tanzu/pinniped/discussions),
|
||||
GitHub [Issues](https://github.com/vmware-tanzu/pinniped/issues),
|
||||
via GitHub [Discussions](https://github.com/vmware/pinniped/discussions),
|
||||
GitHub [Issues](https://github.com/vmware/pinniped/issues),
|
||||
or in the Kubernetes Slack Workspace within the [#pinniped channel](https://go.pinniped.dev/community/slack).
|
||||
Join our [Google Group](https://go.pinniped.dev/community/group) to receive updates and meeting invitations.
|
||||
|
||||
@@ -37,7 +37,7 @@ building and testing the code, submitting PRs, and other contributor topics.
|
||||
## Adopters
|
||||
|
||||
Some organizations and products using Pinniped are featured in [ADOPTERS.md](ADOPTERS.md).
|
||||
Add your own organization or product [here](https://github.com/vmware-tanzu/pinniped/discussions/152).
|
||||
Add your own organization or product [here](https://github.com/vmware/pinniped/discussions/152).
|
||||
|
||||
## Reporting security vulnerabilities
|
||||
|
||||
@@ -47,4 +47,4 @@ Please follow the procedure described in [SECURITY.md](SECURITY.md).
|
||||
|
||||
Pinniped is open source and licensed under Apache License Version 2.0. See [LICENSE](LICENSE).
|
||||
|
||||
Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
|
||||
@@ -10,17 +10,17 @@ help determine if a contribution could be conflicting with a longer term plan.
|
||||
|
||||
Discussion on the roadmap is welcomed. If you want to provide suggestions, use cases, and feedback to an item in the
|
||||
roadmap, please reach out to the maintainers using one of the methods described in the project's
|
||||
[README.md](https://github.com/vmware-tanzu/pinniped#discussion).
|
||||
[Contributions](https://github.com/vmware-tanzu/pinniped/blob/main/CONTRIBUTING.md) to Pinniped are also welcomed.
|
||||
[README.md](https://github.com/vmware/pinniped#discussion).
|
||||
[Contributions](https://github.com/vmware/pinniped/blob/main/CONTRIBUTING.md) to Pinniped are also welcomed.
|
||||
|
||||
### How to add an item to the roadmap
|
||||
|
||||
One of the most important aspects in any open source community is the concept of proposals. Large changes to the
|
||||
codebase and / or new features should be preceded by
|
||||
a [proposal](https://github.com/vmware-tanzu/pinniped/tree/main/proposals) in our repo.
|
||||
a [proposal](https://github.com/vmware/pinniped/tree/main/proposals) in our repo.
|
||||
For smaller enhancements, you can open an issue to track that initiative or feature request.
|
||||
We work with and rely on community feedback to focus our efforts to improve Pinniped and maintain a healthy roadmap.
|
||||
|
||||
Priorities and requirements change based on community feedback, roadblocks encountered, community contributions,
|
||||
etc. If you depend on a specific item, we encourage you to reach out for updated status information, or help us deliver
|
||||
that feature by [contributing](https://github.com/vmware-tanzu/pinniped/blob/main/CONTRIBUTING.md) to Pinniped.
|
||||
that feature by [contributing](https://github.com/vmware/pinniped/blob/main/CONTRIBUTING.md) to Pinniped.
|
||||
|
||||
10
SECURITY.md
10
SECURITY.md
@@ -10,11 +10,11 @@ As of right now, only the latest version of Pinniped is supported.
|
||||
|
||||
Security is of the highest importance and all security vulnerabilities or suspected security vulnerabilities should be reported to Pinniped privately, to minimize attacks against current users of Pinniped before they are fixed. Vulnerabilities will be investigated and patched on the next patch (or minor) release as soon as possible. This information could be kept entirely internal to the project.
|
||||
|
||||
If you know of a publicly disclosed security vulnerability for Pinniped, please **IMMEDIATELY** contact the VMware Security Team (security@vmware.com). The use of encrypted email is encouraged. The public PGP key can be found at https://kb.vmware.com/kb/1055.
|
||||
If you know of a publicly disclosed security vulnerability for Pinniped, please **IMMEDIATELY** contact the VMware Security Team (vmware.psirt@broadcom.com). The use of encrypted email is encouraged. The public PGP key can be found at https://kb.vmware.com/kb/1055.
|
||||
|
||||
**IMPORTANT: Do not file public issues on GitHub for security vulnerabilities**
|
||||
|
||||
To report a vulnerability or a security-related issue, please contact the VMware email address with the details of the vulnerability. The email will be fielded by the VMware Security Team and then shared with the Pinniped maintainers who have committer and release permissions. Emails will be addressed within 3 business days, including a detailed plan to investigate the issue and any potential workarounds to perform in the meantime. Do not report non-security-impacting bugs through this channel. Use [GitHub issues](https://github.com/vmware-tanzu/pinniped/issues/new/choose) instead.
|
||||
To report a vulnerability or a security-related issue, please contact the VMware email address with the details of the vulnerability. The email will be fielded by the VMware Security Team and then shared with the Pinniped maintainers who have committer and release permissions. Emails will be addressed within 3 business days, including a detailed plan to investigate the issue and any potential workarounds to perform in the meantime. Do not report non-security-impacting bugs through this channel. Use [GitHub issues](https://github.com/vmware/pinniped/issues/new/choose) instead.
|
||||
|
||||
## Proposed Email Content
|
||||
|
||||
@@ -48,13 +48,13 @@ The VMware Security Team will respond to vulnerability reports as follows:
|
||||
|
||||
## Public Disclosure Process
|
||||
|
||||
The Security Team publishes a [public advisory](https://github.com/vmware-tanzu/pinniped/security/advisories) to the Pinniped community via GitHub. In most cases, additional communication via Slack, Twitter, mailing lists, blog and other channels will assist in educating Pinniped users and rolling out the patched release to affected users.
|
||||
The Security Team publishes a [public advisory](https://github.com/vmware/pinniped/security/advisories) to the Pinniped community via GitHub. In most cases, additional communication via Slack, Twitter, mailing lists, blog and other channels will assist in educating Pinniped users and rolling out the patched release to affected users.
|
||||
|
||||
The Security Team will also publish any mitigating steps users can take until the fix can be applied to their Pinniped instances. Pinniped distributors will handle creating and publishing their own security advisories.
|
||||
|
||||
## Mailing lists
|
||||
|
||||
* Use security@vmware.com to report security concerns to the VMware Security Team, who uses the list to privately discuss security issues and fixes prior to disclosure. The use of encrypted email is encouraged. The public PGP key can be found at https://kb.vmware.com/kb/1055.
|
||||
* Use vmware.psirt@broadcom.com to report security concerns to the VMware Security Team, who uses the list to privately discuss security issues and fixes prior to disclosure. The use of encrypted email is encouraged. The public PGP key can be found at https://kb.vmware.com/kb/1055.
|
||||
* Join the [Pinniped Distributors](https://groups.google.com/g/project-pinniped-distributors) mailing list for early private information and vulnerability disclosure. Early disclosure may include mitigating steps and additional information on security patch releases. See below for information on how Pinniped distributors or vendors can apply to join this list.
|
||||
|
||||
## Early Disclosure to Pinniped Distributors List
|
||||
@@ -81,7 +81,7 @@ The information that members receive on the Pinniped Distributors mailing list m
|
||||
|
||||
Before you share any information from the list with members of your team who are required to fix the issue, these team members must agree to the same terms, and only be provided with information on a need-to-know basis.
|
||||
|
||||
In the unfortunate event that you share information beyond what is permitted by this policy, you must urgently inform the VMware Security Team (security@vmware.com) of exactly what information was leaked and to whom. If you continue to leak information and break the policy outlined here, you will be permanently removed from the list.
|
||||
In the unfortunate event that you share information beyond what is permitted by this policy, you must urgently inform the VMware Security Team (vmware.psirt@broadcom.com) of exactly what information was leaked and to whom. If you continue to leak information and break the policy outlined here, you will be permanently removed from the list.
|
||||
|
||||
## Requesting to Join
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@@ -18,7 +18,7 @@ const (
|
||||
JWTAuthenticatorPhaseError JWTAuthenticatorPhase = "Error"
|
||||
)
|
||||
|
||||
// Status of a JWT authenticator.
|
||||
// JWTAuthenticatorStatus is the status of a JWT authenticator.
|
||||
type JWTAuthenticatorStatus struct {
|
||||
// Represents the observations of the authenticator's current state.
|
||||
// +patchMergeKey=type
|
||||
@@ -26,46 +26,255 @@ type JWTAuthenticatorStatus struct {
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
|
||||
// Phase summarizes the overall status of the JWTAuthenticator.
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase JWTAuthenticatorPhase `json:"phase,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring a JWT authenticator.
|
||||
// JWTAuthenticatorSpec is the spec for configuring a JWT authenticator.
|
||||
type JWTAuthenticatorSpec struct {
|
||||
// Issuer is the OIDC issuer URL that will be used to discover public signing keys. Issuer is
|
||||
// issuer is the OIDC issuer URL that will be used to discover public signing keys. Issuer is
|
||||
// also used to validate the "iss" JWT claim.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:Pattern=`^https://`
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// Audience is the required value of the "aud" JWT claim.
|
||||
// audience is the required value of the "aud" JWT claim.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Audience string `json:"audience"`
|
||||
|
||||
// Claims allows customization of the claims that will be mapped to user identity
|
||||
// claims allows customization of the claims that will be mapped to user identity
|
||||
// for Kubernetes access.
|
||||
// +optional
|
||||
Claims JWTTokenClaims `json:"claims"`
|
||||
|
||||
// TLS configuration for communicating with the OIDC provider.
|
||||
// claimValidationRules are rules that are applied to validate token claims to authenticate users.
|
||||
// This is similar to claimValidationRules from Kubernetes AuthenticationConfiguration as documented in
|
||||
// https://kubernetes.io/docs/reference/access-authn-authz/authentication.
|
||||
// This is an advanced configuration option. During an end-user login flow, mistakes in this
|
||||
// configuration will cause the user's login to fail.
|
||||
// +optional
|
||||
ClaimValidationRules []ClaimValidationRule `json:"claimValidationRules,omitempty"`
|
||||
|
||||
// userValidationRules are rules that are applied to final user before completing authentication.
|
||||
// These allow invariants to be applied to incoming identities such as preventing the
|
||||
// use of the system: prefix that is commonly used by Kubernetes components.
|
||||
// The validation rules are logically ANDed together and must all return true for the validation to pass.
|
||||
// This is similar to claimValidationRules from Kubernetes AuthenticationConfiguration as documented in
|
||||
// https://kubernetes.io/docs/reference/access-authn-authz/authentication.
|
||||
// This is an advanced configuration option. During an end-user login flow, mistakes in this
|
||||
// configuration will cause the user's login to fail.
|
||||
// +optional
|
||||
UserValidationRules []UserValidationRule `json:"userValidationRules,omitempty"`
|
||||
|
||||
// tls is the configuration for communicating with the OIDC provider via TLS.
|
||||
// +optional
|
||||
TLS *TLSSpec `json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
// ClaimValidationRule provides the configuration for a single claim validation rule.
|
||||
type ClaimValidationRule struct {
|
||||
// claim is the name of a required claim.
|
||||
// Only string claim keys are supported.
|
||||
// Mutually exclusive with expression and message.
|
||||
// +optional
|
||||
Claim string `json:"claim,omitempty"`
|
||||
|
||||
// requiredValue is the value of a required claim.
|
||||
// Only string claim values are supported.
|
||||
// If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string.
|
||||
// Mutually exclusive with expression and message.
|
||||
// +optional
|
||||
RequiredValue string `json:"requiredValue,omitempty"`
|
||||
|
||||
// expression represents the expression which will be evaluated by CEL.
|
||||
// Must produce a boolean.
|
||||
//
|
||||
// CEL expressions have access to the contents of the token claims, organized into CEL variable:
|
||||
// - 'claims' is a map of claim names to claim values.
|
||||
// For example, a variable named 'sub' can be accessed as 'claims.sub'.
|
||||
// Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.
|
||||
// Must return true for the validation to pass.
|
||||
//
|
||||
// Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
//
|
||||
// Mutually exclusive with claim and requiredValue.
|
||||
// +optional
|
||||
Expression string `json:"expression,omitempty"`
|
||||
|
||||
// message customizes the returned error message when expression returns false.
|
||||
// message is a literal string.
|
||||
// Mutually exclusive with claim and requiredValue.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// UserValidationRule provides the configuration for a single user info validation rule.
|
||||
type UserValidationRule struct {
|
||||
// expression represents the expression which will be evaluated by CEL.
|
||||
// Must return true for the validation to pass.
|
||||
//
|
||||
// CEL expressions have access to the contents of UserInfo, organized into CEL variable:
|
||||
// - 'user' - authentication.k8s.io/v1, Kind=UserInfo object
|
||||
// Refer to https://github.com/kubernetes/api/blob/release-1.28/authentication/v1/types.go#L105-L122 for the definition.
|
||||
// API documentation: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#userinfo-v1-authentication-k8s-io
|
||||
//
|
||||
// Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
//
|
||||
// +required
|
||||
Expression string `json:"expression"`
|
||||
|
||||
// message customizes the returned error message when rule returns false.
|
||||
// message is a literal string.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// JWTTokenClaims allows customization of the claims that will be mapped to user identity
|
||||
// for Kubernetes access.
|
||||
type JWTTokenClaims struct {
|
||||
// Groups is the name of the claim which should be read to extract the user's
|
||||
// group membership from the JWT token. When not specified, it will default to "groups".
|
||||
// username is the name of the claim which should be read to extract the
|
||||
// username from the JWT token. When not specified, it will default to "username",
|
||||
// unless usernameExpression is specified.
|
||||
//
|
||||
// Mutually exclusive with usernameExpression. Use either username or usernameExpression to
|
||||
// determine the user's username from the JWT token.
|
||||
// +optional
|
||||
Username string `json:"username"`
|
||||
|
||||
// usernameExpression represents an expression which will be evaluated by CEL.
|
||||
// The expression's result will become the user's username.
|
||||
//
|
||||
// usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration
|
||||
// as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication.
|
||||
// This is an advanced configuration option. During an end-user login flow, each of these CEL expressions
|
||||
// must evaluate to the expected type without errors, or else the user's login will fail.
|
||||
// Additionally, mistakes in this configuration can cause the users to have unintended usernames.
|
||||
//
|
||||
// The expression must produce a non-empty string value.
|
||||
// If the expression uses 'claims.email', then 'claims.email_verified' must be used in
|
||||
// the expression or extra[*].valueExpression or claimValidationRules[*].expression.
|
||||
// An example claim validation rule expression that matches the validation automatically
|
||||
// applied when username.claim is set to 'email' is 'claims.?email_verified.orValue(true) == true'.
|
||||
// By explicitly comparing the value to true, we let type-checking see the result will be a boolean,
|
||||
// and to make sure a non-boolean email_verified claim will be caught at runtime.
|
||||
//
|
||||
// CEL expressions have access to the contents of the token claims, organized into CEL variable:
|
||||
// - 'claims' is a map of claim names to claim values.
|
||||
// For example, a variable named 'sub' can be accessed as 'claims.sub'.
|
||||
// Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.
|
||||
//
|
||||
// Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
//
|
||||
// Mutually exclusive with username. Use either username or usernameExpression to
|
||||
// determine the user's username from the JWT token.
|
||||
// +optional
|
||||
UsernameExpression string `json:"usernameExpression,omitempty"`
|
||||
|
||||
// groups is the name of the claim which should be read to extract the user's
|
||||
// group membership from the JWT token. When not specified, it will default to "groups",
|
||||
// unless groupsExpression is specified.
|
||||
//
|
||||
// Mutually exclusive with groupsExpression. Use either groups or groupsExpression to
|
||||
// determine the user's group membership from the JWT token.
|
||||
// +optional
|
||||
Groups string `json:"groups"`
|
||||
|
||||
// Username is the name of the claim which should be read to extract the
|
||||
// username from the JWT token. When not specified, it will default to "username".
|
||||
// groupsExpression represents an expression which will be evaluated by CEL.
|
||||
// The expression's result will become the user's group memberships.
|
||||
//
|
||||
// groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration
|
||||
// as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication.
|
||||
// This is an advanced configuration option. During an end-user login flow, each of these CEL expressions
|
||||
// must evaluate to one of the expected types without errors, or else the user's login will fail.
|
||||
// Additionally, mistakes in this configuration can cause the users to have unintended group memberships.
|
||||
//
|
||||
// The expression must produce a string or string array value.
|
||||
// "", [], and null values are treated as the group mapping not being present.
|
||||
//
|
||||
// CEL expressions have access to the contents of the token claims, organized into CEL variable:
|
||||
// - 'claims' is a map of claim names to claim values.
|
||||
// For example, a variable named 'sub' can be accessed as 'claims.sub'.
|
||||
// Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.
|
||||
//
|
||||
// Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
//
|
||||
// Mutually exclusive with groups. Use either groups or groupsExpression to
|
||||
// determine the user's group membership from the JWT token.
|
||||
// +optional
|
||||
Username string `json:"username"`
|
||||
GroupsExpression string `json:"groupsExpression,omitempty"`
|
||||
|
||||
// extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration
|
||||
// as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication.
|
||||
//
|
||||
// However, note that the Pinniped Concierge issues client certificates to users for the purpose
|
||||
// of authenticating, and the Kubernetes API server does not have any mechanism for transmitting
|
||||
// auth extras via client certificates. When configured, these extras will appear in client
|
||||
// certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational
|
||||
// Units (OU). However, when this client certificate is presented to Kubernetes for authentication,
|
||||
// Kubernetes will ignore these extras. This is probably only useful if you are using a custom
|
||||
// authenticating proxy in front of your Kubernetes API server which can translate these OUs into
|
||||
// auth extras, as described by
|
||||
// https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy.
|
||||
// This is an advanced configuration option. During an end-user login flow, each of these CEL expressions
|
||||
// must evaluate to either a string or an array of strings, or else the user's login will fail.
|
||||
//
|
||||
// These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("=").
|
||||
//
|
||||
// expression must produce a string or string array value.
|
||||
// If the value is empty, the extra mapping will not be present.
|
||||
//
|
||||
// Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
//
|
||||
// hard-coded extra key/value
|
||||
// - key: "acme.io/foo"
|
||||
// valueExpression: "'bar'"
|
||||
// This will result in an extra attribute - acme.io/foo: ["bar"]
|
||||
//
|
||||
// hard-coded key, value copying claim value
|
||||
// - key: "acme.io/foo"
|
||||
// valueExpression: "claims.some_claim"
|
||||
// This will result in an extra attribute - acme.io/foo: [value of some_claim]
|
||||
//
|
||||
// hard-coded key, value derived from claim value
|
||||
// - key: "acme.io/admin"
|
||||
// valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""'
|
||||
// This will result in:
|
||||
// - if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"]
|
||||
// - if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added
|
||||
//
|
||||
// +optional
|
||||
Extra []ExtraMapping `json:"extra,omitempty"`
|
||||
}
|
||||
|
||||
// ExtraMapping provides the configuration for a single extra mapping.
|
||||
type ExtraMapping struct {
|
||||
// key is a string to use as the extra attribute key.
|
||||
// key must be a domain-prefix path (e.g. example.org/foo). All characters before the first "/" must be a valid
|
||||
// subdomain as defined by RFC 1123. All characters trailing the first "/" must
|
||||
// be valid HTTP Path characters as defined by RFC 3986.
|
||||
// key must be lowercase.
|
||||
// Required to be unique.
|
||||
// Additionally, the key must not contain an equals sign ("=").
|
||||
// +required
|
||||
Key string `json:"key"`
|
||||
|
||||
// valueExpression is a CEL expression to extract extra attribute value.
|
||||
// valueExpression must produce a string or string array value.
|
||||
// "", [], and null values are treated as the extra mapping not being present.
|
||||
// Empty string values contained within a string array are filtered out.
|
||||
//
|
||||
// CEL expressions have access to the contents of the token claims, organized into CEL variable:
|
||||
// - 'claims' is a map of claim names to claim values.
|
||||
// For example, a variable named 'sub' can be accessed as 'claims.sub'.
|
||||
// Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.
|
||||
//
|
||||
// Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
//
|
||||
// +required
|
||||
ValueExpression string `json:"valueExpression"`
|
||||
}
|
||||
|
||||
// JWTAuthenticator describes the configuration of a JWT authenticator.
|
||||
@@ -86,14 +295,14 @@ type JWTAuthenticator struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec for configuring the authenticator.
|
||||
// spec for configuring the authenticator.
|
||||
Spec JWTAuthenticatorSpec `json:"spec"`
|
||||
|
||||
// Status of the authenticator.
|
||||
// status of the authenticator.
|
||||
Status JWTAuthenticatorStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// List of JWTAuthenticator objects.
|
||||
// JWTAuthenticatorList is a list of JWTAuthenticator objects.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type JWTAuthenticatorList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
|
||||
type CredentialIssuerStatus struct {
|
||||
// List of integration strategies that were attempted by Pinniped.
|
||||
Strategies []CredentialIssuerStrategy `json:"strategies"`
|
||||
|
||||
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
// This field is deprecated and will be removed in a future version.
|
||||
// +optional
|
||||
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
|
||||
}
|
||||
|
||||
// CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
// This type is deprecated and will be removed in a future version.
|
||||
type CredentialIssuerKubeConfigInfo struct {
|
||||
// The K8s API server URL.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:Pattern=`^https://|^http://`
|
||||
Server string `json:"server"`
|
||||
|
||||
// The K8s API server CA bundle.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData"`
|
||||
}
|
||||
|
||||
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package identity
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package identity
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package identity
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:conversion-gen=go.pinniped.dev/GENERATED_PKG/apis/concierge/identity
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +k8s:openapi-model-package=dev.pinniped.apis.concierge.identity.v1alpha1
|
||||
// +groupName=identity.concierge.pinniped.dev
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the Pinniped identity API.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package validation
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package login
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package login
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package login
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:conversion-gen=go.pinniped.dev/GENERATED_PKG/apis/concierge/login
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +k8s:openapi-model-package=dev.pinniped.apis.concierge.login.v1alpha1
|
||||
// +groupName=login.concierge.pinniped.dev
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the Pinniped login API.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package clientsecret
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package clientsecret
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:conversion-gen=go.pinniped.dev/GENERATED_PKG/apis/supervisor/clientsecret
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +k8s:openapi-model-package=dev.pinniped.apis.supervisor.clientsecret.v1alpha1
|
||||
// +groupName=clientsecret.supervisor.pinniped.dev
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the Pinniped client secret API.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
|
||||
// See
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2024-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package oidc
|
||||
|
||||
46
cmd/pinniped/cmd/audit_id.go
Normal file
46
cmd/pinniped/cmd/audit_id.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"go.pinniped.dev/internal/httputil/roundtripper"
|
||||
"go.pinniped.dev/internal/plog"
|
||||
)
|
||||
|
||||
type auditIDLoggerFunc func(path string, statusCode int, auditID string)
|
||||
|
||||
func logAuditID(path string, statusCode int, auditID string) {
|
||||
plog.Info("Received auditID for failed request",
|
||||
"path", path,
|
||||
"statusCode", statusCode,
|
||||
"auditID", auditID)
|
||||
}
|
||||
|
||||
func LogAuditIDTransportWrapper(rt http.RoundTripper) http.RoundTripper {
|
||||
return logAuditIDTransportWrapper(rt, logAuditID)
|
||||
}
|
||||
|
||||
func logAuditIDTransportWrapper(rt http.RoundTripper, auditIDLoggerFunc auditIDLoggerFunc) http.RoundTripper {
|
||||
return roundtripper.WrapFunc(rt, func(r *http.Request) (*http.Response, error) {
|
||||
response, responseErr := rt.RoundTrip(r)
|
||||
|
||||
if responseErr != nil ||
|
||||
response == nil ||
|
||||
response.Header.Get("audit-ID") == "" ||
|
||||
response.Request == nil ||
|
||||
response.Request.URL == nil {
|
||||
return response, responseErr
|
||||
}
|
||||
|
||||
// Use the request path from the response's request, in case the
|
||||
// original request was modified by any other roudtrippers in the chain.
|
||||
auditIDLoggerFunc(response.Request.URL.Path,
|
||||
response.StatusCode,
|
||||
response.Header.Get("audit-ID"))
|
||||
|
||||
return response, responseErr
|
||||
})
|
||||
}
|
||||
116
cmd/pinniped/cmd/audit_id_test.go
Normal file
116
cmd/pinniped/cmd/audit_id_test.go
Normal file
@@ -0,0 +1,116 @@
|
||||
// Copyright 2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.pinniped.dev/internal/httputil/roundtripper"
|
||||
)
|
||||
|
||||
func TestLogAuditIDTransportWrapper(t *testing.T) {
|
||||
canonicalAuditIdHeaderName := "Audit-Id"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
response *http.Response
|
||||
responseErr error
|
||||
want func(t *testing.T, called func()) auditIDLoggerFunc
|
||||
wantCalled bool
|
||||
}{
|
||||
{
|
||||
name: "happy HTTP response - no error and no log",
|
||||
response: &http.Response{ // no headers
|
||||
StatusCode: http.StatusOK,
|
||||
Request: &http.Request{
|
||||
URL: &url.URL{
|
||||
Path: "some-path-from-response-request",
|
||||
},
|
||||
},
|
||||
},
|
||||
responseErr: nil,
|
||||
want: func(t *testing.T, called func()) auditIDLoggerFunc {
|
||||
return func(_ string, _ int, _ string) {
|
||||
called()
|
||||
}
|
||||
},
|
||||
wantCalled: false, // make it obvious
|
||||
},
|
||||
{
|
||||
name: "nil HTTP response - no error and no log",
|
||||
response: nil,
|
||||
responseErr: nil,
|
||||
want: func(t *testing.T, called func()) auditIDLoggerFunc {
|
||||
return func(_ string, _ int, _ string) {
|
||||
called()
|
||||
}
|
||||
},
|
||||
wantCalled: false, // make it obvious
|
||||
},
|
||||
{
|
||||
name: "err HTTP response - no error and no log",
|
||||
response: nil,
|
||||
responseErr: errors.New("some error"),
|
||||
want: func(t *testing.T, called func()) auditIDLoggerFunc {
|
||||
return func(_ string, _ int, _ string) {
|
||||
called()
|
||||
}
|
||||
},
|
||||
wantCalled: false, // make it obvious
|
||||
},
|
||||
{
|
||||
name: "happy HTTP response with audit-ID - logs",
|
||||
response: &http.Response{
|
||||
Header: http.Header{
|
||||
canonicalAuditIdHeaderName: []string{"some-audit-id", "some-other-audit-id-that-will-never-be-seen"},
|
||||
},
|
||||
StatusCode: http.StatusBadGateway, // statusCode does not matter
|
||||
Request: &http.Request{
|
||||
URL: &url.URL{
|
||||
Path: "some-path-from-response-request",
|
||||
},
|
||||
},
|
||||
},
|
||||
want: func(t *testing.T, called func()) auditIDLoggerFunc {
|
||||
return func(path string, statusCode int, auditID string) {
|
||||
called()
|
||||
require.Equal(t, "some-path-from-response-request", path)
|
||||
require.Equal(t, http.StatusBadGateway, statusCode)
|
||||
require.Equal(t, "some-audit-id", auditID)
|
||||
}
|
||||
},
|
||||
wantCalled: true, // make it obvious
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
require.NotNil(t, test.want)
|
||||
|
||||
mockRequest := &http.Request{
|
||||
URL: &url.URL{
|
||||
Path: "should-never-use-this-path",
|
||||
},
|
||||
}
|
||||
var mockRt roundtripper.Func = func(r *http.Request) (*http.Response, error) {
|
||||
require.Equal(t, mockRequest, r)
|
||||
return test.response, test.responseErr
|
||||
}
|
||||
called := false
|
||||
subjectRt := logAuditIDTransportWrapper(mockRt, test.want(t, func() {
|
||||
called = true
|
||||
}))
|
||||
actualResponse, err := subjectRt.RoundTrip(mockRequest) //nolint:bodyclose // there is no Body.
|
||||
require.Equal(t, test.responseErr, err) // This roundtripper only returns mocked errors.
|
||||
require.Equal(t, test.response, actualResponse)
|
||||
require.Equal(t, test.wantCalled, called,
|
||||
"want logFunc to be called: %t, actually was called: %t", test.wantCalled, called)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,36 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
|
||||
|
||||
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
|
||||
"go.pinniped.dev/internal/groupsuffix"
|
||||
"go.pinniped.dev/internal/kubeclient"
|
||||
)
|
||||
|
||||
// getConciergeClientsetFunc is a function that can return a clientset for the Concierge API given a
|
||||
// getClientsetsFunc is a function that can return clients for the Concierge and Kubernetes APIs given a
|
||||
// clientConfig and the apiGroupSuffix with which the API is running.
|
||||
type getConciergeClientsetFunc func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, error)
|
||||
type getClientsetsFunc func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, kubernetes.Interface, aggregatorclient.Interface, error)
|
||||
|
||||
// getRealConciergeClientset returns a real implementation of a conciergeclientset.Interface.
|
||||
func getRealConciergeClientset(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, error) {
|
||||
// getRealClientsets returns real implementations of the Concierge and Kubernetes client interfaces.
|
||||
func getRealClientsets(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, kubernetes.Interface, aggregatorclient.Interface, error) {
|
||||
restConfig, err := clientConfig.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
client, err := kubeclient.New(
|
||||
kubeclient.WithConfig(restConfig),
|
||||
kubeclient.WithMiddleware(groupsuffix.New(apiGroupSuffix)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return client.PinnipedConcierge, nil
|
||||
return client.PinnipedConcierge, client.Kubernetes, client.Aggregation, nil
|
||||
}
|
||||
|
||||
// newClientConfig returns a clientcmd.ClientConfig given an optional kubeconfig path override and
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -20,10 +20,12 @@ import (
|
||||
coreosoidc "github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth" // Adds handlers for various dynamic auth plugins in client-go
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
|
||||
|
||||
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
|
||||
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
@@ -38,7 +40,7 @@ import (
|
||||
type kubeconfigDeps struct {
|
||||
getenv func(key string) string
|
||||
getPathToSelf func() (string, error)
|
||||
getClientset getConciergeClientsetFunc
|
||||
getClientsets getClientsetsFunc
|
||||
log plog.MinLogger
|
||||
}
|
||||
|
||||
@@ -46,7 +48,7 @@ func kubeconfigRealDeps() kubeconfigDeps {
|
||||
return kubeconfigDeps{
|
||||
getenv: os.Getenv,
|
||||
getPathToSelf: os.Executable,
|
||||
getClientset: getRealConciergeClientset,
|
||||
getClientsets: getRealClientsets,
|
||||
log: plog.New(),
|
||||
}
|
||||
}
|
||||
@@ -215,7 +217,7 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
return fmt.Errorf("could not load --kubeconfig/--kubeconfig-context: %w", err)
|
||||
}
|
||||
cluster := currentKubeConfig.Clusters[currentKubeconfigNames.ClusterName]
|
||||
clientset, err := deps.getClientset(clientConfig, flags.concierge.apiGroupSuffix)
|
||||
conciergeClient, kubeClient, aggregatorClient, err := deps.getClientsets(clientConfig, flags.concierge.apiGroupSuffix)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not configure Kubernetes client: %w", err)
|
||||
}
|
||||
@@ -228,13 +230,15 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
}
|
||||
|
||||
if !flags.concierge.disabled {
|
||||
credentialIssuer, err := waitForCredentialIssuer(ctx, clientset, flags, deps)
|
||||
// Look up the Concierge's CredentialIssuer, and optionally wait for it to have no pending strategies showing in its status.
|
||||
credentialIssuer, err := waitForCredentialIssuer(ctx, conciergeClient, flags, deps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Decide which Concierge authenticator should be used in the resulting kubeconfig.
|
||||
authenticator, err := lookupAuthenticator(
|
||||
clientset,
|
||||
conciergeClient,
|
||||
flags.concierge.authenticatorType,
|
||||
flags.concierge.authenticatorName,
|
||||
deps.log,
|
||||
@@ -242,10 +246,15 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Discover from the CredentialIssuer how the resulting kubeconfig should be configured to talk to this Concierge.
|
||||
if err := discoverConciergeParams(credentialIssuer, &flags, cluster, deps.log); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := discoverAuthenticatorParams(authenticator, &flags, deps.log); err != nil {
|
||||
|
||||
// Discover how the resulting kubeconfig should interact with the selected authenticator.
|
||||
// For a JWTAuthenticator, this includes discovering how to talk to the OIDC issuer configured in its spec fields.
|
||||
if err := discoverAuthenticatorParams(ctx, authenticator, &flags, kubeClient, aggregatorClient, deps.log); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -255,6 +264,7 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
}
|
||||
|
||||
if len(flags.oidc.issuer) > 0 {
|
||||
// The OIDC provider may or may not be a Pinniped Supervisor. Find out.
|
||||
err = pinnipedSupervisorDiscovery(ctx, &flags, deps.log)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -406,10 +416,7 @@ func waitForCredentialIssuer(ctx context.Context, clientset conciergeclientset.I
|
||||
deadline, _ := ctx.Deadline()
|
||||
attempts := 1
|
||||
|
||||
for {
|
||||
if !hasPendingStrategy(credentialIssuer) {
|
||||
break
|
||||
}
|
||||
for hasPendingStrategy(credentialIssuer) {
|
||||
logStrategies(credentialIssuer, deps.log)
|
||||
deps.log.Info("waiting for CredentialIssuer pending strategies to finish",
|
||||
"attempts", attempts,
|
||||
@@ -488,7 +495,14 @@ func logStrategies(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer, l
|
||||
}
|
||||
}
|
||||
|
||||
func discoverAuthenticatorParams(authenticator metav1.Object, flags *getKubeconfigParams, log plog.MinLogger) error {
|
||||
func discoverAuthenticatorParams(
|
||||
ctx context.Context,
|
||||
authenticator metav1.Object,
|
||||
flags *getKubeconfigParams,
|
||||
kubeClient kubernetes.Interface,
|
||||
aggregatorClient aggregatorclient.Interface,
|
||||
log plog.MinLogger,
|
||||
) error {
|
||||
switch auth := authenticator.(type) {
|
||||
case *authenticationv1alpha1.WebhookAuthenticator:
|
||||
// If the --concierge-authenticator-type/--concierge-authenticator-name flags were not set explicitly, set
|
||||
@@ -520,19 +534,130 @@ func discoverAuthenticatorParams(authenticator metav1.Object, flags *getKubeconf
|
||||
}
|
||||
|
||||
// If the --oidc-ca-bundle flags was not set explicitly, default it to the
|
||||
// spec.tls.certificateAuthorityData field of the JWTAuthenticator.
|
||||
if len(flags.oidc.caBundle) == 0 && auth.Spec.TLS != nil && auth.Spec.TLS.CertificateAuthorityData != "" {
|
||||
decoded, err := base64.StdEncoding.DecodeString(auth.Spec.TLS.CertificateAuthorityData)
|
||||
// spec.tls.certificateAuthorityData field of the JWTAuthenticator, if that field is set, or else
|
||||
// try to discover it from the spec.tls.certificateAuthorityDataSource, if that field is set.
|
||||
if len(flags.oidc.caBundle) == 0 && auth.Spec.TLS != nil {
|
||||
err := discoverOIDCCABundle(ctx, auth, flags, kubeClient, aggregatorClient, log)
|
||||
if err != nil {
|
||||
return fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but JWTAuthenticator %s has invalid spec.tls.certificateAuthorityData: %w", auth.Name, err)
|
||||
return err
|
||||
}
|
||||
log.Info("discovered OIDC CA bundle", "roots", countCACerts(decoded))
|
||||
flags.oidc.caBundle = decoded
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func discoverOIDCCABundle(
|
||||
ctx context.Context,
|
||||
jwtAuthenticator *authenticationv1alpha1.JWTAuthenticator,
|
||||
flags *getKubeconfigParams,
|
||||
kubeClient kubernetes.Interface,
|
||||
aggregatorClient aggregatorclient.Interface,
|
||||
log plog.MinLogger,
|
||||
) error {
|
||||
if jwtAuthenticator.Spec.TLS.CertificateAuthorityData != "" {
|
||||
decodedCABundleData, err := base64.StdEncoding.DecodeString(jwtAuthenticator.Spec.TLS.CertificateAuthorityData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but JWTAuthenticator %s has invalid spec.tls.certificateAuthorityData: %w", jwtAuthenticator.Name, err)
|
||||
}
|
||||
log.Info("discovered OIDC CA bundle", "roots", countCACerts(decodedCABundleData))
|
||||
flags.oidc.caBundle = decodedCABundleData
|
||||
} else if jwtAuthenticator.Spec.TLS.CertificateAuthorityDataSource != nil {
|
||||
caBundleData, err := discoverOIDCCABundleFromCertificateAuthorityDataSource(
|
||||
ctx, jwtAuthenticator, flags.concierge.apiGroupSuffix, kubeClient, aggregatorClient, log)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
flags.oidc.caBundle = caBundleData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func discoverOIDCCABundleFromCertificateAuthorityDataSource(
|
||||
ctx context.Context,
|
||||
jwtAuthenticator *authenticationv1alpha1.JWTAuthenticator,
|
||||
apiGroupSuffix string,
|
||||
kubeClient kubernetes.Interface,
|
||||
aggregatorClient aggregatorclient.Interface,
|
||||
log plog.MinLogger,
|
||||
) ([]byte, error) {
|
||||
conciergeNamespace, err := discoverConciergeNamespace(ctx, apiGroupSuffix, aggregatorClient)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but encountered error discovering namespace of Concierge for JWTAuthenticator %s: %w", jwtAuthenticator.Name, err)
|
||||
}
|
||||
log.Info("discovered Concierge namespace for API group suffix", "apiGroupSuffix", apiGroupSuffix)
|
||||
|
||||
var caBundleData []byte
|
||||
var keyExisted bool
|
||||
caSource := jwtAuthenticator.Spec.TLS.CertificateAuthorityDataSource
|
||||
|
||||
// Note that the Kind, Name, and Key fields must all be non-empty, and Kind must be Secret or ConfigMap, due to CRD validations.
|
||||
switch caSource.Kind {
|
||||
case authenticationv1alpha1.CertificateAuthorityDataSourceKindConfigMap:
|
||||
caBundleConfigMap, err := kubeClient.CoreV1().ConfigMaps(conciergeNamespace).Get(ctx, caSource.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but encountered error getting %s %s/%s specified by JWTAuthenticator %s spec.tls.certificateAuthorityDataSource: %w",
|
||||
caSource.Kind, conciergeNamespace, caSource.Name, jwtAuthenticator.Name, err)
|
||||
}
|
||||
var caBundleDataStr string
|
||||
caBundleDataStr, keyExisted = caBundleConfigMap.Data[caSource.Key]
|
||||
caBundleData = []byte(caBundleDataStr)
|
||||
case authenticationv1alpha1.CertificateAuthorityDataSourceKindSecret:
|
||||
caBundleSecret, err := kubeClient.CoreV1().Secrets(conciergeNamespace).Get(ctx, caSource.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but encountered error getting %s %s/%s specified by JWTAuthenticator %s spec.tls.certificateAuthorityDataSource: %w",
|
||||
caSource.Kind, conciergeNamespace, caSource.Name, jwtAuthenticator.Name, err)
|
||||
}
|
||||
caBundleData, keyExisted = caBundleSecret.Data[caSource.Key]
|
||||
default:
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but JWTAuthenticator %s spec.tls.certificateAuthorityDataSource.Kind value %q is not supported by this CLI version",
|
||||
jwtAuthenticator.Name, caSource.Kind)
|
||||
}
|
||||
|
||||
if !keyExisted {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but key %q specified by JWTAuthenticator %s spec.tls.certificateAuthorityDataSource.key does not exist in %s %s/%s",
|
||||
caSource.Key, jwtAuthenticator.Name, caSource.Kind, conciergeNamespace, caSource.Name)
|
||||
}
|
||||
|
||||
if len(caBundleData) == 0 {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but key %q specified by JWTAuthenticator %s spec.tls.certificateAuthorityDataSource.key exists but has empty value in %s %s/%s",
|
||||
caSource.Key, jwtAuthenticator.Name, caSource.Kind, conciergeNamespace, caSource.Name)
|
||||
}
|
||||
|
||||
numCACerts := countCACerts(caBundleData)
|
||||
if numCACerts == 0 {
|
||||
return nil, fmt.Errorf("tried to autodiscover --oidc-ca-bundle, but value at key %q specified by JWTAuthenticator %s spec.tls.certificateAuthorityDataSource.key does not contain any CA certificates in %s %s/%s",
|
||||
caSource.Key, jwtAuthenticator.Name, caSource.Kind, conciergeNamespace, caSource.Name)
|
||||
}
|
||||
|
||||
log.Info("discovered OIDC CA bundle from JWTAuthenticator spec.tls.certificateAuthorityDataSource", "roots", numCACerts)
|
||||
return caBundleData, nil
|
||||
}
|
||||
|
||||
func discoverConciergeNamespace(ctx context.Context, apiGroupSuffix string, aggregatorClient aggregatorclient.Interface) (string, error) {
|
||||
// Let's look for the APIService for the API group of the Concierge's TokenCredentialRequest aggregated API.
|
||||
apiGroup := "login.concierge." + apiGroupSuffix
|
||||
|
||||
// List all APIServices.
|
||||
apiServiceList, err := aggregatorClient.ApiregistrationV1().APIServices().List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error listing APIServices: %w", err)
|
||||
}
|
||||
|
||||
// Find one with the expected API group name.
|
||||
for _, apiService := range apiServiceList.Items {
|
||||
if apiService.Spec.Group == apiGroup {
|
||||
if apiService.Spec.Service.Namespace != "" {
|
||||
// We are assuming that all API versions (e.g. v1alpha1) of this API group are backed by service(s)
|
||||
// in the same namespace, which is the namespace of the Concierge hosting this API suffix.
|
||||
return apiService.Spec.Service.Namespace, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find any APIService for the expected API group name which contained a namespace reference in its spec.
|
||||
return "", fmt.Errorf("could not find APIService with non-empty spec.service.namespace for API group %s", apiGroup)
|
||||
}
|
||||
|
||||
func getConciergeFrontend(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer, mode conciergeModeFlag) (*conciergeconfigv1alpha1.CredentialIssuerFrontend, error) {
|
||||
for _, strategy := range credentialIssuer.Status.Strategies {
|
||||
// Skip unhealthy strategies.
|
||||
@@ -540,26 +665,15 @@ func getConciergeFrontend(credentialIssuer *conciergeconfigv1alpha1.CredentialIs
|
||||
continue
|
||||
}
|
||||
|
||||
// Backfill the .status.strategies[].frontend field from .status.kubeConfigInfo for backwards compatibility.
|
||||
if strategy.Type == conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType && strategy.Frontend == nil && credentialIssuer.Status.KubeConfigInfo != nil {
|
||||
strategy = *strategy.DeepCopy()
|
||||
strategy.Frontend = &conciergeconfigv1alpha1.CredentialIssuerFrontend{
|
||||
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
|
||||
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
|
||||
Server: credentialIssuer.Status.KubeConfigInfo.Server,
|
||||
CertificateAuthorityData: credentialIssuer.Status.KubeConfigInfo.CertificateAuthorityData,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// If the strategy frontend is still nil, skip.
|
||||
// If the strategy frontend is nil, skip.
|
||||
if strategy.Frontend == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip any unknown frontend types.
|
||||
switch strategy.Frontend.Type {
|
||||
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType, conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
|
||||
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
|
||||
conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -11,15 +11,20 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
kubefake "k8s.io/client-go/kubernetes/fake"
|
||||
kubetesting "k8s.io/client-go/testing"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
|
||||
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
|
||||
aggregatorfake "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
|
||||
@@ -65,14 +70,69 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
jwtAuthenticator := func(issuerCABundle string, issuerURL string) runtime.Object {
|
||||
caBundleInSecret := func(issuerCABundle, secretName, secretNamespace, secretDataKey string) runtime.Object {
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: secretName,
|
||||
Namespace: secretNamespace,
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
secretDataKey: []byte(issuerCABundle),
|
||||
"other": []byte("unrelated"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
caBundleInConfigmap := func(issuerCABundle, cmName, cmNamespace, cmDataKey string) runtime.Object {
|
||||
return &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: cmName,
|
||||
Namespace: cmNamespace,
|
||||
},
|
||||
Data: map[string]string{
|
||||
cmDataKey: issuerCABundle,
|
||||
"other": "unrelated",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
jwtAuthenticator := func(issuerCABundle, issuerURL string) *authenticationv1alpha1.JWTAuthenticator {
|
||||
encodedCABundle := ""
|
||||
if issuerCABundle != "" {
|
||||
encodedCABundle = base64.StdEncoding.EncodeToString([]byte(issuerCABundle))
|
||||
}
|
||||
return &authenticationv1alpha1.JWTAuthenticator{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-authenticator"},
|
||||
Spec: authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: issuerURL,
|
||||
Audience: "test-audience",
|
||||
TLS: &authenticationv1alpha1.TLSSpec{
|
||||
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(issuerCABundle)),
|
||||
CertificateAuthorityData: encodedCABundle,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
jwtAuthenticatorWithCABundleDataSource := func(sourceKind, sourceName, sourceKey, issuerURL string) runtime.Object {
|
||||
authenticator := jwtAuthenticator("", issuerURL)
|
||||
authenticator.Spec.TLS.CertificateAuthorityDataSource = &authenticationv1alpha1.CertificateAuthorityDataSourceSpec{
|
||||
Kind: authenticationv1alpha1.CertificateAuthorityDataSourceKind(sourceKind),
|
||||
Name: sourceName,
|
||||
Key: sourceKey,
|
||||
}
|
||||
return authenticator
|
||||
}
|
||||
|
||||
apiService := func(group, version, serviceNamespace string) *v1.APIService {
|
||||
return &v1.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: version + "." + group,
|
||||
},
|
||||
Spec: v1.APIServiceSpec{
|
||||
Group: group,
|
||||
Version: version,
|
||||
Service: &v1.ServiceReference{
|
||||
Namespace: serviceNamespace,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -145,7 +205,11 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
getPathToSelfErr error
|
||||
getClientsetErr error
|
||||
conciergeObjects func(string, string) []runtime.Object
|
||||
kubeObjects func(string) []runtime.Object
|
||||
apiServiceObjects []runtime.Object
|
||||
conciergeReactions []kubetesting.Reactor
|
||||
kubeReactions []kubetesting.Reactor
|
||||
apiServiceReactions []kubetesting.Reactor
|
||||
oidcDiscoveryResponse func(string) string
|
||||
oidcDiscoveryStatusCode int
|
||||
idpsDiscoveryResponse string
|
||||
@@ -614,18 +678,18 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
&conciergeconfigv1alpha1.CredentialIssuer{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"},
|
||||
Status: conciergeconfigv1alpha1.CredentialIssuerStatus{
|
||||
KubeConfigInfo: &conciergeconfigv1alpha1.CredentialIssuerKubeConfigInfo{
|
||||
Server: "https://concierge-endpoint",
|
||||
CertificateAuthorityData: "ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==",
|
||||
},
|
||||
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{{
|
||||
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
|
||||
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
|
||||
Reason: conciergeconfigv1alpha1.FetchedKeyStrategyReason,
|
||||
Message: "Successfully fetched key",
|
||||
LastUpdateTime: metav1.Now(),
|
||||
// Simulate a previous version of CredentialIssuer that's missing this Frontend field.
|
||||
Frontend: nil,
|
||||
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
|
||||
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
|
||||
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
|
||||
Server: "https://concierge-endpoint.example.com",
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
@@ -657,6 +721,321 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but JWTAuthenticator test-authenticator has invalid spec.tls.certificateAuthorityData: illegal base64 data at input byte 7` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but Secret not found",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but encountered error getting Secret test-concierge-namespace/my-ca-secret specified by JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource: secrets "my-ca-secret" not found` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in ConfigMap, but ConfigMap not found",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("ConfigMap", "my-ca-configmap", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but encountered error getting ConfigMap test-concierge-namespace/my-ca-configmap specified by JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource: configmaps "my-ca-configmap" not found` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but invalid TLS bundle found in Secret",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInSecret("invalid CA bundle data", "my-ca-secret", "test-concierge-namespace", "ca.crt"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but value at key "ca.crt" specified by JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource.key does not contain any CA certificates in Secret test-concierge-namespace/my-ca-secret` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but specified key not found in Secret",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInSecret(issuerCABundle, "my-ca-secret", "test-concierge-namespace", "wrong_key_name"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but key "ca.crt" specified by JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource.key does not exist in Secret test-concierge-namespace/my-ca-secret` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but specified key has empty value in Secret",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInSecret("", "my-ca-secret", "test-concierge-namespace", "ca.crt"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but key "ca.crt" specified by JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource.key exists but has empty value in Secret test-concierge-namespace/my-ca-secret` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle source, but source's Kind is not supported",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Unsupported-Value", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but JWTAuthenticator test-authenticator spec.tls.certificateAuthorityDataSource.Kind value "Unsupported-Value" is not supported by this CLI version` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but no related APIService found",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("unrelated.example.com", "v1alpha1", "test-concierge-namespace"),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but encountered error discovering namespace of Concierge for JWTAuthenticator test-authenticator: could not find APIService with non-empty spec.service.namespace for API group login.concierge.pinniped.dev` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but related APIService has empty namespace in spec",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", ""),
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but encountered error discovering namespace of Concierge for JWTAuthenticator test-authenticator: could not find APIService with non-empty spec.service.namespace for API group login.concierge.pinniped.dev` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret, but error when listing APIServices",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
apiServiceReactions: []kubetesting.Reactor{
|
||||
&kubetesting.SimpleReactor{
|
||||
Verb: "*",
|
||||
Resource: "apiservices",
|
||||
Reaction: func(kubetesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, fmt.Errorf("some list error")
|
||||
},
|
||||
},
|
||||
},
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
}
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantExactErrorString(`Error: tried to autodiscover --oidc-ca-bundle, but encountered error discovering namespace of Concierge for JWTAuthenticator test-authenticator: error listing APIServices: some list error` + "\n")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator, invalid substring in audience",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
@@ -867,7 +1246,7 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
wantError: true,
|
||||
wantStderr: func(issuerCABundle string, issuerURL string) testutil.RequireErrorStringFunc {
|
||||
return testutil.WantSprintfErrorString(
|
||||
"Error: while fetching OIDC discovery data from issuer: oidc: issuer did not match the issuer returned by provider, expected \"%s\" got \"https://wrong-issuer.com\"\n",
|
||||
"Error: while fetching OIDC discovery data from issuer: oidc: issuer URL provided to client (\"%s\") did not match the issuer URL returned by provider (\"https://wrong-issuer.com\")\n",
|
||||
issuerURL)
|
||||
},
|
||||
},
|
||||
@@ -1370,7 +1749,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -1440,7 +1818,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -1504,7 +1881,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -1571,7 +1947,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -1601,6 +1976,254 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in Secret",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
"--skip-validation",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("Secret", "my-ca-secret", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInSecret(issuerCABundle, "my-ca-secret", "test-concierge-namespace", "ca.crt"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
apiService("unrelated.pinniped.dev", "v1alpha1", "unrelated-namespace"),
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha2", "test-concierge-namespace"),
|
||||
},
|
||||
oidcDiscoveryResponse: onlyIssuerOIDCDiscoveryResponse,
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC CA bundle from JWTAuthenticator spec.tls.certificateAuthorityDataSource {"roots": 1}`,
|
||||
}
|
||||
},
|
||||
wantStdout: func(issuerCABundle string, issuerURL string) string {
|
||||
return here.Docf(`
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
|
||||
server: https://fake-server-url-value
|
||||
name: kind-cluster-pinniped
|
||||
contexts:
|
||||
- context:
|
||||
cluster: kind-cluster-pinniped
|
||||
user: kind-user-pinniped
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
exec:
|
||||
apiVersion: client.authentication.k8s.io/v1beta1
|
||||
args:
|
||||
- login
|
||||
- oidc
|
||||
- --enable-concierge
|
||||
- --concierge-api-group-suffix=pinniped.dev
|
||||
- --concierge-authenticator-name=test-authenticator
|
||||
- --concierge-authenticator-type=jwt
|
||||
- --concierge-endpoint=https://fake-server-url-value
|
||||
- --concierge-ca-bundle-data=ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
|
||||
- --issuer=%s
|
||||
- --client-id=pinniped-cli
|
||||
- --scopes=offline_access,openid,pinniped:request-audience,username,groups
|
||||
- --ca-bundle-data=%s
|
||||
- --request-audience=test-audience
|
||||
command: '.../path/to/pinniped'
|
||||
env: []
|
||||
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
|
||||
for more details
|
||||
provideClusterInfo: true
|
||||
`,
|
||||
issuerURL,
|
||||
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in ConfigMap",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
"--skip-validation",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("ConfigMap", "my-ca-configmap", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInConfigmap(issuerCABundle, "my-ca-configmap", "test-concierge-namespace", "ca.crt"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha1", "test-concierge-namespace"),
|
||||
apiService("unrelated.pinniped.dev", "v1alpha1", "unrelated-namespace"),
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha2", "test-concierge-namespace"),
|
||||
},
|
||||
oidcDiscoveryResponse: onlyIssuerOIDCDiscoveryResponse,
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "pinniped.dev"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC CA bundle from JWTAuthenticator spec.tls.certificateAuthorityDataSource {"roots": 1}`,
|
||||
}
|
||||
},
|
||||
wantStdout: func(issuerCABundle string, issuerURL string) string {
|
||||
return here.Docf(`
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
|
||||
server: https://fake-server-url-value
|
||||
name: kind-cluster-pinniped
|
||||
contexts:
|
||||
- context:
|
||||
cluster: kind-cluster-pinniped
|
||||
user: kind-user-pinniped
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
exec:
|
||||
apiVersion: client.authentication.k8s.io/v1beta1
|
||||
args:
|
||||
- login
|
||||
- oidc
|
||||
- --enable-concierge
|
||||
- --concierge-api-group-suffix=pinniped.dev
|
||||
- --concierge-authenticator-name=test-authenticator
|
||||
- --concierge-authenticator-type=jwt
|
||||
- --concierge-endpoint=https://fake-server-url-value
|
||||
- --concierge-ca-bundle-data=ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
|
||||
- --issuer=%s
|
||||
- --client-id=pinniped-cli
|
||||
- --scopes=offline_access,openid,pinniped:request-audience,username,groups
|
||||
- --ca-bundle-data=%s
|
||||
- --request-audience=test-audience
|
||||
command: '.../path/to/pinniped'
|
||||
env: []
|
||||
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
|
||||
for more details
|
||||
provideClusterInfo: true
|
||||
`,
|
||||
issuerURL,
|
||||
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect JWT authenticator with CA bundle in ConfigMap with a custom API group suffix",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
"--concierge-api-group-suffix=acme.com",
|
||||
"--skip-validation",
|
||||
}
|
||||
},
|
||||
conciergeObjects: func(issuerCABundle string, issuerURL string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
credentialIssuer(),
|
||||
jwtAuthenticatorWithCABundleDataSource("ConfigMap", "my-ca-configmap", "ca.crt", issuerURL),
|
||||
}
|
||||
},
|
||||
kubeObjects: func(issuerCABundle string) []runtime.Object {
|
||||
return []runtime.Object{
|
||||
caBundleInConfigmap(issuerCABundle, "my-ca-configmap", "test-concierge-namespace", "ca.crt"),
|
||||
}
|
||||
},
|
||||
apiServiceObjects: []runtime.Object{
|
||||
apiService("login.concierge.acme.com", "v1alpha1", "test-concierge-namespace"),
|
||||
apiService("unrelated.pinniped.dev", "v1alpha1", "unrelated-namespace"),
|
||||
apiService("login.concierge.pinniped.dev", "v1alpha2", "another-unrelated-namespace"),
|
||||
},
|
||||
oidcDiscoveryResponse: onlyIssuerOIDCDiscoveryResponse,
|
||||
wantLogs: func(issuerCABundle string, issuerURL string) []string {
|
||||
return []string{
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered CredentialIssuer {"name": "test-credential-issuer"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge operating in TokenCredentialRequest API mode`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge endpoint {"endpoint": "https://fake-server-url-value"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge certificate authority bundle {"roots": 0}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered JWTAuthenticator {"name": "test-authenticator"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC issuer {"issuer": "` + issuerURL + `"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC audience {"audience": "test-audience"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered Concierge namespace for API group suffix {"apiGroupSuffix": "acme.com"}`,
|
||||
`2099-08-08T13:57:36.123456Z info cmd/kubeconfig.go:<line> discovered OIDC CA bundle from JWTAuthenticator spec.tls.certificateAuthorityDataSource {"roots": 1}`,
|
||||
}
|
||||
},
|
||||
wantAPIGroupSuffix: "acme.com",
|
||||
wantStdout: func(issuerCABundle string, issuerURL string) string {
|
||||
return here.Docf(`
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
|
||||
server: https://fake-server-url-value
|
||||
name: kind-cluster-pinniped
|
||||
contexts:
|
||||
- context:
|
||||
cluster: kind-cluster-pinniped
|
||||
user: kind-user-pinniped
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
exec:
|
||||
apiVersion: client.authentication.k8s.io/v1beta1
|
||||
args:
|
||||
- login
|
||||
- oidc
|
||||
- --enable-concierge
|
||||
- --concierge-api-group-suffix=acme.com
|
||||
- --concierge-authenticator-name=test-authenticator
|
||||
- --concierge-authenticator-type=jwt
|
||||
- --concierge-endpoint=https://fake-server-url-value
|
||||
- --concierge-ca-bundle-data=ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==
|
||||
- --issuer=%s
|
||||
- --client-id=pinniped-cli
|
||||
- --scopes=offline_access,openid,pinniped:request-audience,username,groups
|
||||
- --ca-bundle-data=%s
|
||||
- --request-audience=test-audience
|
||||
command: '.../path/to/pinniped'
|
||||
env: []
|
||||
installHint: The pinniped CLI does not appear to be installed. See https://get.pinniped.dev/cli
|
||||
for more details
|
||||
provideClusterInfo: true
|
||||
`,
|
||||
issuerURL,
|
||||
base64.StdEncoding.EncodeToString([]byte(issuerCABundle)))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "autodetect nothing, set a bunch of options",
|
||||
args: func(issuerCABundle string, issuerURL string) []string {
|
||||
@@ -1651,7 +2274,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-sso
|
||||
current-context: kind-context-sso
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-sso
|
||||
user:
|
||||
@@ -1770,7 +2392,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -1879,7 +2500,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -1956,7 +2576,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2035,7 +2654,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2112,7 +2730,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2185,7 +2802,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2265,7 +2881,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2352,7 +2967,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2440,7 +3054,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2528,7 +3141,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2606,7 +3218,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2689,7 +3300,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2755,7 +3365,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2816,7 +3425,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2877,7 +3485,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -2939,7 +3546,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -3001,7 +3607,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -3062,7 +3667,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -3122,7 +3726,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -3188,7 +3791,6 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: kind-context-pinniped
|
||||
current-context: kind-context-pinniped
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kind-user-pinniped
|
||||
user:
|
||||
@@ -3212,6 +3814,7 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var issuerEndpointPtr *string
|
||||
@@ -3246,6 +3849,40 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
}), nil)
|
||||
issuerEndpointPtr = ptr.To(testServer.URL)
|
||||
|
||||
getClientsetFunc := func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, kubernetes.Interface, aggregatorclient.Interface, error) {
|
||||
if tt.wantAPIGroupSuffix == "" {
|
||||
require.Equal(t, "pinniped.dev", apiGroupSuffix) // "pinniped.dev" = api group suffix default
|
||||
} else {
|
||||
require.Equal(t, tt.wantAPIGroupSuffix, apiGroupSuffix)
|
||||
}
|
||||
if tt.getClientsetErr != nil {
|
||||
return nil, nil, nil, tt.getClientsetErr
|
||||
}
|
||||
//nolint:staticcheck // as of v0.35.0, this package does not offer a NewClientset() function
|
||||
fakeAggregatorClient := aggregatorfake.NewSimpleClientset(tt.apiServiceObjects...)
|
||||
fakeKubeClient := kubefake.NewClientset()
|
||||
if tt.kubeObjects != nil {
|
||||
kubeObjects := tt.kubeObjects(string(testServerCA))
|
||||
fakeKubeClient = kubefake.NewClientset(kubeObjects...)
|
||||
}
|
||||
//nolint:staticcheck // our codegen does not yet generate a NewClientset() function
|
||||
fakeConciergeClient := conciergefake.NewSimpleClientset()
|
||||
if tt.conciergeObjects != nil {
|
||||
//nolint:staticcheck // our codegen does not yet generate a NewClientset() function
|
||||
fakeConciergeClient = conciergefake.NewSimpleClientset(tt.conciergeObjects(string(testServerCA), testServer.URL)...)
|
||||
}
|
||||
if len(tt.conciergeReactions) > 0 {
|
||||
fakeConciergeClient.ReactionChain = slices.Concat(tt.conciergeReactions, fakeConciergeClient.ReactionChain)
|
||||
}
|
||||
if len(tt.kubeReactions) > 0 {
|
||||
fakeKubeClient.ReactionChain = slices.Concat(tt.kubeReactions, fakeKubeClient.ReactionChain)
|
||||
}
|
||||
if len(tt.apiServiceReactions) > 0 {
|
||||
fakeAggregatorClient.ReactionChain = slices.Concat(tt.apiServiceReactions, fakeAggregatorClient.ReactionChain)
|
||||
}
|
||||
return fakeConciergeClient, fakeKubeClient, fakeAggregatorClient, nil
|
||||
}
|
||||
|
||||
var log bytes.Buffer
|
||||
|
||||
cmd := kubeconfigCommand(kubeconfigDeps{
|
||||
@@ -3258,25 +3895,8 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
}
|
||||
return ".../path/to/pinniped", nil
|
||||
},
|
||||
getClientset: func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, error) {
|
||||
if tt.wantAPIGroupSuffix == "" {
|
||||
require.Equal(t, "pinniped.dev", apiGroupSuffix) // "pinniped.dev" = api group suffix default
|
||||
} else {
|
||||
require.Equal(t, tt.wantAPIGroupSuffix, apiGroupSuffix)
|
||||
}
|
||||
if tt.getClientsetErr != nil {
|
||||
return nil, tt.getClientsetErr
|
||||
}
|
||||
fake := conciergefake.NewSimpleClientset()
|
||||
if tt.conciergeObjects != nil {
|
||||
fake = conciergefake.NewSimpleClientset(tt.conciergeObjects(string(testServerCA), testServer.URL)...)
|
||||
}
|
||||
if len(tt.conciergeReactions) > 0 {
|
||||
fake.ReactionChain = slices.Concat(tt.conciergeReactions, fake.ReactionChain)
|
||||
}
|
||||
return fake, nil
|
||||
},
|
||||
log: plog.TestConsoleLogger(t, &log),
|
||||
getClientsets: getClientsetFunc,
|
||||
log: plog.TestConsoleLogger(t, &log),
|
||||
})
|
||||
require.NotNil(t, cmd)
|
||||
|
||||
@@ -3293,14 +3913,10 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
var expectedLogs string
|
||||
if tt.wantLogs != nil {
|
||||
temp := tt.wantLogs(string(testServerCA), testServer.URL)
|
||||
if len(temp) > 0 {
|
||||
expectedLogs = strings.Join(tt.wantLogs(string(testServerCA), testServer.URL), "\n") + "\n"
|
||||
}
|
||||
wantLogs := tt.wantLogs(string(testServerCA), testServer.URL)
|
||||
testutil.RequireLogLines(t, wantLogs, &log)
|
||||
}
|
||||
require.Equal(t, expectedLogs, log.String())
|
||||
|
||||
expectedStdout := ""
|
||||
if tt.wantStdout != nil {
|
||||
|
||||
@@ -224,6 +224,7 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
|
||||
conciergeclient.WithBase64CABundle(flags.conciergeCABundle),
|
||||
conciergeclient.WithAuthenticator(flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName),
|
||||
conciergeclient.WithAPIGroupSuffix(flags.conciergeAPIGroupSuffix),
|
||||
conciergeclient.WithTransportWrapper(LogAuditIDTransportWrapper),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid Concierge parameters: %w", err)
|
||||
|
||||
@@ -274,8 +274,8 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
wantOptionsCount: 4,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
wantLogs: []string{
|
||||
nowStr + ` cmd/login_oidc.go:267 Performing OIDC login {"issuer": "test-issuer", "client id": "test-client-id"}`,
|
||||
nowStr + ` cmd/login_oidc.go:287 No concierge configured, skipping token credential exchange`,
|
||||
nowStr + ` cmd/login_oidc.go:268 Performing OIDC login {"issuer": "test-issuer", "client id": "test-client-id"}`,
|
||||
nowStr + ` cmd/login_oidc.go:288 No concierge configured, skipping token credential exchange`,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -319,10 +319,10 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
wantOptionsCount: 12,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"token":"exchanged-token"}}` + "\n",
|
||||
wantLogs: []string{
|
||||
nowStr + ` cmd/login_oidc.go:267 Performing OIDC login {"issuer": "test-issuer", "client id": "test-client-id"}`,
|
||||
nowStr + ` cmd/login_oidc.go:277 Exchanging token for cluster credential {"endpoint": "https://127.0.0.1:1234/", "authenticator type": "webhook", "authenticator name": "test-authenticator"}`,
|
||||
nowStr + ` cmd/login_oidc.go:285 Successfully exchanged token for cluster credential.`,
|
||||
nowStr + ` cmd/login_oidc.go:292 caching cluster credential for future use.`,
|
||||
nowStr + ` cmd/login_oidc.go:268 Performing OIDC login {"issuer": "test-issuer", "client id": "test-client-id"}`,
|
||||
nowStr + ` cmd/login_oidc.go:278 Exchanging token for cluster credential {"endpoint": "https://127.0.0.1:1234/", "authenticator type": "webhook", "authenticator name": "test-authenticator"}`,
|
||||
nowStr + ` cmd/login_oidc.go:286 Successfully exchanged token for cluster credential.`,
|
||||
nowStr + ` cmd/login_oidc.go:293 caching cluster credential for future use.`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@ func runStaticLogin(cmd *cobra.Command, deps staticLoginDeps, flags staticLoginP
|
||||
conciergeclient.WithBase64CABundle(flags.conciergeCABundle),
|
||||
conciergeclient.WithAuthenticator(flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName),
|
||||
conciergeclient.WithAPIGroupSuffix(flags.conciergeAPIGroupSuffix),
|
||||
conciergeclient.WithTransportWrapper(LogAuditIDTransportWrapper),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid Concierge parameters: %w", err)
|
||||
|
||||
@@ -147,7 +147,7 @@ func TestLoginStaticCommand(t *testing.T) {
|
||||
Error: could not complete Concierge credential exchange: some concierge error
|
||||
`),
|
||||
wantLogs: []string{
|
||||
nowStr + ` cmd/login_static.go:159 exchanging static token for cluster credential {"endpoint": "https://127.0.0.1/", "authenticator type": "webhook", "authenticator name": "test-authenticator"}`,
|
||||
nowStr + ` cmd/login_static.go:160 exchanging static token for cluster credential {"endpoint": "https://127.0.0.1/", "authenticator type": "webhook", "authenticator name": "test-authenticator"}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -25,14 +25,14 @@ import (
|
||||
)
|
||||
|
||||
type whoamiDeps struct {
|
||||
getenv func(key string) string
|
||||
getClientset getConciergeClientsetFunc
|
||||
getenv func(key string) string
|
||||
getClientsets getClientsetsFunc
|
||||
}
|
||||
|
||||
func whoamiRealDeps() whoamiDeps {
|
||||
return whoamiDeps{
|
||||
getenv: os.Getenv,
|
||||
getClientset: getRealConciergeClientset,
|
||||
getenv: os.Getenv,
|
||||
getClientsets: getRealClientsets,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ func newWhoamiCommand(deps whoamiDeps) *cobra.Command {
|
||||
|
||||
func runWhoami(output io.Writer, deps whoamiDeps, flags *whoamiFlags) error {
|
||||
clientConfig := newClientConfig(flags.kubeconfigPath, flags.kubeconfigContextOverride)
|
||||
clientset, err := deps.getClientset(clientConfig, flags.apiGroupSuffix)
|
||||
conciergeClient, _, _, err := deps.getClientsets(clientConfig, flags.apiGroupSuffix)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not configure Kubernetes client: %w", err)
|
||||
}
|
||||
@@ -108,7 +108,7 @@ func runWhoami(output io.Writer, deps whoamiDeps, flags *whoamiFlags) error {
|
||||
defer cancelFunc()
|
||||
}
|
||||
|
||||
whoAmI, err := clientset.IdentityV1alpha1().WhoAmIRequests().Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
|
||||
whoAmI, err := conciergeClient.IdentityV1alpha1().WhoAmIRequests().Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
hint := ""
|
||||
if apierrors.IsNotFound(err) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2023-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2023-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -11,8 +11,10 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
kubetesting "k8s.io/client-go/testing"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
|
||||
|
||||
identityv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/identity/v1alpha1"
|
||||
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
|
||||
@@ -128,9 +130,7 @@ func TestWhoami(t *testing.T) {
|
||||
{
|
||||
"kind": "WhoAmIRequest",
|
||||
"apiVersion": "identity.concierge.pinniped.dev/v1alpha1",
|
||||
"metadata": {
|
||||
"creationTimestamp": null
|
||||
},
|
||||
"metadata": {},
|
||||
"spec": {},
|
||||
"status": {
|
||||
"kubernetesUserInfo": {
|
||||
@@ -152,9 +152,7 @@ func TestWhoami(t *testing.T) {
|
||||
{
|
||||
"kind": "WhoAmIRequest",
|
||||
"apiVersion": "identity.concierge.tuna.io/v1alpha1",
|
||||
"metadata": {
|
||||
"creationTimestamp": null
|
||||
},
|
||||
"metadata": {},
|
||||
"spec": {},
|
||||
"status": {
|
||||
"kubernetesUserInfo": {
|
||||
@@ -175,8 +173,7 @@ func TestWhoami(t *testing.T) {
|
||||
wantStdout: here.Doc(`
|
||||
apiVersion: identity.concierge.pinniped.dev/v1alpha1
|
||||
kind: WhoAmIRequest
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
metadata: {}
|
||||
spec: {}
|
||||
status:
|
||||
kubernetesUserInfo:
|
||||
@@ -193,8 +190,7 @@ func TestWhoami(t *testing.T) {
|
||||
wantStdout: here.Doc(`
|
||||
apiVersion: identity.concierge.tuna.io/v1alpha1
|
||||
kind: WhoAmIRequest
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
metadata: {}
|
||||
spec: {}
|
||||
status:
|
||||
kubernetesUserInfo:
|
||||
@@ -290,14 +286,16 @@ func TestWhoami(t *testing.T) {
|
||||
wantStderr: "Error: could not complete WhoAmIRequest (is the Pinniped WhoAmI API running and healthy?): whoamirequests.identity.concierge.pinniped.dev \"whatever\" not found\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
getClientset := func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, error) {
|
||||
getClientsetFunc := func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, kubernetes.Interface, aggregatorclient.Interface, error) {
|
||||
if test.gettingClientsetErr != nil {
|
||||
return nil, test.gettingClientsetErr
|
||||
return nil, nil, nil, test.gettingClientsetErr
|
||||
}
|
||||
clientset := conciergefake.NewSimpleClientset()
|
||||
clientset.PrependReactor("create", "whoamirequests", func(_ kubetesting.Action) (bool, runtime.Object, error) {
|
||||
//nolint:staticcheck // our codegen does not yet generate a NewClientset() function
|
||||
conciergeClient := conciergefake.NewSimpleClientset()
|
||||
conciergeClient.PrependReactor("create", "whoamirequests", func(_ kubetesting.Action) (bool, runtime.Object, error) {
|
||||
if test.callingAPIErr != nil {
|
||||
return true, nil, test.callingAPIErr
|
||||
}
|
||||
@@ -316,13 +314,14 @@ func TestWhoami(t *testing.T) {
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
return clientset, nil
|
||||
return conciergeClient, nil, nil, nil
|
||||
}
|
||||
|
||||
cmd := newWhoamiCommand(whoamiDeps{
|
||||
getenv: func(key string) string {
|
||||
return test.env[key]
|
||||
},
|
||||
getClientset: getClientset,
|
||||
getClientsets: getClientsetFunc,
|
||||
})
|
||||
|
||||
stdout, stderr := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
name: jwtauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
@@ -58,37 +58,219 @@ spec:
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec for configuring the authenticator.
|
||||
description: spec for configuring the authenticator.
|
||||
properties:
|
||||
audience:
|
||||
description: Audience is the required value of the "aud" JWT claim.
|
||||
description: audience is the required value of the "aud" JWT claim.
|
||||
minLength: 1
|
||||
type: string
|
||||
claimValidationRules:
|
||||
description: |-
|
||||
claimValidationRules are rules that are applied to validate token claims to authenticate users.
|
||||
This is similar to claimValidationRules from Kubernetes AuthenticationConfiguration as documented in
|
||||
https://kubernetes.io/docs/reference/access-authn-authz/authentication.
|
||||
This is an advanced configuration option. During an end-user login flow, mistakes in this
|
||||
configuration will cause the user's login to fail.
|
||||
items:
|
||||
description: ClaimValidationRule provides the configuration for
|
||||
a single claim validation rule.
|
||||
properties:
|
||||
claim:
|
||||
description: |-
|
||||
claim is the name of a required claim.
|
||||
Only string claim keys are supported.
|
||||
Mutually exclusive with expression and message.
|
||||
type: string
|
||||
expression:
|
||||
description: |-
|
||||
expression represents the expression which will be evaluated by CEL.
|
||||
Must produce a boolean.
|
||||
|
||||
CEL expressions have access to the contents of the token claims, organized into CEL variable:
|
||||
- 'claims' is a map of claim names to claim values.
|
||||
For example, a variable named 'sub' can be accessed as 'claims.sub'.
|
||||
Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.
|
||||
Must return true for the validation to pass.
|
||||
|
||||
Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
|
||||
Mutually exclusive with claim and requiredValue.
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message customizes the returned error message when expression returns false.
|
||||
message is a literal string.
|
||||
Mutually exclusive with claim and requiredValue.
|
||||
type: string
|
||||
requiredValue:
|
||||
description: |-
|
||||
requiredValue is the value of a required claim.
|
||||
Only string claim values are supported.
|
||||
If claim is set and requiredValue is not set, the claim must be present with a value set to the empty string.
|
||||
Mutually exclusive with expression and message.
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
claims:
|
||||
description: |-
|
||||
Claims allows customization of the claims that will be mapped to user identity
|
||||
claims allows customization of the claims that will be mapped to user identity
|
||||
for Kubernetes access.
|
||||
properties:
|
||||
extra:
|
||||
description: |-
|
||||
extra is similar to claimMappings.extra from Kubernetes AuthenticationConfiguration
|
||||
as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication.
|
||||
|
||||
However, note that the Pinniped Concierge issues client certificates to users for the purpose
|
||||
of authenticating, and the Kubernetes API server does not have any mechanism for transmitting
|
||||
auth extras via client certificates. When configured, these extras will appear in client
|
||||
certificates issued by the Pinniped Supervisor in the x509 Subject field as Organizational
|
||||
Units (OU). However, when this client certificate is presented to Kubernetes for authentication,
|
||||
Kubernetes will ignore these extras. This is probably only useful if you are using a custom
|
||||
authenticating proxy in front of your Kubernetes API server which can translate these OUs into
|
||||
auth extras, as described by
|
||||
https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy.
|
||||
This is an advanced configuration option. During an end-user login flow, each of these CEL expressions
|
||||
must evaluate to either a string or an array of strings, or else the user's login will fail.
|
||||
|
||||
These keys must be a domain-prefixed path (such as "acme.io/foo") and must not contain an equals sign ("=").
|
||||
|
||||
expression must produce a string or string array value.
|
||||
If the value is empty, the extra mapping will not be present.
|
||||
|
||||
Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
|
||||
hard-coded extra key/value
|
||||
- key: "acme.io/foo"
|
||||
valueExpression: "'bar'"
|
||||
This will result in an extra attribute - acme.io/foo: ["bar"]
|
||||
|
||||
hard-coded key, value copying claim value
|
||||
- key: "acme.io/foo"
|
||||
valueExpression: "claims.some_claim"
|
||||
This will result in an extra attribute - acme.io/foo: [value of some_claim]
|
||||
|
||||
hard-coded key, value derived from claim value
|
||||
- key: "acme.io/admin"
|
||||
valueExpression: '(has(claims.is_admin) && claims.is_admin) ? "true":""'
|
||||
This will result in:
|
||||
- if is_admin claim is present and true, extra attribute - acme.io/admin: ["true"]
|
||||
- if is_admin claim is present and false or is_admin claim is not present, no extra attribute will be added
|
||||
items:
|
||||
description: ExtraMapping provides the configuration for a single
|
||||
extra mapping.
|
||||
properties:
|
||||
key:
|
||||
description: |-
|
||||
key is a string to use as the extra attribute key.
|
||||
key must be a domain-prefix path (e.g. example.org/foo). All characters before the first "/" must be a valid
|
||||
subdomain as defined by RFC 1123. All characters trailing the first "/" must
|
||||
be valid HTTP Path characters as defined by RFC 3986.
|
||||
key must be lowercase.
|
||||
Required to be unique.
|
||||
Additionally, the key must not contain an equals sign ("=").
|
||||
type: string
|
||||
valueExpression:
|
||||
description: |-
|
||||
valueExpression is a CEL expression to extract extra attribute value.
|
||||
valueExpression must produce a string or string array value.
|
||||
"", [], and null values are treated as the extra mapping not being present.
|
||||
Empty string values contained within a string array are filtered out.
|
||||
|
||||
CEL expressions have access to the contents of the token claims, organized into CEL variable:
|
||||
- 'claims' is a map of claim names to claim values.
|
||||
For example, a variable named 'sub' can be accessed as 'claims.sub'.
|
||||
Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.
|
||||
|
||||
Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- valueExpression
|
||||
type: object
|
||||
type: array
|
||||
groups:
|
||||
description: |-
|
||||
Groups is the name of the claim which should be read to extract the user's
|
||||
group membership from the JWT token. When not specified, it will default to "groups".
|
||||
groups is the name of the claim which should be read to extract the user's
|
||||
group membership from the JWT token. When not specified, it will default to "groups",
|
||||
unless groupsExpression is specified.
|
||||
|
||||
Mutually exclusive with groupsExpression. Use either groups or groupsExpression to
|
||||
determine the user's group membership from the JWT token.
|
||||
type: string
|
||||
groupsExpression:
|
||||
description: |-
|
||||
groupsExpression represents an expression which will be evaluated by CEL.
|
||||
The expression's result will become the user's group memberships.
|
||||
|
||||
groupsExpression is similar to claimMappings.groups.expression from Kubernetes AuthenticationConfiguration
|
||||
as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication.
|
||||
This is an advanced configuration option. During an end-user login flow, each of these CEL expressions
|
||||
must evaluate to one of the expected types without errors, or else the user's login will fail.
|
||||
Additionally, mistakes in this configuration can cause the users to have unintended group memberships.
|
||||
|
||||
The expression must produce a string or string array value.
|
||||
"", [], and null values are treated as the group mapping not being present.
|
||||
|
||||
CEL expressions have access to the contents of the token claims, organized into CEL variable:
|
||||
- 'claims' is a map of claim names to claim values.
|
||||
For example, a variable named 'sub' can be accessed as 'claims.sub'.
|
||||
Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.
|
||||
|
||||
Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
|
||||
Mutually exclusive with groups. Use either groups or groupsExpression to
|
||||
determine the user's group membership from the JWT token.
|
||||
type: string
|
||||
username:
|
||||
description: |-
|
||||
Username is the name of the claim which should be read to extract the
|
||||
username from the JWT token. When not specified, it will default to "username".
|
||||
username is the name of the claim which should be read to extract the
|
||||
username from the JWT token. When not specified, it will default to "username",
|
||||
unless usernameExpression is specified.
|
||||
|
||||
Mutually exclusive with usernameExpression. Use either username or usernameExpression to
|
||||
determine the user's username from the JWT token.
|
||||
type: string
|
||||
usernameExpression:
|
||||
description: |-
|
||||
usernameExpression represents an expression which will be evaluated by CEL.
|
||||
The expression's result will become the user's username.
|
||||
|
||||
usernameExpression is similar to claimMappings.username.expression from Kubernetes AuthenticationConfiguration
|
||||
as documented in https://kubernetes.io/docs/reference/access-authn-authz/authentication.
|
||||
This is an advanced configuration option. During an end-user login flow, each of these CEL expressions
|
||||
must evaluate to the expected type without errors, or else the user's login will fail.
|
||||
Additionally, mistakes in this configuration can cause the users to have unintended usernames.
|
||||
|
||||
The expression must produce a non-empty string value.
|
||||
If the expression uses 'claims.email', then 'claims.email_verified' must be used in
|
||||
the expression or extra[*].valueExpression or claimValidationRules[*].expression.
|
||||
An example claim validation rule expression that matches the validation automatically
|
||||
applied when username.claim is set to 'email' is 'claims.?email_verified.orValue(true) == true'.
|
||||
By explicitly comparing the value to true, we let type-checking see the result will be a boolean,
|
||||
and to make sure a non-boolean email_verified claim will be caught at runtime.
|
||||
|
||||
CEL expressions have access to the contents of the token claims, organized into CEL variable:
|
||||
- 'claims' is a map of claim names to claim values.
|
||||
For example, a variable named 'sub' can be accessed as 'claims.sub'.
|
||||
Nested claims can be accessed using dot notation, e.g. 'claims.foo.bar'.
|
||||
|
||||
Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
|
||||
Mutually exclusive with username. Use either username or usernameExpression to
|
||||
determine the user's username from the JWT token.
|
||||
type: string
|
||||
type: object
|
||||
issuer:
|
||||
description: |-
|
||||
Issuer is the OIDC issuer URL that will be used to discover public signing keys. Issuer is
|
||||
issuer is the OIDC issuer URL that will be used to discover public signing keys. Issuer is
|
||||
also used to validate the "iss" JWT claim.
|
||||
minLength: 1
|
||||
pattern: ^https://
|
||||
type: string
|
||||
tls:
|
||||
description: TLS configuration for communicating with the OIDC provider.
|
||||
description: tls is the configuration for communicating with the OIDC
|
||||
provider via TLS.
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: X.509 Certificate Authority (base64-encoded PEM bundle).
|
||||
@@ -128,12 +310,47 @@ spec:
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
userValidationRules:
|
||||
description: |-
|
||||
userValidationRules are rules that are applied to final user before completing authentication.
|
||||
These allow invariants to be applied to incoming identities such as preventing the
|
||||
use of the system: prefix that is commonly used by Kubernetes components.
|
||||
The validation rules are logically ANDed together and must all return true for the validation to pass.
|
||||
This is similar to claimValidationRules from Kubernetes AuthenticationConfiguration as documented in
|
||||
https://kubernetes.io/docs/reference/access-authn-authz/authentication.
|
||||
This is an advanced configuration option. During an end-user login flow, mistakes in this
|
||||
configuration will cause the user's login to fail.
|
||||
items:
|
||||
description: UserValidationRule provides the configuration for a
|
||||
single user info validation rule.
|
||||
properties:
|
||||
expression:
|
||||
description: |-
|
||||
expression represents the expression which will be evaluated by CEL.
|
||||
Must return true for the validation to pass.
|
||||
|
||||
CEL expressions have access to the contents of UserInfo, organized into CEL variable:
|
||||
- 'user' - authentication.k8s.io/v1, Kind=UserInfo object
|
||||
Refer to https://github.com/kubernetes/api/blob/release-1.28/authentication/v1/types.go#L105-L122 for the definition.
|
||||
API documentation: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#userinfo-v1-authentication-k8s-io
|
||||
|
||||
Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message customizes the returned error message when rule returns false.
|
||||
message is a literal string.
|
||||
type: string
|
||||
required:
|
||||
- expression
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- audience
|
||||
- issuer
|
||||
type: object
|
||||
status:
|
||||
description: Status of the authenticator.
|
||||
description: status of the authenticator.
|
||||
properties:
|
||||
conditions:
|
||||
description: Represents the observations of the authenticator's current
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
name: webhookauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
name: credentialissuers.config.concierge.pinniped.dev
|
||||
spec:
|
||||
group: config.concierge.pinniped.dev
|
||||
@@ -134,24 +134,6 @@ spec:
|
||||
status:
|
||||
description: CredentialIssuerStatus describes the status of the Concierge.
|
||||
properties:
|
||||
kubeConfigInfo:
|
||||
description: |-
|
||||
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
|
||||
This field is deprecated and will be removed in a future version.
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: The K8s API server CA bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
server:
|
||||
description: The K8s API server URL.
|
||||
minLength: 1
|
||||
pattern: ^https://|^http://
|
||||
type: string
|
||||
required:
|
||||
- certificateAuthorityData
|
||||
- server
|
||||
type: object
|
||||
strategies:
|
||||
description: List of integration strategies that were attempted by
|
||||
Pinniped.
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
#@ load("@ytt:json", "json")
|
||||
#@ load("helpers.lib.yaml", "defaultLabel", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "getAndValidateLogLevel", "pinnipedDevAPIGroupWithPrefix")
|
||||
#@ load("helpers.lib.yaml",
|
||||
#@ "defaultLabel",
|
||||
#@ "labels",
|
||||
#@ "deploymentPodLabel",
|
||||
#@ "namespace",
|
||||
#@ "defaultResourceName",
|
||||
#@ "defaultResourceNameWithSuffix",
|
||||
#@ "getAndValidateLogLevel",
|
||||
#@ "pinnipedDevAPIGroupWithPrefix",
|
||||
#@ )
|
||||
#@ load("@ytt:template", "template")
|
||||
|
||||
#@ if not data.values.into_namespace:
|
||||
@@ -68,6 +77,7 @@ data:
|
||||
apiGroupSuffix: (@= data.values.api_group_suffix @)
|
||||
# aggregatedAPIServerPort may be set here, although other YAML references to the default port (10250) may also need to be updated
|
||||
# impersonationProxyServerPort may be set here, although other YAML references to the default port (8444) may also need to be updated
|
||||
aggregatedAPIServerDisableAdmissionPlugins: []
|
||||
names:
|
||||
servingCertificateSecret: (@= defaultResourceNameWithSuffix("api-tls-serving-certificate") @)
|
||||
credentialIssuer: (@= defaultResourceNameWithSuffix("config") @)
|
||||
@@ -83,6 +93,7 @@ data:
|
||||
labels: (@= json.encode(labels()).rstrip() @)
|
||||
kubeCertAgent:
|
||||
namePrefix: (@= defaultResourceNameWithSuffix("kube-cert-agent-") @)
|
||||
priorityClassName: (@= data.values.kube_cert_agent_priority_class_name @)
|
||||
(@ if data.values.kube_cert_agent_image: @)
|
||||
image: (@= data.values.kube_cert_agent_image @)
|
||||
(@ else: @)
|
||||
@@ -94,15 +105,17 @@ data:
|
||||
(@ end @)
|
||||
(@ if data.values.image_pull_dockerconfigjson: @)
|
||||
imagePullSecrets:
|
||||
- image-pull-secret
|
||||
- image-pull-secret
|
||||
(@ end @)
|
||||
(@ if data.values.log_level: @)
|
||||
log:
|
||||
level: (@= getAndValidateLogLevel() @)
|
||||
(@ end @)
|
||||
(@ end @)
|
||||
tls:
|
||||
onedottwo:
|
||||
allowedCiphers: (@= str(data.values.allowed_ciphers_for_tls_onedottwo) @)
|
||||
audit:
|
||||
logUsernamesAndGroups: (@= data.values.audit.log_usernames_and_groups @)
|
||||
---
|
||||
#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "":
|
||||
apiVersion: v1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ def validate_strings_map(obj):
|
||||
@@ -52,7 +52,7 @@ replicas: 2
|
||||
#@schema/title "Image repo"
|
||||
#@schema/desc "The repository for the Concierge container image."
|
||||
#@schema/validation min_len=1
|
||||
image_repo: ghcr.io/vmware-tanzu/pinniped/pinniped-server
|
||||
image_repo: ghcr.io/vmware/pinniped/pinniped-server
|
||||
|
||||
#@schema/title "Image digest"
|
||||
#@schema/desc "The image digest for the Concierge container image. If both image_digest or an image_tag are given, only image_digest will be used."
|
||||
@@ -68,15 +68,24 @@ image_digest: ""
|
||||
image_tag: latest
|
||||
|
||||
#@schema/title "Kube Cert Agent image"
|
||||
#@ kube_cert_agent_image = "Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled \
|
||||
#@ kube_cert_agent_image_desc = "Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled \
|
||||
#@ on the control plane. This image needs only to include `sleep` and `cat` binaries. \
|
||||
#@ By default, the same image specified for image_repo/image_digest/image_tag will be re-used."
|
||||
#@schema/desc kube_cert_agent_image
|
||||
#@schema/examples ("Image including tag or digest", "ghcr.io/vmware-tanzu/pinniped/pinniped-server:latest")
|
||||
#@schema/desc kube_cert_agent_image_desc
|
||||
#@schema/examples ("Image including tag or digest", "ghcr.io/vmware/pinniped/pinniped-server:latest")
|
||||
#@schema/nullable
|
||||
#@schema/validation min_len=1
|
||||
kube_cert_agent_image: ""
|
||||
|
||||
#@schema/title "Kube Cert Agent Priority Class Name"
|
||||
#@ kube_cert_agent_priority_class_name_desc = "Optionally specify a PriorityClassName for the 'kube-cert-agent' pod. \
|
||||
#@ See https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/ for more details. \
|
||||
#@ By default, this is the empty string."
|
||||
#@schema/desc kube_cert_agent_priority_class_name_desc
|
||||
#@schema/examples ("name of a PriorityClass object", "high-priority")
|
||||
#@schema/validation min_len=0
|
||||
kube_cert_agent_priority_class_name: ""
|
||||
|
||||
#@schema/title "Image pull dockerconfigjson"
|
||||
#@ image_pull_dockerconfigjson_desc = "A base64 encoded secret to be used when pulling the `image_repo` container image. \
|
||||
#@ Can be used when the image_repo is a private registry. Typically, the value would be the output of: \
|
||||
@@ -231,3 +240,15 @@ no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.
|
||||
#! An empty array is perfectly valid, as is any array of strings.
|
||||
allowed_ciphers_for_tls_onedottwo:
|
||||
- ""
|
||||
|
||||
#@schema/title "Audit logging configuration"
|
||||
#@schema/desc "Customize the content of audit log events."
|
||||
audit:
|
||||
|
||||
#@schema/title "Log usernames and groups"
|
||||
#@ log_usernames_and_groups_desc = "Enables or disables printing usernames and group names in audit logs. Options are 'enabled' or 'disabled'. \
|
||||
#@ If enabled, usernames are group names may be printed in audit log events. \
|
||||
#@ If disabled, usernames and group names will be redacted from audit logs because they might contain personally identifiable information."
|
||||
#@schema/desc log_usernames_and_groups_desc
|
||||
#@schema/validation one_of=["enabled", "disabled"]
|
||||
log_usernames_and_groups: disabled
|
||||
|
||||
@@ -20,7 +20,7 @@ kubectl apply -f https://get.pinniped.dev/latest/install-local-user-authenticato
|
||||
|
||||
## Installing a Specific Version with Default Options
|
||||
|
||||
Choose your preferred [release](https://github.com/vmware-tanzu/pinniped/releases) version number
|
||||
Choose your preferred [release](https://github.com/vmware/pinniped/releases) version number
|
||||
and use it to replace the version number in the URL below.
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@data/values-schema
|
||||
@@ -6,7 +6,7 @@
|
||||
#@schema/title "Image repo"
|
||||
#@schema/desc "The repository for the local-user-authenticator container image."
|
||||
#@schema/validation min_len=1
|
||||
image_repo: ghcr.io/vmware-tanzu/pinniped/pinniped-server
|
||||
image_repo: ghcr.io/vmware/pinniped/pinniped-server
|
||||
|
||||
#@schema/title "Image digest"
|
||||
#@schema/desc "The image digest for the local-user-authenticator container image. If both image_digest or an image_tag are given, only image_digest will be used."
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
name: federationdomains.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
@@ -289,6 +289,9 @@ spec:
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
minLength: 1
|
||||
type: string
|
||||
x-kubernetes-validations:
|
||||
- message: issuer must be an HTTPS URL
|
||||
rule: isURL(self) && url(self).getScheme() == 'https'
|
||||
tls:
|
||||
description: TLS specifies a secret which will contain Transport Layer
|
||||
Security (TLS) configuration for the FederationDomain.
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
name: oidcclients.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@@ -13,7 +13,7 @@
|
||||
#@ "pinnipedDevAPIGroupWithPrefix",
|
||||
#@ "getPinnipedConfigMapData",
|
||||
#@ "hasUnixNetworkEndpoint",
|
||||
#@ )
|
||||
#@ )
|
||||
#@ load("@ytt:template", "template")
|
||||
|
||||
#@ if not data.values.into_namespace:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@@ -57,7 +57,12 @@ _: #@ template.replace(data.values.custom_labels)
|
||||
#@ "onedottwo": {
|
||||
#@ "allowedCiphers": data.values.allowed_ciphers_for_tls_onedottwo
|
||||
#@ }
|
||||
#@ }
|
||||
#@ },
|
||||
#@ "audit": {
|
||||
#@ "logUsernamesAndGroups": data.values.audit.log_usernames_and_groups,
|
||||
#@ "logInternalPaths": data.values.audit.log_internal_paths
|
||||
#@ },
|
||||
#@ "aggregatedAPIServerDisableAdmissionPlugins": []
|
||||
#@ }
|
||||
#@ if data.values.log_level:
|
||||
#@ config["log"] = {}
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
name: githubidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
controller-gen.kubebuilder.io/version: v0.20.0
|
||||
name: oidcidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ def validate_strings_map(obj):
|
||||
@@ -52,7 +52,7 @@ replicas: 2
|
||||
#@schema/title "Image repo"
|
||||
#@schema/desc "The repository for the Supervisor container image."
|
||||
#@schema/validation min_len=1
|
||||
image_repo: ghcr.io/vmware-tanzu/pinniped/pinniped-server
|
||||
image_repo: ghcr.io/vmware/pinniped/pinniped-server
|
||||
|
||||
#@schema/title "Image digest"
|
||||
#@schema/desc "The image digest for the Supervisor container image. If both image_digest or an image_tag are given, only image_digest will be used."
|
||||
@@ -220,3 +220,23 @@ endpoints: { }
|
||||
#! An empty array is perfectly valid, as is any array of strings.
|
||||
allowed_ciphers_for_tls_onedottwo:
|
||||
- ""
|
||||
|
||||
#@schema/title "Audit logging configuration"
|
||||
#@schema/desc "Customize the content of audit log events."
|
||||
audit:
|
||||
|
||||
#@schema/title "Log usernames and groups"
|
||||
#@ log_usernames_and_groups_desc = "Enables or disables printing usernames and group names in audit logs. Options are 'enabled' or 'disabled'. \
|
||||
#@ If enabled, usernames are group names may be printed in audit log events. \
|
||||
#@ If disabled, usernames and group names will be redacted from audit logs because they might contain personally identifiable information."
|
||||
#@schema/desc log_usernames_and_groups_desc
|
||||
#@schema/validation one_of=["enabled", "disabled"]
|
||||
log_usernames_and_groups: disabled
|
||||
|
||||
#@schema/title "Log HTTPS requests for internal paths"
|
||||
#@ log_internal_paths = "Enables or disables request logging for internal paths in audit logs. Options are 'enabled' or 'disabled'. \
|
||||
#@ If enabled, requests to certain paths that are typically only used internal to the cluster (e.g. /healthz) will be enabled, which can be very verbose. \
|
||||
#@ If disabled, requests to those paths will not be audit logged."
|
||||
#@schema/desc log_internal_paths
|
||||
#@schema/validation one_of=["enabled", "disabled"]
|
||||
log_internal_paths: disabled
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
type JWTAuthenticatorPhase string
|
||||
|
||||
const (
|
||||
// JWTAuthenticatorPhasePending is the default phase for newly-created JWTAuthenticator resources.
|
||||
JWTAuthenticatorPhasePending JWTAuthenticatorPhase = "Pending"
|
||||
|
||||
// JWTAuthenticatorPhaseReady is the phase for an JWTAuthenticator resource in a healthy state.
|
||||
JWTAuthenticatorPhaseReady JWTAuthenticatorPhase = "Ready"
|
||||
|
||||
// JWTAuthenticatorPhaseError is the phase for an JWTAuthenticator in an unhealthy state.
|
||||
JWTAuthenticatorPhaseError JWTAuthenticatorPhase = "Error"
|
||||
)
|
||||
|
||||
// Status of a JWT authenticator.
|
||||
type JWTAuthenticatorStatus struct {
|
||||
// Represents the observations of the authenticator's current state.
|
||||
// +patchMergeKey=type
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
// Phase summarizes the overall status of the JWTAuthenticator.
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase JWTAuthenticatorPhase `json:"phase,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring a JWT authenticator.
|
||||
type JWTAuthenticatorSpec struct {
|
||||
// Issuer is the OIDC issuer URL that will be used to discover public signing keys. Issuer is
|
||||
// also used to validate the "iss" JWT claim.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:Pattern=`^https://`
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// Audience is the required value of the "aud" JWT claim.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Audience string `json:"audience"`
|
||||
|
||||
// Claims allows customization of the claims that will be mapped to user identity
|
||||
// for Kubernetes access.
|
||||
// +optional
|
||||
Claims JWTTokenClaims `json:"claims"`
|
||||
|
||||
// TLS configuration for communicating with the OIDC provider.
|
||||
// +optional
|
||||
TLS *TLSSpec `json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
// JWTTokenClaims allows customization of the claims that will be mapped to user identity
|
||||
// for Kubernetes access.
|
||||
type JWTTokenClaims struct {
|
||||
// Groups is the name of the claim which should be read to extract the user's
|
||||
// group membership from the JWT token. When not specified, it will default to "groups".
|
||||
// +optional
|
||||
Groups string `json:"groups"`
|
||||
|
||||
// Username is the name of the claim which should be read to extract the
|
||||
// username from the JWT token. When not specified, it will default to "username".
|
||||
// +optional
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
// JWTAuthenticator describes the configuration of a JWT authenticator.
|
||||
//
|
||||
// Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid
|
||||
// signature, existence of claims, etc.) and extract the username and groups from the token.
|
||||
//
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=pinniped;pinniped-authenticator;pinniped-authenticators,scope=Cluster
|
||||
// +kubebuilder:printcolumn:name="Issuer",type=string,JSONPath=`.spec.issuer`
|
||||
// +kubebuilder:printcolumn:name="Audience",type=string,JSONPath=`.spec.audience`
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:status
|
||||
type JWTAuthenticator struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec for configuring the authenticator.
|
||||
Spec JWTAuthenticatorSpec `json:"spec"`
|
||||
|
||||
// Status of the authenticator.
|
||||
Status JWTAuthenticatorStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// List of JWTAuthenticator objects.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type JWTAuthenticatorList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []JWTAuthenticator `json:"items"`
|
||||
}
|
||||
9
generated/1.25/apis/go.mod
generated
9
generated/1.25/apis/go.mod
generated
@@ -1,9 +0,0 @@
|
||||
// This go.mod file is generated by ./hack/update.sh.
|
||||
module go.pinniped.dev/generated/1.25/apis
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
k8s.io/api v0.25.16
|
||||
k8s.io/apimachinery v0.25.16
|
||||
)
|
||||
285
generated/1.25/apis/go.sum
generated
285
generated/1.25/apis/go.sum
generated
@@ -1,285 +0,0 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
|
||||
github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.25.16 h1:6VsSxn0vCdHuAVh82EZCKoM457LuUpQQb6YXfQunz7Q=
|
||||
k8s.io/api v0.25.16/go.mod h1:7pehrlB/DJ0qzxicMELX7IZlgL6J5lnSOBPey/cuGBs=
|
||||
k8s.io/apimachinery v0.25.16 h1:Mk5h4zbHVZh4ZkgRnciYdLRqOREt2dAGTJesDY0WO7U=
|
||||
k8s.io/apimachinery v0.25.16/go.mod h1:34oJjP2pnWhz64k0GETsMvDeAp2A2v+gKa/u3tV/+6k=
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
|
||||
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU=
|
||||
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4=
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
@@ -1,4 +0,0 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@@ -1,12 +0,0 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package versioned
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
authenticationv1alpha1 "go.pinniped.dev/generated/1.25/client/concierge/clientset/versioned/typed/authentication/v1alpha1"
|
||||
configv1alpha1 "go.pinniped.dev/generated/1.25/client/concierge/clientset/versioned/typed/config/v1alpha1"
|
||||
identityv1alpha1 "go.pinniped.dev/generated/1.25/client/concierge/clientset/versioned/typed/identity/v1alpha1"
|
||||
loginv1alpha1 "go.pinniped.dev/generated/1.25/client/concierge/clientset/versioned/typed/login/v1alpha1"
|
||||
discovery "k8s.io/client-go/discovery"
|
||||
rest "k8s.io/client-go/rest"
|
||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
AuthenticationV1alpha1() authenticationv1alpha1.AuthenticationV1alpha1Interface
|
||||
ConfigV1alpha1() configv1alpha1.ConfigV1alpha1Interface
|
||||
IdentityV1alpha1() identityv1alpha1.IdentityV1alpha1Interface
|
||||
LoginV1alpha1() loginv1alpha1.LoginV1alpha1Interface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups. Each group has exactly one
|
||||
// version included in a Clientset.
|
||||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
authenticationV1alpha1 *authenticationv1alpha1.AuthenticationV1alpha1Client
|
||||
configV1alpha1 *configv1alpha1.ConfigV1alpha1Client
|
||||
identityV1alpha1 *identityv1alpha1.IdentityV1alpha1Client
|
||||
loginV1alpha1 *loginv1alpha1.LoginV1alpha1Client
|
||||
}
|
||||
|
||||
// AuthenticationV1alpha1 retrieves the AuthenticationV1alpha1Client
|
||||
func (c *Clientset) AuthenticationV1alpha1() authenticationv1alpha1.AuthenticationV1alpha1Interface {
|
||||
return c.authenticationV1alpha1
|
||||
}
|
||||
|
||||
// ConfigV1alpha1 retrieves the ConfigV1alpha1Client
|
||||
func (c *Clientset) ConfigV1alpha1() configv1alpha1.ConfigV1alpha1Interface {
|
||||
return c.configV1alpha1
|
||||
}
|
||||
|
||||
// IdentityV1alpha1 retrieves the IdentityV1alpha1Client
|
||||
func (c *Clientset) IdentityV1alpha1() identityv1alpha1.IdentityV1alpha1Interface {
|
||||
return c.identityV1alpha1
|
||||
}
|
||||
|
||||
// LoginV1alpha1 retrieves the LoginV1alpha1Client
|
||||
func (c *Clientset) LoginV1alpha1() loginv1alpha1.LoginV1alpha1Interface {
|
||||
return c.loginV1alpha1
|
||||
}
|
||||
|
||||
// Discovery retrieves the DiscoveryClient
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.DiscoveryClient
|
||||
}
|
||||
|
||||
// NewForConfig creates a new Clientset for the given config.
|
||||
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
||||
// NewForConfig will generate a rate-limiter in configShallowCopy.
|
||||
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||
func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
|
||||
if configShallowCopy.UserAgent == "" {
|
||||
configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
// share the transport between all clients
|
||||
httpClient, err := rest.HTTPClientFor(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
}
|
||||
|
||||
// NewForConfigAndClient creates a new Clientset for the given config and http client.
|
||||
// Note the http client provided takes precedence over the configured transport values.
|
||||
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
||||
// NewForConfigAndClient will generate a rate-limiter in configShallowCopy.
|
||||
func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
||||
if configShallowCopy.Burst <= 0 {
|
||||
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
|
||||
}
|
||||
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
||||
}
|
||||
|
||||
var cs Clientset
|
||||
var err error
|
||||
cs.authenticationV1alpha1, err = authenticationv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.configV1alpha1, err = configv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.identityV1alpha1, err = identityv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.loginV1alpha1, err = loginv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cs, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new Clientset for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
cs, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return cs
|
||||
}
|
||||
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
func New(c rest.Interface) *Clientset {
|
||||
var cs Clientset
|
||||
cs.authenticationV1alpha1 = authenticationv1alpha1.New(c)
|
||||
cs.configV1alpha1 = configv1alpha1.New(c)
|
||||
cs.identityV1alpha1 = identityv1alpha1.New(c)
|
||||
cs.loginV1alpha1 = loginv1alpha1.New(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
return &cs
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated clientset.
|
||||
package versioned
|
||||
@@ -1,120 +0,0 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.25/apis/concierge/authentication/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeJWTAuthenticators implements JWTAuthenticatorInterface
|
||||
type FakeJWTAuthenticators struct {
|
||||
Fake *FakeAuthenticationV1alpha1
|
||||
}
|
||||
|
||||
var jwtauthenticatorsResource = schema.GroupVersionResource{Group: "authentication.concierge.pinniped.dev", Version: "v1alpha1", Resource: "jwtauthenticators"}
|
||||
|
||||
var jwtauthenticatorsKind = schema.GroupVersionKind{Group: "authentication.concierge.pinniped.dev", Version: "v1alpha1", Kind: "JWTAuthenticator"}
|
||||
|
||||
// Get takes name of the jWTAuthenticator, and returns the corresponding jWTAuthenticator object, and an error if there is any.
|
||||
func (c *FakeJWTAuthenticators) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.JWTAuthenticator, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(jwtauthenticatorsResource, name), &v1alpha1.JWTAuthenticator{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.JWTAuthenticator), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of JWTAuthenticators that match those selectors.
|
||||
func (c *FakeJWTAuthenticators) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.JWTAuthenticatorList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(jwtauthenticatorsResource, jwtauthenticatorsKind, opts), &v1alpha1.JWTAuthenticatorList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.JWTAuthenticatorList{ListMeta: obj.(*v1alpha1.JWTAuthenticatorList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.JWTAuthenticatorList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested jWTAuthenticators.
|
||||
func (c *FakeJWTAuthenticators) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(jwtauthenticatorsResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a jWTAuthenticator and creates it. Returns the server's representation of the jWTAuthenticator, and an error, if there is any.
|
||||
func (c *FakeJWTAuthenticators) Create(ctx context.Context, jWTAuthenticator *v1alpha1.JWTAuthenticator, opts v1.CreateOptions) (result *v1alpha1.JWTAuthenticator, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(jwtauthenticatorsResource, jWTAuthenticator), &v1alpha1.JWTAuthenticator{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.JWTAuthenticator), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a jWTAuthenticator and updates it. Returns the server's representation of the jWTAuthenticator, and an error, if there is any.
|
||||
func (c *FakeJWTAuthenticators) Update(ctx context.Context, jWTAuthenticator *v1alpha1.JWTAuthenticator, opts v1.UpdateOptions) (result *v1alpha1.JWTAuthenticator, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(jwtauthenticatorsResource, jWTAuthenticator), &v1alpha1.JWTAuthenticator{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.JWTAuthenticator), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeJWTAuthenticators) UpdateStatus(ctx context.Context, jWTAuthenticator *v1alpha1.JWTAuthenticator, opts v1.UpdateOptions) (*v1alpha1.JWTAuthenticator, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(jwtauthenticatorsResource, "status", jWTAuthenticator), &v1alpha1.JWTAuthenticator{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.JWTAuthenticator), err
|
||||
}
|
||||
|
||||
// Delete takes name of the jWTAuthenticator and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeJWTAuthenticators) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteActionWithOptions(jwtauthenticatorsResource, name, opts), &v1alpha1.JWTAuthenticator{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeJWTAuthenticators) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(jwtauthenticatorsResource, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.JWTAuthenticatorList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched jWTAuthenticator.
|
||||
func (c *FakeJWTAuthenticators) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.JWTAuthenticator, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(jwtauthenticatorsResource, name, pt, data, subresources...), &v1alpha1.JWTAuthenticator{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.JWTAuthenticator), err
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.25/apis/concierge/authentication/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeWebhookAuthenticators implements WebhookAuthenticatorInterface
|
||||
type FakeWebhookAuthenticators struct {
|
||||
Fake *FakeAuthenticationV1alpha1
|
||||
}
|
||||
|
||||
var webhookauthenticatorsResource = schema.GroupVersionResource{Group: "authentication.concierge.pinniped.dev", Version: "v1alpha1", Resource: "webhookauthenticators"}
|
||||
|
||||
var webhookauthenticatorsKind = schema.GroupVersionKind{Group: "authentication.concierge.pinniped.dev", Version: "v1alpha1", Kind: "WebhookAuthenticator"}
|
||||
|
||||
// Get takes name of the webhookAuthenticator, and returns the corresponding webhookAuthenticator object, and an error if there is any.
|
||||
func (c *FakeWebhookAuthenticators) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.WebhookAuthenticator, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(webhookauthenticatorsResource, name), &v1alpha1.WebhookAuthenticator{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.WebhookAuthenticator), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of WebhookAuthenticators that match those selectors.
|
||||
func (c *FakeWebhookAuthenticators) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.WebhookAuthenticatorList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(webhookauthenticatorsResource, webhookauthenticatorsKind, opts), &v1alpha1.WebhookAuthenticatorList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.WebhookAuthenticatorList{ListMeta: obj.(*v1alpha1.WebhookAuthenticatorList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.WebhookAuthenticatorList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested webhookAuthenticators.
|
||||
func (c *FakeWebhookAuthenticators) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(webhookauthenticatorsResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a webhookAuthenticator and creates it. Returns the server's representation of the webhookAuthenticator, and an error, if there is any.
|
||||
func (c *FakeWebhookAuthenticators) Create(ctx context.Context, webhookAuthenticator *v1alpha1.WebhookAuthenticator, opts v1.CreateOptions) (result *v1alpha1.WebhookAuthenticator, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(webhookauthenticatorsResource, webhookAuthenticator), &v1alpha1.WebhookAuthenticator{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.WebhookAuthenticator), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a webhookAuthenticator and updates it. Returns the server's representation of the webhookAuthenticator, and an error, if there is any.
|
||||
func (c *FakeWebhookAuthenticators) Update(ctx context.Context, webhookAuthenticator *v1alpha1.WebhookAuthenticator, opts v1.UpdateOptions) (result *v1alpha1.WebhookAuthenticator, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(webhookauthenticatorsResource, webhookAuthenticator), &v1alpha1.WebhookAuthenticator{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.WebhookAuthenticator), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeWebhookAuthenticators) UpdateStatus(ctx context.Context, webhookAuthenticator *v1alpha1.WebhookAuthenticator, opts v1.UpdateOptions) (*v1alpha1.WebhookAuthenticator, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(webhookauthenticatorsResource, "status", webhookAuthenticator), &v1alpha1.WebhookAuthenticator{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.WebhookAuthenticator), err
|
||||
}
|
||||
|
||||
// Delete takes name of the webhookAuthenticator and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeWebhookAuthenticators) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteActionWithOptions(webhookauthenticatorsResource, name, opts), &v1alpha1.WebhookAuthenticator{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeWebhookAuthenticators) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(webhookauthenticatorsResource, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.WebhookAuthenticatorList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched webhookAuthenticator.
|
||||
func (c *FakeWebhookAuthenticators) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.WebhookAuthenticator, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(webhookauthenticatorsResource, name, pt, data, subresources...), &v1alpha1.WebhookAuthenticator{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.WebhookAuthenticator), err
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.25/apis/concierge/authentication/v1alpha1"
|
||||
scheme "go.pinniped.dev/generated/1.25/client/concierge/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// JWTAuthenticatorsGetter has a method to return a JWTAuthenticatorInterface.
|
||||
// A group's client should implement this interface.
|
||||
type JWTAuthenticatorsGetter interface {
|
||||
JWTAuthenticators() JWTAuthenticatorInterface
|
||||
}
|
||||
|
||||
// JWTAuthenticatorInterface has methods to work with JWTAuthenticator resources.
|
||||
type JWTAuthenticatorInterface interface {
|
||||
Create(ctx context.Context, jWTAuthenticator *v1alpha1.JWTAuthenticator, opts v1.CreateOptions) (*v1alpha1.JWTAuthenticator, error)
|
||||
Update(ctx context.Context, jWTAuthenticator *v1alpha1.JWTAuthenticator, opts v1.UpdateOptions) (*v1alpha1.JWTAuthenticator, error)
|
||||
UpdateStatus(ctx context.Context, jWTAuthenticator *v1alpha1.JWTAuthenticator, opts v1.UpdateOptions) (*v1alpha1.JWTAuthenticator, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.JWTAuthenticator, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.JWTAuthenticatorList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.JWTAuthenticator, err error)
|
||||
JWTAuthenticatorExpansion
|
||||
}
|
||||
|
||||
// jWTAuthenticators implements JWTAuthenticatorInterface
|
||||
type jWTAuthenticators struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newJWTAuthenticators returns a JWTAuthenticators
|
||||
func newJWTAuthenticators(c *AuthenticationV1alpha1Client) *jWTAuthenticators {
|
||||
return &jWTAuthenticators{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the jWTAuthenticator, and returns the corresponding jWTAuthenticator object, and an error if there is any.
|
||||
func (c *jWTAuthenticators) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.JWTAuthenticator, err error) {
|
||||
result = &v1alpha1.JWTAuthenticator{}
|
||||
err = c.client.Get().
|
||||
Resource("jwtauthenticators").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of JWTAuthenticators that match those selectors.
|
||||
func (c *jWTAuthenticators) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.JWTAuthenticatorList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.JWTAuthenticatorList{}
|
||||
err = c.client.Get().
|
||||
Resource("jwtauthenticators").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested jWTAuthenticators.
|
||||
func (c *jWTAuthenticators) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("jwtauthenticators").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a jWTAuthenticator and creates it. Returns the server's representation of the jWTAuthenticator, and an error, if there is any.
|
||||
func (c *jWTAuthenticators) Create(ctx context.Context, jWTAuthenticator *v1alpha1.JWTAuthenticator, opts v1.CreateOptions) (result *v1alpha1.JWTAuthenticator, err error) {
|
||||
result = &v1alpha1.JWTAuthenticator{}
|
||||
err = c.client.Post().
|
||||
Resource("jwtauthenticators").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(jWTAuthenticator).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a jWTAuthenticator and updates it. Returns the server's representation of the jWTAuthenticator, and an error, if there is any.
|
||||
func (c *jWTAuthenticators) Update(ctx context.Context, jWTAuthenticator *v1alpha1.JWTAuthenticator, opts v1.UpdateOptions) (result *v1alpha1.JWTAuthenticator, err error) {
|
||||
result = &v1alpha1.JWTAuthenticator{}
|
||||
err = c.client.Put().
|
||||
Resource("jwtauthenticators").
|
||||
Name(jWTAuthenticator.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(jWTAuthenticator).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *jWTAuthenticators) UpdateStatus(ctx context.Context, jWTAuthenticator *v1alpha1.JWTAuthenticator, opts v1.UpdateOptions) (result *v1alpha1.JWTAuthenticator, err error) {
|
||||
result = &v1alpha1.JWTAuthenticator{}
|
||||
err = c.client.Put().
|
||||
Resource("jwtauthenticators").
|
||||
Name(jWTAuthenticator.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(jWTAuthenticator).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the jWTAuthenticator and deletes it. Returns an error if one occurs.
|
||||
func (c *jWTAuthenticators) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("jwtauthenticators").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *jWTAuthenticators) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("jwtauthenticators").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched jWTAuthenticator.
|
||||
func (c *jWTAuthenticators) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.JWTAuthenticator, err error) {
|
||||
result = &v1alpha1.JWTAuthenticator{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("jwtauthenticators").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.25/apis/concierge/authentication/v1alpha1"
|
||||
scheme "go.pinniped.dev/generated/1.25/client/concierge/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// WebhookAuthenticatorsGetter has a method to return a WebhookAuthenticatorInterface.
|
||||
// A group's client should implement this interface.
|
||||
type WebhookAuthenticatorsGetter interface {
|
||||
WebhookAuthenticators() WebhookAuthenticatorInterface
|
||||
}
|
||||
|
||||
// WebhookAuthenticatorInterface has methods to work with WebhookAuthenticator resources.
|
||||
type WebhookAuthenticatorInterface interface {
|
||||
Create(ctx context.Context, webhookAuthenticator *v1alpha1.WebhookAuthenticator, opts v1.CreateOptions) (*v1alpha1.WebhookAuthenticator, error)
|
||||
Update(ctx context.Context, webhookAuthenticator *v1alpha1.WebhookAuthenticator, opts v1.UpdateOptions) (*v1alpha1.WebhookAuthenticator, error)
|
||||
UpdateStatus(ctx context.Context, webhookAuthenticator *v1alpha1.WebhookAuthenticator, opts v1.UpdateOptions) (*v1alpha1.WebhookAuthenticator, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.WebhookAuthenticator, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.WebhookAuthenticatorList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.WebhookAuthenticator, err error)
|
||||
WebhookAuthenticatorExpansion
|
||||
}
|
||||
|
||||
// webhookAuthenticators implements WebhookAuthenticatorInterface
|
||||
type webhookAuthenticators struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newWebhookAuthenticators returns a WebhookAuthenticators
|
||||
func newWebhookAuthenticators(c *AuthenticationV1alpha1Client) *webhookAuthenticators {
|
||||
return &webhookAuthenticators{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the webhookAuthenticator, and returns the corresponding webhookAuthenticator object, and an error if there is any.
|
||||
func (c *webhookAuthenticators) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.WebhookAuthenticator, err error) {
|
||||
result = &v1alpha1.WebhookAuthenticator{}
|
||||
err = c.client.Get().
|
||||
Resource("webhookauthenticators").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of WebhookAuthenticators that match those selectors.
|
||||
func (c *webhookAuthenticators) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.WebhookAuthenticatorList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.WebhookAuthenticatorList{}
|
||||
err = c.client.Get().
|
||||
Resource("webhookauthenticators").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested webhookAuthenticators.
|
||||
func (c *webhookAuthenticators) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("webhookauthenticators").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a webhookAuthenticator and creates it. Returns the server's representation of the webhookAuthenticator, and an error, if there is any.
|
||||
func (c *webhookAuthenticators) Create(ctx context.Context, webhookAuthenticator *v1alpha1.WebhookAuthenticator, opts v1.CreateOptions) (result *v1alpha1.WebhookAuthenticator, err error) {
|
||||
result = &v1alpha1.WebhookAuthenticator{}
|
||||
err = c.client.Post().
|
||||
Resource("webhookauthenticators").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(webhookAuthenticator).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a webhookAuthenticator and updates it. Returns the server's representation of the webhookAuthenticator, and an error, if there is any.
|
||||
func (c *webhookAuthenticators) Update(ctx context.Context, webhookAuthenticator *v1alpha1.WebhookAuthenticator, opts v1.UpdateOptions) (result *v1alpha1.WebhookAuthenticator, err error) {
|
||||
result = &v1alpha1.WebhookAuthenticator{}
|
||||
err = c.client.Put().
|
||||
Resource("webhookauthenticators").
|
||||
Name(webhookAuthenticator.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(webhookAuthenticator).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *webhookAuthenticators) UpdateStatus(ctx context.Context, webhookAuthenticator *v1alpha1.WebhookAuthenticator, opts v1.UpdateOptions) (result *v1alpha1.WebhookAuthenticator, err error) {
|
||||
result = &v1alpha1.WebhookAuthenticator{}
|
||||
err = c.client.Put().
|
||||
Resource("webhookauthenticators").
|
||||
Name(webhookAuthenticator.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(webhookAuthenticator).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the webhookAuthenticator and deletes it. Returns an error if one occurs.
|
||||
func (c *webhookAuthenticators) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("webhookauthenticators").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *webhookAuthenticators) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("webhookauthenticators").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched webhookAuthenticator.
|
||||
func (c *webhookAuthenticators) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.WebhookAuthenticator, err error) {
|
||||
result = &v1alpha1.WebhookAuthenticator{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("webhookauthenticators").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.25/apis/concierge/config/v1alpha1"
|
||||
scheme "go.pinniped.dev/generated/1.25/client/concierge/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// CredentialIssuersGetter has a method to return a CredentialIssuerInterface.
|
||||
// A group's client should implement this interface.
|
||||
type CredentialIssuersGetter interface {
|
||||
CredentialIssuers() CredentialIssuerInterface
|
||||
}
|
||||
|
||||
// CredentialIssuerInterface has methods to work with CredentialIssuer resources.
|
||||
type CredentialIssuerInterface interface {
|
||||
Create(ctx context.Context, credentialIssuer *v1alpha1.CredentialIssuer, opts v1.CreateOptions) (*v1alpha1.CredentialIssuer, error)
|
||||
Update(ctx context.Context, credentialIssuer *v1alpha1.CredentialIssuer, opts v1.UpdateOptions) (*v1alpha1.CredentialIssuer, error)
|
||||
UpdateStatus(ctx context.Context, credentialIssuer *v1alpha1.CredentialIssuer, opts v1.UpdateOptions) (*v1alpha1.CredentialIssuer, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.CredentialIssuer, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.CredentialIssuerList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.CredentialIssuer, err error)
|
||||
CredentialIssuerExpansion
|
||||
}
|
||||
|
||||
// credentialIssuers implements CredentialIssuerInterface
|
||||
type credentialIssuers struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newCredentialIssuers returns a CredentialIssuers
|
||||
func newCredentialIssuers(c *ConfigV1alpha1Client) *credentialIssuers {
|
||||
return &credentialIssuers{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the credentialIssuer, and returns the corresponding credentialIssuer object, and an error if there is any.
|
||||
func (c *credentialIssuers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.CredentialIssuer, err error) {
|
||||
result = &v1alpha1.CredentialIssuer{}
|
||||
err = c.client.Get().
|
||||
Resource("credentialissuers").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of CredentialIssuers that match those selectors.
|
||||
func (c *credentialIssuers) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.CredentialIssuerList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.CredentialIssuerList{}
|
||||
err = c.client.Get().
|
||||
Resource("credentialissuers").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested credentialIssuers.
|
||||
func (c *credentialIssuers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("credentialissuers").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a credentialIssuer and creates it. Returns the server's representation of the credentialIssuer, and an error, if there is any.
|
||||
func (c *credentialIssuers) Create(ctx context.Context, credentialIssuer *v1alpha1.CredentialIssuer, opts v1.CreateOptions) (result *v1alpha1.CredentialIssuer, err error) {
|
||||
result = &v1alpha1.CredentialIssuer{}
|
||||
err = c.client.Post().
|
||||
Resource("credentialissuers").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(credentialIssuer).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a credentialIssuer and updates it. Returns the server's representation of the credentialIssuer, and an error, if there is any.
|
||||
func (c *credentialIssuers) Update(ctx context.Context, credentialIssuer *v1alpha1.CredentialIssuer, opts v1.UpdateOptions) (result *v1alpha1.CredentialIssuer, err error) {
|
||||
result = &v1alpha1.CredentialIssuer{}
|
||||
err = c.client.Put().
|
||||
Resource("credentialissuers").
|
||||
Name(credentialIssuer.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(credentialIssuer).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *credentialIssuers) UpdateStatus(ctx context.Context, credentialIssuer *v1alpha1.CredentialIssuer, opts v1.UpdateOptions) (result *v1alpha1.CredentialIssuer, err error) {
|
||||
result = &v1alpha1.CredentialIssuer{}
|
||||
err = c.client.Put().
|
||||
Resource("credentialissuers").
|
||||
Name(credentialIssuer.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(credentialIssuer).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the credentialIssuer and deletes it. Returns an error if one occurs.
|
||||
func (c *credentialIssuers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("credentialissuers").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *credentialIssuers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("credentialissuers").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched credentialIssuer.
|
||||
func (c *credentialIssuers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.CredentialIssuer, err error) {
|
||||
result = &v1alpha1.CredentialIssuer{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("credentialissuers").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user