mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-01-24 06:32:26 +00:00
Compare commits
895 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
e86f3cc594 | ||
|
|
be6243c446 | ||
|
|
4263ee52f3 | ||
|
|
d6f1c91b9c | ||
|
|
105dc4a249 | ||
|
|
aa80c8d0b2 | ||
|
|
7c9bdfb96e | ||
|
|
84b3c0ad31 | ||
|
|
f2538689e7 | ||
|
|
66eb7735dd | ||
|
|
33edb7ea15 | ||
|
|
f3c9be07c0 | ||
|
|
0c131f11f8 | ||
|
|
dc86c9305c | ||
|
|
36ff99882f | ||
|
|
3ed4b1c132 | ||
|
|
8fad2c5127 | ||
|
|
a25749f087 | ||
|
|
248b1ef947 | ||
|
|
feef4bf508 | ||
|
|
aa70ff13f4 | ||
|
|
8a6c64095d | ||
|
|
ea40ffef06 | ||
|
|
44d9dc7440 | ||
|
|
fedb9812bd | ||
|
|
febbee347b | ||
|
|
a7edbd19ad | ||
|
|
c39b2fe03d | ||
|
|
1e23f94b36 | ||
|
|
106a480dad | ||
|
|
587e6fbd8a | ||
|
|
dc2275099a | ||
|
|
bcb9175aa8 | ||
|
|
dd71de9aa1 | ||
|
|
1c4fe6e406 | ||
|
|
697757ba8e | ||
|
|
774df36f41 | ||
|
|
a092b68f61 | ||
|
|
2587b0a8ad | ||
|
|
ff0e849730 | ||
|
|
c25d30ae88 | ||
|
|
51bc70a11b | ||
|
|
d26e54fd89 | ||
|
|
fc6bcc2f5b | ||
|
|
96f0ea2311 | ||
|
|
261f4a4e5b | ||
|
|
f1e933e7aa | ||
|
|
590f001f17 | ||
|
|
88e17c8f86 | ||
|
|
009470883e | ||
|
|
99ad89211a | ||
|
|
67841f8e27 | ||
|
|
eb5ed1490c | ||
|
|
46182f03b3 | ||
|
|
e37d1444c4 | ||
|
|
4b1577ab70 | ||
|
|
c235239ee7 | ||
|
|
f36298c542 | ||
|
|
c3afa55738 | ||
|
|
5c252fd083 | ||
|
|
dc195536d0 | ||
|
|
4d2bbac674 | ||
|
|
eca8914760 | ||
|
|
2aa30edb88 | ||
|
|
4f661aaa69 | ||
|
|
60cfa470b5 | ||
|
|
7a41b74ac1 | ||
|
|
b400648e56 | ||
|
|
d4bb12ec6d | ||
|
|
6fe55a3b48 | ||
|
|
3e72e40af2 | ||
|
|
2501d41d93 | ||
|
|
629f89d95b | ||
|
|
bb00587bd7 | ||
|
|
973886b683 | ||
|
|
4e30bc37f1 | ||
|
|
01c2377de0 | ||
|
|
0fab37c089 | ||
|
|
f7fd209f29 | ||
|
|
76a116641f | ||
|
|
1e0f7d8437 | ||
|
|
7295ec661f | ||
|
|
1a1aac7d09 | ||
|
|
ab2c2e30cb | ||
|
|
65b93f0822 | ||
|
|
da77fb1c3f | ||
|
|
d9ccb11092 | ||
|
|
e62f9b2b48 | ||
|
|
62d17155ec | ||
|
|
702d5bdc01 | ||
|
|
8ee08050cc | ||
|
|
1d81474d1b | ||
|
|
00e9b347db | ||
|
|
72fa369fc9 | ||
|
|
08abff1cae | ||
|
|
f476259bbf | ||
|
|
c87f091a44 | ||
|
|
d165899870 | ||
|
|
6c97600174 | ||
|
|
3e2f7456c4 | ||
|
|
ca9503e4c0 | ||
|
|
dc72a36cb1 | ||
|
|
18e2024e3f | ||
|
|
7d83e209c8 | ||
|
|
1bbfa4984d | ||
|
|
557dee06f0 | ||
|
|
c0bab69cd1 | ||
|
|
f480daf7dc | ||
|
|
cf56d808f2 | ||
|
|
b78e2c7ded | ||
|
|
9b3bcca15e | ||
|
|
f7f25a8815 | ||
|
|
94809ee396 | ||
|
|
851855d0ee | ||
|
|
2a6a0d2997 | ||
|
|
c6516af31e | ||
|
|
05098c68f6 | ||
|
|
a1dafcf45a | ||
|
|
0ee8ee80e1 | ||
|
|
436112252d | ||
|
|
8bd9b94d0a | ||
|
|
504f0dc26f | ||
|
|
c12402ee49 | ||
|
|
f09b3c2f72 | ||
|
|
90c1f6a8c9 | ||
|
|
844c169bdc | ||
|
|
c1930833eb | ||
|
|
f194594e5b | ||
|
|
5bb4adea30 | ||
|
|
376b83050a | ||
|
|
bee87395b1 | ||
|
|
21ee90ae41 | ||
|
|
d2f00d832e | ||
|
|
764064716f | ||
|
|
7b051ddc22 | ||
|
|
9aac96313a | ||
|
|
fcdb340623 | ||
|
|
4301eb6553 | ||
|
|
649bbc7c4f | ||
|
|
1eb6145080 | ||
|
|
00f6f39b1c | ||
|
|
d0f5c2c7ab | ||
|
|
1cfb83bca9 | ||
|
|
4ef705ae0f | ||
|
|
5e6f6a1c50 | ||
|
|
59c36ee972 | ||
|
|
ae3cfad10b | ||
|
|
21010b000e | ||
|
|
4d2b00f612 | ||
|
|
bab8b54ed8 | ||
|
|
4bd5db14b4 | ||
|
|
4a9136040c | ||
|
|
8b97414f3d | ||
|
|
1e8e9ecc98 | ||
|
|
2d8ab9ff5d | ||
|
|
17f66331ea | ||
|
|
6bf30bc6b5 | ||
|
|
f798777a3b | ||
|
|
6207121c03 | ||
|
|
248994dab6 | ||
|
|
a68db4f0db | ||
|
|
aad6b676b0 | ||
|
|
bf91b2045c | ||
|
|
fcf6ec6731 | ||
|
|
b377040144 | ||
|
|
c1328d9619 | ||
|
|
f918edd846 | ||
|
|
6b49cd7d28 | ||
|
|
afa3aa2232 | ||
|
|
1c59a41cc5 | ||
|
|
0626b22c70 | ||
|
|
fbbec507d1 | ||
|
|
a4b0416174 | ||
|
|
659f33dc55 | ||
|
|
20ddf553ce | ||
|
|
7483de5e90 | ||
|
|
9f1d6258a2 | ||
|
|
99b59a90b6 | ||
|
|
56bf9bad25 | ||
|
|
229b6a262e | ||
|
|
74d9fb863f | ||
|
|
e332fb505c | ||
|
|
dafde586ec | ||
|
|
cb101e4dbe | ||
|
|
6fdfee36fe | ||
|
|
0787301ddb | ||
|
|
2af510a3ee | ||
|
|
fdeca2c026 | ||
|
|
23fd15f840 | ||
|
|
06b7d302a2 | ||
|
|
b70db9dc03 | ||
|
|
d4ac69d88e | ||
|
|
59c2295dfd | ||
|
|
4eb9a09385 | ||
|
|
db2d7c8c50 | ||
|
|
2ebf9d3d00 | ||
|
|
67de14a3b8 | ||
|
|
a40c88ebf3 | ||
|
|
23129da3e2 | ||
|
|
59402bca7b | ||
|
|
c3405095b2 | ||
|
|
2181418cc5 | ||
|
|
e0235ed190 | ||
|
|
02e41baa47 | ||
|
|
91ef68992c | ||
|
|
43964ff7a2 | ||
|
|
19c4acf391 | ||
|
|
ed502949dd | ||
|
|
a0c259ffbc | ||
|
|
d6d66faae3 | ||
|
|
15c84fcc94 | ||
|
|
1438f06c12 | ||
|
|
ca5bb2170c | ||
|
|
05a2fd97f8 | ||
|
|
dedd51df91 | ||
|
|
290676e4d1 | ||
|
|
8725ab4caa | ||
|
|
3891f90f43 | ||
|
|
9f17ba5ae4 | ||
|
|
81d42cb3b9 | ||
|
|
dfef9f470f | ||
|
|
f5da417450 | ||
|
|
a888083c50 | ||
|
|
99cfc4fbce | ||
|
|
fcceeed9fa | ||
|
|
4cf0e46c38 | ||
|
|
34eff2a2f9 | ||
|
|
e82cb2c7ba | ||
|
|
0711093ccd | ||
|
|
15d0006841 | ||
|
|
282b949c24 | ||
|
|
005dbf3aa8 | ||
|
|
a1dcba4731 | ||
|
|
2a62beeb5f | ||
|
|
242fa8afb2 | ||
|
|
e3ed722252 | ||
|
|
9a16dc28b7 | ||
|
|
de86809b69 | ||
|
|
9420bfde5b | ||
|
|
adb460b644 | ||
|
|
06b47a5792 | ||
|
|
ca2dd2d476 | ||
|
|
60f82d2a55 | ||
|
|
414ff503ef | ||
|
|
4ec5766ea9 | ||
|
|
b7c26c43ca | ||
|
|
4b2ed52f44 | ||
|
|
f381c92f0b | ||
|
|
3a303cc8fb | ||
|
|
09724cfa71 | ||
|
|
d74c2a6e3f | ||
|
|
0f9352db3b | ||
|
|
afec420ce6 | ||
|
|
d5e3ad9da0 | ||
|
|
0f103ed2a4 | ||
|
|
d62d6a1f27 | ||
|
|
a4ad5d68a9 | ||
|
|
30c0fd479e | ||
|
|
756966c55b | ||
|
|
288e092d2e | ||
|
|
72745cd8fe | ||
|
|
8060e82745 | ||
|
|
373713f7e0 | ||
|
|
66401b42d8 | ||
|
|
2d5943b21a | ||
|
|
920b519ebf | ||
|
|
bf1c02d328 | ||
|
|
6e9023e090 | ||
|
|
1b7a26d932 | ||
|
|
cb4b63f8b3 | ||
|
|
8eb15a924f | ||
|
|
6a610a9d51 | ||
|
|
821a893f70 | ||
|
|
afcd80de37 | ||
|
|
edc327ba33 | ||
|
|
90e8cc86c2 | ||
|
|
9ab7c39d56 | ||
|
|
207bac9452 | ||
|
|
199562fd05 | ||
|
|
3a969a83b7 | ||
|
|
aab1ee9edc | ||
|
|
080c75efe6 | ||
|
|
7e6dadb508 | ||
|
|
19c3f2cb04 | ||
|
|
842f14af4c | ||
|
|
05c258026a | ||
|
|
1bb38911dc | ||
|
|
ec943fffdc | ||
|
|
ae1d182b30 | ||
|
|
82c056b955 | ||
|
|
7acc2aa383 | ||
|
|
4e6a39ed11 | ||
|
|
d587c6b10e | ||
|
|
51c5a05ea7 | ||
|
|
f0cac8c5d3 | ||
|
|
76f3430c68 | ||
|
|
0e4f7082b0 | ||
|
|
66f005f275 | ||
|
|
bc10d500b7 | ||
|
|
7c7f0fdae3 | ||
|
|
4fa901c017 | ||
|
|
fd11c37825 | ||
|
|
f1b82dbf1f | ||
|
|
8891455e10 | ||
|
|
5540f25932 | ||
|
|
ee9bbbe50b | ||
|
|
e013c90993 | ||
|
|
fa85be4b94 | ||
|
|
276cba08ee | ||
|
|
0e312c88c1 | ||
|
|
00301e3642 | ||
|
|
a2be4b7b5e | ||
|
|
b5a509f27f | ||
|
|
6b722a14c8 | ||
|
|
dd0c805b09 | ||
|
|
6c35490cfb | ||
|
|
19a04ea804 | ||
|
|
a9a63914b2 | ||
|
|
b7d1c3f5f6 | ||
|
|
a8ccdbc833 | ||
|
|
decf1cf537 | ||
|
|
e5cfa521da | ||
|
|
dd80627dfa | ||
|
|
f79c844c71 | ||
|
|
cb550dfed0 | ||
|
|
602623a0ba | ||
|
|
6d7646c0a2 | ||
|
|
51518aeb03 | ||
|
|
f3e710c814 | ||
|
|
b132b14982 | ||
|
|
6cd45fa81c | ||
|
|
95e4b8fcdf | ||
|
|
b4cd64e999 | ||
|
|
82dbb93e2c | ||
|
|
b7e12334d6 | ||
|
|
a39eac6f1b | ||
|
|
418ec2a01f | ||
|
|
0380a9ce33 | ||
|
|
ed338d1455 | ||
|
|
10699314d4 | ||
|
|
1f7b6133cd | ||
|
|
3c0ed4d5e3 | ||
|
|
e38f0824dc | ||
|
|
a7d2c50550 | ||
|
|
9fee276214 | ||
|
|
ef7c7d879b | ||
|
|
ea64444c8b | ||
|
|
84308f3518 | ||
|
|
88bcdbadce | ||
|
|
b50d1384dc | ||
|
|
b3457271a9 | ||
|
|
fc6de7e86c | ||
|
|
6b87bc3fa9 | ||
|
|
238df12920 | ||
|
|
f7f32f2f98 | ||
|
|
1f8ac0ff23 | ||
|
|
75ff3efb59 | ||
|
|
f0f9efa277 | ||
|
|
4ab2ed10f5 | ||
|
|
53031ad8d4 | ||
|
|
ce1ad010e9 | ||
|
|
5d6dbe1fc3 | ||
|
|
774504e209 | ||
|
|
2275cd5985 | ||
|
|
3b520d6e93 | ||
|
|
80e1fee208 | ||
|
|
011d6ba71b | ||
|
|
9296d95084 | ||
|
|
c6463831ac | ||
|
|
247ac10215 | ||
|
|
678be9902a | ||
|
|
bafd578866 | ||
|
|
8ac2dc2e9e | ||
|
|
5689bf621c | ||
|
|
ae1cf53dcf | ||
|
|
ced019291b | ||
|
|
b483409c63 | ||
|
|
1fe6f2eff9 | ||
|
|
07f8c327e4 | ||
|
|
e9fa98edfb | ||
|
|
6c102f09f2 | ||
|
|
ea9d06c819 | ||
|
|
05fb8b75ef | ||
|
|
ee2aa9ce50 | ||
|
|
8b1bf8d4f9 | ||
|
|
ca9560effb | ||
|
|
6b64a8a9c6 | ||
|
|
dd3c1ac3cf | ||
|
|
16c8911dfd | ||
|
|
8ea9ba8860 | ||
|
|
1d8decfdad | ||
|
|
57431ce6c2 | ||
|
|
01723e0d12 | ||
|
|
8733a24ebf | ||
|
|
58b4ecc0aa | ||
|
|
b43b8439c4 | ||
|
|
f2747ef4e7 | ||
|
|
e3d8c71f97 | ||
|
|
0ace5cf477 | ||
|
|
6364ac9ac7 | ||
|
|
e89daadfcf | ||
|
|
eee737186f | ||
|
|
c5b54ec27e | ||
|
|
2ad43789cc | ||
|
|
38a90fa01e | ||
|
|
037fa65c63 | ||
|
|
de68594fd6 | ||
|
|
6327f51f5b | ||
|
|
781ee82b9d | ||
|
|
34d02466d9 | ||
|
|
8dd34d9ea9 | ||
|
|
3c0bad9ea2 | ||
|
|
2bf11ffde1 | ||
|
|
bb9cb739c6 | ||
|
|
cc8d637715 | ||
|
|
eafc9ad78c | ||
|
|
c1719c8f1a | ||
|
|
d3fb567fdb | ||
|
|
8b1e5aa320 | ||
|
|
37e654faa0 | ||
|
|
7c73b5e3df | ||
|
|
6a9661b374 | ||
|
|
6429164852 | ||
|
|
fa68cbbe4e | ||
|
|
f323690049 | ||
|
|
02ffff01d5 | ||
|
|
2cdeb85cd6 | ||
|
|
6ea7c48ae9 | ||
|
|
65682aa60d | ||
|
|
bb1737daec | ||
|
|
fef494949f | ||
|
|
0a15d488c8 | ||
|
|
e69eb46911 | ||
|
|
8f8db3f542 | ||
|
|
8923704f3c | ||
|
|
ba2d122308 | ||
|
|
938bea9910 | ||
|
|
8719c7a2db | ||
|
|
16fa12f455 | ||
|
|
555b1c80e3 | ||
|
|
a12a5f387a | ||
|
|
c087e33b86 | ||
|
|
49c468f00a | ||
|
|
b7f79f0adc | ||
|
|
2756a106a9 | ||
|
|
efffa0def2 | ||
|
|
6beb1c135c | ||
|
|
24ab2e85e5 | ||
|
|
c6749560b5 | ||
|
|
a0160b8e47 | ||
|
|
2f9df8c8e2 | ||
|
|
0076f1251c | ||
|
|
fe911a7b7a | ||
|
|
bdd79a9984 | ||
|
|
513f43f465 | ||
|
|
f5116cddb4 | ||
|
|
bbe10004b4 | ||
|
|
e9252a9ee3 | ||
|
|
875b0739aa | ||
|
|
7f56115abc | ||
|
|
5a29f19faa | ||
|
|
ae45e158a3 | ||
|
|
81c44528ba | ||
|
|
9cfb6baaf2 | ||
|
|
1de902fe8d | ||
|
|
7ac141ba08 | ||
|
|
fd7838ef2c | ||
|
|
7ffb1de1c9 | ||
|
|
e4daa5a924 | ||
|
|
147022234e | ||
|
|
2054708c53 | ||
|
|
3fe3cf71ab | ||
|
|
7787885463 | ||
|
|
f320980006 | ||
|
|
7e0a3c114d | ||
|
|
a86d7d27c1 | ||
|
|
b00cf65732 | ||
|
|
69364b2183 | ||
|
|
6b3f175885 | ||
|
|
cb7aa561cf | ||
|
|
253869ad46 | ||
|
|
109da32164 | ||
|
|
b69c0ac746 | ||
|
|
4cc61c038e | ||
|
|
ae725feee9 | ||
|
|
49a57576dd | ||
|
|
b94b9ad2d8 | ||
|
|
b28e416d0c | ||
|
|
e13f4a7f29 | ||
|
|
f96cbea521 | ||
|
|
d4fb9be250 | ||
|
|
41cdb6bbaf | ||
|
|
f43b6f04dc | ||
|
|
791b785dea | ||
|
|
d7849c793c | ||
|
|
5568372bb9 | ||
|
|
cba26c92f5 | ||
|
|
47de5118f2 | ||
|
|
81f3acfa38 | ||
|
|
aac48fc308 | ||
|
|
5635d6c862 | ||
|
|
e9d0ac5110 | ||
|
|
7b36c8ab54 | ||
|
|
e04e5e0185 | ||
|
|
67d3b5fb82 | ||
|
|
c31a0e37bf | ||
|
|
ab01ce41ed | ||
|
|
1e6b8a0be0 | ||
|
|
dba0de88f3 | ||
|
|
0cdbb710d2 | ||
|
|
75f024cb19 | ||
|
|
32e4e0d835 | ||
|
|
7c85a511a2 | ||
|
|
6be92f92fb | ||
|
|
7277d00e1a | ||
|
|
29eb3dd384 | ||
|
|
501ec25f5a | ||
|
|
6ae0c0bd22 | ||
|
|
d9c1b104cd | ||
|
|
fbf4284866 | ||
|
|
06126544bd | ||
|
|
e9c93305b9 | ||
|
|
3197156aa1 | ||
|
|
f377292ffe | ||
|
|
ca6a60b534 | ||
|
|
99755624e8 | ||
|
|
96e4442181 | ||
|
|
bc5eb3cf57 | ||
|
|
afb032f8f9 | ||
|
|
c86a615713 | ||
|
|
c494add2ce | ||
|
|
f94b1e70fc | ||
|
|
42ed11a5cb | ||
|
|
a7c6c43112 | ||
|
|
17d6def081 | ||
|
|
73e7aeca6e | ||
|
|
305f3f6abe | ||
|
|
e4d6a72087 | ||
|
|
85e5970d6e | ||
|
|
424e7406af | ||
|
|
3e148b629d | ||
|
|
545df755b8 | ||
|
|
e6cb439d9c | ||
|
|
879b840ee2 | ||
|
|
773fad9701 | ||
|
|
fbc3334e8c | ||
|
|
0baae51425 | ||
|
|
ad7df9f7d1 | ||
|
|
460fbbacc7 | ||
|
|
d67238d46f | ||
|
|
5ec1ee086d | ||
|
|
c0f1e408da | ||
|
|
0a63dd104d | ||
|
|
d34f297b37 | ||
|
|
e0591500ce | ||
|
|
c43193a0c8 | ||
|
|
0896e7164a | ||
|
|
070819754f | ||
|
|
56d7dee25d | ||
|
|
9d21bcacb6 | ||
|
|
d0781c42dc | ||
|
|
00567645d0 | ||
|
|
92b9d68863 | ||
|
|
1f2d2bff71 | ||
|
|
3bdb380a1a | ||
|
|
1ac2215724 | ||
|
|
9d92f21638 | ||
|
|
9838a7cb6d | ||
|
|
0d709ea8db | ||
|
|
9a21cb9cc7 | ||
|
|
6424f45c19 | ||
|
|
51b1dbd2af | ||
|
|
9a8df262d9 | ||
|
|
9c2df74e54 | ||
|
|
581f671643 | ||
|
|
b99da0c805 | ||
|
|
8a961bfa21 | ||
|
|
cd86d57763 | ||
|
|
2753b468fd | ||
|
|
be1915d2d7 | ||
|
|
42ef46b74e | ||
|
|
79d0e74056 | ||
|
|
8de4524428 | ||
|
|
8f71f965b9 | ||
|
|
0e3641bba2 | ||
|
|
e3aa495e0b | ||
|
|
0edee37498 | ||
|
|
7968ed6d69 | ||
|
|
44edba6f75 | ||
|
|
0c7e95539f | ||
|
|
8938990c04 | ||
|
|
57a07a498f | ||
|
|
136bc7ac09 | ||
|
|
a1efcefdce | ||
|
|
5dbf05c31d | ||
|
|
af9612e98e | ||
|
|
b31a893caf | ||
|
|
c8bc192e0b | ||
|
|
def2b35e6e | ||
|
|
14b1b7c862 | ||
|
|
c8b90df6f1 | ||
|
|
d0bbfca831 | ||
|
|
fe5d037600 | ||
|
|
5fe94c4e2b | ||
|
|
1d8310ed44 | ||
|
|
c79f8c89d7 | ||
|
|
7c0c3211d1 | ||
|
|
0ef98f0558 | ||
|
|
94bee9e882 | ||
|
|
da135d9958 | ||
|
|
206a16f9e3 | ||
|
|
e048859afd | ||
|
|
8c081c50d4 | ||
|
|
0dc7dfcb50 | ||
|
|
c9b61ef010 | ||
|
|
59fef0c1b2 | ||
|
|
23d8a279c4 | ||
|
|
349039ff5d | ||
|
|
a72155a57f | ||
|
|
41f8663dcd | ||
|
|
84007cb1ec | ||
|
|
265c51b8aa | ||
|
|
f50ab87b53 | ||
|
|
4c5d041c21 | ||
|
|
df9a06ddfe | ||
|
|
55aaf33d94 | ||
|
|
8ea339139e | ||
|
|
e950e7e001 | ||
|
|
68339f3acb | ||
|
|
f4660f0250 | ||
|
|
bf3cda54ba | ||
|
|
1b4194373b | ||
|
|
241093bb96 | ||
|
|
ccef7bd1bc | ||
|
|
e2db152c6c | ||
|
|
5c490e999d | ||
|
|
a11e1527f0 | ||
|
|
6ac11a554a | ||
|
|
42dd8d1d9d | ||
|
|
722f00e485 | ||
|
|
67c328f4d0 | ||
|
|
146e61ed03 | ||
|
|
6718a32fe4 | ||
|
|
2af6f4cdf6 | ||
|
|
60bdd3eccd | ||
|
|
c1b93179ff | ||
|
|
7387f675e2 | ||
|
|
f0a43e0402 | ||
|
|
c6b0820438 | ||
|
|
f86c46e160 | ||
|
|
eed0c9d5b0 | ||
|
|
e38a27d93d | ||
|
|
b0904c2e99 | ||
|
|
bec5fe85cc | ||
|
|
5bc4e678bf | ||
|
|
90e7343fb5 | ||
|
|
5c0d67dc50 | ||
|
|
b6512bcbb6 | ||
|
|
097e6d5340 | ||
|
|
a45a537cdb | ||
|
|
0467e5c1d5 | ||
|
|
5c1fa6d52c | ||
|
|
337459feb0 | ||
|
|
590e2d18f7 | ||
|
|
ef36b454ba | ||
|
|
4465810ff8 | ||
|
|
d301bc60b7 | ||
|
|
6307a3212b | ||
|
|
92a082b0f7 | ||
|
|
15627e7803 | ||
|
|
a70ce9cef7 | ||
|
|
eab6f0d713 | ||
|
|
cc96f85ec7 | ||
|
|
6557197bae | ||
|
|
ed351938d4 | ||
|
|
718cf234b8 | ||
|
|
159b2d50eb | ||
|
|
bc8aebeffe | ||
|
|
135eab037e | ||
|
|
714aa59a34 | ||
|
|
33fe2bcff4 | ||
|
|
665b921d63 | ||
|
|
b99634764f | ||
|
|
4a8cd180f8 | ||
|
|
6c7d3e62dd | ||
|
|
c4b5476088 | ||
|
|
61835e9f08 | ||
|
|
d49b011d65 | ||
|
|
f881bbb137 | ||
|
|
f55d56bf4a | ||
|
|
ffc49d96b3 | ||
|
|
8a40dda3ab | ||
|
|
ab0682917a | ||
|
|
ed15927d90 | ||
|
|
e43cf81c38 | ||
|
|
eb08a9f91f | ||
|
|
9423ff5e48 | ||
|
|
df580fcb39 | ||
|
|
ca58911cc2 | ||
|
|
6afc48849a | ||
|
|
5569b114ba | ||
|
|
c8bfe780c7 | ||
|
|
b79a2ccf7c | ||
|
|
27d0c58319 | ||
|
|
ffadca7f68 | ||
|
|
62c086a725 | ||
|
|
99781443b0 | ||
|
|
f498cb3918 | ||
|
|
e8482ab9e9 | ||
|
|
868ff9ed2b | ||
|
|
42acf8dcce | ||
|
|
1c7e7048a8 | ||
|
|
73e4d3144b | ||
|
|
1a633adde6 | ||
|
|
09bd51f481 | ||
|
|
084c3114f4 | ||
|
|
47639340ec | ||
|
|
fd14a5794e | ||
|
|
a4447fa606 | ||
|
|
f18d7310a8 | ||
|
|
28251f8b92 | ||
|
|
50b54580de | ||
|
|
d88883328a | ||
|
|
ca6687d428 | ||
|
|
848d83c496 | ||
|
|
5bd73fc10d | ||
|
|
40e548ebf0 | ||
|
|
64b0e69430 | ||
|
|
daec673b81 | ||
|
|
01d6bdb497 | ||
|
|
216fce70aa | ||
|
|
5939ce8cc6 | ||
|
|
9471ed2d09 | ||
|
|
0d31e955ae | ||
|
|
5697bb2915 | ||
|
|
ca7b27de3f | ||
|
|
867468ee66 | ||
|
|
4b4a4ad592 | ||
|
|
b341e52214 | ||
|
|
1e8e7b948e | ||
|
|
1bc13e94f7 | ||
|
|
9db87132b1 | ||
|
|
9992855cb8 | ||
|
|
23dce42a94 | ||
|
|
edf92303ae | ||
|
|
719cd75f64 | ||
|
|
ceb9973657 | ||
|
|
cf82cf996e | ||
|
|
5c702738cf | ||
|
|
485b2271f0 | ||
|
|
dce9409ccc | ||
|
|
d5ce48bd4b | ||
|
|
492dfa84d8 | ||
|
|
e4fddc3596 | ||
|
|
ad9d9ce1a5 | ||
|
|
904a60f04a | ||
|
|
bf3b4bfca7 | ||
|
|
560ee45b50 | ||
|
|
d2794114f4 | ||
|
|
e303a45dd1 | ||
|
|
c47bc74ad0 | ||
|
|
a728822993 | ||
|
|
5cd4d47f9e | ||
|
|
2832e7c45e | ||
|
|
04bb45947d | ||
|
|
f2c9b67854 | ||
|
|
e05ae08b77 | ||
|
|
1ab1fd4c50 | ||
|
|
d17dd65d0f | ||
|
|
a832bb641b | ||
|
|
18da164130 | ||
|
|
07b1a144b3 | ||
|
|
4c3f304ba5 | ||
|
|
c7445def21 | ||
|
|
d23f6690af | ||
|
|
0a8264c9c8 | ||
|
|
8c7cda84e1 | ||
|
|
6767a07a8d | ||
|
|
6908c2ab65 | ||
|
|
80b65619bf | ||
|
|
2aa87dd069 | ||
|
|
bb99d269eb | ||
|
|
84a1f2a771 | ||
|
|
e67838932d | ||
|
|
50e4d6db6c | ||
|
|
bcf070cb73 | ||
|
|
4ce96634c6 | ||
|
|
c356754aaa | ||
|
|
75a130bafd | ||
|
|
1d6e51d14a | ||
|
|
da9432b5b2 | ||
|
|
d4971ef2da | ||
|
|
bdb7f80571 | ||
|
|
c7299f4daf | ||
|
|
659224a207 |
36
.github/ISSUE_TEMPLATE/add_new_k8s_version.md
vendored
Normal file
36
.github/ISSUE_TEMPLATE/add_new_k8s_version.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: Add new K8s version
|
||||
about: 'Checklist for maintainers to add new K8s minor version'
|
||||
title: 'Add new K8s version vX.X'
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Note: Please update the issue title to include the new Kubernetes version number. -->
|
||||
|
||||
# Adding a new Kubernetes Version
|
||||
|
||||
## `pinniped's ci branch`
|
||||
|
||||
- [ ] Update `dockerfile-builders` pipeline
|
||||
- [ ] Update `pull-requests` pipeline
|
||||
- [ ] Update `main` pipeline
|
||||
|
||||
## `pinniped`
|
||||
|
||||
- [ ] Bump all golang dependencies (especially the `k8s.io` dependencies to use the new minor version).
|
||||
- [ ] Be sure to verify that everything compiles and unit tests pass locally. This is probably a good starting point.
|
||||
```shell
|
||||
./hack/update-go-mod/update-go-mod.sh
|
||||
./hack/module.sh unit
|
||||
./hack/prepare-for-integration-tests.sh
|
||||
```
|
||||
- [ ] Log in to github as pinniped-ci-bot, then go to [this page](https://github.com/pinniped-ci-bot?tab=packages) and change the settings for the new `k8s-code-generator-1.*` image to be publicly visible
|
||||
- [ ] Add the new K8s version to `hack/lib/kube-versions.txt` and run code generation.
|
||||
|
||||
## General Tasks
|
||||
|
||||
- [ ] Consider dropping support for any older versions of Kubernetes
|
||||
- [ ] Create stories or chores to take advantage of features in the new Kubernetes version
|
||||
- [ ] Close this issue
|
||||
31
.github/ISSUE_TEMPLATE/release_checklist.md
vendored
Normal file
31
.github/ISSUE_TEMPLATE/release_checklist.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Release checklist
|
||||
about: Checklist for maintainers to prepare for an upcoming release
|
||||
title: 'Release checklist for vX.X.X'
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Note: Please update the issue title to include the planned release's version number. -->
|
||||
|
||||
# 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)
|
||||
- [ ] 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. Try using `hack/update-go-mod/update-majors.sh`.
|
||||
- [ ] 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)
|
||||
- [ ] 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.
|
||||
- [ ] 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
|
||||
- [ ] 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
|
||||
- [ ] 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
|
||||
134
.github/dependabot.yml
vendored
134
.github/dependabot.yml
vendored
@@ -2,11 +2,6 @@
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gomod"
|
||||
open-pull-requests-limit: 100
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "gomod"
|
||||
open-pull-requests-limit: 2
|
||||
@@ -14,12 +9,137 @@ updates:
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "docker"
|
||||
# Use dependabot to automate major-only dependency bumps
|
||||
- package-ecosystem: "gomod"
|
||||
open-pull-requests-limit: 2 # Not sure why there would ever be more than 1, just would not want to hide anything
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
# group all major dependency bumps together so there's only one pull request
|
||||
groups:
|
||||
go-modules:
|
||||
patterns:
|
||||
- "*"
|
||||
update-types:
|
||||
- "major"
|
||||
ignore:
|
||||
# For all packages, ignore all minor and patch updates
|
||||
- dependency-name: "*"
|
||||
update-types:
|
||||
- "version-update:semver-minor"
|
||||
- "version-update:semver-patch"
|
||||
|
||||
# Our own CI job is responsible for updating this Docker file now.
|
||||
# - package-ecosystem: "docker"
|
||||
# directory: "/"
|
||||
# schedule:
|
||||
# interval: "daily"
|
||||
|
||||
# Our own CI job is responsible for updating this Docker file now.
|
||||
# - package-ecosystem: "docker"
|
||||
# directory: "/hack" # this should keep the FIPS dockerfile updated per https://github.com/dependabot/feedback/issues/145#issuecomment-414738498
|
||||
# schedule:
|
||||
# interval: "daily"
|
||||
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/hack" # this should keep the FIPS dockerfile updated per https://github.com/dependabot/feedback/issues/145#issuecomment-414738498
|
||||
directory: "/dockerfiles/code-coverage-uploader/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/crane/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/deployment-yaml-formatter/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/eks-deployer/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/gh-cli/"
|
||||
open-pull-requests-limit: 100
|
||||
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
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/integration-test-runner-beta/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/k8s-app-deployer/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/k8s-code-generator/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/pool-trigger-resource/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/test-bitnami-ldap/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/test-cfssl/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/test-dex/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/test-forward-proxy/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/dockerfiles/test-kubectl/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/pipelines/shared-helpers/test-binaries-image/"
|
||||
open-pull-requests-limit: 100
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: ci
|
||||
|
||||
16
.github/workflows/codeql-analysis.yml
vendored
16
.github/workflows/codeql-analysis.yml
vendored
@@ -29,11 +29,13 @@ jobs:
|
||||
language: [ 'go', 'javascript' ]
|
||||
|
||||
steps:
|
||||
# Checkout our repository.
|
||||
# See https://github.com/actions/checkout for documentation.
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -43,10 +45,16 @@ jobs:
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# Install Go.
|
||||
# See https://github.com/actions/setup-go?tab=readme-ov-file#getting-go-version-from-the-gomod-file.
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -59,6 +67,6 @@ jobs:
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
# https://github.com/golangci/golangci-lint#config-file
|
||||
# https://golangci-lint.run/usage/configuration/
|
||||
run:
|
||||
deadline: 1m
|
||||
skip-dirs:
|
||||
- generated
|
||||
timeout: 1m
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
@@ -22,7 +20,6 @@ linters:
|
||||
# - depguard
|
||||
- dogsled
|
||||
- exhaustive
|
||||
- exportloopref
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
@@ -41,18 +38,32 @@ linters:
|
||||
- nolintlint
|
||||
- prealloc
|
||||
- rowserrcheck
|
||||
- exportloopref
|
||||
- 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:
|
||||
@@ -76,3 +87,76 @@ linters-settings:
|
||||
# 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:]'
|
||||
|
||||
@@ -152,15 +152,43 @@ go build -o pinniped ./cmd/pinniped
|
||||
|
||||
To destroy the local Kubernetes cluster, run `./hack/kind-down.sh`.
|
||||
|
||||
#### Using GoLand to Run an Integration Test
|
||||
|
||||
It can sometimes be convenient to use GoLand to run an integration test. For example, this allows using the
|
||||
GoLand debugger to debug the test itself (not the server, since that it running in-cluster).
|
||||
|
||||
Note that the output of `hack/prepare-for-integration-tests.sh` says:
|
||||
|
||||
```bash
|
||||
# Using GoLand? Paste the result of this command into GoLand's run configuration "Environment".
|
||||
# hack/integration-test-env-goland.sh | pbcopy
|
||||
```
|
||||
|
||||
After using `hack/prepare-for-integration-tests.sh`, run `hack/integration-test-env-goland.sh | pbcopy` as instructed. Then:
|
||||
|
||||
1. Select and run an integration test within GoLand. It will fail complaining about missing env vars.
|
||||
1. Pull down the menu that shows the name of the test which you just ran in the previous step, and choose "Edit Configurations...".
|
||||
1. In the "Environment" text box for the run configuration of the integration test that you just ran,
|
||||
paste the results of `hack/integration-test-env-goland.sh | pbcopy`.
|
||||
1. Apply, and then run the integration test again. This time the test will use the environment variables provided.
|
||||
|
||||
Note that if you run `hack/prepare-for-integration-tests.sh` again, then you may need to repeat these steps.
|
||||
Each run of `hack/prepare-for-integration-tests.sh` can result in different values for some of the env vars.
|
||||
|
||||
### Observing Tests on the Continuous Integration Environment
|
||||
|
||||
[CI](https://hush-house.pivotal.io/teams/tanzu-user-auth/pipelines/pinniped-pull-requests)
|
||||
[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
|
||||
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
|
||||
will appear to view the details of each check.
|
||||
|
||||
## 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.
|
||||
|
||||
## Documentation
|
||||
|
||||
Any pull request which adds a new feature or changes the behavior of any feature which was previously documented
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ARG BUILD_IMAGE=golang:1.21.5@sha256:2ff79bcdaff74368a9fdcb06f6599e54a71caf520fd2357a55feddd504bcaffb
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:91ca4720011393f4d4cab3a01fa5814ee2714b7d40e6c74f2505f74168398ca9
|
||||
ARG BUILD_IMAGE=golang:1.23.4@sha256:574185e5c6b9d09873f455a7c205ea0514bfd99738c5dc7750196403a44ed4b7
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:6cd937e9155bdfd805d1b94e037f9d6a899603306030936a3b11680af0c2ed58
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
|
||||
| Maintainer | GitHub ID | Affiliation |
|
||||
|-----------------|-----------------------------------------------------------|------------------------------------------|
|
||||
| Ben Petersen | [benjaminapetersen](https://github.com/benjaminapetersen) | [VMware](https://www.github.com/vmware/) |
|
||||
| Ryan Richard | [cfryanr](https://github.com/cfryanr) | [VMware](https://www.github.com/vmware/) |
|
||||
| Joshua T. Casey | [joshuatcasey](https://github.com/joshuatcasey) | [VMware](https://www.github.com/vmware/) |
|
||||
|
||||
## Emeritus Maintainers
|
||||
|
||||
| Maintainer | GitHub ID |
|
||||
|-------------------|---------------------------------------------------------|
|
||||
| Andrew Keesler | [ankeesler](https://github.com/ankeesler) |
|
||||
| Anjali Telang | [anjaltelang](https://github.com/anjaltelang) |
|
||||
| Margo Crawford | [margocrawf](https://github.com/margocrawf) |
|
||||
| Matt Moyer | [mattmoyer](https://github.com/mattmoyer) |
|
||||
| Mo Khan | [enj](https://github.com/enj) |
|
||||
| Pablo Schuhmacher | [pabloschuhmacher](https://github.com/pabloschuhmacher) |
|
||||
| Maintainer | GitHub ID |
|
||||
|-------------------|-----------------------------------------------------------|
|
||||
| Andrew Keesler | [ankeesler](https://github.com/ankeesler) |
|
||||
| Anjali Telang | [anjaltelang](https://github.com/anjaltelang) |
|
||||
| Ben Petersen | [benjaminapetersen](https://github.com/benjaminapetersen) |
|
||||
| Margo Crawford | [margocrawf](https://github.com/margocrawf) |
|
||||
| Matt Moyer | [mattmoyer](https://github.com/mattmoyer) |
|
||||
| Mo Khan | [enj](https://github.com/enj) |
|
||||
| Pablo Schuhmacher | [pabloschuhmacher](https://github.com/pabloschuhmacher) |
|
||||
|
||||
@@ -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-2022 the Pinniped contributors. All Rights Reserved.
|
||||
Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
|
||||
17
ROADMAP.md
17
ROADMAP.md
@@ -5,8 +5,6 @@
|
||||
This document provides a high-level overview of the next big features the maintainers are planning to work on. This
|
||||
should serve as a reference point for Pinniped users and contributors to understand where the project is heading, and
|
||||
help determine if a contribution could be conflicting with a longer term plan.
|
||||
The [Pinniped project backlog](https://github.com/orgs/vmware-tanzu/projects/43/) is prioritized based on this roadmap,
|
||||
and it provides a more granular view of what the maintainers are working on a day-to-day basis.
|
||||
|
||||
### How to help
|
||||
|
||||
@@ -23,19 +21,6 @@ a [proposal](https://github.com/vmware-tanzu/pinniped/tree/main/proposals) in ou
|
||||
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.
|
||||
|
||||
### Current Roadmap
|
||||
|
||||
The following table includes the current roadmap for Pinniped. Please take the timelines and dates as proposals and
|
||||
goals. Priorities and requirements change based on community feedback, roadblocks encountered, community contributions,
|
||||
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.
|
||||
|
||||
Last Updated: Sept 2022
|
||||
|Theme|Description|Timeline|
|
||||
|--|--|--|
|
||||
|Improving Usability|Dynamic Oauth Client Support for integrating with UI/Dashboards |Sept/Oct 2022|
|
||||
|Improving Usability|Support for custom claim mappings in OIDCIdentityProvider |Q4 2022|
|
||||
|Improving Usability|Support for Multiple Identity Providers |Q4 2022|
|
||||
|Improving Security Posture|Support Audit logging of security events related to Authentication |Q4 2022|
|
||||
|Improving Security Posture|Session Management |2022/2023|
|
||||
|Improving Security Posture|Secrets Rotation and Management |2022/2023|
|
||||
|
||||
9
SCOPE.md
9
SCOPE.md
@@ -21,12 +21,3 @@ The following items are out of scope for the Pinniped project.
|
||||
- Standalone identity provider for general use.
|
||||
- Machine-to-machine (service) identity.
|
||||
- Running outside of Kubernetes.
|
||||
|
||||
## Roadmap
|
||||
|
||||
See our [open milestones][milestones] and the [`priority/backlog` label][backlog] for an idea about what's next on our roadmap.
|
||||
|
||||
For more details on proposing features and bugs, check out our [contributing](./CONTRIBUTING.md) doc.
|
||||
|
||||
[milestones]: https://github.com/vmware-tanzu/pinniped/milestones
|
||||
[backlog]: https://github.com/vmware-tanzu/pinniped/labels/priority%2Fbacklog
|
||||
@@ -1,9 +1,7 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=authentication.concierge.pinniped.dev
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the Pinniped concierge authentication API.
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// 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.
|
||||
@@ -13,6 +26,10 @@ 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.
|
||||
@@ -62,6 +79,7 @@ type JWTTokenClaims struct {
|
||||
// +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 {
|
||||
|
||||
@@ -1,11 +1,47 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// Configuration for configuring TLS on various authenticators.
|
||||
// CertificateAuthorityDataSourceKind enumerates the sources for CA Bundles.
|
||||
//
|
||||
// +kubebuilder:validation:Enum=Secret;ConfigMap
|
||||
type CertificateAuthorityDataSourceKind string
|
||||
|
||||
const (
|
||||
// CertificateAuthorityDataSourceKindConfigMap uses a Kubernetes configmap to source CA Bundles.
|
||||
CertificateAuthorityDataSourceKindConfigMap = CertificateAuthorityDataSourceKind("ConfigMap")
|
||||
|
||||
// CertificateAuthorityDataSourceKindSecret uses a Kubernetes secret to source CA Bundles.
|
||||
// Secrets used to source CA Bundles must be of type kubernetes.io/tls or Opaque.
|
||||
CertificateAuthorityDataSourceKindSecret = CertificateAuthorityDataSourceKind("Secret")
|
||||
)
|
||||
|
||||
// CertificateAuthorityDataSourceSpec provides a source for CA bundle used for client-side TLS verification.
|
||||
type CertificateAuthorityDataSourceSpec struct {
|
||||
// Kind configures whether the CA bundle is being sourced from a Kubernetes secret or a configmap.
|
||||
// Allowed values are "Secret" or "ConfigMap".
|
||||
// "ConfigMap" uses a Kubernetes configmap to source CA Bundles.
|
||||
// "Secret" uses Kubernetes secrets of type kubernetes.io/tls or Opaque to source CA Bundles.
|
||||
Kind CertificateAuthorityDataSourceKind `json:"kind"`
|
||||
// Name is the resource name of the secret or configmap from which to read the CA bundle.
|
||||
// The referenced secret or configmap must be created in the same namespace where Pinniped Concierge is installed.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Name string `json:"name"`
|
||||
// Key is the key name within the secret or configmap from which to read the CA bundle.
|
||||
// The value found at this key in the secret or configmap must not be empty, and must be a valid PEM-encoded
|
||||
// certificate bundle.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
// TLSSpec provides TLS configuration on various authenticators.
|
||||
type TLSSpec struct {
|
||||
// X.509 Certificate Authority (base64-encoded PEM bundle). If omitted, a default set of system roots will be trusted.
|
||||
// +optional
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData,omitempty"`
|
||||
// Reference to a CA bundle in a secret or a configmap.
|
||||
// Any changes to the CA bundle in the secret or configmap will be dynamically reloaded.
|
||||
// +optional
|
||||
CertificateAuthorityDataSource *CertificateAuthorityDataSourceSpec `json:"certificateAuthorityDataSource,omitempty"`
|
||||
}
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// 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 WebhookAuthenticatorPhase string
|
||||
|
||||
const (
|
||||
// WebhookAuthenticatorPhasePending is the default phase for newly-created WebhookAuthenticator resources.
|
||||
WebhookAuthenticatorPhasePending WebhookAuthenticatorPhase = "Pending"
|
||||
|
||||
// WebhookAuthenticatorPhaseReady is the phase for an WebhookAuthenticator resource in a healthy state.
|
||||
WebhookAuthenticatorPhaseReady WebhookAuthenticatorPhase = "Ready"
|
||||
|
||||
// WebhookAuthenticatorPhaseError is the phase for an WebhookAuthenticator in an unhealthy state.
|
||||
WebhookAuthenticatorPhaseError WebhookAuthenticatorPhase = "Error"
|
||||
)
|
||||
|
||||
// Status of a webhook authenticator.
|
||||
type WebhookAuthenticatorStatus struct {
|
||||
// Represents the observations of the authenticator's current state.
|
||||
@@ -13,6 +26,10 @@ type WebhookAuthenticatorStatus struct {
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
// Phase summarizes the overall status of the WebhookAuthenticator.
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase WebhookAuthenticatorPhase `json:"phase,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring a webhook authenticator.
|
||||
@@ -33,6 +50,7 @@ type WebhookAuthenticatorSpec struct {
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=pinniped;pinniped-authenticator;pinniped-authenticators,scope=Cluster
|
||||
// +kubebuilder:printcolumn:name="Endpoint",type=string,JSONPath=`.spec.endpoint`
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:status
|
||||
type WebhookAuthenticator struct {
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=config.concierge.pinniped.dev
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the Pinniped concierge configuration API.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@@ -49,6 +49,7 @@ type CredentialIssuerSpec struct {
|
||||
}
|
||||
|
||||
// ImpersonationProxyMode enumerates the configuration modes for the impersonation proxy.
|
||||
// Allowed values are "auto", "enabled", or "disabled".
|
||||
//
|
||||
// +kubebuilder:validation:Enum=auto;enabled;disabled
|
||||
type ImpersonationProxyMode string
|
||||
@@ -65,6 +66,7 @@ const (
|
||||
)
|
||||
|
||||
// ImpersonationProxyServiceType enumerates the types of service that can be provisioned for the impersonation proxy.
|
||||
// Allowed values are "LoadBalancer", "ClusterIP", or "None".
|
||||
//
|
||||
// +kubebuilder:validation:Enum=LoadBalancer;ClusterIP;None
|
||||
type ImpersonationProxyServiceType string
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 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/config
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=config.supervisor.pinniped.dev
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the Pinniped supervisor configuration API.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@@ -55,6 +55,7 @@ type FederationDomainTransformsConstant struct {
|
||||
Name string `json:"name"`
|
||||
|
||||
// Type determines the type of the constant, and indicates which other field should be non-empty.
|
||||
// Allowed values are "string" or "stringList".
|
||||
// +kubebuilder:validation:Enum=string;stringList
|
||||
Type string `json:"type"`
|
||||
|
||||
@@ -70,6 +71,7 @@ type FederationDomainTransformsConstant struct {
|
||||
// FederationDomainTransformsExpression defines a transform expression.
|
||||
type FederationDomainTransformsExpression struct {
|
||||
// Type determines the type of the expression. It must be one of the supported types.
|
||||
// Allowed values are "policy/v1", "username/v1", or "groups/v1".
|
||||
// +kubebuilder:validation:Enum=policy/v1;username/v1;groups/v1
|
||||
Type string `json:"type"`
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@@ -71,6 +71,28 @@ type OIDCClientSpec struct {
|
||||
// +listType=set
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
AllowedScopes []Scope `json:"allowedScopes"`
|
||||
|
||||
// tokenLifetimes are the optional overrides of token lifetimes for an OIDCClient.
|
||||
// +optional
|
||||
TokenLifetimes OIDCClientTokenLifetimes `json:"tokenLifetimes,omitempty"`
|
||||
}
|
||||
|
||||
// OIDCClientTokenLifetimes describes the optional overrides of token lifetimes for an OIDCClient.
|
||||
type OIDCClientTokenLifetimes struct {
|
||||
// idTokenSeconds is the lifetime of ID tokens issued to this client, in seconds. This will choose the lifetime of
|
||||
// ID tokens returned by the authorization flow and the refresh grant. It will not influence the lifetime of the ID
|
||||
// tokens returned by RFC8693 token exchange. When null, a short-lived default value will be used.
|
||||
// This value must be between 120 and 1,800 seconds (30 minutes), inclusive. It is recommended to make these tokens
|
||||
// short-lived to force the client to perform the refresh grant often, because the refresh grant will check with the
|
||||
// external identity provider to decide if it is acceptable for the end user to continue their session, and will
|
||||
// update the end user's group memberships from the external identity provider. Giving these tokens a long life is
|
||||
// will allow the end user to continue to use a token while avoiding these updates from the external identity
|
||||
// provider. However, some web applications may have reasons specific to the design of that application to prefer
|
||||
// longer lifetimes.
|
||||
// +kubebuilder:validation:Minimum=120
|
||||
// +kubebuilder:validation:Maximum=1800
|
||||
// +optional
|
||||
IDTokenSeconds *int32 `json:"idTokenSeconds,omitempty"`
|
||||
}
|
||||
|
||||
// OIDCClientStatus is a struct that describes the actual state of an OIDCClient.
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=idp.supervisor.pinniped.dev
|
||||
// +groupGoName=IDP
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@@ -36,6 +36,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
&LDAPIdentityProviderList{},
|
||||
&ActiveDirectoryIdentityProvider{},
|
||||
&ActiveDirectoryIdentityProviderList{},
|
||||
&GitHubIdentityProvider{},
|
||||
&GitHubIdentityProviderList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
// Copyright 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 GitHubIdentityProviderPhase string
|
||||
|
||||
const (
|
||||
// GitHubPhasePending is the default phase for newly-created GitHubIdentityProvider resources.
|
||||
GitHubPhasePending GitHubIdentityProviderPhase = "Pending"
|
||||
|
||||
// GitHubPhaseReady is the phase for an GitHubIdentityProvider resource in a healthy state.
|
||||
GitHubPhaseReady GitHubIdentityProviderPhase = "Ready"
|
||||
|
||||
// GitHubPhaseError is the phase for an GitHubIdentityProvider in an unhealthy state.
|
||||
GitHubPhaseError GitHubIdentityProviderPhase = "Error"
|
||||
)
|
||||
|
||||
type GitHubAllowedAuthOrganizationsPolicy string
|
||||
|
||||
const (
|
||||
// GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers means any GitHub user is allowed to log in using this identity
|
||||
// provider, regardless of their organization membership or lack thereof.
|
||||
GitHubAllowedAuthOrganizationsPolicyAllGitHubUsers GitHubAllowedAuthOrganizationsPolicy = "AllGitHubUsers"
|
||||
|
||||
// GitHubAllowedAuthOrganizationsPolicyOnlyUsersFromAllowedOrganizations means only those users with membership in
|
||||
// the listed GitHub organizations are allowed to log in.
|
||||
GitHubAllowedAuthOrganizationsPolicyOnlyUsersFromAllowedOrganizations GitHubAllowedAuthOrganizationsPolicy = "OnlyUsersFromAllowedOrganizations"
|
||||
)
|
||||
|
||||
// GitHubIdentityProviderStatus is the status of an GitHub identity provider.
|
||||
type GitHubIdentityProviderStatus struct {
|
||||
// Phase summarizes the overall status of the GitHubIdentityProvider.
|
||||
//
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase GitHubIdentityProviderPhase `json:"phase,omitempty"`
|
||||
|
||||
// Conditions represents the observations of an identity provider's current state.
|
||||
//
|
||||
// +patchMergeKey=type
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
}
|
||||
|
||||
// GitHubAPIConfig allows configuration for GitHub Enterprise Server
|
||||
type GitHubAPIConfig struct {
|
||||
// Host is required only for GitHub Enterprise Server.
|
||||
// Defaults to using GitHub's public API ("github.com").
|
||||
// For convenience, specifying "github.com" is equivalent to specifying "api.github.com".
|
||||
// Do not specify a protocol or scheme since "https://" will always be used.
|
||||
// Port is optional. Do not specify a path, query, fragment, or userinfo.
|
||||
// Only specify domain name or IP address, subdomains (optional), and port (optional).
|
||||
// IPv4 and IPv6 are supported. If using an IPv6 address with a port, you must enclose the IPv6 address
|
||||
// in square brackets. Example: "[::1]:443".
|
||||
//
|
||||
// +kubebuilder:default="github.com"
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +optional
|
||||
Host *string `json:"host"`
|
||||
|
||||
// TLS configuration for GitHub Enterprise Server.
|
||||
// Note that this field should not be needed when using GitHub's public API ("github.com").
|
||||
// However, if you choose to specify this field when using GitHub's public API, you must
|
||||
// specify a CA bundle that will verify connections to "api.github.com".
|
||||
//
|
||||
// +optional
|
||||
TLS *TLSSpec `json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
// GitHubUsernameAttribute allows the user to specify which attribute(s) from GitHub to use for the username to present
|
||||
// to Kubernetes. See the response schema for
|
||||
// [Get the authenticated user](https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user).
|
||||
type GitHubUsernameAttribute string
|
||||
|
||||
const (
|
||||
// GitHubUsernameID specifies using the `id` attribute from the GitHub user for the username to present to Kubernetes.
|
||||
GitHubUsernameID GitHubUsernameAttribute = "id"
|
||||
|
||||
// GitHubUsernameLogin specifies using the `login` attribute from the GitHub user as the username to present to Kubernetes.
|
||||
GitHubUsernameLogin GitHubUsernameAttribute = "login"
|
||||
|
||||
// GitHubUsernameLoginAndID specifies combining the `login` and `id` attributes from the GitHub user as the
|
||||
// username to present to Kubernetes, separated by a colon. Example: "my-login:1234"
|
||||
GitHubUsernameLoginAndID GitHubUsernameAttribute = "login:id"
|
||||
)
|
||||
|
||||
// GitHubGroupNameAttribute allows the user to specify which attribute from GitHub to use for the group
|
||||
// names to present to Kubernetes. See the response schema for
|
||||
// [List teams for the authenticated user](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user).
|
||||
type GitHubGroupNameAttribute string
|
||||
|
||||
const (
|
||||
// GitHubUseTeamNameForGroupName specifies using the GitHub team's `name` attribute as the group name to present to Kubernetes.
|
||||
GitHubUseTeamNameForGroupName GitHubGroupNameAttribute = "name"
|
||||
|
||||
// GitHubUseTeamSlugForGroupName specifies using the GitHub team's `slug` attribute as the group name to present to Kubernetes.
|
||||
GitHubUseTeamSlugForGroupName GitHubGroupNameAttribute = "slug"
|
||||
)
|
||||
|
||||
// GitHubClaims allows customization of the username and groups claims.
|
||||
type GitHubClaims struct {
|
||||
// Username configures which property of the GitHub user record shall determine the username in Kubernetes.
|
||||
//
|
||||
// Can be either "id", "login", or "login:id". Defaults to "login:id".
|
||||
//
|
||||
// GitHub's user login attributes can only contain alphanumeric characters and non-repeating hyphens,
|
||||
// and may not start or end with hyphens. GitHub users are allowed to change their login name,
|
||||
// although it is inconvenient. If a GitHub user changed their login name from "foo" to "bar",
|
||||
// then a second user might change their name from "baz" to "foo" in order to take the old
|
||||
// username of the first user. For this reason, it is not as safe to make authorization decisions
|
||||
// based only on the user's login attribute.
|
||||
//
|
||||
// If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's
|
||||
// FederationDomain to further customize how these usernames are presented to Kubernetes.
|
||||
//
|
||||
// Defaults to "login:id", which is the user login attribute, followed by a colon, followed by the unique and
|
||||
// unchanging integer ID number attribute. This blends human-readable login names with the unchanging ID value
|
||||
// from GitHub. Colons are not allowed in GitHub login attributes or ID numbers, so this is a reasonable
|
||||
// choice to concatenate the two values.
|
||||
//
|
||||
// See the response schema for
|
||||
// [Get the authenticated user](https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user).
|
||||
//
|
||||
// +kubebuilder:default="login:id"
|
||||
// +kubebuilder:validation:Enum={"id","login","login:id"}
|
||||
// +optional
|
||||
Username *GitHubUsernameAttribute `json:"username"`
|
||||
|
||||
// Groups configures which property of the GitHub team record shall determine the group names in Kubernetes.
|
||||
//
|
||||
// Can be either "name" or "slug". Defaults to "slug".
|
||||
//
|
||||
// GitHub team names can contain upper and lower case characters, whitespace, and punctuation (e.g. "Kube admins!").
|
||||
//
|
||||
// GitHub team slugs are lower case alphanumeric characters and may contain dashes and underscores (e.g. "kube-admins").
|
||||
//
|
||||
// Group names as presented to Kubernetes will always be prefixed by the GitHub organization name followed by a
|
||||
// forward slash (e.g. "my-org/my-team"). GitHub organization login names can only contain alphanumeric characters
|
||||
// or single hyphens, so the first forward slash `/` will be the separator between the organization login name and
|
||||
// the team name or slug.
|
||||
//
|
||||
// If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's
|
||||
// FederationDomain to further customize how these group names are presented to Kubernetes.
|
||||
//
|
||||
// See the response schema for
|
||||
// [List teams for the authenticated user](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user).
|
||||
//
|
||||
// +kubebuilder:default=slug
|
||||
// +kubebuilder:validation:Enum=name;slug
|
||||
// +optional
|
||||
Groups *GitHubGroupNameAttribute `json:"groups"`
|
||||
}
|
||||
|
||||
// GitHubClientSpec contains information about the GitHub client that this identity provider will use
|
||||
// for web-based login flows.
|
||||
type GitHubClientSpec struct {
|
||||
// SecretName contains the name of a namespace-local Secret object that provides the clientID and
|
||||
// clientSecret for an GitHub App or GitHub OAuth2 client.
|
||||
//
|
||||
// This secret must be of type "secrets.pinniped.dev/github-client" with keys "clientID" and "clientSecret".
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
SecretName string `json:"secretName"`
|
||||
}
|
||||
|
||||
type GitHubOrganizationsSpec struct {
|
||||
// Allowed values are "OnlyUsersFromAllowedOrganizations" or "AllGitHubUsers".
|
||||
// Defaults to "OnlyUsersFromAllowedOrganizations".
|
||||
//
|
||||
// Must be set to "AllGitHubUsers" if the allowed field is empty.
|
||||
//
|
||||
// This field only exists to ensure that Pinniped administrators are aware that an empty list of
|
||||
// allowedOrganizations means all GitHub users are allowed to log in.
|
||||
//
|
||||
// +kubebuilder:default=OnlyUsersFromAllowedOrganizations
|
||||
// +kubebuilder:validation:Enum=OnlyUsersFromAllowedOrganizations;AllGitHubUsers
|
||||
// +optional
|
||||
Policy *GitHubAllowedAuthOrganizationsPolicy `json:"policy"`
|
||||
|
||||
// Allowed, when specified, indicates that only users with membership in at least one of the listed
|
||||
// GitHub organizations may log in. In addition, the group membership presented to Kubernetes will only include
|
||||
// teams within the listed GitHub organizations. Additional login rules or group filtering can optionally be
|
||||
// provided as policy expression on any Pinniped Supervisor FederationDomain that includes this IDP.
|
||||
//
|
||||
// The configured GitHub App or GitHub OAuth App must be allowed to see membership in the listed organizations,
|
||||
// otherwise Pinniped will not be aware that the user belongs to the listed organization or any teams
|
||||
// within that organization.
|
||||
//
|
||||
// If no organizations are listed, you must set organizations: AllGitHubUsers.
|
||||
//
|
||||
// +kubebuilder:validation:MaxItems=64
|
||||
// +listType=set
|
||||
// +optional
|
||||
Allowed []string `json:"allowed,omitempty"`
|
||||
}
|
||||
|
||||
// GitHubAllowAuthenticationSpec allows customization of who can authenticate using this IDP and how.
|
||||
type GitHubAllowAuthenticationSpec struct {
|
||||
// Organizations allows customization of which organizations can authenticate using this IDP.
|
||||
// +kubebuilder:validation:XValidation:message="spec.allowAuthentication.organizations.policy must be 'OnlyUsersFromAllowedOrganizations' when spec.allowAuthentication.organizations.allowed has organizations listed",rule="!(has(self.allowed) && size(self.allowed) > 0 && self.policy == 'AllGitHubUsers')"
|
||||
// +kubebuilder:validation:XValidation:message="spec.allowAuthentication.organizations.policy must be 'AllGitHubUsers' when spec.allowAuthentication.organizations.allowed is empty",rule="!((!has(self.allowed) || size(self.allowed) == 0) && self.policy == 'OnlyUsersFromAllowedOrganizations')"
|
||||
Organizations GitHubOrganizationsSpec `json:"organizations"`
|
||||
}
|
||||
|
||||
// GitHubIdentityProviderSpec is the spec for configuring an GitHub identity provider.
|
||||
type GitHubIdentityProviderSpec struct {
|
||||
// GitHubAPI allows configuration for GitHub Enterprise Server
|
||||
//
|
||||
// +kubebuilder:default={}
|
||||
GitHubAPI GitHubAPIConfig `json:"githubAPI,omitempty"`
|
||||
|
||||
// Claims allows customization of the username and groups claims.
|
||||
//
|
||||
// +kubebuilder:default={}
|
||||
Claims GitHubClaims `json:"claims,omitempty"`
|
||||
|
||||
// AllowAuthentication allows customization of who can authenticate using this IDP and how.
|
||||
AllowAuthentication GitHubAllowAuthenticationSpec `json:"allowAuthentication"`
|
||||
|
||||
// Client identifies the secret with credentials for a GitHub App or GitHub OAuth2 App (a GitHub client).
|
||||
Client GitHubClientSpec `json:"client"`
|
||||
}
|
||||
|
||||
// GitHubIdentityProvider describes the configuration of an upstream GitHub identity provider.
|
||||
// This upstream provider can be configured with either a GitHub App or a GitHub OAuth2 App.
|
||||
//
|
||||
// Right now, only web-based logins are supported, for both the pinniped-cli client and clients configured
|
||||
// as OIDCClients.
|
||||
//
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=pinniped;pinniped-idp;pinniped-idps
|
||||
// +kubebuilder:printcolumn:name="Host",type=string,JSONPath=`.spec.githubAPI.host`
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:status
|
||||
type GitHubIdentityProvider struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec for configuring the identity provider.
|
||||
Spec GitHubIdentityProviderSpec `json:"spec"`
|
||||
|
||||
// Status of the identity provider.
|
||||
Status GitHubIdentityProviderStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GitHubIdentityProviderList lists GitHubIdentityProvider objects.
|
||||
//
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type GitHubIdentityProviderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []GitHubIdentityProvider `json:"items"`
|
||||
}
|
||||
@@ -1,11 +1,47 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// Configuration for TLS parameters related to identity provider integration.
|
||||
// CertificateAuthorityDataSourceKind enumerates the sources for CA Bundles.
|
||||
//
|
||||
// +kubebuilder:validation:Enum=Secret;ConfigMap
|
||||
type CertificateAuthorityDataSourceKind string
|
||||
|
||||
const (
|
||||
// CertificateAuthorityDataSourceKindConfigMap uses a Kubernetes configmap to source CA Bundles.
|
||||
CertificateAuthorityDataSourceKindConfigMap = CertificateAuthorityDataSourceKind("ConfigMap")
|
||||
|
||||
// CertificateAuthorityDataSourceKindSecret uses a Kubernetes secret to source CA Bundles.
|
||||
// Secrets used to source CA Bundles must be of type kubernetes.io/tls or Opaque.
|
||||
CertificateAuthorityDataSourceKindSecret = CertificateAuthorityDataSourceKind("Secret")
|
||||
)
|
||||
|
||||
// CertificateAuthorityDataSourceSpec provides a source for CA bundle used for client-side TLS verification.
|
||||
type CertificateAuthorityDataSourceSpec struct {
|
||||
// Kind configures whether the CA bundle is being sourced from a Kubernetes secret or a configmap.
|
||||
// Allowed values are "Secret" or "ConfigMap".
|
||||
// "ConfigMap" uses a Kubernetes configmap to source CA Bundles.
|
||||
// "Secret" uses Kubernetes secrets of type kubernetes.io/tls or Opaque to source CA Bundles.
|
||||
Kind CertificateAuthorityDataSourceKind `json:"kind"`
|
||||
// Name is the resource name of the secret or configmap from which to read the CA bundle.
|
||||
// The referenced secret or configmap must be created in the same namespace where Pinniped Supervisor is installed.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Name string `json:"name"`
|
||||
// Key is the key name within the secret or configmap from which to read the CA bundle.
|
||||
// The value found at this key in the secret or configmap must not be empty, and must be a valid PEM-encoded
|
||||
// certificate bundle.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
// TLSSpec provides TLS configuration for identity provider integration.
|
||||
type TLSSpec struct {
|
||||
// X.509 Certificate Authority (base64-encoded PEM bundle). If omitted, a default set of system roots will be trusted.
|
||||
// +optional
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData,omitempty"`
|
||||
// Reference to a CA bundle in a secret or a configmap.
|
||||
// Any changes to the CA bundle in the secret or configmap will be dynamically reloaded.
|
||||
// +optional
|
||||
CertificateAuthorityDataSource *CertificateAuthorityDataSourceSpec `json:"certificateAuthorityDataSource,omitempty"`
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
@@ -15,6 +15,7 @@ const (
|
||||
IDPTypeOIDC IDPType = "oidc"
|
||||
IDPTypeLDAP IDPType = "ldap"
|
||||
IDPTypeActiveDirectory IDPType = "activedirectory"
|
||||
IDPTypeGitHub IDPType = "github"
|
||||
|
||||
IDPFlowCLIPassword IDPFlow = "cli_password"
|
||||
IDPFlowBrowserAuthcode IDPFlow = "browser_authcode"
|
||||
@@ -54,7 +55,8 @@ type OIDCDiscoveryResponseIDPEndpoint struct {
|
||||
|
||||
// IDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
|
||||
type IDPDiscoveryResponse struct {
|
||||
PinnipedIDPs []PinnipedIDP `json:"pinniped_identity_providers"`
|
||||
PinnipedIDPs []PinnipedIDP `json:"pinniped_identity_providers"`
|
||||
PinnipedSupportedIDPTypes []PinnipedSupportedIDPType `json:"pinniped_supported_identity_provider_types"`
|
||||
}
|
||||
|
||||
// PinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
|
||||
@@ -64,3 +66,8 @@ type PinnipedIDP struct {
|
||||
Type IDPType `json:"type"`
|
||||
Flows []IDPFlow `json:"flows,omitempty"`
|
||||
}
|
||||
|
||||
// PinnipedSupportedIDPType describes a single identity provider type.
|
||||
type PinnipedSupportedIDPType struct {
|
||||
Type IDPType `json:"type"`
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package oidc
|
||||
@@ -29,6 +29,10 @@ const (
|
||||
// IDTokenClaimSubject is name of the subject claim defined by the OIDC spec.
|
||||
IDTokenClaimSubject = "sub"
|
||||
|
||||
// IDTokenSubClaimIDPNameQueryParam is the name of the query param used in the values of the "sub" claim
|
||||
// in Supervisor-issued ID tokens to identify with which external identity provider the user authenticated.
|
||||
IDTokenSubClaimIDPNameQueryParam = "idpName"
|
||||
|
||||
// IDTokenClaimAuthorizedParty is name of the authorized party claim defined by the OIDC spec.
|
||||
IDTokenClaimAuthorizedParty = "azp"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
@@ -90,12 +90,11 @@ func TestEntrypoint(t *testing.T) {
|
||||
}`,
|
||||
},
|
||||
} {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var logBuf bytes.Buffer
|
||||
testLog := log.New(&logBuf, "", 0)
|
||||
exited := "exiting via fatal"
|
||||
fail = func(format string, v ...interface{}) {
|
||||
fail = func(format string, v ...any) {
|
||||
testLog.Printf(format, v...)
|
||||
panic(exited)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
@@ -38,12 +38,11 @@ func TestEntrypoint(t *testing.T) {
|
||||
wantArgs: []string{"/path/to/valid-test-binary", "foo", "bar"},
|
||||
},
|
||||
} {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var logBuf bytes.Buffer
|
||||
testLog := log.New(&logBuf, "", 0)
|
||||
exited := "exiting via fatal"
|
||||
fail = func(err error, keysAndValues ...interface{}) {
|
||||
fail = func(err error, keysAndValues ...any) {
|
||||
testLog.Print(err)
|
||||
if len(keysAndValues) > 0 {
|
||||
testLog.Print(keysAndValues...)
|
||||
|
||||
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,4 +1,4 @@
|
||||
// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
)
|
||||
|
||||
// conciergeModeFlag represents the method by which we should connect to the Concierge on a cluster during login.
|
||||
@@ -62,12 +62,12 @@ func (f *conciergeModeFlag) Type() string {
|
||||
}
|
||||
|
||||
// MatchesFrontend returns true iff the flag matches the type of the provided frontend.
|
||||
func (f *conciergeModeFlag) MatchesFrontend(frontend *configv1alpha1.CredentialIssuerFrontend) bool {
|
||||
func (f *conciergeModeFlag) MatchesFrontend(frontend *conciergeconfigv1alpha1.CredentialIssuerFrontend) bool {
|
||||
switch *f {
|
||||
case modeImpersonationProxy:
|
||||
return frontend.Type == configv1alpha1.ImpersonationProxyFrontendType
|
||||
return frontend.Type == conciergeconfigv1alpha1.ImpersonationProxyFrontendType
|
||||
case modeTokenCredentialRequestAPI:
|
||||
return frontend.Type == configv1alpha1.TokenCredentialRequestAPIFrontendType
|
||||
return frontend.Type == conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType
|
||||
case modeUnknown:
|
||||
fallthrough
|
||||
default:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
"go.pinniped.dev/internal/certauthority"
|
||||
)
|
||||
|
||||
@@ -24,14 +24,14 @@ func TestConciergeModeFlag(t *testing.T) {
|
||||
require.NoError(t, f.Set(""))
|
||||
require.Equal(t, modeUnknown, f)
|
||||
require.EqualError(t, f.Set("foo"), `invalid mode "foo", valid modes are TokenCredentialRequestAPI and ImpersonationProxy`)
|
||||
require.True(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.TokenCredentialRequestAPIFrontendType}))
|
||||
require.True(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.ImpersonationProxyFrontendType}))
|
||||
require.True(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType}))
|
||||
require.True(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType}))
|
||||
|
||||
require.NoError(t, f.Set("TokenCredentialRequestAPI"))
|
||||
require.Equal(t, modeTokenCredentialRequestAPI, f)
|
||||
require.Equal(t, "TokenCredentialRequestAPI", f.String())
|
||||
require.True(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.TokenCredentialRequestAPIFrontendType}))
|
||||
require.False(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.ImpersonationProxyFrontendType}))
|
||||
require.True(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType}))
|
||||
require.False(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType}))
|
||||
|
||||
require.NoError(t, f.Set("tokencredentialrequestapi"))
|
||||
require.Equal(t, modeTokenCredentialRequestAPI, f)
|
||||
@@ -40,8 +40,8 @@ func TestConciergeModeFlag(t *testing.T) {
|
||||
require.NoError(t, f.Set("ImpersonationProxy"))
|
||||
require.Equal(t, modeImpersonationProxy, f)
|
||||
require.Equal(t, "ImpersonationProxy", f.String())
|
||||
require.False(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.TokenCredentialRequestAPIFrontendType}))
|
||||
require.True(t, f.MatchesFrontend(&configv1alpha1.CredentialIssuerFrontend{Type: configv1alpha1.ImpersonationProxyFrontendType}))
|
||||
require.False(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType}))
|
||||
require.True(t, f.MatchesFrontend(&conciergeconfigv1alpha1.CredentialIssuerFrontend{Type: conciergeconfigv1alpha1.ImpersonationProxyFrontendType}))
|
||||
|
||||
require.NoError(t, f.Set("impersonationproxy"))
|
||||
require.Equal(t, modeImpersonationProxy, f)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -23,10 +24,9 @@ import (
|
||||
_ "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"
|
||||
"k8s.io/utils/strings/slices"
|
||||
|
||||
conciergev1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
|
||||
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
|
||||
conciergeconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
idpdiscoveryv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
|
||||
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
|
||||
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
)
|
||||
|
||||
type kubeconfigDeps struct {
|
||||
getenv func(key string) string
|
||||
getPathToSelf func() (string, error)
|
||||
getClientset getConciergeClientsetFunc
|
||||
log plog.MinLogger
|
||||
@@ -43,6 +44,7 @@ type kubeconfigDeps struct {
|
||||
|
||||
func kubeconfigRealDeps() kubeconfigDeps {
|
||||
return kubeconfigDeps{
|
||||
getenv: os.Getenv,
|
||||
getPathToSelf: os.Executable,
|
||||
getClientset: getRealConciergeClientset,
|
||||
log: plog.New(),
|
||||
@@ -143,9 +145,20 @@ func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
|
||||
f.BoolVar(&flags.oidc.debugSessionCache, "oidc-debug-session-cache", false, "Print debug logs related to the OpenID Connect session cache")
|
||||
f.StringVar(&flags.oidc.requestAudience, "oidc-request-audience", "", "Request a token with an alternate audience using RFC8693 token exchange")
|
||||
f.StringVar(&flags.oidc.upstreamIDPName, "upstream-identity-provider-name", "", "The name of the upstream identity provider used during login with a Supervisor")
|
||||
f.StringVar(&flags.oidc.upstreamIDPType, "upstream-identity-provider-type", "", fmt.Sprintf("The type of the upstream identity provider used during login with a Supervisor (e.g. '%s', '%s', '%s')", idpdiscoveryv1alpha1.IDPTypeOIDC, idpdiscoveryv1alpha1.IDPTypeLDAP, idpdiscoveryv1alpha1.IDPTypeActiveDirectory))
|
||||
f.StringVar(
|
||||
&flags.oidc.upstreamIDPType,
|
||||
"upstream-identity-provider-type",
|
||||
"",
|
||||
fmt.Sprintf(
|
||||
"The type of the upstream identity provider used during login with a Supervisor (e.g. '%s', '%s', '%s', '%s')",
|
||||
idpdiscoveryv1alpha1.IDPTypeOIDC,
|
||||
idpdiscoveryv1alpha1.IDPTypeLDAP,
|
||||
idpdiscoveryv1alpha1.IDPTypeActiveDirectory,
|
||||
idpdiscoveryv1alpha1.IDPTypeGitHub,
|
||||
),
|
||||
)
|
||||
f.StringVar(&flags.oidc.upstreamIDPFlow, "upstream-identity-provider-flow", "", fmt.Sprintf("The type of client flow to use with the upstream identity provider during login with a Supervisor (e.g. '%s', '%s')", idpdiscoveryv1alpha1.IDPFlowCLIPassword, idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode))
|
||||
f.StringVar(&flags.kubeconfigPath, "kubeconfig", os.Getenv("KUBECONFIG"), "Path to kubeconfig file")
|
||||
f.StringVar(&flags.kubeconfigPath, "kubeconfig", deps.getenv("KUBECONFIG"), "Path to kubeconfig file")
|
||||
f.StringVar(&flags.kubeconfigContextOverride, "kubeconfig-context", "", "Kubeconfig context name (default: current active context)")
|
||||
f.BoolVar(&flags.skipValidate, "skip-validation", false, "Skip final validation of the kubeconfig (default: false)")
|
||||
f.DurationVar(&flags.timeout, "timeout", 10*time.Minute, "Timeout for autodiscovery and validation")
|
||||
@@ -163,7 +176,7 @@ func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
|
||||
|
||||
mustMarkDeprecated(cmd, "concierge-namespace", "not needed anymore")
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
cmd.RunE = func(cmd *cobra.Command, _args []string) error {
|
||||
if flags.outputPath != "" {
|
||||
out, err := os.Create(flags.outputPath)
|
||||
if err != nil {
|
||||
@@ -182,7 +195,7 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
ctx, cancel := context.WithTimeout(ctx, flags.timeout)
|
||||
defer cancel()
|
||||
|
||||
// the log statements in this file assume that Info logs are unconditionally printed so we set the global level to info
|
||||
// the log statements in this file assume that Info logs are unconditionally printed, so we set the global level to info
|
||||
if err := plog.ValidateAndSetLogLevelAndFormatGlobally(ctx, plog.LogSpec{Level: plog.LevelInfo, Format: plog.FormatCLI}); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -303,7 +316,7 @@ func newExecConfig(deps kubeconfigDeps, flags getKubeconfigParams) (*clientcmdap
|
||||
if flags.staticToken != "" && flags.staticTokenEnvName != "" {
|
||||
return nil, fmt.Errorf("only one of --static-token and --static-token-env can be specified")
|
||||
}
|
||||
execConfig.Args = append([]string{"login", "static"}, execConfig.Args...)
|
||||
execConfig.Args = slices.Concat([]string{"login", "static"}, execConfig.Args)
|
||||
if flags.staticToken != "" {
|
||||
execConfig.Args = append(execConfig.Args, "--token="+flags.staticToken)
|
||||
}
|
||||
@@ -314,7 +327,7 @@ func newExecConfig(deps kubeconfigDeps, flags getKubeconfigParams) (*clientcmdap
|
||||
}
|
||||
|
||||
// Otherwise continue to parse the OIDC-related flags and output a config that runs `pinniped login oidc`.
|
||||
execConfig.Args = append([]string{"login", "oidc"}, execConfig.Args...)
|
||||
execConfig.Args = slices.Concat([]string{"login", "oidc"}, execConfig.Args)
|
||||
if flags.oidc.issuer == "" {
|
||||
return nil, fmt.Errorf("could not autodiscover --oidc-issuer and none was provided")
|
||||
}
|
||||
@@ -380,7 +393,7 @@ func getCurrentContext(currentKubeConfig clientcmdapi.Config, flags getKubeconfi
|
||||
return &kubeconfigNames{ContextName: contextName, UserName: ctx.AuthInfo, ClusterName: ctx.Cluster}, nil
|
||||
}
|
||||
|
||||
func waitForCredentialIssuer(ctx context.Context, clientset conciergeclientset.Interface, flags getKubeconfigParams, deps kubeconfigDeps) (*configv1alpha1.CredentialIssuer, error) {
|
||||
func waitForCredentialIssuer(ctx context.Context, clientset conciergeclientset.Interface, flags getKubeconfigParams, deps kubeconfigDeps) (*conciergeconfigv1alpha1.CredentialIssuer, error) {
|
||||
credentialIssuer, err := lookupCredentialIssuer(clientset, flags.concierge.credentialIssuer, deps.log)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -416,7 +429,7 @@ func waitForCredentialIssuer(ctx context.Context, clientset conciergeclientset.I
|
||||
return credentialIssuer, nil
|
||||
}
|
||||
|
||||
func discoverConciergeParams(credentialIssuer *configv1alpha1.CredentialIssuer, flags *getKubeconfigParams, v1Cluster *clientcmdapi.Cluster, log plog.MinLogger) error {
|
||||
func discoverConciergeParams(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer, flags *getKubeconfigParams, v1Cluster *clientcmdapi.Cluster, log plog.MinLogger) error {
|
||||
// Autodiscover the --concierge-mode.
|
||||
frontend, err := getConciergeFrontend(credentialIssuer, flags.concierge.mode)
|
||||
if err != nil {
|
||||
@@ -427,10 +440,10 @@ func discoverConciergeParams(credentialIssuer *configv1alpha1.CredentialIssuer,
|
||||
// Auto-set --concierge-mode if it wasn't explicitly set.
|
||||
if flags.concierge.mode == modeUnknown {
|
||||
switch frontend.Type {
|
||||
case configv1alpha1.TokenCredentialRequestAPIFrontendType:
|
||||
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType:
|
||||
log.Info("discovered Concierge operating in TokenCredentialRequest API mode")
|
||||
flags.concierge.mode = modeTokenCredentialRequestAPI
|
||||
case configv1alpha1.ImpersonationProxyFrontendType:
|
||||
case conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
|
||||
log.Info("discovered Concierge operating in impersonation proxy mode")
|
||||
flags.concierge.mode = modeImpersonationProxy
|
||||
}
|
||||
@@ -439,9 +452,9 @@ func discoverConciergeParams(credentialIssuer *configv1alpha1.CredentialIssuer,
|
||||
// Auto-set --concierge-endpoint if it wasn't explicitly set.
|
||||
if flags.concierge.endpoint == "" {
|
||||
switch frontend.Type {
|
||||
case configv1alpha1.TokenCredentialRequestAPIFrontendType:
|
||||
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType:
|
||||
flags.concierge.endpoint = v1Cluster.Server
|
||||
case configv1alpha1.ImpersonationProxyFrontendType:
|
||||
case conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
|
||||
flags.concierge.endpoint = frontend.ImpersonationProxyInfo.Endpoint
|
||||
}
|
||||
log.Info("discovered Concierge endpoint", "endpoint", flags.concierge.endpoint)
|
||||
@@ -450,9 +463,9 @@ func discoverConciergeParams(credentialIssuer *configv1alpha1.CredentialIssuer,
|
||||
// Auto-set --concierge-ca-bundle if it wasn't explicitly set..
|
||||
if len(flags.concierge.caBundle) == 0 {
|
||||
switch frontend.Type {
|
||||
case configv1alpha1.TokenCredentialRequestAPIFrontendType:
|
||||
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType:
|
||||
flags.concierge.caBundle = v1Cluster.CertificateAuthorityData
|
||||
case configv1alpha1.ImpersonationProxyFrontendType:
|
||||
case conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
|
||||
data, err := base64.StdEncoding.DecodeString(frontend.ImpersonationProxyInfo.CertificateAuthorityData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("autodiscovered Concierge CA bundle is invalid: %w", err)
|
||||
@@ -464,7 +477,7 @@ func discoverConciergeParams(credentialIssuer *configv1alpha1.CredentialIssuer,
|
||||
return nil
|
||||
}
|
||||
|
||||
func logStrategies(credentialIssuer *configv1alpha1.CredentialIssuer, log plog.MinLogger) {
|
||||
func logStrategies(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer, log plog.MinLogger) {
|
||||
for _, strategy := range credentialIssuer.Status.Strategies {
|
||||
log.Info("found CredentialIssuer strategy",
|
||||
"type", strategy.Type,
|
||||
@@ -477,7 +490,7 @@ func logStrategies(credentialIssuer *configv1alpha1.CredentialIssuer, log plog.M
|
||||
|
||||
func discoverAuthenticatorParams(authenticator metav1.Object, flags *getKubeconfigParams, log plog.MinLogger) error {
|
||||
switch auth := authenticator.(type) {
|
||||
case *conciergev1alpha1.WebhookAuthenticator:
|
||||
case *authenticationv1alpha1.WebhookAuthenticator:
|
||||
// If the --concierge-authenticator-type/--concierge-authenticator-name flags were not set explicitly, set
|
||||
// them to point at the discovered WebhookAuthenticator.
|
||||
if flags.concierge.authenticatorType == "" && flags.concierge.authenticatorName == "" {
|
||||
@@ -485,7 +498,7 @@ func discoverAuthenticatorParams(authenticator metav1.Object, flags *getKubeconf
|
||||
flags.concierge.authenticatorType = "webhook"
|
||||
flags.concierge.authenticatorName = auth.Name
|
||||
}
|
||||
case *conciergev1alpha1.JWTAuthenticator:
|
||||
case *authenticationv1alpha1.JWTAuthenticator:
|
||||
// If the --concierge-authenticator-type/--concierge-authenticator-name flags were not set explicitly, set
|
||||
// them to point at the discovered JWTAuthenticator.
|
||||
if flags.concierge.authenticatorType == "" && flags.concierge.authenticatorName == "" {
|
||||
@@ -520,19 +533,19 @@ func discoverAuthenticatorParams(authenticator metav1.Object, flags *getKubeconf
|
||||
return nil
|
||||
}
|
||||
|
||||
func getConciergeFrontend(credentialIssuer *configv1alpha1.CredentialIssuer, mode conciergeModeFlag) (*configv1alpha1.CredentialIssuerFrontend, error) {
|
||||
func getConciergeFrontend(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer, mode conciergeModeFlag) (*conciergeconfigv1alpha1.CredentialIssuerFrontend, error) {
|
||||
for _, strategy := range credentialIssuer.Status.Strategies {
|
||||
// Skip unhealthy strategies.
|
||||
if strategy.Status != configv1alpha1.SuccessStrategyStatus {
|
||||
if strategy.Status != conciergeconfigv1alpha1.SuccessStrategyStatus {
|
||||
continue
|
||||
}
|
||||
|
||||
// Backfill the .status.strategies[].frontend field from .status.kubeConfigInfo for backwards compatibility.
|
||||
if strategy.Type == configv1alpha1.KubeClusterSigningCertificateStrategyType && strategy.Frontend == nil && credentialIssuer.Status.KubeConfigInfo != nil {
|
||||
if strategy.Type == conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType && strategy.Frontend == nil && credentialIssuer.Status.KubeConfigInfo != nil {
|
||||
strategy = *strategy.DeepCopy()
|
||||
strategy.Frontend = &configv1alpha1.CredentialIssuerFrontend{
|
||||
Type: configv1alpha1.TokenCredentialRequestAPIFrontendType,
|
||||
TokenCredentialRequestAPIInfo: &configv1alpha1.TokenCredentialRequestAPIInfo{
|
||||
strategy.Frontend = &conciergeconfigv1alpha1.CredentialIssuerFrontend{
|
||||
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
|
||||
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
|
||||
Server: credentialIssuer.Status.KubeConfigInfo.Server,
|
||||
CertificateAuthorityData: credentialIssuer.Status.KubeConfigInfo.CertificateAuthorityData,
|
||||
},
|
||||
@@ -546,7 +559,7 @@ func getConciergeFrontend(credentialIssuer *configv1alpha1.CredentialIssuer, mod
|
||||
|
||||
// Skip any unknown frontend types.
|
||||
switch strategy.Frontend.Type {
|
||||
case configv1alpha1.TokenCredentialRequestAPIFrontendType, configv1alpha1.ImpersonationProxyFrontendType:
|
||||
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType, conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
|
||||
default:
|
||||
continue
|
||||
}
|
||||
@@ -574,7 +587,7 @@ func newExecKubeconfig(cluster *clientcmdapi.Cluster, execConfig *clientcmdapi.E
|
||||
}
|
||||
}
|
||||
|
||||
func lookupCredentialIssuer(clientset conciergeclientset.Interface, name string, log plog.MinLogger) (*configv1alpha1.CredentialIssuer, error) {
|
||||
func lookupCredentialIssuer(clientset conciergeclientset.Interface, name string, log plog.MinLogger) (*conciergeconfigv1alpha1.CredentialIssuer, error) {
|
||||
ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*20)
|
||||
defer cancelFunc()
|
||||
|
||||
@@ -732,13 +745,12 @@ func validateKubeconfig(ctx context.Context, flags getKubeconfigParams, kubeconf
|
||||
func countCACerts(pemData []byte) int {
|
||||
pool := x509.NewCertPool()
|
||||
pool.AppendCertsFromPEM(pemData)
|
||||
//nolint:staticcheck // since we're not using .Subjects() to access the system pool
|
||||
return len(pool.Subjects())
|
||||
return len(pool.Subjects()) //nolint:staticcheck // there's no other clear way to mimic this legacy behavior
|
||||
}
|
||||
|
||||
func hasPendingStrategy(credentialIssuer *configv1alpha1.CredentialIssuer) bool {
|
||||
func hasPendingStrategy(credentialIssuer *conciergeconfigv1alpha1.CredentialIssuer) bool {
|
||||
for _, strategy := range credentialIssuer.Status.Strategies {
|
||||
if strategy.Reason == configv1alpha1.PendingStrategyReason {
|
||||
if strategy.Reason == conciergeconfigv1alpha1.PendingStrategyReason {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -783,12 +795,12 @@ func pinnipedSupervisorDiscovery(ctx context.Context, flags *getKubeconfigParams
|
||||
return err
|
||||
}
|
||||
if !supervisorSupportsBothUsernameAndGroupsScopes {
|
||||
flags.oidc.scopes = slices.Filter(nil, flags.oidc.scopes, func(scope string) bool {
|
||||
flags.oidc.scopes = slices.DeleteFunc(flags.oidc.scopes, func(scope string) bool {
|
||||
if scope == oidcapi.ScopeUsername || scope == oidcapi.ScopeGroups {
|
||||
log.Info("removed scope from --oidc-scopes list because it is not supported by this Supervisor", "scope", scope)
|
||||
return false // Remove username and groups scopes if there were present in the flags.
|
||||
return true // Remove username and groups scopes if there were present in the flags.
|
||||
}
|
||||
return true // Keep any other scopes in the flag list.
|
||||
return false // Keep any other scopes in the flag list.
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@@ -39,6 +38,18 @@ const (
|
||||
// which specifies "cli_password" when using an IDE plugin where there is no interactive CLI available. This allows
|
||||
// the user to use one kubeconfig file for both flows.
|
||||
upstreamIdentityProviderFlowEnvVarName = "PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW"
|
||||
|
||||
// When using a browser-based login flow, the user may skip printing the login URL to the screen in the case
|
||||
// where the browser was launched with the login URL. This can be useful, for example, when using a console-based
|
||||
// UI like k9s, to avoid having any output to stderr which may confuse the UI. Set this env var to "true" to
|
||||
// skip printing the URL.
|
||||
skipPrintLoginURLEnvVarName = "PINNIPED_SKIP_PRINT_LOGIN_URL"
|
||||
|
||||
// Set this env var to "true" to cause debug logs to be printed to stderr.
|
||||
debugEnvVarName = "PINNIPED_DEBUG"
|
||||
|
||||
// The value to use for true/false env vars to enable the behavior caused by the env var.
|
||||
envVarTruthyValue = "true"
|
||||
)
|
||||
|
||||
//nolint:gochecknoinits
|
||||
@@ -47,9 +58,10 @@ func init() {
|
||||
}
|
||||
|
||||
type oidcLoginCommandDeps struct {
|
||||
lookupEnv func(string) (string, bool)
|
||||
login func(string, string, ...oidcclient.Option) (*oidctypes.Token, error)
|
||||
exchangeToken func(context.Context, *conciergeclient.Client, string) (*clientauthv1beta1.ExecCredential, error)
|
||||
lookupEnv func(string) (string, bool)
|
||||
login func(string, string, ...oidcclient.Option) (*oidctypes.Token, error)
|
||||
exchangeToken func(context.Context, *conciergeclient.Client, string) (*clientauthv1beta1.ExecCredential, error)
|
||||
optionsFactory OIDCClientOptions
|
||||
}
|
||||
|
||||
func oidcLoginCommandRealDeps() oidcLoginCommandDeps {
|
||||
@@ -59,6 +71,7 @@ func oidcLoginCommandRealDeps() oidcLoginCommandDeps {
|
||||
exchangeToken: func(ctx context.Context, client *conciergeclient.Client, token string) (*clientauthv1beta1.ExecCredential, error) {
|
||||
return client.ExchangeToken(ctx, token)
|
||||
},
|
||||
optionsFactory: &clientOptions{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,14 +141,23 @@ func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command {
|
||||
cmd.Flags().StringVar(&flags.conciergeAPIGroupSuffix, "concierge-api-group-suffix", groupsuffix.PinnipedDefaultSuffix, "Concierge API group suffix")
|
||||
cmd.Flags().StringVar(&flags.credentialCachePath, "credential-cache", filepath.Join(mustGetConfigDir(), "credentials.yaml"), "Path to cluster-specific credentials cache (\"\" disables the cache)")
|
||||
cmd.Flags().StringVar(&flags.upstreamIdentityProviderName, "upstream-identity-provider-name", "", "The name of the upstream identity provider used during login with a Supervisor")
|
||||
cmd.Flags().StringVar(&flags.upstreamIdentityProviderType, "upstream-identity-provider-type", idpdiscoveryv1alpha1.IDPTypeOIDC.String(), fmt.Sprintf("The type of the upstream identity provider used during login with a Supervisor (e.g. '%s', '%s', '%s')", idpdiscoveryv1alpha1.IDPTypeOIDC, idpdiscoveryv1alpha1.IDPTypeLDAP, idpdiscoveryv1alpha1.IDPTypeActiveDirectory))
|
||||
cmd.Flags().StringVar(&flags.upstreamIdentityProviderType,
|
||||
"upstream-identity-provider-type",
|
||||
idpdiscoveryv1alpha1.IDPTypeOIDC.String(),
|
||||
fmt.Sprintf(
|
||||
"The type of the upstream identity provider used during login with a Supervisor (e.g. '%s', '%s', '%s', '%s')",
|
||||
idpdiscoveryv1alpha1.IDPTypeOIDC,
|
||||
idpdiscoveryv1alpha1.IDPTypeLDAP,
|
||||
idpdiscoveryv1alpha1.IDPTypeActiveDirectory,
|
||||
idpdiscoveryv1alpha1.IDPTypeGitHub,
|
||||
))
|
||||
cmd.Flags().StringVar(&flags.upstreamIdentityProviderFlow, "upstream-identity-provider-flow", "", fmt.Sprintf("The type of client flow to use with the upstream identity provider during login with a Supervisor (e.g. '%s', '%s')", idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode, idpdiscoveryv1alpha1.IDPFlowCLIPassword))
|
||||
|
||||
// --skip-listen is mainly needed for testing. We'll leave it hidden until we have a non-testing use case.
|
||||
mustMarkHidden(cmd, "skip-listen")
|
||||
mustMarkHidden(cmd, "debug-session-cache")
|
||||
mustMarkRequired(cmd, "issuer")
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error { return runOIDCLogin(cmd, deps, flags) }
|
||||
cmd.RunE = func(cmd *cobra.Command, _args []string) error { return runOIDCLogin(cmd, deps, flags) }
|
||||
|
||||
mustMarkDeprecated(cmd, "concierge-namespace", "not needed anymore")
|
||||
mustMarkHidden(cmd, "concierge-namespace")
|
||||
@@ -154,43 +176,45 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
|
||||
|
||||
// If the hidden --debug-session-cache option is passed, log all the errors from the session cache.
|
||||
if flags.debugSessionCache {
|
||||
logger := plog.WithName("session")
|
||||
sessionOptions = append(sessionOptions, filesession.WithErrorReporter(func(err error) {
|
||||
logger.Error("error during session cache operation", err)
|
||||
pLogger.Error("error during session cache operation", err)
|
||||
}))
|
||||
}
|
||||
sessionCache := filesession.New(flags.sessionCachePath, sessionOptions...)
|
||||
|
||||
// Initialize the login handler.
|
||||
opts := []oidcclient.Option{
|
||||
oidcclient.WithContext(cmd.Context()),
|
||||
oidcclient.WithLogger(plog.Logr()), //nolint:staticcheck // old code with lots of log statements
|
||||
oidcclient.WithScopes(flags.scopes),
|
||||
oidcclient.WithSessionCache(sessionCache),
|
||||
deps.optionsFactory.WithContext(cmd.Context()),
|
||||
deps.optionsFactory.WithLoginLogger(pLogger),
|
||||
deps.optionsFactory.WithScopes(flags.scopes),
|
||||
deps.optionsFactory.WithSessionCache(sessionCache),
|
||||
}
|
||||
|
||||
skipPrintLoginURL, _ := deps.lookupEnv(skipPrintLoginURLEnvVarName)
|
||||
if skipPrintLoginURL == envVarTruthyValue {
|
||||
opts = append(opts, deps.optionsFactory.WithSkipPrintLoginURL())
|
||||
}
|
||||
|
||||
if flags.listenPort != 0 {
|
||||
opts = append(opts, oidcclient.WithListenPort(flags.listenPort))
|
||||
opts = append(opts, deps.optionsFactory.WithListenPort(flags.listenPort))
|
||||
}
|
||||
|
||||
if flags.requestAudience != "" {
|
||||
opts = append(opts, oidcclient.WithRequestAudience(flags.requestAudience))
|
||||
opts = append(opts, deps.optionsFactory.WithRequestAudience(flags.requestAudience))
|
||||
}
|
||||
|
||||
if flags.upstreamIdentityProviderName != "" {
|
||||
opts = append(opts, oidcclient.WithUpstreamIdentityProvider(
|
||||
opts = append(opts, deps.optionsFactory.WithUpstreamIdentityProvider(
|
||||
flags.upstreamIdentityProviderName, flags.upstreamIdentityProviderType))
|
||||
}
|
||||
|
||||
flowOpts, err := flowOptions(
|
||||
idpdiscoveryv1alpha1.IDPType(flags.upstreamIdentityProviderType),
|
||||
idpdiscoveryv1alpha1.IDPFlow(flags.upstreamIdentityProviderFlow),
|
||||
deps,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
requestedFlow, flowSource := idpdiscoveryv1alpha1.IDPFlow(flags.upstreamIdentityProviderFlow), "--upstream-identity-provider-flow"
|
||||
if flowOverride, hasFlowOverride := deps.lookupEnv(upstreamIdentityProviderFlowEnvVarName); hasFlowOverride {
|
||||
requestedFlow, flowSource = idpdiscoveryv1alpha1.IDPFlow(flowOverride), upstreamIdentityProviderFlowEnvVarName
|
||||
}
|
||||
if requestedFlow != "" {
|
||||
opts = append(opts, deps.optionsFactory.WithLoginFlow(requestedFlow, flowSource))
|
||||
}
|
||||
opts = append(opts, flowOpts...)
|
||||
|
||||
var concierge *conciergeclient.Client
|
||||
if flags.conciergeEnabled {
|
||||
@@ -200,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)
|
||||
@@ -208,12 +233,12 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
|
||||
|
||||
// --skip-browser skips opening the browser.
|
||||
if flags.skipBrowser {
|
||||
opts = append(opts, oidcclient.WithSkipBrowserOpen())
|
||||
opts = append(opts, deps.optionsFactory.WithSkipBrowserOpen())
|
||||
}
|
||||
|
||||
// --skip-listen skips starting the localhost callback listener.
|
||||
if flags.skipListen {
|
||||
opts = append(opts, oidcclient.WithSkipListen())
|
||||
opts = append(opts, deps.optionsFactory.WithSkipListen())
|
||||
}
|
||||
|
||||
if len(flags.caBundlePaths) > 0 || len(flags.caBundleData) > 0 {
|
||||
@@ -221,7 +246,7 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts = append(opts, oidcclient.WithClient(client))
|
||||
opts = append(opts, deps.optionsFactory.WithClient(client))
|
||||
}
|
||||
// Look up cached credentials based on a hash of all the CLI arguments and the cluster info.
|
||||
cacheKey := struct {
|
||||
@@ -241,12 +266,12 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
|
||||
}
|
||||
|
||||
pLogger.Debug("Performing OIDC login", "issuer", flags.issuer, "client id", flags.clientID)
|
||||
// Do the basic login to get an OIDC token.
|
||||
// Do the basic login to get an OIDC token. Although this can return several tokens, we only need the ID token here.
|
||||
token, err := deps.login(flags.issuer, flags.clientID, opts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not complete Pinniped login: %w", err)
|
||||
}
|
||||
cred := tokenCredential(token)
|
||||
cred := tokenCredential(token.IDToken)
|
||||
|
||||
// If the concierge was configured, exchange the credential for a separate short-lived, cluster-specific credential.
|
||||
if concierge != nil {
|
||||
@@ -271,60 +296,6 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
|
||||
return json.NewEncoder(cmd.OutOrStdout()).Encode(cred)
|
||||
}
|
||||
|
||||
func flowOptions(
|
||||
requestedIDPType idpdiscoveryv1alpha1.IDPType,
|
||||
requestedFlow idpdiscoveryv1alpha1.IDPFlow,
|
||||
deps oidcLoginCommandDeps,
|
||||
) ([]oidcclient.Option, error) {
|
||||
useCLIFlow := []oidcclient.Option{oidcclient.WithCLISendingCredentials()}
|
||||
|
||||
// If the env var is set to override the --upstream-identity-provider-type flag, then override it.
|
||||
flowOverride, hasFlowOverride := deps.lookupEnv(upstreamIdentityProviderFlowEnvVarName)
|
||||
flowSource := "--upstream-identity-provider-flow"
|
||||
if hasFlowOverride {
|
||||
requestedFlow = idpdiscoveryv1alpha1.IDPFlow(flowOverride)
|
||||
flowSource = upstreamIdentityProviderFlowEnvVarName
|
||||
}
|
||||
|
||||
switch requestedIDPType {
|
||||
case idpdiscoveryv1alpha1.IDPTypeOIDC:
|
||||
switch requestedFlow {
|
||||
case idpdiscoveryv1alpha1.IDPFlowCLIPassword:
|
||||
return useCLIFlow, nil
|
||||
case idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode, "":
|
||||
return nil, nil // browser authcode flow is the default Option, so don't need to return an Option here
|
||||
default:
|
||||
return nil, fmt.Errorf(
|
||||
"%s value not recognized for identity provider type %q: %s (supported values: %s)",
|
||||
flowSource, requestedIDPType, requestedFlow,
|
||||
strings.Join([]string{idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode.String(), idpdiscoveryv1alpha1.IDPFlowCLIPassword.String()}, ", "))
|
||||
}
|
||||
case idpdiscoveryv1alpha1.IDPTypeLDAP, idpdiscoveryv1alpha1.IDPTypeActiveDirectory:
|
||||
switch requestedFlow {
|
||||
case idpdiscoveryv1alpha1.IDPFlowCLIPassword, "":
|
||||
return useCLIFlow, nil
|
||||
case idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode:
|
||||
return nil, nil // browser authcode flow is the default Option, so don't need to return an Option here
|
||||
default:
|
||||
return nil, fmt.Errorf(
|
||||
"%s value not recognized for identity provider type %q: %s (supported values: %s)",
|
||||
flowSource, requestedIDPType, requestedFlow,
|
||||
strings.Join([]string{idpdiscoveryv1alpha1.IDPFlowCLIPassword.String(), idpdiscoveryv1alpha1.IDPFlowBrowserAuthcode.String()}, ", "))
|
||||
}
|
||||
default:
|
||||
// Surprisingly cobra does not support this kind of flag validation. See https://github.com/spf13/pflag/issues/236
|
||||
return nil, fmt.Errorf(
|
||||
"--upstream-identity-provider-type value not recognized: %s (supported values: %s)",
|
||||
requestedIDPType,
|
||||
strings.Join([]string{
|
||||
idpdiscoveryv1alpha1.IDPTypeOIDC.String(),
|
||||
idpdiscoveryv1alpha1.IDPTypeLDAP.String(),
|
||||
idpdiscoveryv1alpha1.IDPTypeActiveDirectory.String(),
|
||||
}, ", "),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func makeClient(caBundlePaths []string, caBundleData []string) (*http.Client, error) {
|
||||
pool := x509.NewCertPool()
|
||||
for _, p := range caBundlePaths {
|
||||
@@ -344,32 +315,31 @@ func makeClient(caBundlePaths []string, caBundleData []string) (*http.Client, er
|
||||
return phttp.Default(pool), nil
|
||||
}
|
||||
|
||||
func tokenCredential(token *oidctypes.Token) *clientauthv1beta1.ExecCredential {
|
||||
func tokenCredential(idToken *oidctypes.IDToken) *clientauthv1beta1.ExecCredential {
|
||||
cred := clientauthv1beta1.ExecCredential{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "ExecCredential",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
},
|
||||
Status: &clientauthv1beta1.ExecCredentialStatus{
|
||||
Token: token.IDToken.Token,
|
||||
Token: idToken.Token,
|
||||
},
|
||||
}
|
||||
if !token.IDToken.Expiry.IsZero() {
|
||||
cred.Status.ExpirationTimestamp = &token.IDToken.Expiry
|
||||
if !idToken.Expiry.IsZero() {
|
||||
cred.Status.ExpirationTimestamp = &idToken.Expiry
|
||||
}
|
||||
return &cred
|
||||
}
|
||||
|
||||
func SetLogLevel(ctx context.Context, lookupEnv func(string) (string, bool)) (plog.Logger, error) {
|
||||
debug, _ := lookupEnv("PINNIPED_DEBUG")
|
||||
if debug == "true" {
|
||||
debug, _ := lookupEnv(debugEnvVarName)
|
||||
if debug == envVarTruthyValue {
|
||||
err := plog.ValidateAndSetLogLevelAndFormatGlobally(ctx, plog.LogSpec{Level: plog.LevelDebug, Format: plog.FormatCLI})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
logger := plog.New().WithName("pinniped-login")
|
||||
return logger, nil
|
||||
return plog.New(), nil
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -10,18 +10,22 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clientauthv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||
clocktesting "k8s.io/utils/clock/testing"
|
||||
|
||||
idpdiscoveryv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
|
||||
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
|
||||
"go.pinniped.dev/internal/certauthority"
|
||||
"go.pinniped.dev/internal/here"
|
||||
"go.pinniped.dev/internal/mocks/mockoidcclientoptions"
|
||||
"go.pinniped.dev/internal/plog"
|
||||
"go.pinniped.dev/internal/testutil"
|
||||
"go.pinniped.dev/pkg/conciergeclient"
|
||||
"go.pinniped.dev/pkg/oidcclient"
|
||||
"go.pinniped.dev/pkg/oidcclient/oidctypes"
|
||||
@@ -42,6 +46,13 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
nowStr := now.Local().Format(time.RFC1123)
|
||||
|
||||
defaultWantedOptions := func(f *mockoidcclientoptions.MockOIDCClientOptions) {
|
||||
f.EXPECT().WithContext(gomock.Any())
|
||||
f.EXPECT().WithLoginLogger(gomock.Any())
|
||||
f.EXPECT().WithScopes([]string{oidcapi.ScopeOfflineAccess, oidcapi.ScopeOpenID, oidcapi.ScopeRequestAudience, oidcapi.ScopeUsername, oidcapi.ScopeGroups})
|
||||
f.EXPECT().WithSessionCache(gomock.Any())
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
@@ -51,6 +62,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
wantError bool
|
||||
wantStdout string
|
||||
wantStderr string
|
||||
wantOptions func(f *mockoidcclientoptions.MockOIDCClientOptions)
|
||||
wantOptionsCount int
|
||||
wantLogs []string
|
||||
}{
|
||||
@@ -91,7 +103,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
--skip-browser Skip opening the browser (just print the URL)
|
||||
--upstream-identity-provider-flow string The type of client flow to use with the upstream identity provider during login with a Supervisor (e.g. 'browser_authcode', 'cli_password')
|
||||
--upstream-identity-provider-name string The name of the upstream identity provider used during login with a Supervisor
|
||||
--upstream-identity-provider-type string The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap', 'activedirectory') (default "oidc")
|
||||
--upstream-identity-provider-type string The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap', 'activedirectory', 'github') (default "oidc")
|
||||
`),
|
||||
},
|
||||
{
|
||||
@@ -109,7 +121,8 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--issuer", "test-issuer",
|
||||
"--enable-concierge",
|
||||
},
|
||||
wantError: true,
|
||||
wantOptions: defaultWantedOptions,
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: invalid Concierge parameters: endpoint must not be empty
|
||||
`),
|
||||
@@ -121,7 +134,8 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--issuer", "test-issuer",
|
||||
"--ca-bundle", "./does/not/exist",
|
||||
},
|
||||
wantError: true,
|
||||
wantOptions: defaultWantedOptions,
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: could not read --ca-bundle: open ./does/not/exist: no such file or directory
|
||||
`),
|
||||
@@ -133,7 +147,8 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--issuer", "test-issuer",
|
||||
"--ca-bundle-data", "invalid-base64",
|
||||
},
|
||||
wantError: true,
|
||||
wantOptions: defaultWantedOptions,
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: could not read --ca-bundle-data: illegal base64 data at input byte 7
|
||||
`),
|
||||
@@ -148,34 +163,12 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--concierge-authenticator-name", "test-authenticator",
|
||||
"--concierge-endpoint", "https://127.0.0.1:1234/",
|
||||
},
|
||||
wantError: true,
|
||||
wantOptions: defaultWantedOptions,
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: invalid Concierge parameters: invalid API group suffix: a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "invalid upstream type is an error",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--upstream-identity-provider-type", "invalid",
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: --upstream-identity-provider-type value not recognized: invalid (supported values: oidc, ldap, activedirectory)
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "invalid upstream type when flow override env var is used is still an error",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--upstream-identity-provider-type", "invalid",
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "browser_authcode"},
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: --upstream-identity-provider-type value not recognized: invalid (supported values: oidc, ldap, activedirectory)
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "oidc upstream type with default flow is allowed",
|
||||
args: []string{
|
||||
@@ -184,268 +177,57 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--upstream-identity-provider-type", "oidc",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
wantOptions: defaultWantedOptions,
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "oidc upstream type with CLI flow is allowed",
|
||||
name: "PINNIPED_SKIP_PRINT_LOGIN_URL adds an option",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "oidc",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_SKIP_PRINT_LOGIN_URL": "true"},
|
||||
wantOptions: func(f *mockoidcclientoptions.MockOIDCClientOptions) {
|
||||
defaultWantedOptions(f)
|
||||
f.EXPECT().WithSkipPrintLoginURL()
|
||||
},
|
||||
wantOptionsCount: 5,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "--upstream-identity-provider-flow adds an option",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-flow", "cli_password",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
wantOptionsCount: 5,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "oidc upstream type with browser flow is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "oidc",
|
||||
"--upstream-identity-provider-flow", "browser_authcode",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "oidc upstream type with CLI flow in flow override env var is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "oidc",
|
||||
"--upstream-identity-provider-flow", "browser_authcode",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "cli_password"},
|
||||
wantOptionsCount: 5,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "oidc upstream type with with browser flow in flow override env var is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "oidc",
|
||||
"--upstream-identity-provider-flow", "cli_password",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "browser_authcode"},
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "oidc upstream type with unsupported flow is an error",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "oidc",
|
||||
"--upstream-identity-provider-flow", "foobar",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: --upstream-identity-provider-flow value not recognized for identity provider type "oidc": foobar (supported values: browser_authcode, cli_password)
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "oidc upstream type with unsupported flow in flow override env var is an error",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "oidc",
|
||||
"--upstream-identity-provider-flow", "browser_authcode",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "foo"},
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW value not recognized for identity provider type "oidc": foo (supported values: browser_authcode, cli_password)
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "ldap upstream type with default flow is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "ldap",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
wantOptions: func(f *mockoidcclientoptions.MockOIDCClientOptions) {
|
||||
defaultWantedOptions(f)
|
||||
f.EXPECT().WithLoginFlow(idpdiscoveryv1alpha1.IDPFlowCLIPassword, "--upstream-identity-provider-flow")
|
||||
},
|
||||
wantOptionsCount: 5,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "activedirectory upstream type with default flow is allowed",
|
||||
name: "PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW adds an option that overrides --upstream-identity-provider-flow",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "activedirectory",
|
||||
"--upstream-identity-provider-flow", "ignored-value-from-param",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "actual-value-from-env"},
|
||||
wantOptions: func(f *mockoidcclientoptions.MockOIDCClientOptions) {
|
||||
defaultWantedOptions(f)
|
||||
f.EXPECT().WithLoginFlow(idpdiscoveryv1alpha1.IDPFlow("actual-value-from-env"), "PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW")
|
||||
},
|
||||
wantOptionsCount: 5,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "ldap upstream type with CLI flow is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "ldap",
|
||||
"--upstream-identity-provider-flow", "cli_password",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
wantOptionsCount: 5,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "ldap upstream type with browser_authcode flow is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "ldap",
|
||||
"--upstream-identity-provider-flow", "browser_authcode",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "ldap upstream type with CLI flow in flow override env var is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "ldap",
|
||||
"--upstream-identity-provider-flow", "browser_authcode",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "cli_password"},
|
||||
wantOptionsCount: 5,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "ldap upstream type with browser_authcode flow in flow override env var is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "ldap",
|
||||
"--upstream-identity-provider-flow", "cli_password",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "browser_authcode"},
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "ldap upstream type with unsupported flow is an error",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "ldap",
|
||||
"--upstream-identity-provider-flow", "foo",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: --upstream-identity-provider-flow value not recognized for identity provider type "ldap": foo (supported values: cli_password, browser_authcode)
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "ldap upstream type with unsupported flow in flow override env var is an error",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "ldap",
|
||||
"--upstream-identity-provider-flow", "browser_authcode",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "foo"},
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW value not recognized for identity provider type "ldap": foo (supported values: cli_password, browser_authcode)
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "active directory upstream type with CLI flow is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "activedirectory",
|
||||
"--upstream-identity-provider-flow", "cli_password",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
wantOptionsCount: 5,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "active directory upstream type with browser_authcode is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "activedirectory",
|
||||
"--upstream-identity-provider-flow", "browser_authcode",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "active directory upstream type with CLI flow in flow override env var is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "activedirectory",
|
||||
"--upstream-identity-provider-flow", "browser_authcode",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "cli_password"},
|
||||
wantOptionsCount: 5,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "active directory upstream type with browser_authcode in flow override env var is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "activedirectory",
|
||||
"--upstream-identity-provider-flow", "cli_password",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "browser_authcode"},
|
||||
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",
|
||||
},
|
||||
{
|
||||
name: "active directory upstream type with unsupported flow is an error",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "activedirectory",
|
||||
"--upstream-identity-provider-flow", "foo",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: --upstream-identity-provider-flow value not recognized for identity provider type "activedirectory": foo (supported values: cli_password, browser_authcode)
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "active directory upstream type with unsupported flow in flow override env var is an error",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "activedirectory",
|
||||
"--upstream-identity-provider-flow", "browser_authcode",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW": "foo"},
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: PINNIPED_UPSTREAM_IDENTITY_PROVIDER_FLOW value not recognized for identity provider type "activedirectory": foo (supported values: cli_password, browser_authcode)
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "login error",
|
||||
args: []string{
|
||||
@@ -454,6 +236,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
loginErr: fmt.Errorf("some login error"),
|
||||
wantOptions: defaultWantedOptions,
|
||||
wantOptionsCount: 4,
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
@@ -472,6 +255,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
conciergeErr: fmt.Errorf("some concierge error"),
|
||||
wantOptions: defaultWantedOptions,
|
||||
wantOptionsCount: 4,
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
@@ -486,11 +270,12 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_DEBUG": "true"},
|
||||
wantOptions: defaultWantedOptions,
|
||||
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 + ` pinniped-login cmd/login_oidc.go:243 Performing OIDC login {"issuer": "test-issuer", "client id": "test-client-id"}`,
|
||||
nowStr + ` pinniped-login cmd/login_oidc.go:263 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`,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -514,24 +299,45 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--credential-cache", t.TempDir() + "/credentials.yaml", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
"--upstream-identity-provider-name", "some-upstream-name",
|
||||
"--upstream-identity-provider-type", "ldap",
|
||||
"--upstream-identity-provider-flow", "some-flow-type",
|
||||
},
|
||||
env: map[string]string{"PINNIPED_DEBUG": "true"},
|
||||
wantOptionsCount: 11,
|
||||
env: map[string]string{"PINNIPED_DEBUG": "true", "PINNIPED_SKIP_PRINT_LOGIN_URL": "true"},
|
||||
wantOptions: func(f *mockoidcclientoptions.MockOIDCClientOptions) {
|
||||
f.EXPECT().WithContext(gomock.Any())
|
||||
f.EXPECT().WithLoginLogger(gomock.Any())
|
||||
f.EXPECT().WithScopes([]string{oidcapi.ScopeOfflineAccess, oidcapi.ScopeOpenID, oidcapi.ScopeRequestAudience, oidcapi.ScopeUsername, oidcapi.ScopeGroups})
|
||||
f.EXPECT().WithSessionCache(gomock.Any())
|
||||
f.EXPECT().WithListenPort(uint16(1234))
|
||||
f.EXPECT().WithSkipBrowserOpen()
|
||||
f.EXPECT().WithSkipListen()
|
||||
f.EXPECT().WithSkipPrintLoginURL()
|
||||
f.EXPECT().WithClient(gomock.Any())
|
||||
f.EXPECT().WithRequestAudience("cluster-1234")
|
||||
f.EXPECT().WithLoginFlow(idpdiscoveryv1alpha1.IDPFlow("some-flow-type"), "--upstream-identity-provider-flow")
|
||||
f.EXPECT().WithUpstreamIdentityProvider("some-upstream-name", "ldap")
|
||||
},
|
||||
wantOptionsCount: 12,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"token":"exchanged-token"}}` + "\n",
|
||||
wantLogs: []string{
|
||||
nowStr + ` pinniped-login cmd/login_oidc.go:243 Performing OIDC login {"issuer": "test-issuer", "client id": "test-client-id"}`,
|
||||
nowStr + ` pinniped-login cmd/login_oidc.go:253 Exchanging token for cluster credential {"endpoint": "https://127.0.0.1:1234/", "authenticator type": "webhook", "authenticator name": "test-authenticator"}`,
|
||||
nowStr + ` pinniped-login cmd/login_oidc.go:261 Successfully exchanged token for cluster credential.`,
|
||||
nowStr + ` pinniped-login cmd/login_oidc.go:268 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.`,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
ctx := plog.AddZapOverridesToContext(context.Background(), t, &buf, nil, clocktesting.NewFakeClock(now))
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
t.Cleanup(ctrl.Finish)
|
||||
optionsFactory := mockoidcclientoptions.NewMockOIDCClientOptions(ctrl)
|
||||
if tt.wantOptions != nil {
|
||||
tt.wantOptions(optionsFactory)
|
||||
}
|
||||
|
||||
var gotOptions []oidcclient.Option
|
||||
cmd := oidcLoginCommand(oidcLoginCommandDeps{
|
||||
lookupEnv: func(s string) (string, bool) {
|
||||
@@ -567,6 +373,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
optionsFactory: optionsFactory,
|
||||
})
|
||||
require.NotNil(t, cmd)
|
||||
|
||||
@@ -584,15 +391,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
require.Equal(t, tt.wantStderr, stderr.String(), "unexpected stderr")
|
||||
require.Len(t, gotOptions, tt.wantOptionsCount)
|
||||
|
||||
require.Equal(t, tt.wantLogs, logLines(buf.String()))
|
||||
require.Equal(t, tt.wantLogs, testutil.SplitByNewline(buf.String()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func logLines(logs string) []string {
|
||||
if len(logs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return strings.Split(strings.TrimSpace(logs), "\n")
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -86,7 +86,7 @@ func staticLoginCommand(deps staticLoginDeps) *cobra.Command {
|
||||
cmd.Flags().StringVar(&flags.conciergeAPIGroupSuffix, "concierge-api-group-suffix", groupsuffix.PinnipedDefaultSuffix, "Concierge API group suffix")
|
||||
cmd.Flags().StringVar(&flags.credentialCachePath, "credential-cache", filepath.Join(mustGetConfigDir(), "credentials.yaml"), "Path to cluster-specific credentials cache (\"\" disables the cache)")
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error { return runStaticLogin(cmd, deps, flags) }
|
||||
cmd.RunE = func(cmd *cobra.Command, _args []string) error { return runStaticLogin(cmd, deps, flags) }
|
||||
|
||||
mustMarkDeprecated(cmd, "concierge-namespace", "not needed anymore")
|
||||
mustMarkHidden(cmd, "concierge-namespace")
|
||||
@@ -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)
|
||||
@@ -133,7 +134,7 @@ func runStaticLogin(cmd *cobra.Command, deps staticLoginDeps, flags staticLoginP
|
||||
return fmt.Errorf("--token-env variable %q is empty", flags.staticTokenEnvName)
|
||||
}
|
||||
}
|
||||
cred := tokenCredential(&oidctypes.Token{IDToken: &oidctypes.IDToken{Token: token}})
|
||||
cred := tokenCredential(&oidctypes.IDToken{Token: token})
|
||||
|
||||
// Look up cached credentials based on a hash of all the CLI arguments, the current token value, and the cluster info.
|
||||
cacheKey := struct {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"go.pinniped.dev/internal/certauthority"
|
||||
"go.pinniped.dev/internal/here"
|
||||
"go.pinniped.dev/internal/plog"
|
||||
"go.pinniped.dev/internal/testutil"
|
||||
"go.pinniped.dev/pkg/conciergeclient"
|
||||
)
|
||||
|
||||
@@ -146,7 +147,7 @@ func TestLoginStaticCommand(t *testing.T) {
|
||||
Error: could not complete Concierge credential exchange: some concierge error
|
||||
`),
|
||||
wantLogs: []string{
|
||||
nowStr + ` pinniped-login 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"}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -174,7 +175,6 @@ func TestLoginStaticCommand(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
ctx := plog.AddZapOverridesToContext(context.Background(), t, &buf, nil, clocktesting.NewFakeClock(now))
|
||||
@@ -215,7 +215,7 @@ func TestLoginStaticCommand(t *testing.T) {
|
||||
require.Equal(t, tt.wantStdout, stdout.String(), "unexpected stdout")
|
||||
require.Equal(t, tt.wantStderr, stderr.String(), "unexpected stderr")
|
||||
|
||||
require.Equal(t, tt.wantLogs, logLines(buf.String()))
|
||||
require.Equal(t, tt.wantLogs, testutil.SplitByNewline(buf.String()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
84
cmd/pinniped/cmd/oidc_client_options.go
Normal file
84
cmd/pinniped/cmd/oidc_client_options.go
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
|
||||
"go.pinniped.dev/pkg/oidcclient"
|
||||
)
|
||||
|
||||
// OIDCClientOptions is an interface that wraps the creation of Options for the purpose of making them
|
||||
// more friendly to unit tests. Because the Option type refers to a private struct type, it is hard
|
||||
// to create mocks for them in tests of other packages. This provides a seam that can be mocked.
|
||||
// No need for this interface to include deprecated options (such as WithLogger), since those should never be invoked.
|
||||
type OIDCClientOptions interface {
|
||||
WithContext(ctx context.Context) oidcclient.Option
|
||||
WithLoginLogger(logger oidcclient.Logger) oidcclient.Option
|
||||
WithListenPort(port uint16) oidcclient.Option
|
||||
WithSkipBrowserOpen() oidcclient.Option
|
||||
WithSkipListen() oidcclient.Option
|
||||
WithSkipPrintLoginURL() oidcclient.Option
|
||||
WithSessionCache(cache oidcclient.SessionCache) oidcclient.Option
|
||||
WithClient(httpClient *http.Client) oidcclient.Option
|
||||
WithScopes(scopes []string) oidcclient.Option
|
||||
WithRequestAudience(audience string) oidcclient.Option
|
||||
WithLoginFlow(loginFlow v1alpha1.IDPFlow, flowSource string) oidcclient.Option
|
||||
WithUpstreamIdentityProvider(upstreamName, upstreamType string) oidcclient.Option
|
||||
}
|
||||
|
||||
// clientOptions implements OIDCClientOptions for production use.
|
||||
type clientOptions struct{}
|
||||
|
||||
var _ OIDCClientOptions = (*clientOptions)(nil)
|
||||
|
||||
func (o *clientOptions) WithContext(ctx context.Context) oidcclient.Option {
|
||||
return oidcclient.WithContext(ctx)
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithLoginLogger(logger oidcclient.Logger) oidcclient.Option {
|
||||
return oidcclient.WithLoginLogger(logger)
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithListenPort(port uint16) oidcclient.Option {
|
||||
return oidcclient.WithListenPort(port)
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithSkipBrowserOpen() oidcclient.Option {
|
||||
return oidcclient.WithSkipBrowserOpen()
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithSkipListen() oidcclient.Option {
|
||||
return oidcclient.WithSkipListen()
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithSkipPrintLoginURL() oidcclient.Option {
|
||||
return oidcclient.WithSkipPrintLoginURL()
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithSessionCache(cache oidcclient.SessionCache) oidcclient.Option {
|
||||
return oidcclient.WithSessionCache(cache)
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithClient(httpClient *http.Client) oidcclient.Option {
|
||||
return oidcclient.WithClient(httpClient)
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithScopes(scopes []string) oidcclient.Option {
|
||||
return oidcclient.WithScopes(scopes)
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithRequestAudience(audience string) oidcclient.Option {
|
||||
return oidcclient.WithRequestAudience(audience)
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithLoginFlow(loginFlow v1alpha1.IDPFlow, flowSource string) oidcclient.Option {
|
||||
return oidcclient.WithLoginFlow(loginFlow, flowSource)
|
||||
}
|
||||
|
||||
func (o *clientOptions) WithUpstreamIdentityProvider(upstreamName, upstreamType string) oidcclient.Option {
|
||||
return oidcclient.WithUpstreamIdentityProvider(upstreamName, upstreamType)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -126,7 +126,6 @@ func TestNewVersionCmd(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.getBuildInfo != nil {
|
||||
getBuildInfo = tt.getBuildInfo
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
@@ -24,9 +24,21 @@ import (
|
||||
"go.pinniped.dev/internal/here"
|
||||
)
|
||||
|
||||
type whoamiDeps struct {
|
||||
getenv func(key string) string
|
||||
getClientset getConciergeClientsetFunc
|
||||
}
|
||||
|
||||
func whoamiRealDeps() whoamiDeps {
|
||||
return whoamiDeps{
|
||||
getenv: os.Getenv,
|
||||
getClientset: getRealConciergeClientset,
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:gochecknoinits
|
||||
func init() {
|
||||
rootCmd.AddCommand(newWhoamiCommand(getRealConciergeClientset))
|
||||
rootCmd.AddCommand(newWhoamiCommand(whoamiRealDeps()))
|
||||
}
|
||||
|
||||
type whoamiFlags struct {
|
||||
@@ -44,7 +56,7 @@ type clusterInfo struct {
|
||||
url string
|
||||
}
|
||||
|
||||
func newWhoamiCommand(getClientset getConciergeClientsetFunc) *cobra.Command {
|
||||
func newWhoamiCommand(deps whoamiDeps) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.NoArgs, // do not accept positional arguments for this command
|
||||
Use: "whoami",
|
||||
@@ -56,21 +68,21 @@ func newWhoamiCommand(getClientset getConciergeClientsetFunc) *cobra.Command {
|
||||
// flags
|
||||
f := cmd.Flags()
|
||||
f.StringVarP(&flags.outputFormat, "output", "o", "text", "Output format (e.g., 'yaml', 'json', 'text')")
|
||||
f.StringVar(&flags.kubeconfigPath, "kubeconfig", os.Getenv("KUBECONFIG"), "Path to kubeconfig file")
|
||||
f.StringVar(&flags.kubeconfigPath, "kubeconfig", deps.getenv("KUBECONFIG"), "Path to kubeconfig file")
|
||||
f.StringVar(&flags.kubeconfigContextOverride, "kubeconfig-context", "", "Kubeconfig context name (default: current active context)")
|
||||
f.StringVar(&flags.apiGroupSuffix, "api-group-suffix", groupsuffix.PinnipedDefaultSuffix, "Concierge API group suffix")
|
||||
f.DurationVar(&flags.timeout, "timeout", 0, "Timeout for the WhoAmI API request (default: 0, meaning no timeout)")
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, _ []string) error {
|
||||
return runWhoami(cmd.OutOrStdout(), getClientset, flags)
|
||||
return runWhoami(cmd.OutOrStdout(), deps, flags)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runWhoami(output io.Writer, getClientset getConciergeClientsetFunc, flags *whoamiFlags) error {
|
||||
func runWhoami(output io.Writer, deps whoamiDeps, flags *whoamiFlags) error {
|
||||
clientConfig := newClientConfig(flags.kubeconfigPath, flags.kubeconfigContextOverride)
|
||||
clientset, err := getClientset(clientConfig, flags.apiGroupSuffix)
|
||||
clientset, err := deps.getClientset(clientConfig, flags.apiGroupSuffix)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not configure Kubernetes client: %w", err)
|
||||
}
|
||||
@@ -99,7 +111,7 @@ func runWhoami(output io.Writer, getClientset getConciergeClientsetFunc, flags *
|
||||
whoAmI, err := clientset.IdentityV1alpha1().WhoAmIRequests().Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
hint := ""
|
||||
if errors.IsNotFound(err) {
|
||||
if apierrors.IsNotFound(err) {
|
||||
hint = " (is the Pinniped WhoAmI API running and healthy?)"
|
||||
}
|
||||
return fmt.Errorf("could not complete WhoAmIRequest%s: %w", hint, err)
|
||||
|
||||
@@ -1,29 +1,46 @@
|
||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2023-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
kubetesting "k8s.io/client-go/testing"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
identityv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/identity/v1alpha1"
|
||||
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
|
||||
fakeconciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
|
||||
conciergefake "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
|
||||
"go.pinniped.dev/internal/constable"
|
||||
"go.pinniped.dev/internal/here"
|
||||
)
|
||||
|
||||
func TestWhoami(t *testing.T) {
|
||||
helpOutputFormatString := here.Doc(`
|
||||
Print information about the current user
|
||||
|
||||
Usage:
|
||||
whoami [flags]
|
||||
|
||||
Flags:
|
||||
--api-group-suffix string Concierge API group suffix (default "pinniped.dev")
|
||||
-h, --help help for whoami
|
||||
--kubeconfig string Path to kubeconfig file%s
|
||||
--kubeconfig-context string Kubeconfig context name (default: current active context)
|
||||
-o, --output string Output format (e.g., 'yaml', 'json', 'text') (default "text")
|
||||
--timeout duration Timeout for the WhoAmI API request (default: 0, meaning no timeout)
|
||||
`)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
env map[string]string
|
||||
groupsOverride []string
|
||||
gettingClientsetErr error
|
||||
callingAPIErr error
|
||||
@@ -31,22 +48,17 @@ func TestWhoami(t *testing.T) {
|
||||
wantStdout, wantStderr string
|
||||
}{
|
||||
{
|
||||
name: "help flag",
|
||||
args: []string{"--help"},
|
||||
wantStdout: here.Doc(`
|
||||
Print information about the current user
|
||||
|
||||
Usage:
|
||||
whoami [flags]
|
||||
|
||||
Flags:
|
||||
--api-group-suffix string Concierge API group suffix (default "pinniped.dev")
|
||||
-h, --help help for whoami
|
||||
--kubeconfig string Path to kubeconfig file
|
||||
--kubeconfig-context string Kubeconfig context name (default: current active context)
|
||||
-o, --output string Output format (e.g., 'yaml', 'json', 'text') (default "text")
|
||||
--timeout duration Timeout for the WhoAmI API request (default: 0, meaning no timeout)
|
||||
`),
|
||||
name: "help flag passed",
|
||||
args: []string{"--help"},
|
||||
wantStdout: fmt.Sprintf(helpOutputFormatString, ""),
|
||||
},
|
||||
{
|
||||
name: "help flag passed with KUBECONFIG env var set",
|
||||
env: map[string]string{
|
||||
"KUBECONFIG": "/path/to/kubeconfig",
|
||||
},
|
||||
args: []string{"--help"},
|
||||
wantStdout: fmt.Sprintf(helpOutputFormatString, ` (default "/path/to/kubeconfig")`),
|
||||
},
|
||||
{
|
||||
name: "text output",
|
||||
@@ -107,8 +119,7 @@ func TestWhoami(t *testing.T) {
|
||||
Current user info:
|
||||
|
||||
Username: some-username
|
||||
Groups:
|
||||
`),
|
||||
Groups:` + " \n"), // Linters and codeformatters don't like the extra space after "Groups:" and before the newline
|
||||
},
|
||||
{
|
||||
name: "json output",
|
||||
@@ -274,19 +285,18 @@ func TestWhoami(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "calling API fails because WhoAmI API is not installed",
|
||||
callingAPIErr: errors.NewNotFound(identityv1alpha1.SchemeGroupVersion.WithResource("whoamirequests").GroupResource(), "whatever"),
|
||||
callingAPIErr: apierrors.NewNotFound(identityv1alpha1.SchemeGroupVersion.WithResource("whoamirequests").GroupResource(), "whatever"),
|
||||
wantError: true,
|
||||
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 {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
getClientset := func(clientConfig clientcmd.ClientConfig, apiGroupSuffix string) (conciergeclientset.Interface, error) {
|
||||
if test.gettingClientsetErr != nil {
|
||||
return nil, test.gettingClientsetErr
|
||||
}
|
||||
clientset := fakeconciergeclientset.NewSimpleClientset()
|
||||
clientset := conciergefake.NewSimpleClientset()
|
||||
clientset.PrependReactor("create", "whoamirequests", func(_ kubetesting.Action) (bool, runtime.Object, error) {
|
||||
if test.callingAPIErr != nil {
|
||||
return true, nil, test.callingAPIErr
|
||||
@@ -308,7 +318,12 @@ func TestWhoami(t *testing.T) {
|
||||
})
|
||||
return clientset, nil
|
||||
}
|
||||
cmd := newWhoamiCommand(getClientset)
|
||||
cmd := newWhoamiCommand(whoamiDeps{
|
||||
getenv: func(key string) string {
|
||||
return test.env[key]
|
||||
},
|
||||
getClientset: getClientset,
|
||||
})
|
||||
|
||||
stdout, stderr := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
cmd.SetOut(stdout)
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: jwtauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
@@ -25,26 +25,35 @@ spec:
|
||||
- jsonPath: .spec.audience
|
||||
name: Audience
|
||||
type: string
|
||||
- jsonPath: .status.phase
|
||||
name: Status
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: "JWTAuthenticator describes the configuration of a JWT authenticator.
|
||||
\n 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."
|
||||
description: |-
|
||||
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.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -56,24 +65,25 @@ spec:
|
||||
minLength: 1
|
||||
type: string
|
||||
claims:
|
||||
description: Claims allows customization of the claims that will be
|
||||
mapped to user identity for Kubernetes access.
|
||||
description: |-
|
||||
Claims allows customization of the claims that will be mapped to user identity
|
||||
for Kubernetes access.
|
||||
properties:
|
||||
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".
|
||||
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".
|
||||
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".
|
||||
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".
|
||||
type: string
|
||||
type: object
|
||||
issuer:
|
||||
description: 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.
|
||||
description: |-
|
||||
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
|
||||
@@ -84,6 +94,39 @@ spec:
|
||||
description: X.509 Certificate Authority (base64-encoded PEM bundle).
|
||||
If omitted, a default set of system roots will be trusted.
|
||||
type: string
|
||||
certificateAuthorityDataSource:
|
||||
description: |-
|
||||
Reference to a CA bundle in a secret or a configmap.
|
||||
Any changes to the CA bundle in the secret or configmap will be dynamically reloaded.
|
||||
properties:
|
||||
key:
|
||||
description: |-
|
||||
Key is the key name within the secret or configmap from which to read the CA bundle.
|
||||
The value found at this key in the secret or configmap must not be empty, and must be a valid PEM-encoded
|
||||
certificate bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind configures whether the CA bundle is being sourced from a Kubernetes secret or a configmap.
|
||||
Allowed values are "Secret" or "ConfigMap".
|
||||
"ConfigMap" uses a Kubernetes configmap to source CA Bundles.
|
||||
"Secret" uses Kubernetes secrets of type kubernetes.io/tls or Opaque to source CA Bundles.
|
||||
enum:
|
||||
- Secret
|
||||
- ConfigMap
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name is the resource name of the secret or configmap from which to read the CA bundle.
|
||||
The referenced secret or configmap must be created in the same namespace where Pinniped Concierge is installed.
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- audience
|
||||
@@ -96,43 +139,35 @@ spec:
|
||||
description: Represents the observations of the authenticator's current
|
||||
state.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
@@ -147,10 +182,6 @@ spec:
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
@@ -165,6 +196,14 @@ spec:
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
phase:
|
||||
default: Pending
|
||||
description: Phase summarizes the overall status of the JWTAuthenticator.
|
||||
enum:
|
||||
- Pending
|
||||
- Ready
|
||||
- Error
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: webhookauthenticators.authentication.concierge.pinniped.dev
|
||||
spec:
|
||||
group: authentication.concierge.pinniped.dev
|
||||
@@ -22,6 +22,9 @@ spec:
|
||||
- jsonPath: .spec.endpoint
|
||||
name: Endpoint
|
||||
type: string
|
||||
- jsonPath: .status.phase
|
||||
name: Status
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
@@ -32,14 +35,19 @@ spec:
|
||||
authenticator.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -58,6 +66,39 @@ spec:
|
||||
description: X.509 Certificate Authority (base64-encoded PEM bundle).
|
||||
If omitted, a default set of system roots will be trusted.
|
||||
type: string
|
||||
certificateAuthorityDataSource:
|
||||
description: |-
|
||||
Reference to a CA bundle in a secret or a configmap.
|
||||
Any changes to the CA bundle in the secret or configmap will be dynamically reloaded.
|
||||
properties:
|
||||
key:
|
||||
description: |-
|
||||
Key is the key name within the secret or configmap from which to read the CA bundle.
|
||||
The value found at this key in the secret or configmap must not be empty, and must be a valid PEM-encoded
|
||||
certificate bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind configures whether the CA bundle is being sourced from a Kubernetes secret or a configmap.
|
||||
Allowed values are "Secret" or "ConfigMap".
|
||||
"ConfigMap" uses a Kubernetes configmap to source CA Bundles.
|
||||
"Secret" uses Kubernetes secrets of type kubernetes.io/tls or Opaque to source CA Bundles.
|
||||
enum:
|
||||
- Secret
|
||||
- ConfigMap
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name is the resource name of the secret or configmap from which to read the CA bundle.
|
||||
The referenced secret or configmap must be created in the same namespace where Pinniped Concierge is installed.
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- endpoint
|
||||
@@ -69,43 +110,35 @@ spec:
|
||||
description: Represents the observations of the authenticator's current
|
||||
state.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
@@ -120,10 +153,6 @@ spec:
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
@@ -138,6 +167,14 @@ spec:
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
phase:
|
||||
default: Pending
|
||||
description: Phase summarizes the overall status of the WebhookAuthenticator.
|
||||
enum:
|
||||
- Pending
|
||||
- Ready
|
||||
- Error
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: credentialissuers.config.concierge.pinniped.dev
|
||||
spec:
|
||||
group: config.concierge.pinniped.dev
|
||||
@@ -33,14 +33,19 @@ spec:
|
||||
Pinniped Concierge credential issuer.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -52,18 +57,18 @@ spec:
|
||||
of the Concierge impersonation proxy.
|
||||
properties:
|
||||
externalEndpoint:
|
||||
description: "ExternalEndpoint describes the HTTPS endpoint where
|
||||
the proxy will be exposed. If not set, the proxy will be served
|
||||
using the external name of the LoadBalancer service or the cluster
|
||||
service DNS name. \n This field must be non-empty when spec.impersonationProxy.service.type
|
||||
is \"None\"."
|
||||
description: |-
|
||||
ExternalEndpoint describes the HTTPS endpoint where the proxy will be exposed. If not set, the proxy will
|
||||
be served using the external name of the LoadBalancer service or the cluster service DNS name.
|
||||
|
||||
This field must be non-empty when spec.impersonationProxy.service.type is "None".
|
||||
type: string
|
||||
mode:
|
||||
description: 'Mode configures whether the impersonation proxy
|
||||
should be started: - "disabled" explicitly disables the impersonation
|
||||
proxy. This is the default. - "enabled" explicitly enables the
|
||||
impersonation proxy. - "auto" enables or disables the impersonation
|
||||
proxy based upon the cluster in which it is running.'
|
||||
description: |-
|
||||
Mode configures whether the impersonation proxy should be started:
|
||||
- "disabled" explicitly disables the impersonation proxy. This is the default.
|
||||
- "enabled" explicitly enables the impersonation proxy.
|
||||
- "auto" enables or disables the impersonation proxy based upon the cluster in which it is running.
|
||||
enum:
|
||||
- auto
|
||||
- enabled
|
||||
@@ -82,20 +87,19 @@ spec:
|
||||
pairs to set as annotations on the provisioned Service.
|
||||
type: object
|
||||
loadBalancerIP:
|
||||
description: LoadBalancerIP specifies the IP address to set
|
||||
in the spec.loadBalancerIP field of the provisioned Service.
|
||||
description: |-
|
||||
LoadBalancerIP specifies the IP address to set in the spec.loadBalancerIP field of the provisioned Service.
|
||||
This is not supported on all cloud providers.
|
||||
maxLength: 255
|
||||
minLength: 1
|
||||
type: string
|
||||
type:
|
||||
default: LoadBalancer
|
||||
description: "Type specifies the type of Service to provision
|
||||
for the impersonation proxy. \n If the type is \"None\",
|
||||
then the \"spec.impersonationProxy.externalEndpoint\" field
|
||||
must be set to a non-empty value so that the Concierge can
|
||||
properly advertise the endpoint in the CredentialIssuer's
|
||||
status."
|
||||
description: |-
|
||||
Type specifies the type of Service to provision for the impersonation proxy.
|
||||
|
||||
If the type is "None", then the "spec.impersonationProxy.externalEndpoint" field must be set to a non-empty
|
||||
value so that the Concierge can properly advertise the endpoint in the CredentialIssuer's status.
|
||||
enum:
|
||||
- LoadBalancer
|
||||
- ClusterIP
|
||||
@@ -103,20 +107,20 @@ spec:
|
||||
type: string
|
||||
type: object
|
||||
tls:
|
||||
description: "TLS contains information about how the Concierge
|
||||
impersonation proxy should serve TLS. \n If this field is empty,
|
||||
the impersonation proxy will generate its own TLS certificate."
|
||||
description: |-
|
||||
TLS contains information about how the Concierge impersonation proxy should serve TLS.
|
||||
|
||||
If this field is empty, the impersonation proxy will generate its own TLS certificate.
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: X.509 Certificate Authority (base64-encoded PEM
|
||||
bundle). Used to advertise the CA bundle for the impersonation
|
||||
proxy endpoint.
|
||||
description: |-
|
||||
X.509 Certificate Authority (base64-encoded PEM bundle).
|
||||
Used to advertise the CA bundle for the impersonation proxy endpoint.
|
||||
type: string
|
||||
secretName:
|
||||
description: SecretName is the name of a Secret in the same
|
||||
namespace, of type `kubernetes.io/tls`, which contains the
|
||||
TLS serving certificate for the Concierge impersonation
|
||||
proxy endpoint.
|
||||
description: |-
|
||||
SecretName is the name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains
|
||||
the TLS serving certificate for the Concierge impersonation proxy endpoint.
|
||||
minLength: 1
|
||||
type: string
|
||||
type: object
|
||||
@@ -131,9 +135,9 @@ spec:
|
||||
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.
|
||||
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.
|
||||
@@ -160,9 +164,9 @@ spec:
|
||||
this strategy.
|
||||
properties:
|
||||
impersonationProxyInfo:
|
||||
description: ImpersonationProxyInfo describes the parameters
|
||||
for the impersonation proxy on this Concierge. This field
|
||||
is only set when Type is "ImpersonationProxy".
|
||||
description: |-
|
||||
ImpersonationProxyInfo describes the parameters for the impersonation proxy on this Concierge.
|
||||
This field is only set when Type is "ImpersonationProxy".
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: CertificateAuthorityData is the base64-encoded
|
||||
@@ -180,9 +184,9 @@ spec:
|
||||
- endpoint
|
||||
type: object
|
||||
tokenCredentialRequestInfo:
|
||||
description: TokenCredentialRequestAPIInfo describes the
|
||||
parameters for the TokenCredentialRequest API on this
|
||||
Concierge. This field is only set when Type is "TokenCredentialRequestAPI".
|
||||
description: |-
|
||||
TokenCredentialRequestAPIInfo describes the parameters for the TokenCredentialRequest API on this Concierge.
|
||||
This field is only set when Type is "TokenCredentialRequestAPI".
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: CertificateAuthorityData is the base64-encoded
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@@ -96,15 +96,15 @@ data:
|
||||
imagePullSecrets:
|
||||
- image-pull-secret
|
||||
(@ end @)
|
||||
(@ if data.values.log_level or data.values.deprecated_log_format: @)
|
||||
(@ if data.values.log_level: @)
|
||||
log:
|
||||
(@ if data.values.log_level: @)
|
||||
level: (@= getAndValidateLogLevel() @)
|
||||
(@ end @)
|
||||
(@ if data.values.deprecated_log_format: @)
|
||||
format: (@= data.values.deprecated_log_format @)
|
||||
(@ 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-2023 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@@ -19,7 +19,7 @@ rules:
|
||||
resources: [ apiservices ]
|
||||
verbs: [ get, list, patch, update, watch ]
|
||||
- apiGroups: [ admissionregistration.k8s.io ]
|
||||
resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations ]
|
||||
resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations, validatingadmissionpolicies, validatingadmissionpolicybindings ]
|
||||
verbs: [ get, list, watch ]
|
||||
- apiGroups: [ flowcontrol.apiserver.k8s.io ]
|
||||
resources: [ flowschemas, prioritylevelconfigurations ]
|
||||
@@ -43,6 +43,10 @@ rules:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
||||
resources: [ jwtauthenticators, webhookauthenticators ]
|
||||
verbs: [ get, list, watch ]
|
||||
- apiGroups:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
||||
resources: [ jwtauthenticators/status, webhookauthenticators/status ]
|
||||
verbs: [ get, list, watch, update ]
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2024 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: projects.registry.vmware.com/pinniped/pinniped-server
|
||||
image_repo: ghcr.io/vmware-tanzu/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."
|
||||
@@ -72,7 +72,7 @@ image_tag: latest
|
||||
#@ 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", "projects.registry.vmware.com/pinniped/pinniped-server:latest")
|
||||
#@schema/examples ("Image including tag or digest", "ghcr.io/vmware-tanzu/pinniped/pinniped-server:latest")
|
||||
#@schema/nullable
|
||||
#@schema/validation min_len=1
|
||||
kube_cert_agent_image: ""
|
||||
@@ -124,17 +124,6 @@ api_serving_certificate_renew_before_seconds: 2160000
|
||||
#@schema/validation one_of=["info", "debug", "trace", "all"]
|
||||
log_level: ""
|
||||
|
||||
#@schema/title "Log format"
|
||||
#@ deprecated_log_format_desc = "Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). \
|
||||
#@ By default, when this value is left unset, logs are formatted in json. \
|
||||
#@ This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json."
|
||||
#@schema/desc deprecated_log_format_desc
|
||||
#@schema/examples ("Set logs to JSON format","json")
|
||||
#@schema/nullable
|
||||
#@schema/validation one_of=["json", "text"]
|
||||
#@schema/deprecated "This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json."
|
||||
deprecated_log_format: ""
|
||||
|
||||
#@schema/title "Run as user"
|
||||
#@schema/desc "The user ID that will own the process."
|
||||
#! See the Dockerfile for the reasoning behind this default value.
|
||||
@@ -225,3 +214,32 @@ https_proxy: ""
|
||||
#@ localhost endpoints, and the known instance metadata IP address for public cloud providers."
|
||||
#@schema/desc no_proxy_desc
|
||||
no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local"
|
||||
|
||||
#@schema/title "Allowed Ciphers for TLS 1.2"
|
||||
#@ allowed_ciphers_for_tls_onedottwo_desc = "When specified, only the ciphers listed will be used for TLS 1.2. \
|
||||
#@ This includes both server-side and client-side TLS connections. \
|
||||
#@ This list must only include cipher suites that Pinniped is configured to accept \
|
||||
#@ (see internal/crypto/ptls/profiles.go and internal/crypto/ptls/profiles_fips_strict.go). \
|
||||
#@ Allowing too few ciphers may cause critical parts of Pinniped to be unable to function. For example, \
|
||||
#@ Kubernetes pod readiness checks, Pinniped pods acting as a client to the Kubernetes API server, \
|
||||
#@ Pinniped pods acting as a client to external identity providers, or Pinniped pods acting as an APIService server \
|
||||
#@ all need to be able to function with the allowed TLS cipher suites. \
|
||||
#@ An empty array means accept Pinniped's defaults."
|
||||
#@schema/desc allowed_ciphers_for_tls_onedottwo_desc
|
||||
#@schema/examples ("Example with a few secure ciphers", ["TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"])
|
||||
#! No type, default, or validation is required here.
|
||||
#! 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2024 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: projects.registry.vmware.com/pinniped/pinniped-server
|
||||
image_repo: ghcr.io/vmware-tanzu/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.13.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: federationdomains.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
@@ -32,14 +32,19 @@ spec:
|
||||
description: FederationDomain describes the configuration of an OIDC provider.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -47,63 +52,52 @@ spec:
|
||||
description: Spec of the OIDC provider.
|
||||
properties:
|
||||
identityProviders:
|
||||
description: "IdentityProviders is the list of identity providers
|
||||
available for use by this FederationDomain. \n An identity provider
|
||||
CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes
|
||||
how to connect to a server, how to talk in a specific protocol for
|
||||
authentication, and how to use the schema of that server/protocol
|
||||
to extract a normalized user identity. Normalized user identities
|
||||
include a username and a list of group names. In contrast, IdentityProviders
|
||||
describes how to use that normalized identity in those Kubernetes
|
||||
clusters which belong to this FederationDomain. Each entry in IdentityProviders
|
||||
can be configured with arbitrary transformations on that normalized
|
||||
identity. For example, a transformation can add a prefix to all
|
||||
usernames to help avoid accidental conflicts when multiple identity
|
||||
providers have different users with the same username (e.g. \"idp1:ryan\"
|
||||
versus \"idp2:ryan\"). Each entry in IdentityProviders can also
|
||||
implement arbitrary authentication rejection policies. Even though
|
||||
a user was able to authenticate with the identity provider, a policy
|
||||
can disallow the authentication to the Kubernetes clusters that
|
||||
belong to this FederationDomain. For example, a policy could disallow
|
||||
the authentication unless the user belongs to a specific group in
|
||||
the identity provider. \n For backwards compatibility with versions
|
||||
of Pinniped which predate support for multiple identity providers,
|
||||
an empty IdentityProviders list will cause the FederationDomain
|
||||
to use all available identity providers which exist in the same
|
||||
namespace, but also to reject all authentication requests when there
|
||||
is more than one identity provider currently defined. In this backwards
|
||||
compatibility mode, the name of the identity provider resource (e.g.
|
||||
the Name of an OIDCIdentityProvider resource) will be used as the
|
||||
name of the identity provider in this FederationDomain. This mode
|
||||
is provided to make upgrading from older versions easier. However,
|
||||
instead of relying on this backwards compatibility mode, please
|
||||
consider this mode to be deprecated and please instead explicitly
|
||||
list the identity provider using this IdentityProviders field."
|
||||
description: |-
|
||||
IdentityProviders is the list of identity providers available for use by this FederationDomain.
|
||||
|
||||
An identity provider CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes how to connect to a server,
|
||||
how to talk in a specific protocol for authentication, and how to use the schema of that server/protocol to
|
||||
extract a normalized user identity. Normalized user identities include a username and a list of group names.
|
||||
In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which
|
||||
belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations
|
||||
on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid
|
||||
accidental conflicts when multiple identity providers have different users with the same username (e.g.
|
||||
"idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication
|
||||
rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow
|
||||
the authentication to the Kubernetes clusters that belong to this FederationDomain. For example, a policy could
|
||||
disallow the authentication unless the user belongs to a specific group in the identity provider.
|
||||
|
||||
For backwards compatibility with versions of Pinniped which predate support for multiple identity providers,
|
||||
an empty IdentityProviders list will cause the FederationDomain to use all available identity providers which
|
||||
exist in the same namespace, but also to reject all authentication requests when there is more than one identity
|
||||
provider currently defined. In this backwards compatibility mode, the name of the identity provider resource
|
||||
(e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this
|
||||
FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of
|
||||
relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead
|
||||
explicitly list the identity provider using this IdentityProviders field.
|
||||
items:
|
||||
description: FederationDomainIdentityProvider describes how an identity
|
||||
provider is made available in this FederationDomain.
|
||||
properties:
|
||||
displayName:
|
||||
description: DisplayName is the name of this identity provider
|
||||
as it will appear to clients. This name ends up in the kubeconfig
|
||||
of end users, so changing the name of an identity provider
|
||||
that is in use by end users will be a disruptive change for
|
||||
those users.
|
||||
description: |-
|
||||
DisplayName is the name of this identity provider as it will appear to clients. This name ends up in the
|
||||
kubeconfig of end users, so changing the name of an identity provider that is in use by end users will be a
|
||||
disruptive change for those users.
|
||||
minLength: 1
|
||||
type: string
|
||||
objectRef:
|
||||
description: ObjectRef is a reference to a Pinniped identity
|
||||
provider resource. A valid reference is required. If the reference
|
||||
cannot be resolved then the identity provider will not be
|
||||
made available. Must refer to a resource of one of the Pinniped
|
||||
identity provider types, e.g. OIDCIdentityProvider, LDAPIdentityProvider,
|
||||
ActiveDirectoryIdentityProvider.
|
||||
description: |-
|
||||
ObjectRef is a reference to a Pinniped identity provider resource. A valid reference is required.
|
||||
If the reference cannot be resolved then the identity provider will not be made available.
|
||||
Must refer to a resource of one of the Pinniped identity provider types, e.g. OIDCIdentityProvider,
|
||||
LDAPIdentityProvider, ActiveDirectoryIdentityProvider.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup is the group for the resource being
|
||||
referenced. If APIGroup is not specified, the specified
|
||||
Kind must be in the core API group. For any other third-party
|
||||
types, APIGroup is required.
|
||||
description: |-
|
||||
APIGroup is the group for the resource being referenced.
|
||||
If APIGroup is not specified, the specified Kind must be in the core API group.
|
||||
For any other third-party types, APIGroup is required.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is the type of resource being referenced
|
||||
@@ -117,17 +111,17 @@ spec:
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
transforms:
|
||||
description: Transforms is an optional way to specify transformations
|
||||
to be applied during user authentication and session refresh.
|
||||
description: |-
|
||||
Transforms is an optional way to specify transformations to be applied during user authentication and
|
||||
session refresh.
|
||||
properties:
|
||||
constants:
|
||||
description: Constants defines constant variables and their
|
||||
values which will be made available to the transform expressions.
|
||||
items:
|
||||
description: FederationDomainTransformsConstant defines
|
||||
a constant variable and its value which will be made
|
||||
available to the transform expressions. This is a union
|
||||
type, and Type is the discriminator field.
|
||||
description: |-
|
||||
FederationDomainTransformsConstant defines a constant variable and its value which will be made available to
|
||||
the transform expressions. This is a union type, and Type is the discriminator field.
|
||||
properties:
|
||||
name:
|
||||
description: Name determines the name of the constant.
|
||||
@@ -147,8 +141,9 @@ spec:
|
||||
Type is "string", and is otherwise ignored.
|
||||
type: string
|
||||
type:
|
||||
description: Type determines the type of the constant,
|
||||
and indicates which other field should be non-empty.
|
||||
description: |-
|
||||
Type determines the type of the constant, and indicates which other field should be non-empty.
|
||||
Allowed values are "string" or "stringList".
|
||||
enum:
|
||||
- string
|
||||
- stringList
|
||||
@@ -162,25 +157,21 @@ spec:
|
||||
- name
|
||||
x-kubernetes-list-type: map
|
||||
examples:
|
||||
description: Examples can optionally be used to ensure that
|
||||
the sequence of transformation expressions are working
|
||||
as expected. Examples define sample input identities which
|
||||
are then run through the expression list, and the results
|
||||
are compared to the expected results. If any example in
|
||||
this list fails, then this identity provider will not
|
||||
be available for use within this FederationDomain, and
|
||||
the error(s) will be added to the FederationDomain status.
|
||||
This can be used to help guard against programming mistakes
|
||||
in the expressions, and also act as living documentation
|
||||
for other administrators to better understand the expressions.
|
||||
description: |-
|
||||
Examples can optionally be used to ensure that the sequence of transformation expressions are working as
|
||||
expected. Examples define sample input identities which are then run through the expression list, and the
|
||||
results are compared to the expected results. If any example in this list fails, then this
|
||||
identity provider will not be available for use within this FederationDomain, and the error(s) will be
|
||||
added to the FederationDomain status. This can be used to help guard against programming mistakes in the
|
||||
expressions, and also act as living documentation for other administrators to better understand the expressions.
|
||||
items:
|
||||
description: FederationDomainTransformsExample defines
|
||||
a transform example.
|
||||
properties:
|
||||
expects:
|
||||
description: Expects is the expected output of the
|
||||
entire sequence of transforms when they are run
|
||||
against the input Username and Groups.
|
||||
description: |-
|
||||
Expects is the expected output of the entire sequence of transforms when they are run against the
|
||||
input Username and Groups.
|
||||
properties:
|
||||
groups:
|
||||
description: Groups is the expected list of group
|
||||
@@ -189,27 +180,18 @@ spec:
|
||||
type: string
|
||||
type: array
|
||||
message:
|
||||
description: Message is the expected error message
|
||||
of the transforms. When Rejected is true, then
|
||||
Message is the expected message for the policy
|
||||
which rejected the authentication attempt. When
|
||||
Rejected is true and Message is blank, then
|
||||
Message will be treated as the default error
|
||||
message for authentication attempts which are
|
||||
rejected by a policy. When Rejected is false,
|
||||
then Message is the expected error message for
|
||||
some other non-policy transformation error,
|
||||
such as a runtime error. When Rejected is false,
|
||||
there is no default expected Message.
|
||||
description: |-
|
||||
Message is the expected error message of the transforms. When Rejected is true, then Message is the expected
|
||||
message for the policy which rejected the authentication attempt. When Rejected is true and Message is blank,
|
||||
then Message will be treated as the default error message for authentication attempts which are rejected by a
|
||||
policy. When Rejected is false, then Message is the expected error message for some other non-policy
|
||||
transformation error, such as a runtime error. When Rejected is false, there is no default expected Message.
|
||||
type: string
|
||||
rejected:
|
||||
description: Rejected is a boolean that indicates
|
||||
whether authentication is expected to be rejected
|
||||
by a policy expression after the transformations
|
||||
have been applied. True means that it is expected
|
||||
that the authentication would be rejected. The
|
||||
default value of false means that it is expected
|
||||
that the authentication would not be rejected
|
||||
description: |-
|
||||
Rejected is a boolean that indicates whether authentication is expected to be rejected by a policy expression
|
||||
after the transformations have been applied. True means that it is expected that the authentication would be
|
||||
rejected. The default value of false means that it is expected that the authentication would not be rejected
|
||||
by any policy expression.
|
||||
type: boolean
|
||||
username:
|
||||
@@ -232,44 +214,35 @@ spec:
|
||||
type: object
|
||||
type: array
|
||||
expressions:
|
||||
description: "Expressions are an optional list of transforms
|
||||
and policies to be executed in the order given during
|
||||
every authentication attempt, including during every session
|
||||
refresh. Each is a CEL expression. It may use the basic
|
||||
CEL language as defined in https://github.com/google/cel-spec/blob/master/doc/langdef.md
|
||||
plus the CEL string extensions defined in https://github.com/google/cel-go/tree/master/ext#strings.
|
||||
\n The username and groups extracted from the identity
|
||||
provider, and the constants defined in this CR, are available
|
||||
as variables in all expressions. The username is provided
|
||||
via a variable called `username` and the list of group
|
||||
names is provided via a variable called `groups` (which
|
||||
may be an empty list). Each user-provided constants is
|
||||
provided via a variable named `strConst.varName` for string
|
||||
constants and `strListConst.varName` for string list constants.
|
||||
\n The only allowed types for expressions are currently
|
||||
policy/v1, username/v1, and groups/v1. Each policy/v1
|
||||
must return a boolean, and when it returns false, no more
|
||||
expressions from the list are evaluated and the authentication
|
||||
attempt is rejected. Transformations of type policy/v1
|
||||
do not return usernames or group names, and therefore
|
||||
cannot change the username or group names. Each username/v1
|
||||
transform must return the new username (a string), which
|
||||
can be the same as the old username. Transformations of
|
||||
type username/v1 do not return group names, and therefore
|
||||
cannot change the group names. Each groups/v1 transform
|
||||
must return the new groups list (list of strings), which
|
||||
can be the same as the old groups list. Transformations
|
||||
of type groups/v1 do not return usernames, and therefore
|
||||
cannot change the usernames. After each expression, the
|
||||
new (potentially changed) username or groups get passed
|
||||
to the following expression. \n Any compilation or static
|
||||
type-checking failure of any expression will cause an
|
||||
error status on the FederationDomain. During an authentication
|
||||
attempt, any unexpected runtime evaluation errors (e.g.
|
||||
division by zero) cause the authentication attempt to
|
||||
fail. When all expressions evaluate successfully, then
|
||||
the (potentially changed) username and group names have
|
||||
been decided for that authentication attempt."
|
||||
description: |-
|
||||
Expressions are an optional list of transforms and policies to be executed in the order given during every
|
||||
authentication attempt, including during every session refresh.
|
||||
Each is a CEL expression. It may use the basic CEL language as defined in
|
||||
https://github.com/google/cel-spec/blob/master/doc/langdef.md plus the CEL string extensions defined in
|
||||
https://github.com/google/cel-go/tree/master/ext#strings.
|
||||
|
||||
The username and groups extracted from the identity provider, and the constants defined in this CR, are
|
||||
available as variables in all expressions. The username is provided via a variable called `username` and
|
||||
the list of group names is provided via a variable called `groups` (which may be an empty list).
|
||||
Each user-provided constants is provided via a variable named `strConst.varName` for string constants
|
||||
and `strListConst.varName` for string list constants.
|
||||
|
||||
The only allowed types for expressions are currently policy/v1, username/v1, and groups/v1.
|
||||
Each policy/v1 must return a boolean, and when it returns false, no more expressions from the list are evaluated
|
||||
and the authentication attempt is rejected.
|
||||
Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the
|
||||
username or group names.
|
||||
Each username/v1 transform must return the new username (a string), which can be the same as the old username.
|
||||
Transformations of type username/v1 do not return group names, and therefore cannot change the group names.
|
||||
Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old
|
||||
groups list.
|
||||
Transformations of type groups/v1 do not return usernames, and therefore cannot change the usernames.
|
||||
After each expression, the new (potentially changed) username or groups get passed to the following expression.
|
||||
|
||||
Any compilation or static type-checking failure of any expression will cause an error status on the FederationDomain.
|
||||
During an authentication attempt, any unexpected runtime evaluation errors (e.g. division by zero) cause the
|
||||
authentication attempt to fail. When all expressions evaluate successfully, then the (potentially changed) username
|
||||
and group names have been decided for that authentication attempt.
|
||||
items:
|
||||
description: FederationDomainTransformsExpression defines
|
||||
a transform expression.
|
||||
@@ -280,14 +253,14 @@ spec:
|
||||
minLength: 1
|
||||
type: string
|
||||
message:
|
||||
description: Message is only used when Type is policy/v1.
|
||||
It defines an error message to be used when the
|
||||
policy rejects an authentication attempt. When empty,
|
||||
a default message will be used.
|
||||
description: |-
|
||||
Message is only used when Type is policy/v1. It defines an error message to be used when the policy rejects
|
||||
an authentication attempt. When empty, a default message will be used.
|
||||
type: string
|
||||
type:
|
||||
description: Type determines the type of the expression.
|
||||
It must be one of the supported types.
|
||||
description: |-
|
||||
Type determines the type of the expression. It must be one of the supported types.
|
||||
Allowed values are "policy/v1", "username/v1", or "groups/v1".
|
||||
enum:
|
||||
- policy/v1
|
||||
- username/v1
|
||||
@@ -305,14 +278,15 @@ spec:
|
||||
type: object
|
||||
type: array
|
||||
issuer:
|
||||
description: "Issuer is the OIDC Provider's issuer, per the OIDC Discovery
|
||||
Metadata document, as well as the identifier that it will use for
|
||||
the iss claim in issued JWTs. This field will also be used as the
|
||||
base URL for any endpoints used by the OIDC Provider (e.g., if your
|
||||
issuer is https://example.com/foo, then your authorization endpoint
|
||||
will look like https://example.com/foo/some/path/to/auth/endpoint).
|
||||
\n See https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3
|
||||
for more information."
|
||||
description: |-
|
||||
Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the
|
||||
identifier that it will use for the iss claim in issued JWTs. This field will also be used as
|
||||
the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is
|
||||
https://example.com/foo, then your authorization endpoint will look like
|
||||
https://example.com/foo/some/path/to/auth/endpoint).
|
||||
|
||||
See
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
minLength: 1
|
||||
type: string
|
||||
tls:
|
||||
@@ -320,26 +294,24 @@ spec:
|
||||
Security (TLS) configuration for the FederationDomain.
|
||||
properties:
|
||||
secretName:
|
||||
description: "SecretName is an optional name of a Secret in the
|
||||
same namespace, of type `kubernetes.io/tls`, which contains
|
||||
the TLS serving certificate for the HTTPS endpoints served by
|
||||
this FederationDomain. When provided, the TLS Secret named here
|
||||
must contain keys named `tls.crt` and `tls.key` that contain
|
||||
the certificate and private key to use for TLS. \n Server Name
|
||||
Indication (SNI) is an extension to the Transport Layer Security
|
||||
(TLS) supported by all major browsers. \n SecretName is required
|
||||
if you would like to use different TLS certificates for issuers
|
||||
of different hostnames. SNI requests do not include port numbers,
|
||||
so all issuers with the same DNS hostname must use the same
|
||||
SecretName value even if they have different port numbers. \n
|
||||
SecretName is not required when you would like to use only the
|
||||
HTTP endpoints (e.g. when the HTTP listener is configured to
|
||||
listen on loopback interfaces or UNIX domain sockets for traffic
|
||||
from a service mesh sidecar). It is also not required when you
|
||||
would like all requests to this OIDC Provider's HTTPS endpoints
|
||||
to use the default TLS certificate, which is configured elsewhere.
|
||||
\n When your Issuer URL's host is an IP address, then this field
|
||||
is ignored. SNI does not work for IP addresses."
|
||||
description: |-
|
||||
SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains
|
||||
the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret
|
||||
named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use
|
||||
for TLS.
|
||||
|
||||
Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
|
||||
|
||||
SecretName is required if you would like to use different TLS certificates for issuers of different hostnames.
|
||||
SNI requests do not include port numbers, so all issuers with the same DNS hostname must use the same
|
||||
SecretName value even if they have different port numbers.
|
||||
|
||||
SecretName is not required when you would like to use only the HTTP endpoints (e.g. when the HTTP listener is
|
||||
configured to listen on loopback interfaces or UNIX domain sockets for traffic from a service mesh sidecar).
|
||||
It is also not required when you would like all requests to this OIDC Provider's HTTPS endpoints to
|
||||
use the default TLS certificate, which is configured elsewhere.
|
||||
|
||||
When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
@@ -352,43 +324,35 @@ spec:
|
||||
description: Conditions represent the observations of an FederationDomain's
|
||||
current state.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
@@ -403,10 +367,6 @@ spec:
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
@@ -434,46 +394,67 @@ spec:
|
||||
secrets.
|
||||
properties:
|
||||
jwks:
|
||||
description: JWKS holds the name of the corev1.Secret in which
|
||||
this OIDC Provider's signing/verification keys are stored. If
|
||||
it is empty, then the signing/verification keys are either unknown
|
||||
or they don't exist.
|
||||
description: |-
|
||||
JWKS holds the name of the corev1.Secret in which this OIDC Provider's signing/verification keys are
|
||||
stored. If it is empty, then the signing/verification keys are either unknown or they don't
|
||||
exist.
|
||||
properties:
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
TODO: Add other useful fields. apiVersion, kind, uid?'
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
stateEncryptionKey:
|
||||
description: StateSigningKey holds the name of the corev1.Secret
|
||||
in which this OIDC Provider's key for encrypting state parameters
|
||||
is stored.
|
||||
description: |-
|
||||
StateSigningKey holds the name of the corev1.Secret in which this OIDC Provider's key for
|
||||
encrypting state parameters is stored.
|
||||
properties:
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
TODO: Add other useful fields. apiVersion, kind, uid?'
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
stateSigningKey:
|
||||
description: StateSigningKey holds the name of the corev1.Secret
|
||||
in which this OIDC Provider's key for signing state parameters
|
||||
is stored.
|
||||
description: |-
|
||||
StateSigningKey holds the name of the corev1.Secret in which this OIDC Provider's key for
|
||||
signing state parameters is stored.
|
||||
properties:
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
TODO: Add other useful fields. apiVersion, kind, uid?'
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
tokenSigningKey:
|
||||
description: TokenSigningKey holds the name of the corev1.Secret
|
||||
in which this OIDC Provider's key for signing tokens is stored.
|
||||
description: |-
|
||||
TokenSigningKey holds the name of the corev1.Secret in which this OIDC Provider's key for
|
||||
signing tokens is stored.
|
||||
properties:
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
TODO: Add other useful fields. apiVersion, kind, uid?'
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: oidcclients.config.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: config.supervisor.pinniped.dev
|
||||
@@ -35,14 +35,19 @@ spec:
|
||||
description: OIDCClient describes the configuration of an OIDC client.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -50,17 +55,18 @@ spec:
|
||||
description: Spec of the OIDC client.
|
||||
properties:
|
||||
allowedGrantTypes:
|
||||
description: "allowedGrantTypes is a list of the allowed grant_type
|
||||
param values that should be accepted during OIDC flows with this
|
||||
client. \n Must only contain the following values: - authorization_code:
|
||||
allows the client to perform the authorization code grant flow,
|
||||
i.e. allows the webapp to authenticate users. This grant must always
|
||||
be listed. - refresh_token: allows the client to perform refresh
|
||||
grants for the user to extend the user's session. This grant must
|
||||
be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange:
|
||||
allows the client to perform RFC8693 token exchange, which is a
|
||||
step in the process to be able to get a cluster credential for the
|
||||
user. This grant must be listed if allowedScopes lists pinniped:request-audience."
|
||||
description: |-
|
||||
allowedGrantTypes is a list of the allowed grant_type param values that should be accepted during OIDC flows with this
|
||||
client.
|
||||
|
||||
Must only contain the following values:
|
||||
- authorization_code: allows the client to perform the authorization code grant flow, i.e. allows the webapp to
|
||||
authenticate users. This grant must always be listed.
|
||||
- refresh_token: allows the client to perform refresh grants for the user to extend the user's session.
|
||||
This grant must be listed if allowedScopes lists offline_access.
|
||||
- urn:ietf:params:oauth:grant-type:token-exchange: allows the client to perform RFC8693 token exchange,
|
||||
which is a step in the process to be able to get a cluster credential for the user.
|
||||
This grant must be listed if allowedScopes lists pinniped:request-audience.
|
||||
items:
|
||||
enum:
|
||||
- authorization_code
|
||||
@@ -71,12 +77,11 @@ spec:
|
||||
type: array
|
||||
x-kubernetes-list-type: set
|
||||
allowedRedirectURIs:
|
||||
description: allowedRedirectURIs is a list of the allowed redirect_uri
|
||||
param values that should be accepted during OIDC flows with this
|
||||
client. Any other uris will be rejected. Must be a URI with the
|
||||
https scheme, unless the hostname is 127.0.0.1 or ::1 which may
|
||||
use the http scheme. Port numbers are not required for 127.0.0.1
|
||||
or ::1 and are ignored when checking for a matching redirect_uri.
|
||||
description: |-
|
||||
allowedRedirectURIs is a list of the allowed redirect_uri param values that should be accepted during OIDC flows with this
|
||||
client. Any other uris will be rejected.
|
||||
Must be a URI with the https scheme, unless the hostname is 127.0.0.1 or ::1 which may use the http scheme.
|
||||
Port numbers are not required for 127.0.0.1 or ::1 and are ignored when checking for a matching redirect_uri.
|
||||
items:
|
||||
pattern: ^https://.+|^http://(127\.0\.0\.1|\[::1\])(:\d+)?/
|
||||
type: string
|
||||
@@ -84,27 +89,23 @@ spec:
|
||||
type: array
|
||||
x-kubernetes-list-type: set
|
||||
allowedScopes:
|
||||
description: "allowedScopes is a list of the allowed scopes param
|
||||
values that should be accepted during OIDC flows with this client.
|
||||
\n Must only contain the following values: - openid: The client
|
||||
is allowed to request ID tokens. ID tokens only include the required
|
||||
claims by default (iss, sub, aud, exp, iat). This scope must always
|
||||
be listed. - offline_access: The client is allowed to request an
|
||||
initial refresh token during the authorization code grant flow.
|
||||
This scope must be listed if allowedGrantTypes lists refresh_token.
|
||||
- pinniped:request-audience: The client is allowed to request a
|
||||
new audience value during a RFC8693 token exchange, which is a step
|
||||
in the process to be able to get a cluster credential for the user.
|
||||
openid, username and groups scopes must be listed when this scope
|
||||
is present. This scope must be listed if allowedGrantTypes lists
|
||||
urn:ietf:params:oauth:grant-type:token-exchange. - username: The
|
||||
client is allowed to request that ID tokens contain the user's username.
|
||||
Without the username scope being requested and allowed, the ID token
|
||||
will not contain the user's username. - groups: The client is allowed
|
||||
to request that ID tokens contain the user's group membership, if
|
||||
their group membership is discoverable by the Supervisor. Without
|
||||
the groups scope being requested and allowed, the ID token will
|
||||
not contain groups."
|
||||
description: |-
|
||||
allowedScopes is a list of the allowed scopes param values that should be accepted during OIDC flows with this client.
|
||||
|
||||
Must only contain the following values:
|
||||
- openid: The client is allowed to request ID tokens. ID tokens only include the required claims by default (iss, sub, aud, exp, iat).
|
||||
This scope must always be listed.
|
||||
- offline_access: The client is allowed to request an initial refresh token during the authorization code grant flow.
|
||||
This scope must be listed if allowedGrantTypes lists refresh_token.
|
||||
- pinniped:request-audience: The client is allowed to request a new audience value during a RFC8693 token exchange,
|
||||
which is a step in the process to be able to get a cluster credential for the user.
|
||||
openid, username and groups scopes must be listed when this scope is present.
|
||||
This scope must be listed if allowedGrantTypes lists urn:ietf:params:oauth:grant-type:token-exchange.
|
||||
- username: The client is allowed to request that ID tokens contain the user's username.
|
||||
Without the username scope being requested and allowed, the ID token will not contain the user's username.
|
||||
- groups: The client is allowed to request that ID tokens contain the user's group membership,
|
||||
if their group membership is discoverable by the Supervisor.
|
||||
Without the groups scope being requested and allowed, the ID token will not contain groups.
|
||||
items:
|
||||
enum:
|
||||
- openid
|
||||
@@ -116,6 +117,27 @@ spec:
|
||||
minItems: 1
|
||||
type: array
|
||||
x-kubernetes-list-type: set
|
||||
tokenLifetimes:
|
||||
description: tokenLifetimes are the optional overrides of token lifetimes
|
||||
for an OIDCClient.
|
||||
properties:
|
||||
idTokenSeconds:
|
||||
description: |-
|
||||
idTokenSeconds is the lifetime of ID tokens issued to this client, in seconds. This will choose the lifetime of
|
||||
ID tokens returned by the authorization flow and the refresh grant. It will not influence the lifetime of the ID
|
||||
tokens returned by RFC8693 token exchange. When null, a short-lived default value will be used.
|
||||
This value must be between 120 and 1,800 seconds (30 minutes), inclusive. It is recommended to make these tokens
|
||||
short-lived to force the client to perform the refresh grant often, because the refresh grant will check with the
|
||||
external identity provider to decide if it is acceptable for the end user to continue their session, and will
|
||||
update the end user's group memberships from the external identity provider. Giving these tokens a long life is
|
||||
will allow the end user to continue to use a token while avoiding these updates from the external identity
|
||||
provider. However, some web applications may have reasons specific to the design of that application to prefer
|
||||
longer lifetimes.
|
||||
format: int32
|
||||
maximum: 1800
|
||||
minimum: 120
|
||||
type: integer
|
||||
type: object
|
||||
required:
|
||||
- allowedGrantTypes
|
||||
- allowedRedirectURIs
|
||||
@@ -128,43 +150,35 @@ spec:
|
||||
description: conditions represent the observations of an OIDCClient's
|
||||
current state.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
@@ -179,10 +193,6 @@ spec:
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@@ -53,17 +53,20 @@ _: #@ template.replace(data.values.custom_labels)
|
||||
#@ "apiService": defaultResourceNameWithSuffix("api"),
|
||||
#@ },
|
||||
#@ "labels": labels(),
|
||||
#@ "insecureAcceptExternalUnencryptedHttpRequests": data.values.deprecated_insecure_accept_external_unencrypted_http_requests
|
||||
#@ "tls": {
|
||||
#@ "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
|
||||
#@ }
|
||||
#@ }
|
||||
#@ if data.values.log_level or data.values.deprecated_log_format:
|
||||
#@ config["log"] = {}
|
||||
#@ end
|
||||
#@ if data.values.log_level:
|
||||
#@ config["log"] = {}
|
||||
#@ config["log"]["level"] = getAndValidateLogLevel()
|
||||
#@ end
|
||||
#@ if data.values.deprecated_log_format:
|
||||
#@ config["log"]["format"] = data.values.deprecated_log_format
|
||||
#@ end
|
||||
#@ if data.values.endpoints:
|
||||
#@ config["endpoints"] = data.values.endpoints
|
||||
#@ end
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
@@ -35,14 +35,19 @@ spec:
|
||||
an upstream Microsoft Active Directory identity provider.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -50,19 +55,16 @@ spec:
|
||||
description: Spec for configuring the identity provider.
|
||||
properties:
|
||||
bind:
|
||||
description: Bind contains the configuration for how to provide access
|
||||
credentials during an initial bind to the ActiveDirectory server
|
||||
to be allowed to perform searches and binds to validate a user's
|
||||
credentials during a user's authentication attempt.
|
||||
description: |-
|
||||
Bind contains the configuration for how to provide access credentials during an initial bind to the ActiveDirectory server
|
||||
to be allowed to perform searches and binds to validate a user's credentials during a user's authentication attempt.
|
||||
properties:
|
||||
secretName:
|
||||
description: SecretName contains the name of a namespace-local
|
||||
Secret object that provides the username and password for an
|
||||
Active Directory bind user. This account will be used to perform
|
||||
LDAP searches. The Secret should be of type "kubernetes.io/basic-auth"
|
||||
which includes "username" and "password" keys. The username
|
||||
value should be the full dn (distinguished name) of your bind
|
||||
account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
|
||||
description: |-
|
||||
SecretName contains the name of a namespace-local Secret object that provides the username and
|
||||
password for an Active Directory bind user. This account will be used to perform LDAP searches. The Secret should be
|
||||
of type "kubernetes.io/basic-auth" which includes "username" and "password" keys. The username value
|
||||
should be the full dn (distinguished name) of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
|
||||
The password must be non-empty.
|
||||
minLength: 1
|
||||
type: string
|
||||
@@ -74,87 +76,82 @@ spec:
|
||||
for a user's group membership in ActiveDirectory.
|
||||
properties:
|
||||
attributes:
|
||||
description: Attributes specifies how the group's information
|
||||
should be read from each ActiveDirectory entry which was found
|
||||
as the result of the group search.
|
||||
description: |-
|
||||
Attributes specifies how the group's information should be read from each ActiveDirectory entry which was found as
|
||||
the result of the group search.
|
||||
properties:
|
||||
groupName:
|
||||
description: GroupName specifies the name of the attribute
|
||||
in the Active Directory entries whose value shall become
|
||||
a group name in the user's list of groups after a successful
|
||||
authentication. The value of this field is case-sensitive
|
||||
and must match the case of the attribute name returned by
|
||||
the ActiveDirectory server in the user's entry. E.g. "cn"
|
||||
for common name. Distinguished names can be used by specifying
|
||||
lower-case "dn". Optional. When not specified, this defaults
|
||||
to a custom field that looks like "sAMAccountName@domain",
|
||||
where domain is constructed from the domain components of
|
||||
the group DN.
|
||||
description: |-
|
||||
GroupName specifies the name of the attribute in the Active Directory entries whose value shall become a group name
|
||||
in the user's list of groups after a successful authentication.
|
||||
The value of this field is case-sensitive and must match the case of the attribute name returned by the ActiveDirectory
|
||||
server in the user's entry. E.g. "cn" for common name. Distinguished names can be used by specifying lower-case "dn".
|
||||
Optional. When not specified, this defaults to a custom field that looks like "sAMAccountName@domain",
|
||||
where domain is constructed from the domain components of the group DN.
|
||||
type: string
|
||||
type: object
|
||||
base:
|
||||
description: Base is the dn (distinguished name) that should be
|
||||
used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com".
|
||||
Optional, when not specified it will be based on the result
|
||||
of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse).
|
||||
description: |-
|
||||
Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g.
|
||||
"ou=groups,dc=example,dc=com".
|
||||
Optional, when not specified it will be based on the result of a query for the defaultNamingContext
|
||||
(see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse).
|
||||
The default behavior searches your entire domain for groups.
|
||||
It may make sense to specify a subtree as a search base if you
|
||||
wish to exclude some groups for security reasons or to make
|
||||
searches faster.
|
||||
It may make sense to specify a subtree as a search base if you wish to exclude some groups
|
||||
for security reasons or to make searches faster.
|
||||
type: string
|
||||
filter:
|
||||
description: Filter is the ActiveDirectory search filter which
|
||||
should be applied when searching for groups for a user. The
|
||||
pattern "{}" must occur in the filter at least once and will
|
||||
be dynamically replaced by the value of an attribute of the
|
||||
user entry found as a result of the user search. Which attribute's
|
||||
value is used to replace the placeholder(s) depends on the value
|
||||
of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})".
|
||||
description: |-
|
||||
Filter is the ActiveDirectory search filter which should be applied when searching for groups for a user.
|
||||
The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the
|
||||
value of an attribute of the user entry found as a result of the user search. Which attribute's
|
||||
value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter.
|
||||
E.g. "member={}" or "&(objectClass=groupOfNames)(member={})".
|
||||
For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters.
|
||||
Note that the dn (distinguished name) is not an attribute of
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})".
|
||||
This searches nested groups by default. Note that nested group
|
||||
search can be slow for some Active Directory servers. To disable
|
||||
it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||
Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used.
|
||||
Optional. When not specified, the default will act as if the filter were specified as
|
||||
"(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})".
|
||||
This searches nested groups by default.
|
||||
Note that nested group search can be slow for some Active Directory servers. To disable it,
|
||||
you can set the filter to
|
||||
"(&(objectClass=group)(member={})"
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
description: |-
|
||||
The user's group membership is refreshed as they interact with the supervisor
|
||||
to obtain new credentials (as their old credentials expire). This allows group
|
||||
membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
group membership is often used to bind authorization policies, it is important
|
||||
to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
provider.
|
||||
|
||||
In some environments, frequent group membership queries may result in a
|
||||
significant performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak the group query
|
||||
to be more performant, for example by disabling nested group search or by
|
||||
using a more targeted group search base.
|
||||
|
||||
If the group search query cannot be made performant and you are willing to
|
||||
have group memberships remain static for approximately a day, then set
|
||||
skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
policies that are bound to group membership will not notice if a user has
|
||||
been removed from a particular group until their next login.
|
||||
|
||||
This is an experimental feature that may be removed or significantly altered
|
||||
in the future. Consumers of this configuration should carefully read all
|
||||
release notes before upgrading to ensure that the meaning of this field has
|
||||
not changed.
|
||||
type: boolean
|
||||
userAttributeForFilter:
|
||||
description: UserAttributeForFilter specifies which attribute's
|
||||
value from the user entry found as a result of the user search
|
||||
will be used to replace the "{}" placeholder(s) in the group
|
||||
search Filter. For example, specifying "uid" as the UserAttributeForFilter
|
||||
while specifying "&(objectClass=posixGroup)(memberUid={})" as
|
||||
the Filter would search for groups by replacing the "{}" placeholder
|
||||
in the Filter with the value of the user's "uid" attribute.
|
||||
Optional. When not specified, the default will act as if "dn"
|
||||
were specified. For example, leaving UserAttributeForFilter
|
||||
unspecified while specifying "&(objectClass=groupOfNames)(member={})"
|
||||
as the Filter would search for groups by replacing the "{}"
|
||||
placeholder(s) with the dn (distinguished name) of the user.
|
||||
description: |-
|
||||
UserAttributeForFilter specifies which attribute's value from the user entry found as a result of
|
||||
the user search will be used to replace the "{}" placeholder(s) in the group search Filter.
|
||||
For example, specifying "uid" as the UserAttributeForFilter while specifying
|
||||
"&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing
|
||||
the "{}" placeholder in the Filter with the value of the user's "uid" attribute.
|
||||
Optional. When not specified, the default will act as if "dn" were specified. For example, leaving
|
||||
UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter
|
||||
would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||
type: string
|
||||
type: object
|
||||
host:
|
||||
@@ -170,55 +167,85 @@ spec:
|
||||
description: X.509 Certificate Authority (base64-encoded PEM bundle).
|
||||
If omitted, a default set of system roots will be trusted.
|
||||
type: string
|
||||
certificateAuthorityDataSource:
|
||||
description: |-
|
||||
Reference to a CA bundle in a secret or a configmap.
|
||||
Any changes to the CA bundle in the secret or configmap will be dynamically reloaded.
|
||||
properties:
|
||||
key:
|
||||
description: |-
|
||||
Key is the key name within the secret or configmap from which to read the CA bundle.
|
||||
The value found at this key in the secret or configmap must not be empty, and must be a valid PEM-encoded
|
||||
certificate bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind configures whether the CA bundle is being sourced from a Kubernetes secret or a configmap.
|
||||
Allowed values are "Secret" or "ConfigMap".
|
||||
"ConfigMap" uses a Kubernetes configmap to source CA Bundles.
|
||||
"Secret" uses Kubernetes secrets of type kubernetes.io/tls or Opaque to source CA Bundles.
|
||||
enum:
|
||||
- Secret
|
||||
- ConfigMap
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name is the resource name of the secret or configmap from which to read the CA bundle.
|
||||
The referenced secret or configmap must be created in the same namespace where Pinniped Supervisor is installed.
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
userSearch:
|
||||
description: UserSearch contains the configuration for searching for
|
||||
a user by name in Active Directory.
|
||||
properties:
|
||||
attributes:
|
||||
description: Attributes specifies how the user's information should
|
||||
be read from the ActiveDirectory entry which was found as the
|
||||
result of the user search.
|
||||
description: |-
|
||||
Attributes specifies how the user's information should be read from the ActiveDirectory entry which was found as
|
||||
the result of the user search.
|
||||
properties:
|
||||
uid:
|
||||
description: UID specifies the name of the attribute in the
|
||||
ActiveDirectory entry which whose value shall be used to
|
||||
uniquely identify the user within this ActiveDirectory provider
|
||||
after a successful authentication. Optional, when empty
|
||||
this defaults to "objectGUID".
|
||||
description: |-
|
||||
UID specifies the name of the attribute in the ActiveDirectory entry which whose value shall be used to uniquely
|
||||
identify the user within this ActiveDirectory provider after a successful authentication.
|
||||
Optional, when empty this defaults to "objectGUID".
|
||||
type: string
|
||||
username:
|
||||
description: Username specifies the name of the attribute
|
||||
in Active Directory entry whose value shall become the username
|
||||
of the user after a successful authentication. Optional,
|
||||
when empty this defaults to "userPrincipalName".
|
||||
description: |-
|
||||
Username specifies the name of the attribute in Active Directory entry whose value shall become the username
|
||||
of the user after a successful authentication.
|
||||
Optional, when empty this defaults to "userPrincipalName".
|
||||
type: string
|
||||
type: object
|
||||
base:
|
||||
description: Base is the dn (distinguished name) that should be
|
||||
used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
Optional, when not specified it will be based on the result
|
||||
of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse).
|
||||
description: |-
|
||||
Base is the dn (distinguished name) that should be used as the search base when searching for users.
|
||||
E.g. "ou=users,dc=example,dc=com".
|
||||
Optional, when not specified it will be based on the result of a query for the defaultNamingContext
|
||||
(see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse).
|
||||
The default behavior searches your entire domain for users.
|
||||
It may make sense to specify a subtree as a search base if you
|
||||
wish to exclude some users or to make searches faster.
|
||||
It may make sense to specify a subtree as a search base if you wish to exclude some users
|
||||
or to make searches faster.
|
||||
type: string
|
||||
filter:
|
||||
description: Filter is the search filter which should be applied
|
||||
when searching for users. The pattern "{}" must occur in the
|
||||
filter at least once and will be dynamically replaced by the
|
||||
username for which the search is being run. E.g. "mail={}" or
|
||||
"&(objectClass=person)(uid={})". For more information about
|
||||
LDAP filters, see https://ldap.com/ldap-filters. Note that the
|
||||
dn (distinguished name) is not an attribute of an entry, so
|
||||
"dn={}" cannot be used. Optional. When not specified, the default
|
||||
will be '(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={}")(mail={})(userPrincipalName={})(sAMAccountType=805306368))'
|
||||
This means that the user is a person, is not a computer, the
|
||||
sAMAccountType is for a normal user account, and is not shown
|
||||
in advanced view only (which would likely mean its a system
|
||||
created service account with advanced permissions). Also, either
|
||||
the sAMAccountName, the userPrincipalName, or the mail attribute
|
||||
matches the input username.
|
||||
description: |-
|
||||
Filter is the search filter which should be applied when searching for users. The pattern "{}" must occur
|
||||
in the filter at least once and will be dynamically replaced by the username for which the search is being run.
|
||||
E.g. "mail={}" or "&(objectClass=person)(uid={})". For more information about LDAP filters, see
|
||||
https://ldap.com/ldap-filters.
|
||||
Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used.
|
||||
Optional. When not specified, the default will be
|
||||
'(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={}")(mail={})(userPrincipalName={})(sAMAccountType=805306368))'
|
||||
This means that the user is a person, is not a computer, the sAMAccountType is for a normal user account,
|
||||
and is not shown in advanced view only
|
||||
(which would likely mean its a system created service account with advanced permissions).
|
||||
Also, either the sAMAccountName, the userPrincipalName, or the mail attribute matches the input username.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
@@ -231,43 +258,35 @@ spec:
|
||||
description: Represents the observations of an identity provider's
|
||||
current state.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
@@ -282,10 +301,6 @@ spec:
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
|
||||
@@ -0,0 +1,338 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: githubidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
names:
|
||||
categories:
|
||||
- pinniped
|
||||
- pinniped-idp
|
||||
- pinniped-idps
|
||||
kind: GitHubIdentityProvider
|
||||
listKind: GitHubIdentityProviderList
|
||||
plural: githubidentityproviders
|
||||
singular: githubidentityprovider
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.githubAPI.host
|
||||
name: Host
|
||||
type: string
|
||||
- jsonPath: .status.phase
|
||||
name: Status
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: |-
|
||||
GitHubIdentityProvider describes the configuration of an upstream GitHub identity provider.
|
||||
This upstream provider can be configured with either a GitHub App or a GitHub OAuth2 App.
|
||||
|
||||
Right now, only web-based logins are supported, for both the pinniped-cli client and clients configured
|
||||
as OIDCClients.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec for configuring the identity provider.
|
||||
properties:
|
||||
allowAuthentication:
|
||||
description: AllowAuthentication allows customization of who can authenticate
|
||||
using this IDP and how.
|
||||
properties:
|
||||
organizations:
|
||||
description: Organizations allows customization of which organizations
|
||||
can authenticate using this IDP.
|
||||
properties:
|
||||
allowed:
|
||||
description: |-
|
||||
Allowed, when specified, indicates that only users with membership in at least one of the listed
|
||||
GitHub organizations may log in. In addition, the group membership presented to Kubernetes will only include
|
||||
teams within the listed GitHub organizations. Additional login rules or group filtering can optionally be
|
||||
provided as policy expression on any Pinniped Supervisor FederationDomain that includes this IDP.
|
||||
|
||||
The configured GitHub App or GitHub OAuth App must be allowed to see membership in the listed organizations,
|
||||
otherwise Pinniped will not be aware that the user belongs to the listed organization or any teams
|
||||
within that organization.
|
||||
|
||||
If no organizations are listed, you must set organizations: AllGitHubUsers.
|
||||
items:
|
||||
type: string
|
||||
maxItems: 64
|
||||
type: array
|
||||
x-kubernetes-list-type: set
|
||||
policy:
|
||||
default: OnlyUsersFromAllowedOrganizations
|
||||
description: |-
|
||||
Allowed values are "OnlyUsersFromAllowedOrganizations" or "AllGitHubUsers".
|
||||
Defaults to "OnlyUsersFromAllowedOrganizations".
|
||||
|
||||
Must be set to "AllGitHubUsers" if the allowed field is empty.
|
||||
|
||||
This field only exists to ensure that Pinniped administrators are aware that an empty list of
|
||||
allowedOrganizations means all GitHub users are allowed to log in.
|
||||
enum:
|
||||
- OnlyUsersFromAllowedOrganizations
|
||||
- AllGitHubUsers
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-validations:
|
||||
- message: spec.allowAuthentication.organizations.policy must
|
||||
be 'OnlyUsersFromAllowedOrganizations' when spec.allowAuthentication.organizations.allowed
|
||||
has organizations listed
|
||||
rule: '!(has(self.allowed) && size(self.allowed) > 0 && self.policy
|
||||
== ''AllGitHubUsers'')'
|
||||
- message: spec.allowAuthentication.organizations.policy must
|
||||
be 'AllGitHubUsers' when spec.allowAuthentication.organizations.allowed
|
||||
is empty
|
||||
rule: '!((!has(self.allowed) || size(self.allowed) == 0) &&
|
||||
self.policy == ''OnlyUsersFromAllowedOrganizations'')'
|
||||
required:
|
||||
- organizations
|
||||
type: object
|
||||
claims:
|
||||
default: {}
|
||||
description: Claims allows customization of the username and groups
|
||||
claims.
|
||||
properties:
|
||||
groups:
|
||||
default: slug
|
||||
description: |-
|
||||
Groups configures which property of the GitHub team record shall determine the group names in Kubernetes.
|
||||
|
||||
Can be either "name" or "slug". Defaults to "slug".
|
||||
|
||||
GitHub team names can contain upper and lower case characters, whitespace, and punctuation (e.g. "Kube admins!").
|
||||
|
||||
GitHub team slugs are lower case alphanumeric characters and may contain dashes and underscores (e.g. "kube-admins").
|
||||
|
||||
Group names as presented to Kubernetes will always be prefixed by the GitHub organization name followed by a
|
||||
forward slash (e.g. "my-org/my-team"). GitHub organization login names can only contain alphanumeric characters
|
||||
or single hyphens, so the first forward slash `/` will be the separator between the organization login name and
|
||||
the team name or slug.
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's
|
||||
FederationDomain to further customize how these group names are presented to Kubernetes.
|
||||
|
||||
See the response schema for
|
||||
[List teams for the authenticated user](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user).
|
||||
enum:
|
||||
- name
|
||||
- slug
|
||||
type: string
|
||||
username:
|
||||
default: login:id
|
||||
description: |-
|
||||
Username configures which property of the GitHub user record shall determine the username in Kubernetes.
|
||||
|
||||
Can be either "id", "login", or "login:id". Defaults to "login:id".
|
||||
|
||||
GitHub's user login attributes can only contain alphanumeric characters and non-repeating hyphens,
|
||||
and may not start or end with hyphens. GitHub users are allowed to change their login name,
|
||||
although it is inconvenient. If a GitHub user changed their login name from "foo" to "bar",
|
||||
then a second user might change their name from "baz" to "foo" in order to take the old
|
||||
username of the first user. For this reason, it is not as safe to make authorization decisions
|
||||
based only on the user's login attribute.
|
||||
|
||||
If desired, an admin could configure identity transformation expressions on the Pinniped Supervisor's
|
||||
FederationDomain to further customize how these usernames are presented to Kubernetes.
|
||||
|
||||
Defaults to "login:id", which is the user login attribute, followed by a colon, followed by the unique and
|
||||
unchanging integer ID number attribute. This blends human-readable login names with the unchanging ID value
|
||||
from GitHub. Colons are not allowed in GitHub login attributes or ID numbers, so this is a reasonable
|
||||
choice to concatenate the two values.
|
||||
|
||||
See the response schema for
|
||||
[Get the authenticated user](https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user).
|
||||
enum:
|
||||
- id
|
||||
- login
|
||||
- login:id
|
||||
type: string
|
||||
type: object
|
||||
client:
|
||||
description: Client identifies the secret with credentials for a GitHub
|
||||
App or GitHub OAuth2 App (a GitHub client).
|
||||
properties:
|
||||
secretName:
|
||||
description: |-
|
||||
SecretName contains the name of a namespace-local Secret object that provides the clientID and
|
||||
clientSecret for an GitHub App or GitHub OAuth2 client.
|
||||
|
||||
This secret must be of type "secrets.pinniped.dev/github-client" with keys "clientID" and "clientSecret".
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- secretName
|
||||
type: object
|
||||
githubAPI:
|
||||
default: {}
|
||||
description: GitHubAPI allows configuration for GitHub Enterprise
|
||||
Server
|
||||
properties:
|
||||
host:
|
||||
default: github.com
|
||||
description: |-
|
||||
Host is required only for GitHub Enterprise Server.
|
||||
Defaults to using GitHub's public API ("github.com").
|
||||
For convenience, specifying "github.com" is equivalent to specifying "api.github.com".
|
||||
Do not specify a protocol or scheme since "https://" will always be used.
|
||||
Port is optional. Do not specify a path, query, fragment, or userinfo.
|
||||
Only specify domain name or IP address, subdomains (optional), and port (optional).
|
||||
IPv4 and IPv6 are supported. If using an IPv6 address with a port, you must enclose the IPv6 address
|
||||
in square brackets. Example: "[::1]:443".
|
||||
minLength: 1
|
||||
type: string
|
||||
tls:
|
||||
description: |-
|
||||
TLS configuration for GitHub Enterprise Server.
|
||||
Note that this field should not be needed when using GitHub's public API ("github.com").
|
||||
However, if you choose to specify this field when using GitHub's public API, you must
|
||||
specify a CA bundle that will verify connections to "api.github.com".
|
||||
properties:
|
||||
certificateAuthorityData:
|
||||
description: X.509 Certificate Authority (base64-encoded PEM
|
||||
bundle). If omitted, a default set of system roots will
|
||||
be trusted.
|
||||
type: string
|
||||
certificateAuthorityDataSource:
|
||||
description: |-
|
||||
Reference to a CA bundle in a secret or a configmap.
|
||||
Any changes to the CA bundle in the secret or configmap will be dynamically reloaded.
|
||||
properties:
|
||||
key:
|
||||
description: |-
|
||||
Key is the key name within the secret or configmap from which to read the CA bundle.
|
||||
The value found at this key in the secret or configmap must not be empty, and must be a valid PEM-encoded
|
||||
certificate bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind configures whether the CA bundle is being sourced from a Kubernetes secret or a configmap.
|
||||
Allowed values are "Secret" or "ConfigMap".
|
||||
"ConfigMap" uses a Kubernetes configmap to source CA Bundles.
|
||||
"Secret" uses Kubernetes secrets of type kubernetes.io/tls or Opaque to source CA Bundles.
|
||||
enum:
|
||||
- Secret
|
||||
- ConfigMap
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name is the resource name of the secret or configmap from which to read the CA bundle.
|
||||
The referenced secret or configmap must be created in the same namespace where Pinniped Supervisor is installed.
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- allowAuthentication
|
||||
- client
|
||||
type: object
|
||||
status:
|
||||
description: Status of the identity provider.
|
||||
properties:
|
||||
conditions:
|
||||
description: Conditions represents the observations of an identity
|
||||
provider's current state.
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
phase:
|
||||
default: Pending
|
||||
description: Phase summarizes the overall status of the GitHubIdentityProvider.
|
||||
enum:
|
||||
- Pending
|
||||
- Ready
|
||||
- Error
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
@@ -31,18 +31,24 @@ spec:
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: LDAPIdentityProvider describes the configuration of an upstream
|
||||
Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||
description: |-
|
||||
LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access
|
||||
Protocol (LDAP) identity provider.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -50,20 +56,17 @@ spec:
|
||||
description: Spec for configuring the identity provider.
|
||||
properties:
|
||||
bind:
|
||||
description: Bind contains the configuration for how to provide access
|
||||
credentials during an initial bind to the LDAP server to be allowed
|
||||
to perform searches and binds to validate a user's credentials during
|
||||
a user's authentication attempt.
|
||||
description: |-
|
||||
Bind contains the configuration for how to provide access credentials during an initial bind to the LDAP server
|
||||
to be allowed to perform searches and binds to validate a user's credentials during a user's authentication attempt.
|
||||
properties:
|
||||
secretName:
|
||||
description: SecretName contains the name of a namespace-local
|
||||
Secret object that provides the username and password for an
|
||||
LDAP bind user. This account will be used to perform LDAP searches.
|
||||
The Secret should be of type "kubernetes.io/basic-auth" which
|
||||
includes "username" and "password" keys. The username value
|
||||
should be the full dn (distinguished name) of your bind account,
|
||||
e.g. "cn=bind-account,ou=users,dc=example,dc=com". The password
|
||||
must be non-empty.
|
||||
description: |-
|
||||
SecretName contains the name of a namespace-local Secret object that provides the username and
|
||||
password for an LDAP bind user. This account will be used to perform LDAP searches. The Secret should be
|
||||
of type "kubernetes.io/basic-auth" which includes "username" and "password" keys. The username value
|
||||
should be the full dn (distinguished name) of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
|
||||
The password must be non-empty.
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
@@ -74,79 +77,72 @@ spec:
|
||||
for a user's group membership in the LDAP provider.
|
||||
properties:
|
||||
attributes:
|
||||
description: Attributes specifies how the group's information
|
||||
should be read from each LDAP entry which was found as the result
|
||||
of the group search.
|
||||
description: |-
|
||||
Attributes specifies how the group's information should be read from each LDAP entry which was found as
|
||||
the result of the group search.
|
||||
properties:
|
||||
groupName:
|
||||
description: GroupName specifies the name of the attribute
|
||||
in the LDAP entries whose value shall become a group name
|
||||
description: |-
|
||||
GroupName specifies the name of the attribute in the LDAP entries whose value shall become a group name
|
||||
in the user's list of groups after a successful authentication.
|
||||
The value of this field is case-sensitive and must match
|
||||
the case of the attribute name returned by the LDAP server
|
||||
in the user's entry. E.g. "cn" for common name. Distinguished
|
||||
names can be used by specifying lower-case "dn". Optional.
|
||||
When not specified, the default will act as if the GroupName
|
||||
were specified as "dn" (distinguished name).
|
||||
The value of this field is case-sensitive and must match the case of the attribute name returned by the LDAP
|
||||
server in the user's entry. E.g. "cn" for common name. Distinguished names can be used by specifying lower-case "dn".
|
||||
Optional. When not specified, the default will act as if the GroupName were specified as "dn" (distinguished name).
|
||||
type: string
|
||||
type: object
|
||||
base:
|
||||
description: Base is the dn (distinguished name) that should be
|
||||
used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com".
|
||||
When not specified, no group search will be performed and authenticated
|
||||
users will not belong to any groups from the LDAP provider.
|
||||
Also, when not specified, the values of Filter, UserAttributeForFilter,
|
||||
Attributes, and SkipGroupRefresh are ignored.
|
||||
description: |-
|
||||
Base is the dn (distinguished name) that should be used as the search base when searching for groups. E.g.
|
||||
"ou=groups,dc=example,dc=com". When not specified, no group search will be performed and
|
||||
authenticated users will not belong to any groups from the LDAP provider. Also, when not specified,
|
||||
the values of Filter, UserAttributeForFilter, Attributes, and SkipGroupRefresh are ignored.
|
||||
type: string
|
||||
filter:
|
||||
description: Filter is the LDAP search filter which should be
|
||||
applied when searching for groups for a user. The pattern "{}"
|
||||
must occur in the filter at least once and will be dynamically
|
||||
replaced by the value of an attribute of the user entry found
|
||||
as a result of the user search. Which attribute's value is used
|
||||
to replace the placeholder(s) depends on the value of UserAttributeForFilter.
|
||||
description: |-
|
||||
Filter is the LDAP search filter which should be applied when searching for groups for a user.
|
||||
The pattern "{}" must occur in the filter at least once and will be dynamically replaced by the
|
||||
value of an attribute of the user entry found as a result of the user search. Which attribute's
|
||||
value is used to replace the placeholder(s) depends on the value of UserAttributeForFilter.
|
||||
For more information about LDAP filters, see https://ldap.com/ldap-filters.
|
||||
Note that the dn (distinguished name) is not an attribute of
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as "member={}".
|
||||
Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used.
|
||||
Optional. When not specified, the default will act as if the Filter were specified as "member={}".
|
||||
type: string
|
||||
skipGroupRefresh:
|
||||
description: "The user's group membership is refreshed as they
|
||||
interact with the supervisor to obtain new credentials (as their
|
||||
old credentials expire). This allows group membership changes
|
||||
to be quickly reflected into Kubernetes clusters. Since group
|
||||
membership is often used to bind authorization policies, it
|
||||
is important to keep the groups observed in Kubernetes clusters
|
||||
in-sync with the identity provider. \n In some environments,
|
||||
frequent group membership queries may result in a significant
|
||||
performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak
|
||||
the group query to be more performant, for example by disabling
|
||||
nested group search or by using a more targeted group search
|
||||
base. \n If the group search query cannot be made performant
|
||||
and you are willing to have group memberships remain static
|
||||
for approximately a day, then set skipGroupRefresh to true.
|
||||
\ This is an insecure configuration as authorization policies
|
||||
that are bound to group membership will not notice if a user
|
||||
has been removed from a particular group until their next login.
|
||||
\n This is an experimental feature that may be removed or significantly
|
||||
altered in the future. Consumers of this configuration should
|
||||
carefully read all release notes before upgrading to ensure
|
||||
that the meaning of this field has not changed."
|
||||
description: |-
|
||||
The user's group membership is refreshed as they interact with the supervisor
|
||||
to obtain new credentials (as their old credentials expire). This allows group
|
||||
membership changes to be quickly reflected into Kubernetes clusters. Since
|
||||
group membership is often used to bind authorization policies, it is important
|
||||
to keep the groups observed in Kubernetes clusters in-sync with the identity
|
||||
provider.
|
||||
|
||||
In some environments, frequent group membership queries may result in a
|
||||
significant performance impact on the identity provider and/or the supervisor.
|
||||
The best approach to handle performance impacts is to tweak the group query
|
||||
to be more performant, for example by disabling nested group search or by
|
||||
using a more targeted group search base.
|
||||
|
||||
If the group search query cannot be made performant and you are willing to
|
||||
have group memberships remain static for approximately a day, then set
|
||||
skipGroupRefresh to true. This is an insecure configuration as authorization
|
||||
policies that are bound to group membership will not notice if a user has
|
||||
been removed from a particular group until their next login.
|
||||
|
||||
This is an experimental feature that may be removed or significantly altered
|
||||
in the future. Consumers of this configuration should carefully read all
|
||||
release notes before upgrading to ensure that the meaning of this field has
|
||||
not changed.
|
||||
type: boolean
|
||||
userAttributeForFilter:
|
||||
description: UserAttributeForFilter specifies which attribute's
|
||||
value from the user entry found as a result of the user search
|
||||
will be used to replace the "{}" placeholder(s) in the group
|
||||
search Filter. For example, specifying "uid" as the UserAttributeForFilter
|
||||
while specifying "&(objectClass=posixGroup)(memberUid={})" as
|
||||
the Filter would search for groups by replacing the "{}" placeholder
|
||||
in the Filter with the value of the user's "uid" attribute.
|
||||
Optional. When not specified, the default will act as if "dn"
|
||||
were specified. For example, leaving UserAttributeForFilter
|
||||
unspecified while specifying "&(objectClass=groupOfNames)(member={})"
|
||||
as the Filter would search for groups by replacing the "{}"
|
||||
placeholder(s) with the dn (distinguished name) of the user.
|
||||
description: |-
|
||||
UserAttributeForFilter specifies which attribute's value from the user entry found as a result of
|
||||
the user search will be used to replace the "{}" placeholder(s) in the group search Filter.
|
||||
For example, specifying "uid" as the UserAttributeForFilter while specifying
|
||||
"&(objectClass=posixGroup)(memberUid={})" as the Filter would search for groups by replacing
|
||||
the "{}" placeholder in the Filter with the value of the user's "uid" attribute.
|
||||
Optional. When not specified, the default will act as if "dn" were specified. For example, leaving
|
||||
UserAttributeForFilter unspecified while specifying "&(objectClass=groupOfNames)(member={})" as the Filter
|
||||
would search for groups by replacing the "{}" placeholder(s) with the dn (distinguished name) of the user.
|
||||
type: string
|
||||
type: object
|
||||
host:
|
||||
@@ -162,60 +158,85 @@ spec:
|
||||
description: X.509 Certificate Authority (base64-encoded PEM bundle).
|
||||
If omitted, a default set of system roots will be trusted.
|
||||
type: string
|
||||
certificateAuthorityDataSource:
|
||||
description: |-
|
||||
Reference to a CA bundle in a secret or a configmap.
|
||||
Any changes to the CA bundle in the secret or configmap will be dynamically reloaded.
|
||||
properties:
|
||||
key:
|
||||
description: |-
|
||||
Key is the key name within the secret or configmap from which to read the CA bundle.
|
||||
The value found at this key in the secret or configmap must not be empty, and must be a valid PEM-encoded
|
||||
certificate bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind configures whether the CA bundle is being sourced from a Kubernetes secret or a configmap.
|
||||
Allowed values are "Secret" or "ConfigMap".
|
||||
"ConfigMap" uses a Kubernetes configmap to source CA Bundles.
|
||||
"Secret" uses Kubernetes secrets of type kubernetes.io/tls or Opaque to source CA Bundles.
|
||||
enum:
|
||||
- Secret
|
||||
- ConfigMap
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name is the resource name of the secret or configmap from which to read the CA bundle.
|
||||
The referenced secret or configmap must be created in the same namespace where Pinniped Supervisor is installed.
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
userSearch:
|
||||
description: UserSearch contains the configuration for searching for
|
||||
a user by name in the LDAP provider.
|
||||
properties:
|
||||
attributes:
|
||||
description: Attributes specifies how the user's information should
|
||||
be read from the LDAP entry which was found as the result of
|
||||
the user search.
|
||||
description: |-
|
||||
Attributes specifies how the user's information should be read from the LDAP entry which was found as
|
||||
the result of the user search.
|
||||
properties:
|
||||
uid:
|
||||
description: UID specifies the name of the attribute in the
|
||||
LDAP entry which whose value shall be used to uniquely identify
|
||||
the user within this LDAP provider after a successful authentication.
|
||||
E.g. "uidNumber" or "objectGUID". The value of this field
|
||||
is case-sensitive and must match the case of the attribute
|
||||
name returned by the LDAP server in the user's entry. Distinguished
|
||||
names can be used by specifying lower-case "dn".
|
||||
description: |-
|
||||
UID specifies the name of the attribute in the LDAP entry which whose value shall be used to uniquely
|
||||
identify the user within this LDAP provider after a successful authentication. E.g. "uidNumber" or "objectGUID".
|
||||
The value of this field is case-sensitive and must match the case of the attribute name returned by the LDAP
|
||||
server in the user's entry. Distinguished names can be used by specifying lower-case "dn".
|
||||
minLength: 1
|
||||
type: string
|
||||
username:
|
||||
description: Username specifies the name of the attribute
|
||||
in the LDAP entry whose value shall become the username
|
||||
of the user after a successful authentication. This would
|
||||
typically be the same attribute name used in the user search
|
||||
filter, although it can be different. E.g. "mail" or "uid"
|
||||
or "userPrincipalName". The value of this field is case-sensitive
|
||||
and must match the case of the attribute name returned by
|
||||
the LDAP server in the user's entry. Distinguished names
|
||||
can be used by specifying lower-case "dn". When this field
|
||||
is set to "dn" then the LDAPIdentityProviderUserSearch's
|
||||
Filter field cannot be blank, since the default value of
|
||||
"dn={}" would not work.
|
||||
description: |-
|
||||
Username specifies the name of the attribute in the LDAP entry whose value shall become the username
|
||||
of the user after a successful authentication. This would typically be the same attribute name used in
|
||||
the user search filter, although it can be different. E.g. "mail" or "uid" or "userPrincipalName".
|
||||
The value of this field is case-sensitive and must match the case of the attribute name returned by the LDAP
|
||||
server in the user's entry. Distinguished names can be used by specifying lower-case "dn". When this field
|
||||
is set to "dn" then the LDAPIdentityProviderUserSearch's Filter field cannot be blank, since the default
|
||||
value of "dn={}" would not work.
|
||||
minLength: 1
|
||||
type: string
|
||||
type: object
|
||||
base:
|
||||
description: Base is the dn (distinguished name) that should be
|
||||
used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
description: |-
|
||||
Base is the dn (distinguished name) that should be used as the search base when searching for users.
|
||||
E.g. "ou=users,dc=example,dc=com".
|
||||
minLength: 1
|
||||
type: string
|
||||
filter:
|
||||
description: Filter is the LDAP search filter which should be
|
||||
applied when searching for users. The pattern "{}" must occur
|
||||
in the filter at least once and will be dynamically replaced
|
||||
by the username for which the search is being run. E.g. "mail={}"
|
||||
or "&(objectClass=person)(uid={})". For more information about
|
||||
LDAP filters, see https://ldap.com/ldap-filters. Note that the
|
||||
dn (distinguished name) is not an attribute of an entry, so
|
||||
"dn={}" cannot be used. Optional. When not specified, the default
|
||||
will act as if the Filter were specified as the value from Attributes.Username
|
||||
appended by "={}". When the Attributes.Username is set to "dn"
|
||||
then the Filter must be explicitly specified, since the default
|
||||
value of "dn={}" would not work.
|
||||
description: |-
|
||||
Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur
|
||||
in the filter at least once and will be dynamically replaced by the username for which the search is being run.
|
||||
E.g. "mail={}" or "&(objectClass=person)(uid={})". For more information about LDAP filters, see
|
||||
https://ldap.com/ldap-filters.
|
||||
Note that the dn (distinguished name) is not an attribute of an entry, so "dn={}" cannot be used.
|
||||
Optional. When not specified, the default will act as if the Filter were specified as the value from
|
||||
Attributes.Username appended by "={}". When the Attributes.Username is set to "dn" then the Filter must be
|
||||
explicitly specified, since the default value of "dn={}" would not work.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
@@ -228,43 +249,35 @@ spec:
|
||||
description: Represents the observations of an identity provider's
|
||||
current state.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
@@ -279,10 +292,6 @@ spec:
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: oidcidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
@@ -35,14 +35,19 @@ spec:
|
||||
OpenID Connect identity provider.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
@@ -50,39 +55,29 @@ spec:
|
||||
description: Spec for configuring the identity provider.
|
||||
properties:
|
||||
authorizationConfig:
|
||||
description: AuthorizationConfig holds information about how to form
|
||||
the OAuth2 authorization request parameters to be used with this
|
||||
OIDC identity provider.
|
||||
description: |-
|
||||
AuthorizationConfig holds information about how to form the OAuth2 authorization request
|
||||
parameters to be used with this OIDC identity provider.
|
||||
properties:
|
||||
additionalAuthorizeParameters:
|
||||
description: additionalAuthorizeParameters are extra query parameters
|
||||
that should be included in the authorize request to your OIDC
|
||||
provider in the authorization request during an OIDC Authorization
|
||||
Code Flow. By default, no extra parameters are sent. The standard
|
||||
parameters that will be sent are "response_type", "scope", "client_id",
|
||||
"state", "nonce", "code_challenge", "code_challenge_method",
|
||||
and "redirect_uri". These parameters cannot be included in this
|
||||
setting. Additionally, the "hd" parameter cannot be included
|
||||
in this setting at this time. The "hd" parameter is used by
|
||||
Google's OIDC provider to provide a hint as to which "hosted
|
||||
domain" the user should use during login. However, Pinniped
|
||||
does not yet support validating the hosted domain in the resulting
|
||||
ID token, so it is not yet safe to use this feature of Google's
|
||||
OIDC provider with Pinniped. This setting does not influence
|
||||
the parameters sent to the token endpoint in the Resource Owner
|
||||
Password Credentials Grant. The Pinniped Supervisor requires
|
||||
that your OIDC provider returns refresh tokens to the Supervisor
|
||||
from the authorization flows. Some OIDC providers may require
|
||||
a certain value for the "prompt" parameter in order to properly
|
||||
request refresh tokens. See the documentation of your OIDC provider's
|
||||
authorization endpoint for its requirements for what to include
|
||||
in the request in order to receive a refresh token in the response,
|
||||
if anything. If your provider requires the prompt parameter
|
||||
to request a refresh token, then include it here. Also note
|
||||
that most providers also require a certain scope to be requested
|
||||
in order to receive refresh tokens. See the additionalScopes
|
||||
setting for more information about using scopes to request refresh
|
||||
tokens.
|
||||
description: |-
|
||||
additionalAuthorizeParameters are extra query parameters that should be included in the authorize request to your
|
||||
OIDC provider in the authorization request during an OIDC Authorization Code Flow. By default, no extra
|
||||
parameters are sent. The standard parameters that will be sent are "response_type", "scope", "client_id",
|
||||
"state", "nonce", "code_challenge", "code_challenge_method", and "redirect_uri". These parameters cannot be
|
||||
included in this setting. Additionally, the "hd" parameter cannot be included in this setting at this time.
|
||||
The "hd" parameter is used by Google's OIDC provider to provide a hint as to which "hosted domain" the user
|
||||
should use during login. However, Pinniped does not yet support validating the hosted domain in the resulting
|
||||
ID token, so it is not yet safe to use this feature of Google's OIDC provider with Pinniped.
|
||||
This setting does not influence the parameters sent to the token endpoint in the Resource Owner Password
|
||||
Credentials Grant. The Pinniped Supervisor requires that your OIDC provider returns refresh tokens to the
|
||||
Supervisor from the authorization flows. Some OIDC providers may require a certain value for the "prompt"
|
||||
parameter in order to properly request refresh tokens. See the documentation of your OIDC provider's
|
||||
authorization endpoint for its requirements for what to include in the request in order to receive a refresh
|
||||
token in the response, if anything. If your provider requires the prompt parameter to request a refresh token,
|
||||
then include it here. Also note that most providers also require a certain scope to be requested in order to
|
||||
receive refresh tokens. See the additionalScopes setting for more information about using scopes to request
|
||||
refresh tokens.
|
||||
items:
|
||||
description: Parameter is a key/value pair which represents
|
||||
a parameter in an HTTP request.
|
||||
@@ -102,139 +97,109 @@ spec:
|
||||
- name
|
||||
x-kubernetes-list-type: map
|
||||
additionalScopes:
|
||||
description: 'additionalScopes are the additional scopes that
|
||||
will be requested from your OIDC provider in the authorization
|
||||
request during an OIDC Authorization Code Flow and in the token
|
||||
request during a Resource Owner Password Credentials Grant.
|
||||
Note that the "openid" scope will always be requested regardless
|
||||
of the value in this setting, since it is always required according
|
||||
to the OIDC spec. By default, when this field is not set, the
|
||||
Supervisor will request the following scopes: "openid", "offline_access",
|
||||
"email", and "profile". See https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
|
||||
for a description of the "profile" and "email" scopes. See https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
|
||||
for a description of the "offline_access" scope. This default
|
||||
value may change in future versions of Pinniped as the standard
|
||||
evolves, or as common patterns used by providers who implement
|
||||
the standard in the ecosystem evolve. By setting this list to
|
||||
anything other than an empty list, you are overriding the default
|
||||
value, so you may wish to include some of "offline_access",
|
||||
"email", and "profile" in your override list. If you do not
|
||||
want any of these scopes to be requested, you may set this list
|
||||
to contain only "openid". Some OIDC providers may also require
|
||||
a scope to get access to the user''s group membership, in which
|
||||
case you may wish to include it in this list. Sometimes the
|
||||
scope to request the user''s group membership is called "groups",
|
||||
but unfortunately this is not specified in the OIDC standard.
|
||||
Generally speaking, you should include any scopes required to
|
||||
cause the appropriate claims to be the returned by your OIDC
|
||||
provider in the ID token or userinfo endpoint results for those
|
||||
claims which you would like to use in the oidcClaims settings
|
||||
to determine the usernames and group memberships of your Kubernetes
|
||||
users. See your OIDC provider''s documentation for more information
|
||||
about what scopes are available to request claims. Additionally,
|
||||
the Pinniped Supervisor requires that your OIDC provider returns
|
||||
refresh tokens to the Supervisor from these authorization flows.
|
||||
For most OIDC providers, the scope required to receive refresh
|
||||
tokens will be "offline_access". See the documentation of your
|
||||
OIDC provider''s authorization and token endpoints for its requirements
|
||||
for what to include in the request in order to receive a refresh
|
||||
token in the response, if anything. Note that it may be safe
|
||||
to send "offline_access" even to providers which do not require
|
||||
it, since the provider may ignore scopes that it does not understand
|
||||
or require (see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3).
|
||||
In the unusual case that you must avoid sending the "offline_access"
|
||||
scope, then you must override the default value of this setting.
|
||||
This is required if your OIDC provider will reject the request
|
||||
when it includes "offline_access" (e.g. GitLab''s OIDC provider).'
|
||||
description: |-
|
||||
additionalScopes are the additional scopes that will be requested from your OIDC provider in the authorization
|
||||
request during an OIDC Authorization Code Flow and in the token request during a Resource Owner Password Credentials
|
||||
Grant. Note that the "openid" scope will always be requested regardless of the value in this setting, since it is
|
||||
always required according to the OIDC spec. By default, when this field is not set, the Supervisor will request
|
||||
the following scopes: "openid", "offline_access", "email", and "profile". See
|
||||
https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims for a description of the "profile" and "email"
|
||||
scopes. See https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess for a description of the
|
||||
"offline_access" scope. This default value may change in future versions of Pinniped as the standard evolves,
|
||||
or as common patterns used by providers who implement the standard in the ecosystem evolve.
|
||||
By setting this list to anything other than an empty list, you are overriding the
|
||||
default value, so you may wish to include some of "offline_access", "email", and "profile" in your override list.
|
||||
If you do not want any of these scopes to be requested, you may set this list to contain only "openid".
|
||||
Some OIDC providers may also require a scope to get access to the user's group membership, in which case you
|
||||
may wish to include it in this list. Sometimes the scope to request the user's group membership is called
|
||||
"groups", but unfortunately this is not specified in the OIDC standard.
|
||||
Generally speaking, you should include any scopes required to cause the appropriate claims to be the returned by
|
||||
your OIDC provider in the ID token or userinfo endpoint results for those claims which you would like to use in
|
||||
the oidcClaims settings to determine the usernames and group memberships of your Kubernetes users. See
|
||||
your OIDC provider's documentation for more information about what scopes are available to request claims.
|
||||
Additionally, the Pinniped Supervisor requires that your OIDC provider returns refresh tokens to the Supervisor
|
||||
from these authorization flows. For most OIDC providers, the scope required to receive refresh tokens will be
|
||||
"offline_access". See the documentation of your OIDC provider's authorization and token endpoints for its
|
||||
requirements for what to include in the request in order to receive a refresh token in the response, if anything.
|
||||
Note that it may be safe to send "offline_access" even to providers which do not require it, since the provider
|
||||
may ignore scopes that it does not understand or require (see
|
||||
https://datatracker.ietf.org/doc/html/rfc6749#section-3.3). In the unusual case that you must avoid sending the
|
||||
"offline_access" scope, then you must override the default value of this setting. This is required if your OIDC
|
||||
provider will reject the request when it includes "offline_access" (e.g. GitLab's OIDC provider).
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
allowPasswordGrant:
|
||||
description: allowPasswordGrant, when true, will allow the use
|
||||
of OAuth 2.0's Resource Owner Password Credentials Grant (see
|
||||
https://datatracker.ietf.org/doc/html/rfc6749#section-4.3) to
|
||||
authenticate to the OIDC provider using a username and password
|
||||
without a web browser, in addition to the usual browser-based
|
||||
OIDC Authorization Code Flow. The Resource Owner Password Credentials
|
||||
Grant is not officially part of the OIDC specification, so it
|
||||
may not be supported by your OIDC provider. If your OIDC provider
|
||||
supports returning ID tokens from a Resource Owner Password
|
||||
Credentials Grant token request, then you can choose to set
|
||||
this field to true. This will allow end users to choose to present
|
||||
their username and password to the kubectl CLI (using the Pinniped
|
||||
plugin) to authenticate to the cluster, without using a web
|
||||
browser to log in as is customary in OIDC Authorization Code
|
||||
Flow. This may be convenient for users, especially for identities
|
||||
from your OIDC provider which are not intended to represent
|
||||
a human actor, such as service accounts performing actions in
|
||||
a CI/CD environment. Even if your OIDC provider supports it,
|
||||
you may wish to disable this behavior by setting this field
|
||||
to false when you prefer to only allow users of this OIDCIdentityProvider
|
||||
to log in via the browser-based OIDC Authorization Code Flow.
|
||||
Using the Resource Owner Password Credentials Grant means that
|
||||
the Pinniped CLI and Pinniped Supervisor will directly handle
|
||||
your end users' passwords (similar to LDAPIdentityProvider),
|
||||
and you will not be able to require multi-factor authentication
|
||||
or use the other web-based login features of your OIDC provider
|
||||
during Resource Owner Password Credentials Grant logins. allowPasswordGrant
|
||||
defaults to false.
|
||||
description: |-
|
||||
allowPasswordGrant, when true, will allow the use of OAuth 2.0's Resource Owner Password Credentials Grant
|
||||
(see https://datatracker.ietf.org/doc/html/rfc6749#section-4.3) to authenticate to the OIDC provider using a
|
||||
username and password without a web browser, in addition to the usual browser-based OIDC Authorization Code Flow.
|
||||
The Resource Owner Password Credentials Grant is not officially part of the OIDC specification, so it may not be
|
||||
supported by your OIDC provider. If your OIDC provider supports returning ID tokens from a Resource Owner Password
|
||||
Credentials Grant token request, then you can choose to set this field to true. This will allow end users to choose
|
||||
to present their username and password to the kubectl CLI (using the Pinniped plugin) to authenticate to the
|
||||
cluster, without using a web browser to log in as is customary in OIDC Authorization Code Flow. This may be
|
||||
convenient for users, especially for identities from your OIDC provider which are not intended to represent a human
|
||||
actor, such as service accounts performing actions in a CI/CD environment. Even if your OIDC provider supports it,
|
||||
you may wish to disable this behavior by setting this field to false when you prefer to only allow users of this
|
||||
OIDCIdentityProvider to log in via the browser-based OIDC Authorization Code Flow. Using the Resource Owner Password
|
||||
Credentials Grant means that the Pinniped CLI and Pinniped Supervisor will directly handle your end users' passwords
|
||||
(similar to LDAPIdentityProvider), and you will not be able to require multi-factor authentication or use the other
|
||||
web-based login features of your OIDC provider during Resource Owner Password Credentials Grant logins.
|
||||
allowPasswordGrant defaults to false.
|
||||
type: boolean
|
||||
type: object
|
||||
claims:
|
||||
description: Claims provides the names of token claims that will be
|
||||
used when inspecting an identity from this OIDC identity provider.
|
||||
description: |-
|
||||
Claims provides the names of token claims that will be used when inspecting an identity from
|
||||
this OIDC identity provider.
|
||||
properties:
|
||||
additionalClaimMappings:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: AdditionalClaimMappings allows for additional arbitrary
|
||||
upstream claim values to be mapped into the "additionalClaims"
|
||||
claim of the ID tokens generated by the Supervisor. This should
|
||||
be specified as a map of new claim names as the keys, and upstream
|
||||
claim names as the values. These new claim names will be nested
|
||||
under the top-level "additionalClaims" claim in ID tokens generated
|
||||
by the Supervisor when this OIDCIdentityProvider was used for
|
||||
user authentication. These claims will be made available to
|
||||
all clients. This feature is not required to use the Supervisor
|
||||
to provide authentication for Kubernetes clusters, but can be
|
||||
used when using the Supervisor for other authentication purposes.
|
||||
When this map is empty or the upstream claims are not available,
|
||||
the "additionalClaims" claim will be excluded from the ID tokens
|
||||
generated by the Supervisor.
|
||||
description: |-
|
||||
AdditionalClaimMappings allows for additional arbitrary upstream claim values to be mapped into the
|
||||
"additionalClaims" claim of the ID tokens generated by the Supervisor. This should be specified as a map of
|
||||
new claim names as the keys, and upstream claim names as the values. These new claim names will be nested
|
||||
under the top-level "additionalClaims" claim in ID tokens generated by the Supervisor when this
|
||||
OIDCIdentityProvider was used for user authentication. These claims will be made available to all clients.
|
||||
This feature is not required to use the Supervisor to provide authentication for Kubernetes clusters, but can be
|
||||
used when using the Supervisor for other authentication purposes. When this map is empty or the upstream claims
|
||||
are not available, the "additionalClaims" claim will be excluded from the ID tokens generated by the Supervisor.
|
||||
type: object
|
||||
groups:
|
||||
description: Groups provides the name of the ID token claim or
|
||||
userinfo endpoint response claim that will be used to ascertain
|
||||
the groups to which an identity belongs. By default, the identities
|
||||
will not include any group memberships when this setting is
|
||||
not configured.
|
||||
description: |-
|
||||
Groups provides the name of the ID token claim or userinfo endpoint response claim that will be used to ascertain
|
||||
the groups to which an identity belongs. By default, the identities will not include any group memberships when
|
||||
this setting is not configured.
|
||||
type: string
|
||||
username:
|
||||
description: Username provides the name of the ID token claim
|
||||
or userinfo endpoint response claim that will be used to ascertain
|
||||
an identity's username. When not set, the username will be an
|
||||
automatically constructed unique string which will include the
|
||||
issuer URL of your OIDC provider along with the value of the
|
||||
"sub" (subject) claim from the ID token.
|
||||
description: |-
|
||||
Username provides the name of the ID token claim or userinfo endpoint response claim that will be used to
|
||||
ascertain an identity's username. When not set, the username will be an automatically constructed unique string
|
||||
which will include the issuer URL of your OIDC provider along with the value of the "sub" (subject) claim from
|
||||
the ID token.
|
||||
type: string
|
||||
type: object
|
||||
client:
|
||||
description: OIDCClient contains OIDC client information to be used
|
||||
used with this OIDC identity provider.
|
||||
description: |-
|
||||
OIDCClient contains OIDC client information to be used used with this OIDC identity
|
||||
provider.
|
||||
properties:
|
||||
secretName:
|
||||
description: SecretName contains the name of a namespace-local
|
||||
Secret object that provides the clientID and clientSecret for
|
||||
an OIDC client. If only the SecretName is specified in an OIDCClient
|
||||
struct, then it is expected that the Secret is of type "secrets.pinniped.dev/oidc-client"
|
||||
with keys "clientID" and "clientSecret".
|
||||
description: |-
|
||||
SecretName contains the name of a namespace-local Secret object that provides the clientID and
|
||||
clientSecret for an OIDC client. If only the SecretName is specified in an OIDCClient
|
||||
struct, then it is expected that the Secret is of type "secrets.pinniped.dev/oidc-client" with keys
|
||||
"clientID" and "clientSecret".
|
||||
type: string
|
||||
required:
|
||||
- secretName
|
||||
type: object
|
||||
issuer:
|
||||
description: Issuer is the issuer URL of this OIDC identity provider,
|
||||
i.e., where to fetch /.well-known/openid-configuration.
|
||||
description: |-
|
||||
Issuer is the issuer URL of this OIDC identity provider, i.e., where to fetch
|
||||
/.well-known/openid-configuration.
|
||||
minLength: 1
|
||||
pattern: ^https://
|
||||
type: string
|
||||
@@ -246,6 +211,39 @@ spec:
|
||||
description: X.509 Certificate Authority (base64-encoded PEM bundle).
|
||||
If omitted, a default set of system roots will be trusted.
|
||||
type: string
|
||||
certificateAuthorityDataSource:
|
||||
description: |-
|
||||
Reference to a CA bundle in a secret or a configmap.
|
||||
Any changes to the CA bundle in the secret or configmap will be dynamically reloaded.
|
||||
properties:
|
||||
key:
|
||||
description: |-
|
||||
Key is the key name within the secret or configmap from which to read the CA bundle.
|
||||
The value found at this key in the secret or configmap must not be empty, and must be a valid PEM-encoded
|
||||
certificate bundle.
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind configures whether the CA bundle is being sourced from a Kubernetes secret or a configmap.
|
||||
Allowed values are "Secret" or "ConfigMap".
|
||||
"ConfigMap" uses a Kubernetes configmap to source CA Bundles.
|
||||
"Secret" uses Kubernetes secrets of type kubernetes.io/tls or Opaque to source CA Bundles.
|
||||
enum:
|
||||
- Secret
|
||||
- ConfigMap
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name is the resource name of the secret or configmap from which to read the CA bundle.
|
||||
The referenced secret or configmap must be created in the same namespace where Pinniped Supervisor is installed.
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- client
|
||||
@@ -258,43 +256,35 @@ spec:
|
||||
description: Represents the observations of an identity provider's
|
||||
current state.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
@@ -309,10 +299,6 @@ spec:
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@@ -16,6 +16,9 @@ rules:
|
||||
- apiGroups: [""]
|
||||
resources: [secrets]
|
||||
verbs: [create, get, list, patch, update, watch, delete]
|
||||
- apiGroups: [""]
|
||||
resources: [configmaps]
|
||||
verbs: [get, list, watch]
|
||||
- apiGroups:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||
resources: [federationdomains]
|
||||
@@ -56,6 +59,14 @@ rules:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||
resources: [activedirectoryidentityproviders/status]
|
||||
verbs: [get, patch, update]
|
||||
- apiGroups:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||
resources: [githubidentityproviders]
|
||||
verbs: [get, list, watch]
|
||||
- apiGroups:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||
resources: [githubidentityproviders/status]
|
||||
verbs: [get, patch, update]
|
||||
#! We want to be able to read pods/replicasets/deployment so we can learn who our deployment is to set
|
||||
#! as an owner reference.
|
||||
- apiGroups: [""]
|
||||
@@ -131,7 +142,7 @@ rules:
|
||||
resources: [ apiservices ]
|
||||
verbs: [ get, list, patch, update, watch ]
|
||||
- apiGroups: [ admissionregistration.k8s.io ]
|
||||
resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations ]
|
||||
resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations, validatingadmissionpolicies, validatingadmissionpolicybindings ]
|
||||
verbs: [ get, list, watch ]
|
||||
- apiGroups: [ flowcontrol.apiserver.k8s.io ]
|
||||
resources: [ flowschemas, prioritylevelconfigurations ]
|
||||
|
||||
@@ -1,24 +1,10 @@
|
||||
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
#@ load("@ytt:assert", "assert")
|
||||
#@ load("helpers.lib.yaml", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix")
|
||||
|
||||
#@ if hasattr(data.values, "service_http_nodeport_port"):
|
||||
#@ assert.fail('value "service_http_nodeport_port" has been renamed to "deprecated_service_http_nodeport_port" and will be removed in a future release')
|
||||
#@ end
|
||||
#@ if hasattr(data.values, "service_http_nodeport_nodeport"):
|
||||
#@ assert.fail('value "service_http_nodeport_nodeport" has been renamed to "deprecated_service_http_nodeport_nodeport" and will be removed in a future release')
|
||||
#@ end
|
||||
#@ if hasattr(data.values, "service_http_loadbalancer_port"):
|
||||
#@ assert.fail('value "service_http_loadbalancer_port" has been renamed to "deprecated_service_http_loadbalancer_port" and will be removed in a future release')
|
||||
#@ end
|
||||
#@ if hasattr(data.values, "service_http_clusterip_port"):
|
||||
#@ assert.fail('value "service_http_clusterip_port" has been renamed to "deprecated_service_http_clusterip_port" and will be removed in a future release')
|
||||
#@ end
|
||||
|
||||
#@ if data.values.deprecated_service_http_nodeport_port or data.values.service_https_nodeport_port:
|
||||
#@ if data.values.service_https_nodeport_port:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -33,15 +19,6 @@ spec:
|
||||
type: NodePort
|
||||
selector: #@ deploymentPodLabel()
|
||||
ports:
|
||||
#@ if data.values.deprecated_service_http_nodeport_port:
|
||||
- name: http
|
||||
protocol: TCP
|
||||
port: #@ data.values.deprecated_service_http_nodeport_port
|
||||
targetPort: 8080
|
||||
#@ if data.values.deprecated_service_http_nodeport_nodeport:
|
||||
nodePort: #@ data.values.deprecated_service_http_nodeport_nodeport
|
||||
#@ end
|
||||
#@ end
|
||||
#@ if data.values.service_https_nodeport_port:
|
||||
- name: https
|
||||
protocol: TCP
|
||||
@@ -53,7 +30,7 @@ spec:
|
||||
#@ end
|
||||
#@ end
|
||||
|
||||
#@ if data.values.deprecated_service_http_clusterip_port or data.values.service_https_clusterip_port:
|
||||
#@ if data.values.service_https_clusterip_port:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -68,12 +45,6 @@ spec:
|
||||
type: ClusterIP
|
||||
selector: #@ deploymentPodLabel()
|
||||
ports:
|
||||
#@ if data.values.deprecated_service_http_clusterip_port:
|
||||
- name: http
|
||||
protocol: TCP
|
||||
port: #@ data.values.deprecated_service_http_clusterip_port
|
||||
targetPort: 8080
|
||||
#@ end
|
||||
#@ if data.values.service_https_clusterip_port:
|
||||
- name: https
|
||||
protocol: TCP
|
||||
@@ -82,7 +53,7 @@ spec:
|
||||
#@ end
|
||||
#@ end
|
||||
|
||||
#@ if data.values.deprecated_service_http_loadbalancer_port or data.values.service_https_loadbalancer_port:
|
||||
#@ if data.values.service_https_loadbalancer_port:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -100,12 +71,6 @@ spec:
|
||||
loadBalancerIP: #@ data.values.service_loadbalancer_ip
|
||||
#@ end
|
||||
ports:
|
||||
#@ if data.values.deprecated_service_http_loadbalancer_port:
|
||||
- name: http
|
||||
protocol: TCP
|
||||
port: #@ data.values.deprecated_service_http_loadbalancer_port
|
||||
targetPort: 8080
|
||||
#@ end
|
||||
#@ if data.values.service_https_loadbalancer_port:
|
||||
- name: https
|
||||
protocol: TCP
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2024 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: projects.registry.vmware.com/pinniped/pinniped-server
|
||||
image_repo: ghcr.io/vmware-tanzu/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."
|
||||
@@ -79,34 +79,6 @@ image_tag: latest
|
||||
#@schema/validation min_len=1
|
||||
image_pull_dockerconfigjson: ""
|
||||
|
||||
#@schema/title "Deprecated service HTTP nodeport port"
|
||||
#@schema/desc "When specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`"
|
||||
#@schema/examples ("Specify port",31234)
|
||||
#@schema/nullable
|
||||
#@schema/deprecated "This data value will be removed in a future release"
|
||||
deprecated_service_http_nodeport_port: 0
|
||||
|
||||
#@schema/title "Deprecated service http nodeport nodeport"
|
||||
#@schema/desc "The `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified"
|
||||
#@schema/examples ("Specify port",31234)
|
||||
#@schema/nullable
|
||||
#@schema/deprecated "This data value will be removed in a future release"
|
||||
deprecated_service_http_nodeport_nodeport: 0
|
||||
|
||||
#@schema/title "Deprecated service http loadbalancer port"
|
||||
#@schema/desc "When specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`"
|
||||
#@schema/examples ("Specify port",8443)
|
||||
#@schema/nullable
|
||||
#@schema/deprecated "This data value will be removed in a future release"
|
||||
deprecated_service_http_loadbalancer_port: 0
|
||||
|
||||
#@schema/title "Deprecated service http clusterip port"
|
||||
#@schema/desc "Creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`"
|
||||
#@schema/examples ("Specify port",8443)
|
||||
#@schema/nullable
|
||||
#@schema/deprecated "This data value will be removed in a future release"
|
||||
deprecated_service_http_clusterip_port: 0
|
||||
|
||||
#@schema/title "Service https nodeport port"
|
||||
#@schema/desc "When specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`"
|
||||
#@schema/examples ("Specify port",31243)
|
||||
@@ -147,17 +119,6 @@ service_loadbalancer_ip: ""
|
||||
#@schema/validation one_of=["info", "debug", "trace", "all"]
|
||||
log_level: ""
|
||||
|
||||
#@schema/title "Log format"
|
||||
#@ deprecated_log_format_desc = "Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). \
|
||||
#@ By default, when this value is left unset, logs are formatted in json. \
|
||||
#@ This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json."
|
||||
#@schema/desc deprecated_log_format_desc
|
||||
#@schema/examples ("Set logs to JSON format","json")
|
||||
#@schema/nullable
|
||||
#@schema/validation one_of=["json", "text"]
|
||||
#@schema/deprecated "This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json."
|
||||
deprecated_log_format: ""
|
||||
|
||||
#@schema/title "Run as user"
|
||||
#@schema/desc "The user ID that will own the process."
|
||||
#! See the Dockerfile for the reasoning behind this default value.
|
||||
@@ -243,18 +204,39 @@ no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.
|
||||
#@schema/validation ("a map with keys 'http' and 'https', whose values are either the string 'disabled' or a map having keys 'network' and 'address', and the value of 'network' must be one of the allowed values", validate_endpoints)
|
||||
endpoints: { }
|
||||
|
||||
#@ deprecated_insecure_accept_external_unencrypted_http_requests_desc = "Optionally override the validation on the endpoints.http \
|
||||
#@ value which checks that only loopback interfaces are used. \
|
||||
#@ When deprecated_insecure_accept_external_unencrypted_http_requests is true, the HTTP listener is allowed to bind to any \
|
||||
#@ interface, including interfaces that are listening for traffic from outside the pod. This value is being introduced \
|
||||
#@ to ease the transition to the new loopback interface validation for the HTTP port for any users who need more time \
|
||||
#@ to change their ingress strategy to avoid using plain HTTP into the Supervisor pods. \
|
||||
#@ This value is immediately deprecated upon its introduction. It will be removed in some future release, at which time \
|
||||
#@ traffic from outside the pod will need to be sent to the HTTPS listener instead, with no simple workaround available. \
|
||||
#@ Allowed values are true (boolean), 'true' (string), false (boolean), and 'false' (string). The default is false."
|
||||
#@schema/desc deprecated_insecure_accept_external_unencrypted_http_requests_desc
|
||||
#@schema/type any=True
|
||||
#@schema/validation ("a boolean or string version of boolean", lambda v: type(v) in ["string", "boolean"])
|
||||
#@schema/validation one_of=["true", "false", True, False]
|
||||
#@schema/deprecated "This data value will be removed in a future release"
|
||||
deprecated_insecure_accept_external_unencrypted_http_requests: false
|
||||
#@schema/title "Allowed Ciphers for TLS 1.2"
|
||||
#@ allowed_ciphers_for_tls_onedottwo_desc = "When specified, only the ciphers listed will be used for TLS 1.2. \
|
||||
#@ This includes both server-side and client-side TLS connections. \
|
||||
#@ This list must only include cipher suites that Pinniped is configured to accept \
|
||||
#@ (see internal/crypto/ptls/profiles.go and internal/crypto/ptls/profiles_fips_strict.go). \
|
||||
#@ Allowing too few ciphers may cause critical parts of Pinniped to be unable to function. For example, \
|
||||
#@ Kubernetes pod readiness checks, Pinniped pods acting as a client to the Kubernetes API server, \
|
||||
#@ Pinniped pods acting as a client to external identity providers, or Pinniped pods acting as an APIService server \
|
||||
#@ all need to be able to function with the allowed TLS cipher suites. \
|
||||
#@ An empty array means accept Pinniped's defaults."
|
||||
#@schema/desc allowed_ciphers_for_tls_onedottwo_desc
|
||||
#@schema/examples ("Example with a few secure ciphers", ["TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"])
|
||||
#! No type, default, or validation is required here.
|
||||
#! 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,4 +1,4 @@
|
||||
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:overlay", "overlay")
|
||||
@@ -41,6 +41,15 @@ metadata:
|
||||
spec:
|
||||
group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||
|
||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"githubidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1
|
||||
---
|
||||
metadata:
|
||||
#@overlay/match missing_ok=True
|
||||
labels: #@ labels()
|
||||
name: #@ pinnipedDevAPIGroupWithPrefix("githubidentityproviders.idp.supervisor")
|
||||
spec:
|
||||
group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||
|
||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcclients.config.supervisor.pinniped.dev"}}), expects=1
|
||||
---
|
||||
metadata:
|
||||
|
||||
1777
generated/1.21/README.adoc
generated
1777
generated/1.21/README.adoc
generated
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// Configuration for configuring TLS on various authenticators.
|
||||
type TLSSpec struct {
|
||||
// X.509 Certificate Authority (base64-encoded PEM bundle). If omitted, a default set of system roots will be trusted.
|
||||
// +optional
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData,omitempty"`
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by conversion-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
unsafe "unsafe"
|
||||
|
||||
identity "go.pinniped.dev/generated/1.21/apis/concierge/identity"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(RegisterConversions)
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*KubernetesUserInfo)(nil), (*identity.KubernetesUserInfo)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_KubernetesUserInfo_To_identity_KubernetesUserInfo(a.(*KubernetesUserInfo), b.(*identity.KubernetesUserInfo), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*identity.KubernetesUserInfo)(nil), (*KubernetesUserInfo)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_identity_KubernetesUserInfo_To_v1alpha1_KubernetesUserInfo(a.(*identity.KubernetesUserInfo), b.(*KubernetesUserInfo), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*UserInfo)(nil), (*identity.UserInfo)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_UserInfo_To_identity_UserInfo(a.(*UserInfo), b.(*identity.UserInfo), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*identity.UserInfo)(nil), (*UserInfo)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_identity_UserInfo_To_v1alpha1_UserInfo(a.(*identity.UserInfo), b.(*UserInfo), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*WhoAmIRequest)(nil), (*identity.WhoAmIRequest)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_WhoAmIRequest_To_identity_WhoAmIRequest(a.(*WhoAmIRequest), b.(*identity.WhoAmIRequest), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*identity.WhoAmIRequest)(nil), (*WhoAmIRequest)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_identity_WhoAmIRequest_To_v1alpha1_WhoAmIRequest(a.(*identity.WhoAmIRequest), b.(*WhoAmIRequest), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*WhoAmIRequestList)(nil), (*identity.WhoAmIRequestList)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_WhoAmIRequestList_To_identity_WhoAmIRequestList(a.(*WhoAmIRequestList), b.(*identity.WhoAmIRequestList), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*identity.WhoAmIRequestList)(nil), (*WhoAmIRequestList)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_identity_WhoAmIRequestList_To_v1alpha1_WhoAmIRequestList(a.(*identity.WhoAmIRequestList), b.(*WhoAmIRequestList), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*WhoAmIRequestSpec)(nil), (*identity.WhoAmIRequestSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_WhoAmIRequestSpec_To_identity_WhoAmIRequestSpec(a.(*WhoAmIRequestSpec), b.(*identity.WhoAmIRequestSpec), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*identity.WhoAmIRequestSpec)(nil), (*WhoAmIRequestSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_identity_WhoAmIRequestSpec_To_v1alpha1_WhoAmIRequestSpec(a.(*identity.WhoAmIRequestSpec), b.(*WhoAmIRequestSpec), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*WhoAmIRequestStatus)(nil), (*identity.WhoAmIRequestStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_WhoAmIRequestStatus_To_identity_WhoAmIRequestStatus(a.(*WhoAmIRequestStatus), b.(*identity.WhoAmIRequestStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*identity.WhoAmIRequestStatus)(nil), (*WhoAmIRequestStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_identity_WhoAmIRequestStatus_To_v1alpha1_WhoAmIRequestStatus(a.(*identity.WhoAmIRequestStatus), b.(*WhoAmIRequestStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_KubernetesUserInfo_To_identity_KubernetesUserInfo(in *KubernetesUserInfo, out *identity.KubernetesUserInfo, s conversion.Scope) error {
|
||||
if err := Convert_v1alpha1_UserInfo_To_identity_UserInfo(&in.User, &out.User, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_KubernetesUserInfo_To_identity_KubernetesUserInfo is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_KubernetesUserInfo_To_identity_KubernetesUserInfo(in *KubernetesUserInfo, out *identity.KubernetesUserInfo, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_KubernetesUserInfo_To_identity_KubernetesUserInfo(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_identity_KubernetesUserInfo_To_v1alpha1_KubernetesUserInfo(in *identity.KubernetesUserInfo, out *KubernetesUserInfo, s conversion.Scope) error {
|
||||
if err := Convert_identity_UserInfo_To_v1alpha1_UserInfo(&in.User, &out.User, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_identity_KubernetesUserInfo_To_v1alpha1_KubernetesUserInfo is an autogenerated conversion function.
|
||||
func Convert_identity_KubernetesUserInfo_To_v1alpha1_KubernetesUserInfo(in *identity.KubernetesUserInfo, out *KubernetesUserInfo, s conversion.Scope) error {
|
||||
return autoConvert_identity_KubernetesUserInfo_To_v1alpha1_KubernetesUserInfo(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_UserInfo_To_identity_UserInfo(in *UserInfo, out *identity.UserInfo, s conversion.Scope) error {
|
||||
out.Username = in.Username
|
||||
out.UID = in.UID
|
||||
out.Groups = *(*[]string)(unsafe.Pointer(&in.Groups))
|
||||
out.Extra = *(*map[string]identity.ExtraValue)(unsafe.Pointer(&in.Extra))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_UserInfo_To_identity_UserInfo is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_UserInfo_To_identity_UserInfo(in *UserInfo, out *identity.UserInfo, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_UserInfo_To_identity_UserInfo(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_identity_UserInfo_To_v1alpha1_UserInfo(in *identity.UserInfo, out *UserInfo, s conversion.Scope) error {
|
||||
out.Username = in.Username
|
||||
out.UID = in.UID
|
||||
out.Groups = *(*[]string)(unsafe.Pointer(&in.Groups))
|
||||
out.Extra = *(*map[string]ExtraValue)(unsafe.Pointer(&in.Extra))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_identity_UserInfo_To_v1alpha1_UserInfo is an autogenerated conversion function.
|
||||
func Convert_identity_UserInfo_To_v1alpha1_UserInfo(in *identity.UserInfo, out *UserInfo, s conversion.Scope) error {
|
||||
return autoConvert_identity_UserInfo_To_v1alpha1_UserInfo(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_WhoAmIRequest_To_identity_WhoAmIRequest(in *WhoAmIRequest, out *identity.WhoAmIRequest, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1alpha1_WhoAmIRequestSpec_To_identity_WhoAmIRequestSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1alpha1_WhoAmIRequestStatus_To_identity_WhoAmIRequestStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_WhoAmIRequest_To_identity_WhoAmIRequest is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_WhoAmIRequest_To_identity_WhoAmIRequest(in *WhoAmIRequest, out *identity.WhoAmIRequest, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_WhoAmIRequest_To_identity_WhoAmIRequest(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_identity_WhoAmIRequest_To_v1alpha1_WhoAmIRequest(in *identity.WhoAmIRequest, out *WhoAmIRequest, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_identity_WhoAmIRequestSpec_To_v1alpha1_WhoAmIRequestSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_identity_WhoAmIRequestStatus_To_v1alpha1_WhoAmIRequestStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_identity_WhoAmIRequest_To_v1alpha1_WhoAmIRequest is an autogenerated conversion function.
|
||||
func Convert_identity_WhoAmIRequest_To_v1alpha1_WhoAmIRequest(in *identity.WhoAmIRequest, out *WhoAmIRequest, s conversion.Scope) error {
|
||||
return autoConvert_identity_WhoAmIRequest_To_v1alpha1_WhoAmIRequest(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_WhoAmIRequestList_To_identity_WhoAmIRequestList(in *WhoAmIRequestList, out *identity.WhoAmIRequestList, s conversion.Scope) error {
|
||||
out.ListMeta = in.ListMeta
|
||||
out.Items = *(*[]identity.WhoAmIRequest)(unsafe.Pointer(&in.Items))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_WhoAmIRequestList_To_identity_WhoAmIRequestList is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_WhoAmIRequestList_To_identity_WhoAmIRequestList(in *WhoAmIRequestList, out *identity.WhoAmIRequestList, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_WhoAmIRequestList_To_identity_WhoAmIRequestList(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_identity_WhoAmIRequestList_To_v1alpha1_WhoAmIRequestList(in *identity.WhoAmIRequestList, out *WhoAmIRequestList, s conversion.Scope) error {
|
||||
out.ListMeta = in.ListMeta
|
||||
out.Items = *(*[]WhoAmIRequest)(unsafe.Pointer(&in.Items))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_identity_WhoAmIRequestList_To_v1alpha1_WhoAmIRequestList is an autogenerated conversion function.
|
||||
func Convert_identity_WhoAmIRequestList_To_v1alpha1_WhoAmIRequestList(in *identity.WhoAmIRequestList, out *WhoAmIRequestList, s conversion.Scope) error {
|
||||
return autoConvert_identity_WhoAmIRequestList_To_v1alpha1_WhoAmIRequestList(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_WhoAmIRequestSpec_To_identity_WhoAmIRequestSpec(in *WhoAmIRequestSpec, out *identity.WhoAmIRequestSpec, s conversion.Scope) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_WhoAmIRequestSpec_To_identity_WhoAmIRequestSpec is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_WhoAmIRequestSpec_To_identity_WhoAmIRequestSpec(in *WhoAmIRequestSpec, out *identity.WhoAmIRequestSpec, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_WhoAmIRequestSpec_To_identity_WhoAmIRequestSpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_identity_WhoAmIRequestSpec_To_v1alpha1_WhoAmIRequestSpec(in *identity.WhoAmIRequestSpec, out *WhoAmIRequestSpec, s conversion.Scope) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_identity_WhoAmIRequestSpec_To_v1alpha1_WhoAmIRequestSpec is an autogenerated conversion function.
|
||||
func Convert_identity_WhoAmIRequestSpec_To_v1alpha1_WhoAmIRequestSpec(in *identity.WhoAmIRequestSpec, out *WhoAmIRequestSpec, s conversion.Scope) error {
|
||||
return autoConvert_identity_WhoAmIRequestSpec_To_v1alpha1_WhoAmIRequestSpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_WhoAmIRequestStatus_To_identity_WhoAmIRequestStatus(in *WhoAmIRequestStatus, out *identity.WhoAmIRequestStatus, s conversion.Scope) error {
|
||||
if err := Convert_v1alpha1_KubernetesUserInfo_To_identity_KubernetesUserInfo(&in.KubernetesUserInfo, &out.KubernetesUserInfo, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_WhoAmIRequestStatus_To_identity_WhoAmIRequestStatus is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_WhoAmIRequestStatus_To_identity_WhoAmIRequestStatus(in *WhoAmIRequestStatus, out *identity.WhoAmIRequestStatus, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_WhoAmIRequestStatus_To_identity_WhoAmIRequestStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_identity_WhoAmIRequestStatus_To_v1alpha1_WhoAmIRequestStatus(in *identity.WhoAmIRequestStatus, out *WhoAmIRequestStatus, s conversion.Scope) error {
|
||||
if err := Convert_identity_KubernetesUserInfo_To_v1alpha1_KubernetesUserInfo(&in.KubernetesUserInfo, &out.KubernetesUserInfo, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_identity_WhoAmIRequestStatus_To_v1alpha1_WhoAmIRequestStatus is an autogenerated conversion function.
|
||||
func Convert_identity_WhoAmIRequestStatus_To_v1alpha1_WhoAmIRequestStatus(in *identity.WhoAmIRequestStatus, out *WhoAmIRequestStatus, s conversion.Scope) error {
|
||||
return autoConvert_identity_WhoAmIRequestStatus_To_v1alpha1_WhoAmIRequestStatus(in, out, s)
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ExtraValue) DeepCopyInto(out *ExtraValue) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(ExtraValue, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtraValue.
|
||||
func (in ExtraValue) DeepCopy() ExtraValue {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtraValue)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubernetesUserInfo) DeepCopyInto(out *KubernetesUserInfo) {
|
||||
*out = *in
|
||||
in.User.DeepCopyInto(&out.User)
|
||||
if in.Audiences != nil {
|
||||
in, out := &in.Audiences, &out.Audiences
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesUserInfo.
|
||||
func (in *KubernetesUserInfo) DeepCopy() *KubernetesUserInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubernetesUserInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UserInfo) DeepCopyInto(out *UserInfo) {
|
||||
*out = *in
|
||||
if in.Groups != nil {
|
||||
in, out := &in.Groups, &out.Groups
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Extra != nil {
|
||||
in, out := &in.Extra, &out.Extra
|
||||
*out = make(map[string]ExtraValue, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make(ExtraValue, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserInfo.
|
||||
func (in *UserInfo) DeepCopy() *UserInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UserInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WhoAmIRequest) DeepCopyInto(out *WhoAmIRequest) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WhoAmIRequest.
|
||||
func (in *WhoAmIRequest) DeepCopy() *WhoAmIRequest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WhoAmIRequest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *WhoAmIRequest) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WhoAmIRequestList) DeepCopyInto(out *WhoAmIRequestList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]WhoAmIRequest, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WhoAmIRequestList.
|
||||
func (in *WhoAmIRequestList) DeepCopy() *WhoAmIRequestList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WhoAmIRequestList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *WhoAmIRequestList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WhoAmIRequestSpec) DeepCopyInto(out *WhoAmIRequestSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WhoAmIRequestSpec.
|
||||
func (in *WhoAmIRequestSpec) DeepCopy() *WhoAmIRequestSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WhoAmIRequestSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WhoAmIRequestStatus) DeepCopyInto(out *WhoAmIRequestStatus) {
|
||||
*out = *in
|
||||
in.KubernetesUserInfo.DeepCopyInto(&out.KubernetesUserInfo)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WhoAmIRequestStatus.
|
||||
func (in *WhoAmIRequestStatus) DeepCopy() *WhoAmIRequestStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WhoAmIRequestStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
11
generated/1.21/apis/concierge/login/v1alpha1/doc.go
generated
11
generated/1.21/apis/concierge/login/v1alpha1/doc.go
generated
@@ -1,11 +0,0 @@
|
||||
// Copyright 2020-2022 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/1.21/apis/concierge/login
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=login.concierge.pinniped.dev
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the Pinniped login API.
|
||||
package v1alpha1
|
||||
9
generated/1.21/apis/go.mod
generated
9
generated/1.21/apis/go.mod
generated
@@ -1,9 +0,0 @@
|
||||
// This go.mod file is generated by ./hack/codegen.sh.
|
||||
module go.pinniped.dev/generated/1.21/apis
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
k8s.io/api v0.21.14
|
||||
k8s.io/apimachinery v0.21.14
|
||||
)
|
||||
163
generated/1.21/apis/go.sum
generated
163
generated/1.21/apis/go.sum
generated
@@ -1,163 +0,0 @@
|
||||
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/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
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 v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
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/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
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/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
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 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
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/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
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/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
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-20200324143707-d3edc9973b7e/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-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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/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-20190616124812-15dcb6c0061f/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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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=
|
||||
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.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/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 h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.21.14 h1:5P/Yv95EhpU7rzgLqaDkoA1JeJmZ1Gv02GJTj9Nm7EM=
|
||||
k8s.io/api v0.21.14/go.mod h1:fUA7ZgNoFEADCpwq0Bn35XZiurViVXp7Uw9n05UYEog=
|
||||
k8s.io/apimachinery v0.21.14 h1:tC5klgLnEkSqcS4qJdKP+Cmm8gVdaY9Hu31+ozRgv6E=
|
||||
k8s.io/apimachinery v0.21.14/go.mod h1:NI5S3z6+ZZ6Da3whzPF+MnJCjU1NyLuTq9WnKIj5I20=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
|
||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-openapi v0.0.0-20211110012726-3cc51fd1e909/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
@@ -1,106 +0,0 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCClientSecretRequest) DeepCopyInto(out *OIDCClientSecretRequest) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
out.Status = in.Status
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCClientSecretRequest.
|
||||
func (in *OIDCClientSecretRequest) DeepCopy() *OIDCClientSecretRequest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OIDCClientSecretRequest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *OIDCClientSecretRequest) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCClientSecretRequestList) DeepCopyInto(out *OIDCClientSecretRequestList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]OIDCClientSecretRequest, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCClientSecretRequestList.
|
||||
func (in *OIDCClientSecretRequestList) DeepCopy() *OIDCClientSecretRequestList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OIDCClientSecretRequestList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *OIDCClientSecretRequestList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCClientSecretRequestSpec) DeepCopyInto(out *OIDCClientSecretRequestSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCClientSecretRequestSpec.
|
||||
func (in *OIDCClientSecretRequestSpec) DeepCopy() *OIDCClientSecretRequestSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OIDCClientSecretRequestSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCClientSecretRequestStatus) DeepCopyInto(out *OIDCClientSecretRequestStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCClientSecretRequestStatus.
|
||||
func (in *OIDCClientSecretRequestStatus) DeepCopy() *OIDCClientSecretRequestStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OIDCClientSecretRequestStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package clientsecret
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCClientSecretRequest) DeepCopyInto(out *OIDCClientSecretRequest) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
out.Status = in.Status
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCClientSecretRequest.
|
||||
func (in *OIDCClientSecretRequest) DeepCopy() *OIDCClientSecretRequest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OIDCClientSecretRequest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *OIDCClientSecretRequest) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCClientSecretRequestList) DeepCopyInto(out *OIDCClientSecretRequestList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]OIDCClientSecretRequest, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCClientSecretRequestList.
|
||||
func (in *OIDCClientSecretRequestList) DeepCopy() *OIDCClientSecretRequestList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OIDCClientSecretRequestList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *OIDCClientSecretRequestList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCClientSecretRequestSpec) DeepCopyInto(out *OIDCClientSecretRequestSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCClientSecretRequestSpec.
|
||||
func (in *OIDCClientSecretRequestSpec) DeepCopy() *OIDCClientSecretRequestSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OIDCClientSecretRequestSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCClientSecretRequestStatus) DeepCopyInto(out *OIDCClientSecretRequestStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCClientSecretRequestStatus.
|
||||
func (in *OIDCClientSecretRequestStatus) DeepCopy() *OIDCClientSecretRequestStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OIDCClientSecretRequestStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@@ -1,312 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type FederationDomainPhase string
|
||||
|
||||
const (
|
||||
// FederationDomainPhasePending is the default phase for newly-created FederationDomain resources.
|
||||
FederationDomainPhasePending FederationDomainPhase = "Pending"
|
||||
|
||||
// FederationDomainPhaseReady is the phase for an FederationDomain resource in a healthy state.
|
||||
FederationDomainPhaseReady FederationDomainPhase = "Ready"
|
||||
|
||||
// FederationDomainPhaseError is the phase for an FederationDomain in an unhealthy state.
|
||||
FederationDomainPhaseError FederationDomainPhase = "Error"
|
||||
)
|
||||
|
||||
// FederationDomainTLSSpec is a struct that describes the TLS configuration for an OIDC Provider.
|
||||
type FederationDomainTLSSpec struct {
|
||||
// SecretName is an optional name of a Secret in the same namespace, of type `kubernetes.io/tls`, which contains
|
||||
// the TLS serving certificate for the HTTPS endpoints served by this FederationDomain. When provided, the TLS Secret
|
||||
// named here must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use
|
||||
// for TLS.
|
||||
//
|
||||
// Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) supported by all major browsers.
|
||||
//
|
||||
// SecretName is required if you would like to use different TLS certificates for issuers of different hostnames.
|
||||
// SNI requests do not include port numbers, so all issuers with the same DNS hostname must use the same
|
||||
// SecretName value even if they have different port numbers.
|
||||
//
|
||||
// SecretName is not required when you would like to use only the HTTP endpoints (e.g. when the HTTP listener is
|
||||
// configured to listen on loopback interfaces or UNIX domain sockets for traffic from a service mesh sidecar).
|
||||
// It is also not required when you would like all requests to this OIDC Provider's HTTPS endpoints to
|
||||
// use the default TLS certificate, which is configured elsewhere.
|
||||
//
|
||||
// When your Issuer URL's host is an IP address, then this field is ignored. SNI does not work for IP addresses.
|
||||
//
|
||||
// +optional
|
||||
SecretName string `json:"secretName,omitempty"`
|
||||
}
|
||||
|
||||
// FederationDomainTransformsConstant defines a constant variable and its value which will be made available to
|
||||
// the transform expressions. This is a union type, and Type is the discriminator field.
|
||||
type FederationDomainTransformsConstant struct {
|
||||
// Name determines the name of the constant. It must be a valid identifier name.
|
||||
// +kubebuilder:validation:Pattern=`^[a-zA-Z][_a-zA-Z0-9]*$`
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=64
|
||||
Name string `json:"name"`
|
||||
|
||||
// Type determines the type of the constant, and indicates which other field should be non-empty.
|
||||
// +kubebuilder:validation:Enum=string;stringList
|
||||
Type string `json:"type"`
|
||||
|
||||
// StringValue should hold the value when Type is "string", and is otherwise ignored.
|
||||
// +optional
|
||||
StringValue string `json:"stringValue,omitempty"`
|
||||
|
||||
// StringListValue should hold the value when Type is "stringList", and is otherwise ignored.
|
||||
// +optional
|
||||
StringListValue []string `json:"stringListValue,omitempty"`
|
||||
}
|
||||
|
||||
// FederationDomainTransformsExpression defines a transform expression.
|
||||
type FederationDomainTransformsExpression struct {
|
||||
// Type determines the type of the expression. It must be one of the supported types.
|
||||
// +kubebuilder:validation:Enum=policy/v1;username/v1;groups/v1
|
||||
Type string `json:"type"`
|
||||
|
||||
// Expression is a CEL expression that will be evaluated based on the Type during an authentication.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Expression string `json:"expression"`
|
||||
|
||||
// Message is only used when Type is policy/v1. It defines an error message to be used when the policy rejects
|
||||
// an authentication attempt. When empty, a default message will be used.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// FederationDomainTransformsExample defines a transform example.
|
||||
type FederationDomainTransformsExample struct {
|
||||
// Username is the input username.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Username string `json:"username"`
|
||||
|
||||
// Groups is the input list of group names.
|
||||
// +optional
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
|
||||
// Expects is the expected output of the entire sequence of transforms when they are run against the
|
||||
// input Username and Groups.
|
||||
Expects FederationDomainTransformsExampleExpects `json:"expects"`
|
||||
}
|
||||
|
||||
// FederationDomainTransformsExampleExpects defines the expected result for a transforms example.
|
||||
type FederationDomainTransformsExampleExpects struct {
|
||||
// Username is the expected username after the transformations have been applied.
|
||||
// +optional
|
||||
Username string `json:"username,omitempty"`
|
||||
|
||||
// Groups is the expected list of group names after the transformations have been applied.
|
||||
// +optional
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
|
||||
// Rejected is a boolean that indicates whether authentication is expected to be rejected by a policy expression
|
||||
// after the transformations have been applied. True means that it is expected that the authentication would be
|
||||
// rejected. The default value of false means that it is expected that the authentication would not be rejected
|
||||
// by any policy expression.
|
||||
// +optional
|
||||
Rejected bool `json:"rejected,omitempty"`
|
||||
|
||||
// Message is the expected error message of the transforms. When Rejected is true, then Message is the expected
|
||||
// message for the policy which rejected the authentication attempt. When Rejected is true and Message is blank,
|
||||
// then Message will be treated as the default error message for authentication attempts which are rejected by a
|
||||
// policy. When Rejected is false, then Message is the expected error message for some other non-policy
|
||||
// transformation error, such as a runtime error. When Rejected is false, there is no default expected Message.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// FederationDomainTransforms defines identity transformations for an identity provider's usage on a FederationDomain.
|
||||
type FederationDomainTransforms struct {
|
||||
// Constants defines constant variables and their values which will be made available to the transform expressions.
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +optional
|
||||
Constants []FederationDomainTransformsConstant `json:"constants,omitempty"`
|
||||
|
||||
// Expressions are an optional list of transforms and policies to be executed in the order given during every
|
||||
// authentication attempt, including during every session refresh.
|
||||
// Each is a CEL expression. It may use the basic CEL language as defined in
|
||||
// https://github.com/google/cel-spec/blob/master/doc/langdef.md plus the CEL string extensions defined in
|
||||
// https://github.com/google/cel-go/tree/master/ext#strings.
|
||||
//
|
||||
// The username and groups extracted from the identity provider, and the constants defined in this CR, are
|
||||
// available as variables in all expressions. The username is provided via a variable called `username` and
|
||||
// the list of group names is provided via a variable called `groups` (which may be an empty list).
|
||||
// Each user-provided constants is provided via a variable named `strConst.varName` for string constants
|
||||
// and `strListConst.varName` for string list constants.
|
||||
//
|
||||
// The only allowed types for expressions are currently policy/v1, username/v1, and groups/v1.
|
||||
// Each policy/v1 must return a boolean, and when it returns false, no more expressions from the list are evaluated
|
||||
// and the authentication attempt is rejected.
|
||||
// Transformations of type policy/v1 do not return usernames or group names, and therefore cannot change the
|
||||
// username or group names.
|
||||
// Each username/v1 transform must return the new username (a string), which can be the same as the old username.
|
||||
// Transformations of type username/v1 do not return group names, and therefore cannot change the group names.
|
||||
// Each groups/v1 transform must return the new groups list (list of strings), which can be the same as the old
|
||||
// groups list.
|
||||
// Transformations of type groups/v1 do not return usernames, and therefore cannot change the usernames.
|
||||
// After each expression, the new (potentially changed) username or groups get passed to the following expression.
|
||||
//
|
||||
// Any compilation or static type-checking failure of any expression will cause an error status on the FederationDomain.
|
||||
// During an authentication attempt, any unexpected runtime evaluation errors (e.g. division by zero) cause the
|
||||
// authentication attempt to fail. When all expressions evaluate successfully, then the (potentially changed) username
|
||||
// and group names have been decided for that authentication attempt.
|
||||
//
|
||||
// +optional
|
||||
Expressions []FederationDomainTransformsExpression `json:"expressions,omitempty"`
|
||||
|
||||
// Examples can optionally be used to ensure that the sequence of transformation expressions are working as
|
||||
// expected. Examples define sample input identities which are then run through the expression list, and the
|
||||
// results are compared to the expected results. If any example in this list fails, then this
|
||||
// identity provider will not be available for use within this FederationDomain, and the error(s) will be
|
||||
// added to the FederationDomain status. This can be used to help guard against programming mistakes in the
|
||||
// expressions, and also act as living documentation for other administrators to better understand the expressions.
|
||||
// +optional
|
||||
Examples []FederationDomainTransformsExample `json:"examples,omitempty"`
|
||||
}
|
||||
|
||||
// FederationDomainIdentityProvider describes how an identity provider is made available in this FederationDomain.
|
||||
type FederationDomainIdentityProvider struct {
|
||||
// DisplayName is the name of this identity provider as it will appear to clients. This name ends up in the
|
||||
// kubeconfig of end users, so changing the name of an identity provider that is in use by end users will be a
|
||||
// disruptive change for those users.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
DisplayName string `json:"displayName"`
|
||||
|
||||
// ObjectRef is a reference to a Pinniped identity provider resource. A valid reference is required.
|
||||
// If the reference cannot be resolved then the identity provider will not be made available.
|
||||
// Must refer to a resource of one of the Pinniped identity provider types, e.g. OIDCIdentityProvider,
|
||||
// LDAPIdentityProvider, ActiveDirectoryIdentityProvider.
|
||||
ObjectRef corev1.TypedLocalObjectReference `json:"objectRef"`
|
||||
|
||||
// Transforms is an optional way to specify transformations to be applied during user authentication and
|
||||
// session refresh.
|
||||
// +optional
|
||||
Transforms FederationDomainTransforms `json:"transforms,omitempty"`
|
||||
}
|
||||
|
||||
// FederationDomainSpec is a struct that describes an OIDC Provider.
|
||||
type FederationDomainSpec struct {
|
||||
// Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the
|
||||
// identifier that it will use for the iss claim in issued JWTs. This field will also be used as
|
||||
// the base URL for any endpoints used by the OIDC Provider (e.g., if your issuer is
|
||||
// https://example.com/foo, then your authorization endpoint will look like
|
||||
// https://example.com/foo/some/path/to/auth/endpoint).
|
||||
//
|
||||
// See
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Issuer string `json:"issuer"`
|
||||
|
||||
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.
|
||||
// +optional
|
||||
TLS *FederationDomainTLSSpec `json:"tls,omitempty"`
|
||||
|
||||
// IdentityProviders is the list of identity providers available for use by this FederationDomain.
|
||||
//
|
||||
// An identity provider CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes how to connect to a server,
|
||||
// how to talk in a specific protocol for authentication, and how to use the schema of that server/protocol to
|
||||
// extract a normalized user identity. Normalized user identities include a username and a list of group names.
|
||||
// In contrast, IdentityProviders describes how to use that normalized identity in those Kubernetes clusters which
|
||||
// belong to this FederationDomain. Each entry in IdentityProviders can be configured with arbitrary transformations
|
||||
// on that normalized identity. For example, a transformation can add a prefix to all usernames to help avoid
|
||||
// accidental conflicts when multiple identity providers have different users with the same username (e.g.
|
||||
// "idp1:ryan" versus "idp2:ryan"). Each entry in IdentityProviders can also implement arbitrary authentication
|
||||
// rejection policies. Even though a user was able to authenticate with the identity provider, a policy can disallow
|
||||
// the authentication to the Kubernetes clusters that belong to this FederationDomain. For example, a policy could
|
||||
// disallow the authentication unless the user belongs to a specific group in the identity provider.
|
||||
//
|
||||
// For backwards compatibility with versions of Pinniped which predate support for multiple identity providers,
|
||||
// an empty IdentityProviders list will cause the FederationDomain to use all available identity providers which
|
||||
// exist in the same namespace, but also to reject all authentication requests when there is more than one identity
|
||||
// provider currently defined. In this backwards compatibility mode, the name of the identity provider resource
|
||||
// (e.g. the Name of an OIDCIdentityProvider resource) will be used as the name of the identity provider in this
|
||||
// FederationDomain. This mode is provided to make upgrading from older versions easier. However, instead of
|
||||
// relying on this backwards compatibility mode, please consider this mode to be deprecated and please instead
|
||||
// explicitly list the identity provider using this IdentityProviders field.
|
||||
//
|
||||
// +optional
|
||||
IdentityProviders []FederationDomainIdentityProvider `json:"identityProviders,omitempty"`
|
||||
}
|
||||
|
||||
// FederationDomainSecrets holds information about this OIDC Provider's secrets.
|
||||
type FederationDomainSecrets struct {
|
||||
// JWKS holds the name of the corev1.Secret in which this OIDC Provider's signing/verification keys are
|
||||
// stored. If it is empty, then the signing/verification keys are either unknown or they don't
|
||||
// exist.
|
||||
// +optional
|
||||
JWKS corev1.LocalObjectReference `json:"jwks,omitempty"`
|
||||
|
||||
// TokenSigningKey holds the name of the corev1.Secret in which this OIDC Provider's key for
|
||||
// signing tokens is stored.
|
||||
// +optional
|
||||
TokenSigningKey corev1.LocalObjectReference `json:"tokenSigningKey,omitempty"`
|
||||
|
||||
// StateSigningKey holds the name of the corev1.Secret in which this OIDC Provider's key for
|
||||
// signing state parameters is stored.
|
||||
// +optional
|
||||
StateSigningKey corev1.LocalObjectReference `json:"stateSigningKey,omitempty"`
|
||||
|
||||
// StateSigningKey holds the name of the corev1.Secret in which this OIDC Provider's key for
|
||||
// encrypting state parameters is stored.
|
||||
// +optional
|
||||
StateEncryptionKey corev1.LocalObjectReference `json:"stateEncryptionKey,omitempty"`
|
||||
}
|
||||
|
||||
// FederationDomainStatus is a struct that describes the actual state of an OIDC Provider.
|
||||
type FederationDomainStatus struct {
|
||||
// Phase summarizes the overall status of the FederationDomain.
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase FederationDomainPhase `json:"phase,omitempty"`
|
||||
|
||||
// Conditions represent the observations of an FederationDomain's current state.
|
||||
// +patchMergeKey=type
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
|
||||
// Secrets contains information about this OIDC Provider's secrets.
|
||||
// +optional
|
||||
Secrets FederationDomainSecrets `json:"secrets,omitempty"`
|
||||
}
|
||||
|
||||
// FederationDomain describes the configuration of an OIDC provider.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=pinniped
|
||||
// +kubebuilder:printcolumn:name="Issuer",type=string,JSONPath=`.spec.issuer`
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:status
|
||||
type FederationDomain struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec of the OIDC provider.
|
||||
Spec FederationDomainSpec `json:"spec"`
|
||||
|
||||
// Status of the OIDC provider.
|
||||
Status FederationDomainStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// List of FederationDomain objects.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type FederationDomainList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []FederationDomain `json:"items"`
|
||||
}
|
||||
11
generated/1.21/apis/supervisor/idp/v1alpha1/doc.go
generated
11
generated/1.21/apis/supervisor/idp/v1alpha1/doc.go
generated
@@ -1,11 +0,0 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=idp.supervisor.pinniped.dev
|
||||
// +groupGoName=IDP
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the Pinniped supervisor identity provider (IDP) API.
|
||||
package v1alpha1
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// Configuration for TLS parameters related to identity provider integration.
|
||||
type TLSSpec struct {
|
||||
// X.509 Certificate Authority (base64-encoded PEM bundle). If omitted, a default set of system roots will be trusted.
|
||||
// +optional
|
||||
CertificateAuthorityData string `json:"certificateAuthorityData,omitempty"`
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package oidc
|
||||
|
||||
// Constants related to the Supervisor FederationDomain's authorization and token endpoints.
|
||||
const (
|
||||
// AuthorizeUsernameHeaderName is the name of the HTTP header which can be used to transmit a username
|
||||
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
|
||||
// or an LDAPIdentityProvider.
|
||||
AuthorizeUsernameHeaderName = "Pinniped-Username"
|
||||
|
||||
// AuthorizePasswordHeaderName is the name of the HTTP header which can be used to transmit a password
|
||||
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
|
||||
// or an LDAPIdentityProvider.
|
||||
AuthorizePasswordHeaderName = "Pinniped-Password" //nolint:gosec // this is not a credential
|
||||
|
||||
// AuthorizeUpstreamIDPNameParamName is the name of the HTTP request parameter which can be used to help select
|
||||
// which identity provider should be used for authentication by sending the name of the desired identity provider.
|
||||
AuthorizeUpstreamIDPNameParamName = "pinniped_idp_name"
|
||||
|
||||
// AuthorizeUpstreamIDPTypeParamName is the name of the HTTP request parameter which can be used to help select
|
||||
// which identity provider should be used for authentication by sending the type of the desired identity provider.
|
||||
AuthorizeUpstreamIDPTypeParamName = "pinniped_idp_type"
|
||||
|
||||
// IDTokenClaimIssuer is name of the issuer claim defined by the OIDC spec.
|
||||
IDTokenClaimIssuer = "iss"
|
||||
|
||||
// IDTokenClaimSubject is name of the subject claim defined by the OIDC spec.
|
||||
IDTokenClaimSubject = "sub"
|
||||
|
||||
// IDTokenClaimAuthorizedParty is name of the authorized party claim defined by the OIDC spec.
|
||||
IDTokenClaimAuthorizedParty = "azp"
|
||||
|
||||
// IDTokenClaimUsername is the name of a custom claim in the downstream ID token whose value will contain the user's
|
||||
// username which was mapped from the upstream identity provider.
|
||||
IDTokenClaimUsername = "username"
|
||||
|
||||
// IDTokenClaimGroups is the name of a custom claim in the downstream ID token whose value will contain the user's
|
||||
// group names which were mapped from the upstream identity provider.
|
||||
IDTokenClaimGroups = "groups"
|
||||
|
||||
// IDTokenClaimAdditionalClaims is the top level claim used to hold additional claims in the downstream ID
|
||||
// token, if any claims are present.
|
||||
IDTokenClaimAdditionalClaims = "additionalClaims"
|
||||
|
||||
// GrantTypeAuthorizationCode is the name of the grant type for authorization code flows defined by the OIDC spec.
|
||||
GrantTypeAuthorizationCode = "authorization_code"
|
||||
|
||||
// GrantTypeRefreshToken is the name of the grant type for refresh flow defined by the OIDC spec.
|
||||
GrantTypeRefreshToken = "refresh_token"
|
||||
|
||||
// GrantTypeTokenExchange is the name of a custom grant type for RFC8693 token exchanges.
|
||||
GrantTypeTokenExchange = "urn:ietf:params:oauth:grant-type:token-exchange" //nolint:gosec // this is not a credential
|
||||
|
||||
// ScopeOpenID is name of the openid scope defined by the OIDC spec.
|
||||
ScopeOpenID = "openid"
|
||||
|
||||
// ScopeOfflineAccess is name of the offline access scope defined by the OIDC spec, used for requesting refresh
|
||||
// tokens.
|
||||
ScopeOfflineAccess = "offline_access"
|
||||
|
||||
// ScopeEmail is name of the email scope defined by the OIDC spec.
|
||||
ScopeEmail = "email"
|
||||
|
||||
// ScopeProfile is name of the profile scope defined by the OIDC spec.
|
||||
ScopeProfile = "profile"
|
||||
|
||||
// ScopeUsername is the name of a custom scope that determines whether the username claim will be returned inside
|
||||
// ID tokens.
|
||||
ScopeUsername = "username"
|
||||
|
||||
// ScopeGroups is the name of a custom scope that determines whether the groups claim will be returned inside
|
||||
// ID tokens.
|
||||
ScopeGroups = "groups"
|
||||
|
||||
// ScopeRequestAudience is the name of a custom scope that determines whether a RFC8693 token exchange is allowed to
|
||||
// be used to request a different audience.
|
||||
ScopeRequestAudience = "pinniped:request-audience"
|
||||
|
||||
// ClientIDPinnipedCLI is the client ID of the statically defined public OIDC client which is used by the CLI.
|
||||
ClientIDPinnipedCLI = "pinniped-cli"
|
||||
|
||||
// ClientIDRequiredOIDCClientPrefix is the required prefix for the metadata.name of OIDCClient CRs.
|
||||
ClientIDRequiredOIDCClientPrefix = "client.oauth.pinniped.dev-"
|
||||
)
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2020-2023 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,90 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
clientset "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned"
|
||||
authenticationv1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/typed/authentication/v1alpha1"
|
||||
fakeauthenticationv1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/typed/authentication/v1alpha1/fake"
|
||||
configv1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/typed/config/v1alpha1"
|
||||
fakeconfigv1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/typed/config/v1alpha1/fake"
|
||||
identityv1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/typed/identity/v1alpha1"
|
||||
fakeidentityv1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/typed/identity/v1alpha1/fake"
|
||||
loginv1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/typed/login/v1alpha1"
|
||||
fakeloginv1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/typed/login/v1alpha1/fake"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/discovery"
|
||||
fakediscovery "k8s.io/client-go/discovery/fake"
|
||||
"k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// NewSimpleClientset returns a clientset that will respond with the provided objects.
|
||||
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
|
||||
// without applying any validations and/or defaults. It shouldn't be considered a replacement
|
||||
// for a real clientset and is mostly useful in simple unit tests.
|
||||
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
|
||||
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
|
||||
for _, obj := range objects {
|
||||
if err := o.Add(obj); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
cs := &Clientset{tracker: o}
|
||||
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
|
||||
cs.AddReactor("*", "*", testing.ObjectReaction(o))
|
||||
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
|
||||
gvr := action.GetResource()
|
||||
ns := action.GetNamespace()
|
||||
watch, err := o.Watch(gvr, ns)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return true, watch, nil
|
||||
})
|
||||
|
||||
return cs
|
||||
}
|
||||
|
||||
// Clientset implements clientset.Interface. Meant to be embedded into a
|
||||
// struct to get a default implementation. This makes faking out just the method
|
||||
// you want to test easier.
|
||||
type Clientset struct {
|
||||
testing.Fake
|
||||
discovery *fakediscovery.FakeDiscovery
|
||||
tracker testing.ObjectTracker
|
||||
}
|
||||
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
return c.discovery
|
||||
}
|
||||
|
||||
func (c *Clientset) Tracker() testing.ObjectTracker {
|
||||
return c.tracker
|
||||
}
|
||||
|
||||
var _ clientset.Interface = &Clientset{}
|
||||
|
||||
// AuthenticationV1alpha1 retrieves the AuthenticationV1alpha1Client
|
||||
func (c *Clientset) AuthenticationV1alpha1() authenticationv1alpha1.AuthenticationV1alpha1Interface {
|
||||
return &fakeauthenticationv1alpha1.FakeAuthenticationV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// ConfigV1alpha1 retrieves the ConfigV1alpha1Client
|
||||
func (c *Clientset) ConfigV1alpha1() configv1alpha1.ConfigV1alpha1Interface {
|
||||
return &fakeconfigv1alpha1.FakeConfigV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// IdentityV1alpha1 retrieves the IdentityV1alpha1Client
|
||||
func (c *Clientset) IdentityV1alpha1() identityv1alpha1.IdentityV1alpha1Interface {
|
||||
return &fakeidentityv1alpha1.FakeIdentityV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// LoginV1alpha1 retrieves the LoginV1alpha1Client
|
||||
func (c *Clientset) LoginV1alpha1() loginv1alpha1.LoginV1alpha1Interface {
|
||||
return &fakeloginv1alpha1.FakeLoginV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package scheme
|
||||
|
||||
import (
|
||||
authenticationv1alpha1 "go.pinniped.dev/generated/1.21/apis/concierge/authentication/v1alpha1"
|
||||
configv1alpha1 "go.pinniped.dev/generated/1.21/apis/concierge/config/v1alpha1"
|
||||
identityv1alpha1 "go.pinniped.dev/generated/1.21/apis/concierge/identity/v1alpha1"
|
||||
loginv1alpha1 "go.pinniped.dev/generated/1.21/apis/concierge/login/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
)
|
||||
|
||||
var Scheme = runtime.NewScheme()
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
authenticationv1alpha1.AddToScheme,
|
||||
configv1alpha1.AddToScheme,
|
||||
identityv1alpha1.AddToScheme,
|
||||
loginv1alpha1.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
// of clientsets, like in:
|
||||
//
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
//
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
//
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
var AddToScheme = localSchemeBuilder.AddToScheme
|
||||
|
||||
func init() {
|
||||
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
|
||||
utilruntime.Must(AddToScheme(Scheme))
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
// Copyright 2020-2023 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.21/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.NewRootDeleteAction(jwtauthenticatorsResource, name), &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,171 +0,0 @@
|
||||
// Copyright 2020-2023 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.21/apis/concierge/authentication/v1alpha1"
|
||||
scheme "go.pinniped.dev/generated/1.21/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,76 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.21/apis/concierge/config/v1alpha1"
|
||||
"go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type ConfigV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
CredentialIssuersGetter
|
||||
}
|
||||
|
||||
// ConfigV1alpha1Client is used to interact with features provided by the config.concierge.pinniped.dev group.
|
||||
type ConfigV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *ConfigV1alpha1Client) CredentialIssuers() CredentialIssuerInterface {
|
||||
return newCredentialIssuers(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new ConfigV1alpha1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*ConfigV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ConfigV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new ConfigV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *ConfigV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new ConfigV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *ConfigV1alpha1Client {
|
||||
return &ConfigV1alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *ConfigV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
// Copyright 2020-2023 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.21/apis/concierge/config/v1alpha1"
|
||||
scheme "go.pinniped.dev/generated/1.21/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
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/typed/login/v1alpha1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeLoginV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeLoginV1alpha1) TokenCredentialRequests() v1alpha1.TokenCredentialRequestInterface {
|
||||
return &FakeTokenCredentialRequests{c}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeLoginV1alpha1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.21/apis/concierge/login/v1alpha1"
|
||||
"go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type LoginV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
TokenCredentialRequestsGetter
|
||||
}
|
||||
|
||||
// LoginV1alpha1Client is used to interact with features provided by the login.concierge.pinniped.dev group.
|
||||
type LoginV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *LoginV1alpha1Client) TokenCredentialRequests() TokenCredentialRequestInterface {
|
||||
return newTokenCredentialRequests(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new LoginV1alpha1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*LoginV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &LoginV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new LoginV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *LoginV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new LoginV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *LoginV1alpha1Client {
|
||||
return &LoginV1alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *LoginV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
internalinterfaces "go.pinniped.dev/generated/1.21/client/concierge/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// JWTAuthenticators returns a JWTAuthenticatorInformer.
|
||||
JWTAuthenticators() JWTAuthenticatorInformer
|
||||
// WebhookAuthenticators returns a WebhookAuthenticatorInformer.
|
||||
WebhookAuthenticators() WebhookAuthenticatorInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// JWTAuthenticators returns a JWTAuthenticatorInformer.
|
||||
func (v *version) JWTAuthenticators() JWTAuthenticatorInformer {
|
||||
return &jWTAuthenticatorInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// WebhookAuthenticators returns a WebhookAuthenticatorInformer.
|
||||
func (v *version) WebhookAuthenticators() WebhookAuthenticatorInformer {
|
||||
return &webhookAuthenticatorInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
authenticationv1alpha1 "go.pinniped.dev/generated/1.21/apis/concierge/authentication/v1alpha1"
|
||||
versioned "go.pinniped.dev/generated/1.21/client/concierge/clientset/versioned"
|
||||
internalinterfaces "go.pinniped.dev/generated/1.21/client/concierge/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/listers/authentication/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// JWTAuthenticatorInformer provides access to a shared informer and lister for
|
||||
// JWTAuthenticators.
|
||||
type JWTAuthenticatorInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.JWTAuthenticatorLister
|
||||
}
|
||||
|
||||
type jWTAuthenticatorInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewJWTAuthenticatorInformer constructs a new informer for JWTAuthenticator type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewJWTAuthenticatorInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredJWTAuthenticatorInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredJWTAuthenticatorInformer constructs a new informer for JWTAuthenticator type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredJWTAuthenticatorInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AuthenticationV1alpha1().JWTAuthenticators().List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AuthenticationV1alpha1().JWTAuthenticators().Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&authenticationv1alpha1.JWTAuthenticator{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *jWTAuthenticatorInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredJWTAuthenticatorInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *jWTAuthenticatorInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&authenticationv1alpha1.JWTAuthenticator{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *jWTAuthenticatorInformer) Lister() v1alpha1.JWTAuthenticatorLister {
|
||||
return v1alpha1.NewJWTAuthenticatorLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.21/client/concierge/informers/externalversions/config/v1alpha1"
|
||||
internalinterfaces "go.pinniped.dev/generated/1.21/client/concierge/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1alpha1 provides access to shared informers for resources in V1alpha1.
|
||||
V1alpha1() v1alpha1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1alpha1 returns a new v1alpha1.Interface.
|
||||
func (g *group) V1alpha1() v1alpha1.Interface {
|
||||
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
internalinterfaces "go.pinniped.dev/generated/1.21/client/concierge/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// CredentialIssuers returns a CredentialIssuerInformer.
|
||||
CredentialIssuers() CredentialIssuerInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// CredentialIssuers returns a CredentialIssuerInformer.
|
||||
func (v *version) CredentialIssuers() CredentialIssuerInformer {
|
||||
return &credentialIssuerInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.21/apis/concierge/authentication/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// JWTAuthenticatorLister helps list JWTAuthenticators.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type JWTAuthenticatorLister interface {
|
||||
// List lists all JWTAuthenticators in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.JWTAuthenticator, err error)
|
||||
// Get retrieves the JWTAuthenticator from the index for a given name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*v1alpha1.JWTAuthenticator, error)
|
||||
JWTAuthenticatorListerExpansion
|
||||
}
|
||||
|
||||
// jWTAuthenticatorLister implements the JWTAuthenticatorLister interface.
|
||||
type jWTAuthenticatorLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewJWTAuthenticatorLister returns a new JWTAuthenticatorLister.
|
||||
func NewJWTAuthenticatorLister(indexer cache.Indexer) JWTAuthenticatorLister {
|
||||
return &jWTAuthenticatorLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all JWTAuthenticators in the indexer.
|
||||
func (s *jWTAuthenticatorLister) List(selector labels.Selector) (ret []*v1alpha1.JWTAuthenticator, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.JWTAuthenticator))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the JWTAuthenticator from the index for a given name.
|
||||
func (s *jWTAuthenticatorLister) Get(name string) (*v1alpha1.JWTAuthenticator, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("jwtauthenticator"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.JWTAuthenticator), nil
|
||||
}
|
||||
14
generated/1.21/client/go.mod
generated
14
generated/1.21/client/go.mod
generated
@@ -1,14 +0,0 @@
|
||||
// This go.mod file is generated by ./hack/codegen.sh.
|
||||
module go.pinniped.dev/generated/1.21/client
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/go-openapi/spec v0.19.3
|
||||
go.pinniped.dev/generated/1.21/apis v0.0.0
|
||||
k8s.io/apimachinery v0.21.14
|
||||
k8s.io/client-go v0.21.14
|
||||
k8s.io/kube-openapi v0.0.0-20211110012726-3cc51fd1e909
|
||||
)
|
||||
|
||||
replace go.pinniped.dev/generated/1.21/apis => ../apis
|
||||
433
generated/1.21/client/go.sum
generated
433
generated/1.21/client/go.sum
generated
@@ -1,433 +0,0 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
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 v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
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.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
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/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
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 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
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/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I=
|
||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
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/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
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 h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
||||
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 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
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/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
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/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
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/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-20190108225652-1e06a53dbb7e/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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/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-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
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/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
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 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/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 h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.21.14 h1:5P/Yv95EhpU7rzgLqaDkoA1JeJmZ1Gv02GJTj9Nm7EM=
|
||||
k8s.io/api v0.21.14/go.mod h1:fUA7ZgNoFEADCpwq0Bn35XZiurViVXp7Uw9n05UYEog=
|
||||
k8s.io/apimachinery v0.21.14 h1:tC5klgLnEkSqcS4qJdKP+Cmm8gVdaY9Hu31+ozRgv6E=
|
||||
k8s.io/apimachinery v0.21.14/go.mod h1:NI5S3z6+ZZ6Da3whzPF+MnJCjU1NyLuTq9WnKIj5I20=
|
||||
k8s.io/client-go v0.21.14 h1:wTEWP4YIfMQizrLd8igYc8yyj3f4wzY9fr3SmMqWimU=
|
||||
k8s.io/client-go v0.21.14/go.mod h1:jQRH8Oltg5abxLmZDZirSNQY4vnrBh9Ri4Pfd9StdoA=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
|
||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-openapi v0.0.0-20211110012726-3cc51fd1e909 h1:s77MRc/+/eQjsF89MB12JssAlsoi9mnNoaacRqibeAU=
|
||||
k8s.io/kube-openapi v0.0.0-20211110012726-3cc51fd1e909/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
||||
k8s.io/utils v0.0.0-20211116205334-6203023598ed h1:ck1fRPWPJWsMd8ZRFsWc6mh/zHp5fZ/shhbrgPUxDAE=
|
||||
k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
@@ -1,112 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package versioned
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
clientsecretv1alpha1 "go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned/typed/clientsecret/v1alpha1"
|
||||
configv1alpha1 "go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned/typed/config/v1alpha1"
|
||||
idpv1alpha1 "go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned/typed/idp/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
|
||||
ClientsecretV1alpha1() clientsecretv1alpha1.ClientsecretV1alpha1Interface
|
||||
ConfigV1alpha1() configv1alpha1.ConfigV1alpha1Interface
|
||||
IDPV1alpha1() idpv1alpha1.IDPV1alpha1Interface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups. Each group has exactly one
|
||||
// version included in a Clientset.
|
||||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
clientsecretV1alpha1 *clientsecretv1alpha1.ClientsecretV1alpha1Client
|
||||
configV1alpha1 *configv1alpha1.ConfigV1alpha1Client
|
||||
iDPV1alpha1 *idpv1alpha1.IDPV1alpha1Client
|
||||
}
|
||||
|
||||
// ClientsecretV1alpha1 retrieves the ClientsecretV1alpha1Client
|
||||
func (c *Clientset) ClientsecretV1alpha1() clientsecretv1alpha1.ClientsecretV1alpha1Interface {
|
||||
return c.clientsecretV1alpha1
|
||||
}
|
||||
|
||||
// ConfigV1alpha1 retrieves the ConfigV1alpha1Client
|
||||
func (c *Clientset) ConfigV1alpha1() configv1alpha1.ConfigV1alpha1Interface {
|
||||
return c.configV1alpha1
|
||||
}
|
||||
|
||||
// IDPV1alpha1 retrieves the IDPV1alpha1Client
|
||||
func (c *Clientset) IDPV1alpha1() idpv1alpha1.IDPV1alpha1Interface {
|
||||
return c.iDPV1alpha1
|
||||
}
|
||||
|
||||
// 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.
|
||||
func NewForConfig(c *rest.Config) (*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.clientsecretV1alpha1, err = clientsecretv1alpha1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.configV1alpha1, err = configv1alpha1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.iDPV1alpha1, err = idpv1alpha1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
|
||||
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 {
|
||||
var cs Clientset
|
||||
cs.clientsecretV1alpha1 = clientsecretv1alpha1.NewForConfigOrDie(c)
|
||||
cs.configV1alpha1 = configv1alpha1.NewForConfigOrDie(c)
|
||||
cs.iDPV1alpha1 = idpv1alpha1.NewForConfigOrDie(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||
return &cs
|
||||
}
|
||||
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
func New(c rest.Interface) *Clientset {
|
||||
var cs Clientset
|
||||
cs.clientsecretV1alpha1 = clientsecretv1alpha1.New(c)
|
||||
cs.configV1alpha1 = configv1alpha1.New(c)
|
||||
cs.iDPV1alpha1 = idpv1alpha1.New(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
return &cs
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2020-2023 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,83 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
clientset "go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned"
|
||||
clientsecretv1alpha1 "go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned/typed/clientsecret/v1alpha1"
|
||||
fakeclientsecretv1alpha1 "go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned/typed/clientsecret/v1alpha1/fake"
|
||||
configv1alpha1 "go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned/typed/config/v1alpha1"
|
||||
fakeconfigv1alpha1 "go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned/typed/config/v1alpha1/fake"
|
||||
idpv1alpha1 "go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned/typed/idp/v1alpha1"
|
||||
fakeidpv1alpha1 "go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned/typed/idp/v1alpha1/fake"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/discovery"
|
||||
fakediscovery "k8s.io/client-go/discovery/fake"
|
||||
"k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// NewSimpleClientset returns a clientset that will respond with the provided objects.
|
||||
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
|
||||
// without applying any validations and/or defaults. It shouldn't be considered a replacement
|
||||
// for a real clientset and is mostly useful in simple unit tests.
|
||||
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
|
||||
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
|
||||
for _, obj := range objects {
|
||||
if err := o.Add(obj); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
cs := &Clientset{tracker: o}
|
||||
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
|
||||
cs.AddReactor("*", "*", testing.ObjectReaction(o))
|
||||
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
|
||||
gvr := action.GetResource()
|
||||
ns := action.GetNamespace()
|
||||
watch, err := o.Watch(gvr, ns)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return true, watch, nil
|
||||
})
|
||||
|
||||
return cs
|
||||
}
|
||||
|
||||
// Clientset implements clientset.Interface. Meant to be embedded into a
|
||||
// struct to get a default implementation. This makes faking out just the method
|
||||
// you want to test easier.
|
||||
type Clientset struct {
|
||||
testing.Fake
|
||||
discovery *fakediscovery.FakeDiscovery
|
||||
tracker testing.ObjectTracker
|
||||
}
|
||||
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
return c.discovery
|
||||
}
|
||||
|
||||
func (c *Clientset) Tracker() testing.ObjectTracker {
|
||||
return c.tracker
|
||||
}
|
||||
|
||||
var _ clientset.Interface = &Clientset{}
|
||||
|
||||
// ClientsecretV1alpha1 retrieves the ClientsecretV1alpha1Client
|
||||
func (c *Clientset) ClientsecretV1alpha1() clientsecretv1alpha1.ClientsecretV1alpha1Interface {
|
||||
return &fakeclientsecretv1alpha1.FakeClientsecretV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// ConfigV1alpha1 retrieves the ConfigV1alpha1Client
|
||||
func (c *Clientset) ConfigV1alpha1() configv1alpha1.ConfigV1alpha1Interface {
|
||||
return &fakeconfigv1alpha1.FakeConfigV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// IDPV1alpha1 retrieves the IDPV1alpha1Client
|
||||
func (c *Clientset) IDPV1alpha1() idpv1alpha1.IDPV1alpha1Interface {
|
||||
return &fakeidpv1alpha1.FakeIDPV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2020-2023 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 typed clients.
|
||||
package v1alpha1
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,8 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type OIDCClientSecretRequestExpansion interface{}
|
||||
@@ -1,81 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.21/apis/supervisor/config/v1alpha1"
|
||||
"go.pinniped.dev/generated/1.21/client/supervisor/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type ConfigV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
FederationDomainsGetter
|
||||
OIDCClientsGetter
|
||||
}
|
||||
|
||||
// ConfigV1alpha1Client is used to interact with features provided by the config.supervisor.pinniped.dev group.
|
||||
type ConfigV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *ConfigV1alpha1Client) FederationDomains(namespace string) FederationDomainInterface {
|
||||
return newFederationDomains(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ConfigV1alpha1Client) OIDCClients(namespace string) OIDCClientInterface {
|
||||
return newOIDCClients(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new ConfigV1alpha1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*ConfigV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ConfigV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new ConfigV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *ConfigV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new ConfigV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *ConfigV1alpha1Client {
|
||||
return &ConfigV1alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *ConfigV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2020-2023 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 typed clients.
|
||||
package v1alpha1
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2020-2023 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 typed clients.
|
||||
package v1alpha1
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user