mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-02-20 04:50:18 +00:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0054921ba3 | ||
|
|
fc08cb3b66 | ||
|
|
4e5067c551 | ||
|
|
8572b56aec | ||
|
|
32c1fad116 | ||
|
|
6f9858a6b5 | ||
|
|
22b9ddba3d | ||
|
|
e5366d782d | ||
|
|
745c93af51 | ||
|
|
fda421fa87 | ||
|
|
22273651f4 | ||
|
|
60bc490e9d | ||
|
|
325ef5c2a2 | ||
|
|
e1189e5da8 | ||
|
|
2a24d09a01 | ||
|
|
39d35ceca0 | ||
|
|
da86068f4e | ||
|
|
eef4934775 | ||
|
|
a72c51f823 | ||
|
|
6797d8622a | ||
|
|
beeb6dad6e | ||
|
|
5f6bbc691b | ||
|
|
13cc7b147d | ||
|
|
cc80df6107 | ||
|
|
736e2472c6 | ||
|
|
0f0f3997a0 | ||
|
|
de32fdc304 | ||
|
|
ec334d1175 | ||
|
|
5d9b7a3346 | ||
|
|
6577c523de | ||
|
|
a47c5bf5fe | ||
|
|
43fe4a886e | ||
|
|
174b3026c7 | ||
|
|
e009d22900 | ||
|
|
4b7fbc144e | ||
|
|
98621c76b5 | ||
|
|
6d8aed7f40 | ||
|
|
3031a070d1 |
@@ -1,10 +1,10 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ARG BUILD_IMAGE=golang:1.25.5@sha256:36b4f45d2874905b9e8573b783292629bcb346d0a70d8d7150b6df545234818f
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:2b7c93f6d6648c11f0e80a48558c8f77885eb0445213b8e69a6a0d7c89fc6ae4
|
||||
ARG BUILD_IMAGE=golang:1.26.0@sha256:c83e68f3ebb6943a2904fa66348867d108119890a2c6a2e6f07b38d0eb6c25c5
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:01e550fdb7ab79ee7be5ff440a563a58f1fd000ad9e0c532e65c3d23f917f1c5
|
||||
|
||||
# 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
|
||||
|
||||
4
generated/1.32/apis/go.mod
generated
4
generated/1.32/apis/go.mod
generated
@@ -4,8 +4,8 @@ module go.pinniped.dev/generated/1.32/apis
|
||||
go 1.23.0
|
||||
|
||||
require (
|
||||
k8s.io/api v0.32.10
|
||||
k8s.io/apimachinery v0.32.10
|
||||
k8s.io/api v0.32.11
|
||||
k8s.io/apimachinery v0.32.11
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
8
generated/1.32/apis/go.sum
generated
8
generated/1.32/apis/go.sum
generated
@@ -79,10 +79,10 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.32.10 h1:ocp4turNfa1V40TuBW/LuA17TeXG9g/GI2ebg0KxBNk=
|
||||
k8s.io/api v0.32.10/go.mod h1:AsMsc4b6TuampYqgMEGSv0HBFpRS4BlKTXAVCAa7oF4=
|
||||
k8s.io/apimachinery v0.32.10 h1:SAg2kUPLYRcBJQj66oniP1BnXSqw+l1GvJFsJlBmVvQ=
|
||||
k8s.io/apimachinery v0.32.10/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/api v0.32.11 h1:0MnAbAc3GDHJcMyoWufyNTOiAMu46SnOg+pGaNdL6mc=
|
||||
k8s.io/api v0.32.11/go.mod h1:FOEM0Zd1QYD4cqXI9CvJz/tmqMcxFQv222KNOZtghO0=
|
||||
k8s.io/apimachinery v0.32.11 h1:QCjwmozCmod1kK+lvLGKlq4AXSw0ncCD5OSI6JyOrE8=
|
||||
k8s.io/apimachinery v0.32.11/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
|
||||
|
||||
6
generated/1.32/client/go.mod
generated
6
generated/1.32/client/go.mod
generated
@@ -7,9 +7,9 @@ replace go.pinniped.dev/generated/1.32/apis => ../apis
|
||||
|
||||
require (
|
||||
go.pinniped.dev/generated/1.32/apis v0.0.0
|
||||
k8s.io/api v0.32.10
|
||||
k8s.io/apimachinery v0.32.10
|
||||
k8s.io/client-go v0.32.10
|
||||
k8s.io/api v0.32.11
|
||||
k8s.io/apimachinery v0.32.11
|
||||
k8s.io/client-go v0.32.11
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f
|
||||
)
|
||||
|
||||
|
||||
12
generated/1.32/client/go.sum
generated
12
generated/1.32/client/go.sum
generated
@@ -134,12 +134,12 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.32.10 h1:ocp4turNfa1V40TuBW/LuA17TeXG9g/GI2ebg0KxBNk=
|
||||
k8s.io/api v0.32.10/go.mod h1:AsMsc4b6TuampYqgMEGSv0HBFpRS4BlKTXAVCAa7oF4=
|
||||
k8s.io/apimachinery v0.32.10 h1:SAg2kUPLYRcBJQj66oniP1BnXSqw+l1GvJFsJlBmVvQ=
|
||||
k8s.io/apimachinery v0.32.10/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/client-go v0.32.10 h1:MFmIjsKtcnn7mStjrJG1ZW2WzLsKKn6ZtL9hHM/W0xU=
|
||||
k8s.io/client-go v0.32.10/go.mod h1:qJy/Ws3zSwnu/nD75D+/of1uxbwWHxrYT5P3FuobVLI=
|
||||
k8s.io/api v0.32.11 h1:0MnAbAc3GDHJcMyoWufyNTOiAMu46SnOg+pGaNdL6mc=
|
||||
k8s.io/api v0.32.11/go.mod h1:FOEM0Zd1QYD4cqXI9CvJz/tmqMcxFQv222KNOZtghO0=
|
||||
k8s.io/apimachinery v0.32.11 h1:QCjwmozCmod1kK+lvLGKlq4AXSw0ncCD5OSI6JyOrE8=
|
||||
k8s.io/apimachinery v0.32.11/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/client-go v0.32.11 h1:HHcSUf+wuiQ+2kpM0CbzhXQ3mhHOmnzw6ctGbLre+ho=
|
||||
k8s.io/client-go v0.32.11/go.mod h1:8pdqbF5/hF++ZEK1I7poxNH4CTlFNkHN48h4si+qDqQ=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
|
||||
|
||||
4
generated/1.33/apis/go.mod
generated
4
generated/1.33/apis/go.mod
generated
@@ -4,8 +4,8 @@ module go.pinniped.dev/generated/1.33/apis
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
k8s.io/api v0.33.6
|
||||
k8s.io/apimachinery v0.33.6
|
||||
k8s.io/api v0.33.7
|
||||
k8s.io/apimachinery v0.33.7
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
8
generated/1.33/apis/go.sum
generated
8
generated/1.33/apis/go.sum
generated
@@ -75,10 +75,10 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.33.6 h1:9O22ZqwT6CkQ3iboVpvTR5BEWuT3Xm6/8NX6MOLmc38=
|
||||
k8s.io/api v0.33.6/go.mod h1:bdon4pRFmRmdsFyltGIoCaPqutN7y//OQ4srD0uy9X0=
|
||||
k8s.io/apimachinery v0.33.6 h1:Pq+px1i1t7lNgE58dIeBwJh7OWId6pfGD1dYBm/U5HI=
|
||||
k8s.io/apimachinery v0.33.6/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
||||
k8s.io/api v0.33.7 h1:Koh06KurzmXwCwe/DOaIiM1A8vEXTZ6B1tTDnmLLfxw=
|
||||
k8s.io/api v0.33.7/go.mod h1:pu6qwFzTj0ijPbNYAbMgLFDEWgLFu2VUB6PVvQNtswc=
|
||||
k8s.io/apimachinery v0.33.7 h1:f1kF3V+Stdr+2IGB8QhrfZ6J9JkXF6e1gWX2wKP5slU=
|
||||
k8s.io/apimachinery v0.33.7/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
|
||||
|
||||
6
generated/1.33/client/go.mod
generated
6
generated/1.33/client/go.mod
generated
@@ -7,9 +7,9 @@ replace go.pinniped.dev/generated/1.33/apis => ../apis
|
||||
|
||||
require (
|
||||
go.pinniped.dev/generated/1.33/apis v0.0.0
|
||||
k8s.io/api v0.33.6
|
||||
k8s.io/apimachinery v0.33.6
|
||||
k8s.io/client-go v0.33.6
|
||||
k8s.io/api v0.33.7
|
||||
k8s.io/apimachinery v0.33.7
|
||||
k8s.io/client-go v0.33.7
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff
|
||||
)
|
||||
|
||||
|
||||
12
generated/1.33/client/go.sum
generated
12
generated/1.33/client/go.sum
generated
@@ -132,12 +132,12 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.33.6 h1:9O22ZqwT6CkQ3iboVpvTR5BEWuT3Xm6/8NX6MOLmc38=
|
||||
k8s.io/api v0.33.6/go.mod h1:bdon4pRFmRmdsFyltGIoCaPqutN7y//OQ4srD0uy9X0=
|
||||
k8s.io/apimachinery v0.33.6 h1:Pq+px1i1t7lNgE58dIeBwJh7OWId6pfGD1dYBm/U5HI=
|
||||
k8s.io/apimachinery v0.33.6/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
||||
k8s.io/client-go v0.33.6 h1:icPU5E5XHl/5mdwMUdSxpGtHnnjWzG0MSputTR9odrg=
|
||||
k8s.io/client-go v0.33.6/go.mod h1:3z/Cwqdi6/Uo+E17k+OgQi4QfXS0XuIUmfHpK6rQdZU=
|
||||
k8s.io/api v0.33.7 h1:Koh06KurzmXwCwe/DOaIiM1A8vEXTZ6B1tTDnmLLfxw=
|
||||
k8s.io/api v0.33.7/go.mod h1:pu6qwFzTj0ijPbNYAbMgLFDEWgLFu2VUB6PVvQNtswc=
|
||||
k8s.io/apimachinery v0.33.7 h1:f1kF3V+Stdr+2IGB8QhrfZ6J9JkXF6e1gWX2wKP5slU=
|
||||
k8s.io/apimachinery v0.33.7/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
||||
k8s.io/client-go v0.33.7 h1:sEcU4syZnbwaiGDctJE6G/IKsuays3wjEWGuyrD7M8c=
|
||||
k8s.io/client-go v0.33.7/go.mod h1:0MEM10zY5dGdc3FdkyNCTKXiTr8P+2Vj65njzvE0Vhw=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
|
||||
|
||||
4
generated/1.34/apis/go.mod
generated
4
generated/1.34/apis/go.mod
generated
@@ -4,8 +4,8 @@ module go.pinniped.dev/generated/1.34/apis
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
k8s.io/api v0.34.2
|
||||
k8s.io/apimachinery v0.34.2
|
||||
k8s.io/api v0.34.3
|
||||
k8s.io/apimachinery v0.34.3
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
8
generated/1.34/apis/go.sum
generated
8
generated/1.34/apis/go.sum
generated
@@ -77,10 +77,10 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY=
|
||||
k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw=
|
||||
k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4=
|
||||
k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||
k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4=
|
||||
k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk=
|
||||
k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE=
|
||||
k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
|
||||
|
||||
6
generated/1.34/client/go.mod
generated
6
generated/1.34/client/go.mod
generated
@@ -7,9 +7,9 @@ replace go.pinniped.dev/generated/1.34/apis => ../apis
|
||||
|
||||
require (
|
||||
go.pinniped.dev/generated/1.34/apis v0.0.0
|
||||
k8s.io/api v0.34.2
|
||||
k8s.io/apimachinery v0.34.2
|
||||
k8s.io/client-go v0.34.2
|
||||
k8s.io/api v0.34.3
|
||||
k8s.io/apimachinery v0.34.3
|
||||
k8s.io/client-go v0.34.3
|
||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b
|
||||
)
|
||||
|
||||
|
||||
12
generated/1.34/client/go.sum
generated
12
generated/1.34/client/go.sum
generated
@@ -136,12 +136,12 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY=
|
||||
k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw=
|
||||
k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4=
|
||||
k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||
k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M=
|
||||
k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE=
|
||||
k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4=
|
||||
k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk=
|
||||
k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE=
|
||||
k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||
k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A=
|
||||
k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=
|
||||
|
||||
51
go.mod
51
go.mod
@@ -18,9 +18,9 @@ require (
|
||||
github.com/go-logr/stdr v1.2.2
|
||||
github.com/go-logr/zapr v1.3.0
|
||||
github.com/gofrs/flock v0.13.0
|
||||
github.com/google/cel-go v0.26.1
|
||||
github.com/google/cel-go v0.27.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/google/go-github/v76 v76.0.0
|
||||
github.com/google/go-github/v83 v83.0.0
|
||||
github.com/google/gofuzz v1.2.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/securecookie v1.1.2
|
||||
@@ -38,31 +38,31 @@ require (
|
||||
github.com/tdewolff/minify/v2 v2.24.8
|
||||
go.uber.org/mock v0.6.0
|
||||
go.uber.org/zap v1.27.1
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/net v0.48.0
|
||||
golang.org/x/oauth2 v0.34.0
|
||||
golang.org/x/crypto v0.48.0
|
||||
golang.org/x/net v0.50.0
|
||||
golang.org/x/oauth2 v0.35.0
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/term v0.38.0
|
||||
golang.org/x/text v0.32.0
|
||||
k8s.io/api v0.35.0
|
||||
k8s.io/apiextensions-apiserver v0.35.0
|
||||
k8s.io/apimachinery v0.35.0
|
||||
k8s.io/apiserver v0.35.0
|
||||
k8s.io/client-go v0.35.0
|
||||
k8s.io/component-base v0.35.0
|
||||
golang.org/x/term v0.40.0
|
||||
golang.org/x/text v0.34.0
|
||||
k8s.io/api v0.35.1
|
||||
k8s.io/apiextensions-apiserver v0.35.1
|
||||
k8s.io/apimachinery v0.35.1
|
||||
k8s.io/apiserver v0.35.1
|
||||
k8s.io/client-go v0.35.1
|
||||
k8s.io/component-base v0.35.1
|
||||
k8s.io/gengo v0.0.0-20251215205346-5ee0d033ba5b
|
||||
k8s.io/klog/v2 v2.130.1
|
||||
k8s.io/kube-aggregator v0.35.0
|
||||
k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e
|
||||
k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2
|
||||
k8s.io/kube-aggregator v0.35.1
|
||||
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2
|
||||
sigs.k8s.io/yaml v1.6.0
|
||||
)
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.24.0 // indirect
|
||||
cel.dev/expr v0.25.1 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
@@ -92,7 +92,7 @@ require (
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/gnostic-models v0.7.0 // indirect
|
||||
github.com/google/go-github/v73 v73.0.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/go-querystring v1.2.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
|
||||
@@ -131,7 +131,6 @@ require (
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/viper v1.16.0 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/tdewolff/parse/v2 v2.8.5 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
@@ -158,22 +157,22 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||
golang.org/x/mod v0.30.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect
|
||||
golang.org/x/mod v0.32.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.39.0 // indirect
|
||||
golang.org/x/tools v0.41.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
|
||||
google.golang.org/grpc v1.72.2 // indirect
|
||||
google.golang.org/protobuf v1.36.8 // indirect
|
||||
google.golang.org/protobuf v1.36.10 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
||||
gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/kms v0.35.0 // indirect
|
||||
k8s.io/kms v0.35.1 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
|
||||
107
go.sum
107
go.sum
@@ -1,5 +1,5 @@
|
||||
cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
|
||||
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
|
||||
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
|
||||
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=
|
||||
@@ -51,8 +51,8 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI=
|
||||
github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
@@ -231,8 +231,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ=
|
||||
github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
|
||||
github.com/google/cel-go v0.27.0 h1:e7ih85+4qVrBuqQWTW4FKSqZYokVuc3HnhH5keboFTo=
|
||||
github.com/google/cel-go v0.27.0/go.mod h1:tTJ11FWqnhw5KKpnWpvW9CJC3Y9GK4EIS0WXnBbebzw=
|
||||
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
||||
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
@@ -245,14 +245,15 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-github/v73 v73.0.0 h1:aR+Utnh+Y4mMkS+2qLQwcQ/cF9mOTpdwnzlaw//rG24=
|
||||
github.com/google/go-github/v73 v73.0.0/go.mod h1:fa6w8+/V+edSU0muqdhCVY7Beh1M8F1IlQPZIANKIYw=
|
||||
github.com/google/go-github/v76 v76.0.0 h1:MCa9VQn+VG5GG7Y7BAkBvSRUN3o+QpaEOuZwFPJmdFA=
|
||||
github.com/google/go-github/v76 v76.0.0/go.mod h1:38+d/8pYDO4fBLYfBhXF5EKO0wA3UkXBjfmQapFsNCQ=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/go-github/v83 v83.0.0 h1:Ydy4gAfqxrnFUwXAuKl/OMhhGa0KtMtnJ3EozIIuHT0=
|
||||
github.com/google/go-github/v83 v83.0.0/go.mod h1:gbqarhK37mpSu8Xy7sz21ITtznvzouyHSAajSaYCHe8=
|
||||
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
|
||||
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
@@ -544,8 +545,6 @@ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
|
||||
github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
|
||||
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
|
||||
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
@@ -688,8 +687,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||
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=
|
||||
@@ -700,8 +699,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
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/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA=
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
||||
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=
|
||||
@@ -728,8 +727,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
|
||||
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
|
||||
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-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -769,8 +768,8 @@ golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfS
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||
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=
|
||||
@@ -780,8 +779,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
|
||||
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
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=
|
||||
@@ -850,10 +849,10 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 h1:E2/AqCUMZGgd73TQkxUMcMla25GB9i/5HOdLr+uH7Vo=
|
||||
golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 h1:O1cMQHRfwNpDfDJerqRoE2oD+AFlyid87D40L/OkkJo=
|
||||
golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -862,8 +861,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
|
||||
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
|
||||
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=
|
||||
@@ -875,8 +874,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
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=
|
||||
@@ -940,8 +939,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
|
||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
||||
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -1042,8 +1041,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
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=
|
||||
@@ -1075,31 +1074,31 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
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=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY=
|
||||
k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA=
|
||||
k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4=
|
||||
k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU=
|
||||
k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8=
|
||||
k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
|
||||
k8s.io/apiserver v0.35.0 h1:CUGo5o+7hW9GcAEF3x3usT3fX4f9r8xmgQeCBDaOgX4=
|
||||
k8s.io/apiserver v0.35.0/go.mod h1:QUy1U4+PrzbJaM3XGu2tQ7U9A4udRRo5cyxkFX0GEds=
|
||||
k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE=
|
||||
k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o=
|
||||
k8s.io/component-base v0.35.0 h1:+yBrOhzri2S1BVqyVSvcM3PtPyx5GUxCK2tinZz1G94=
|
||||
k8s.io/component-base v0.35.0/go.mod h1:85SCX4UCa6SCFt6p3IKAPej7jSnF3L8EbfSyMZayJR0=
|
||||
k8s.io/api v0.35.1 h1:0PO/1FhlK/EQNVK5+txc4FuhQibV25VLSdLMmGpDE/Q=
|
||||
k8s.io/api v0.35.1/go.mod h1:28uR9xlXWml9eT0uaGo6y71xK86JBELShLy4wR1XtxM=
|
||||
k8s.io/apiextensions-apiserver v0.35.1 h1:p5vvALkknlOcAqARwjS20kJffgzHqwyQRM8vHLwgU7w=
|
||||
k8s.io/apiextensions-apiserver v0.35.1/go.mod h1:2CN4fe1GZ3HMe4wBr25qXyJnJyZaquy4nNlNmb3R7AQ=
|
||||
k8s.io/apimachinery v0.35.1 h1:yxO6gV555P1YV0SANtnTjXYfiivaTPvCTKX6w6qdDsU=
|
||||
k8s.io/apimachinery v0.35.1/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
|
||||
k8s.io/apiserver v0.35.1 h1:potxdhhTL4i6AYAa2QCwtlhtB1eCdWQFvJV6fXgJzxs=
|
||||
k8s.io/apiserver v0.35.1/go.mod h1:BiL6Dd3A2I/0lBnteXfWmCFobHM39vt5+hJQd7Lbpi4=
|
||||
k8s.io/client-go v0.35.1 h1:+eSfZHwuo/I19PaSxqumjqZ9l5XiTEKbIaJ+j1wLcLM=
|
||||
k8s.io/client-go v0.35.1/go.mod h1:1p1KxDt3a0ruRfc/pG4qT/3oHmUj1AhSHEcxNSGg+OA=
|
||||
k8s.io/component-base v0.35.1 h1:XgvpRf4srp037QWfGBLFsYMUQJkE5yMa94UsJU7pmcE=
|
||||
k8s.io/component-base v0.35.1/go.mod h1:HI/6jXlwkiOL5zL9bqA3en1Ygv60F03oEpnuU1G56Bs=
|
||||
k8s.io/gengo v0.0.0-20251215205346-5ee0d033ba5b h1:X0Afwan8Q1l7bMcNgh6DAah2jKCQ2irT7EoAXIChFqk=
|
||||
k8s.io/gengo v0.0.0-20251215205346-5ee0d033ba5b/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kms v0.35.0 h1:/x87FED2kDSo66csKtcYCEHsxF/DBlNl7LfJ1fVQs1o=
|
||||
k8s.io/kms v0.35.0/go.mod h1:VT+4ekZAdrZDMgShK37vvlyHUVhwI9t/9tvh0AyCWmQ=
|
||||
k8s.io/kube-aggregator v0.35.0 h1:FBtbuRFA7Ohe2QKirFZcJf8rgimC8oSaNiCi4pdU5xw=
|
||||
k8s.io/kube-aggregator v0.35.0/go.mod h1:vKBRpQUfDryb7udwUwF3eCSvv3AJNgHtL4PGl6PqAg8=
|
||||
k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ=
|
||||
k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
||||
k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 h1:OfgiEo21hGiwx1oJUU5MpEaeOEg6coWndBkZF/lkFuE=
|
||||
k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||
k8s.io/kms v0.35.1 h1:kjv2r9g1mY7uL+l1RhyAZvWVZIA/4qIfBHXyjFGLRhU=
|
||||
k8s.io/kms v0.35.1/go.mod h1:VT+4ekZAdrZDMgShK37vvlyHUVhwI9t/9tvh0AyCWmQ=
|
||||
k8s.io/kube-aggregator v0.35.1 h1:LN+btMJ3yp7biqVgT/0LF6SKIKLyfPU0R+JJ1mycs2I=
|
||||
k8s.io/kube-aggregator v0.35.1/go.mod h1:HQSjPQfOFRzcv7biQ7jV3cEfKHG+bczpLCfh4QfvxZU=
|
||||
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 h1:HhDfevmPS+OalTjQRKbTHppRIz01AWi8s45TMXStgYY=
|
||||
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||
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=
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2022-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# this dockerfile is used to produce a binary of Pinniped that uses
|
||||
@@ -16,8 +16,8 @@
|
||||
# See https://go.googlesource.com/go/+/dev.boringcrypto/README.boringcrypto.md
|
||||
# and https://kupczynski.info/posts/fips-golang/ for details.
|
||||
|
||||
ARG BUILD_IMAGE=golang:1.25.5@sha256:36b4f45d2874905b9e8573b783292629bcb346d0a70d8d7150b6df545234818f
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:2b7c93f6d6648c11f0e80a48558c8f77885eb0445213b8e69a6a0d7c89fc6ae4
|
||||
ARG BUILD_IMAGE=golang:1.26.0@sha256:c83e68f3ebb6943a2904fa66348867d108119890a2c6a2e6f07b38d0eb6c25c5
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:01e550fdb7ab79ee7be5ff440a563a58f1fd000ad9e0c532e65c3d23f917f1c5
|
||||
|
||||
# This is not currently using --platform to prepare to cross-compile because we use gcc below to build
|
||||
# platform-specific GCO code. This makes multi-arch builds slow due to target platform emulation.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2022-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -euo pipefail
|
||||
@@ -13,19 +13,14 @@ go version
|
||||
|
||||
lint_version="v$(cat hack/lib/lint-version.txt)"
|
||||
|
||||
# Find the toolchain version from our go.mod file. "go install" pays attention to $GOTOOLCHAIN.
|
||||
GOTOOLCHAIN=$(sed -rn 's/^toolchain (go[0-9\.]+)$/\1/p' go.mod)
|
||||
# Find the Go version from our Dockerfile. "go install" pays attention to $GOTOOLCHAIN.
|
||||
GOTOOLCHAIN=$(sed -rn 's/^ARG BUILD_IMAGE=golang:([0-9\.]+)@sha256:.*$/\1/p' Dockerfile)
|
||||
if [[ -z "$GOTOOLCHAIN" ]]; then
|
||||
# Did not find toolchain directive. The directive is not needed in a go.mod file when it would be the same
|
||||
# version as the go directive, so it will not always be there. Try using go directive instead.
|
||||
GOTOOLCHAIN=$(sed -rn 's/^go ([0-9]+\.[0-9]+\.[0-9]+)$/\1/p' go.mod)
|
||||
if [[ -z "$GOTOOLCHAIN" ]]; then
|
||||
echo "ERROR: Could not find Go patch version from go.mod file."
|
||||
exit 1
|
||||
fi
|
||||
GOTOOLCHAIN="go${GOTOOLCHAIN}"
|
||||
echo "ERROR: Could not find Go patch version from Dockerfile."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GOTOOLCHAIN="go${GOTOOLCHAIN}"
|
||||
export GOTOOLCHAIN
|
||||
|
||||
echo "Installing golangci-lint@${lint_version} using toolchain ${GOTOOLCHAIN}"
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
# is edited in this file, please run hack/update.sh.
|
||||
#
|
||||
1.35.0
|
||||
1.34.2
|
||||
1.33.6
|
||||
1.32.10
|
||||
1.34.3
|
||||
1.33.7
|
||||
1.32.11
|
||||
1.31.14
|
||||
1.30.14
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.7.2
|
||||
2.9.0
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2021-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ "$OSTYPE" != "darwin"* ]]; then
|
||||
echo "This script was only written for MacOS (due to differences with Linux sed flags)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
files=$(git diff --cached --name-only)
|
||||
year=$(date +"%Y")
|
||||
|
||||
@@ -25,15 +20,25 @@ done
|
||||
|
||||
if [[ "${#missing_copyright_files[@]}" -gt "0" ]]; then
|
||||
echo "Fixing copyright notice in the following files:"
|
||||
|
||||
for f in "${missing_copyright_files[@]}"; do
|
||||
echo " $f"
|
||||
# The rule when updating copyrights is to always keep the starting year,
|
||||
# and to replace the ending year with the current year.
|
||||
# This uses MacOS sed flags to replace "XXXX-YYYY" with "XXXX-year" in the copyright notice.
|
||||
sed -E -e 's/Copyright ([0-9]{4})-([0-9]{4}) the Pinniped contributors/Copyright \1-'"$year"' the Pinniped contributors/' -i '' "$f"
|
||||
# This uses MacOS sed flags to replace "XXXX" with "XXXX-year" in the copyright notice.
|
||||
sed -E -e 's/Copyright ([0-9]{4}) the Pinniped contributors/Copyright \1-'"$year"' the Pinniped contributors/' -i '' "$f"
|
||||
if [[ "$(uname -s)" == "Linux" ]]; then
|
||||
# sed on Linux uses -i'' (no space in between).
|
||||
# Replace "XXXX-YYYY" with "XXXX-year" in the copyright notice.
|
||||
sed -E -e 's/Copyright ([0-9]{4})-([0-9]{4}) the Pinniped contributors/Copyright \1-'"$year"' the Pinniped contributors/' -i'' "$f"
|
||||
# Replace "XXXX" with "XXXX-year" in the copyright notice.
|
||||
sed -E -e 's/Copyright ([0-9]{4}) the Pinniped contributors/Copyright \1-'"$year"' the Pinniped contributors/' -i'' "$f"
|
||||
else
|
||||
# sed on MacOS uses -i '' (with space in between).
|
||||
# Replace "XXXX-YYYY" with "XXXX-year" in the copyright notice.
|
||||
sed -E -e 's/Copyright ([0-9]{4})-([0-9]{4}) the Pinniped contributors/Copyright \1-'"$year"' the Pinniped contributors/' -i '' "$f"
|
||||
# Replace "XXXX" with "XXXX-year" in the copyright notice.
|
||||
sed -E -e 's/Copyright ([0-9]{4}) the Pinniped contributors/Copyright \1-'"$year"' the Pinniped contributors/' -i '' "$f"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Done!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -2,4 +2,4 @@ module go.pinniped.dev/update-go-mod
|
||||
|
||||
go 1.25.0
|
||||
|
||||
require golang.org/x/mod v0.29.0
|
||||
require golang.org/x/mod v0.33.0
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2024 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2024-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -euo pipefail
|
||||
@@ -36,30 +36,26 @@ for m in $modules; do
|
||||
found_new_version=$?
|
||||
if [[ $found_new_version == 0 ]]; then
|
||||
echo "Found new version $next_version. Replacing imports..."
|
||||
find . -name './.*' -prune -o \
|
||||
-path ./generated -prune -o \
|
||||
-type f -name '*.go' -print0 |
|
||||
xargs -0 sed -i '' "s#${m}#${next_version}#g"
|
||||
if [[ "$(uname -s)" == "Linux" ]]; then
|
||||
# sed on Linux uses -i'' (no space in between).
|
||||
find . -wholename './.*' -prune -o \
|
||||
-path ./generated -prune -o \
|
||||
-type f -name '*.go' -print0 |
|
||||
xargs -0 sed -i'' "s#${m}#${next_version}#g"
|
||||
else
|
||||
# sed on MacOS uses -i '' (with space in between).
|
||||
find . -wholename './.*' -prune -o \
|
||||
-path ./generated -prune -o \
|
||||
-type f -name '*.go' -print0 |
|
||||
xargs -0 sed -i '' "s#${m}#${next_version}#g"
|
||||
fi
|
||||
fi
|
||||
set -e
|
||||
done
|
||||
|
||||
go mod tidy
|
||||
|
||||
if git diff --quiet; then
|
||||
echo
|
||||
echo "No changes."
|
||||
else
|
||||
echo
|
||||
echo "Showing resulting diffs..."
|
||||
git --no-pager diff
|
||||
|
||||
echo
|
||||
echo "Running unit tests..."
|
||||
./hack/module.sh units
|
||||
fi
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
echo
|
||||
echo "Done!"
|
||||
echo "Done updating majors! Check for git diffs to see results."
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package apiserver
|
||||
@@ -79,7 +79,7 @@ func (c completedConfig) New() (*PinnipedServer, error) {
|
||||
GenericAPIServer: genericServer,
|
||||
}
|
||||
|
||||
var errs []error //nolint:prealloc
|
||||
var errs []error
|
||||
for _, f := range []func() (schema.GroupVersionResource, rest.Storage){
|
||||
func() (schema.GroupVersionResource, rest.Storage) {
|
||||
tokenCredReqGVR := c.ExtraConfig.LoginConciergeGroupVersion.WithResource("tokencredentialrequests")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package impersonator
|
||||
@@ -236,12 +236,12 @@ func newInternal(
|
||||
serverConfig.AuditPolicyRuleEvaluator = policy.NewFakePolicyRuleEvaluator(auditinternal.LevelMetadata, nil)
|
||||
serverConfig.AuditBackend = &auditfake.Backend{}
|
||||
|
||||
// Probe the API server to figure out if anonymous auth is enabled.
|
||||
anonymousAuthEnabled, err := isAnonymousAuthEnabled(kubeClientUnsafeForProxying.JSONConfig)
|
||||
// Probe the Kubernetes API server to figure out if anonymous auth is enabled.
|
||||
anonymousAuthProbeResult, err := isAnonymousAuthEnabled(kubeClientUnsafeForProxying.JSONConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not detect if anonymous authentication is enabled: %w", err)
|
||||
}
|
||||
plog.Debug("anonymous authentication probed", "anonymousAuthEnabled", anonymousAuthEnabled)
|
||||
plog.Debug("anonymous authentication probed", "results", anonymousAuthProbeResult)
|
||||
|
||||
// if we ever start unioning a TCR bearer token authenticator with serverConfig.Authenticator
|
||||
// then we will need to update the related assumption in tokenPassthroughRoundTripper
|
||||
@@ -251,8 +251,15 @@ func newInternal(
|
||||
RequestFunc: func(req *http.Request) (*authenticator.Response, bool, error) {
|
||||
resp, ok, err := delegatingAuthenticator.AuthenticateRequest(req)
|
||||
|
||||
// anonymous auth is enabled so no further check is necessary
|
||||
if anonymousAuthEnabled {
|
||||
reqIsHealthCheck := isRequestForHealthCheck(req)
|
||||
|
||||
if anonymousAuthProbeResult.HealthCheckEndpointsAllowAnonAuth && reqIsHealthCheck {
|
||||
// anonymous auth is enabled for health check endpoints, so no further check is necessary
|
||||
return resp, ok, err
|
||||
}
|
||||
|
||||
if anonymousAuthProbeResult.OtherEndpointsAllowAnonAuth && !reqIsHealthCheck {
|
||||
// anonymous auth is enabled for all other endpoints, so no further check is necessary
|
||||
return resp, ok, err
|
||||
}
|
||||
|
||||
@@ -266,6 +273,10 @@ func newInternal(
|
||||
return resp, ok, err
|
||||
}
|
||||
|
||||
// If we got this far, then anonymous auth is disabled for this request's path,
|
||||
// and authentication succeeded, and the user is system:anonymous.
|
||||
// Now we want to allow these anonymous users to make requests _only_ to the TCR endpoint.
|
||||
|
||||
reqInfo, ok := genericapirequest.RequestInfoFrom(req.Context())
|
||||
if !ok {
|
||||
return nil, false, constable.Error("no RequestInfo found in the context")
|
||||
@@ -276,7 +287,7 @@ func newInternal(
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// any resource besides TKR should not be authenticated
|
||||
// any resource besides TKR should not be authenticated because anonymous auth is disabled on this cluster
|
||||
if !isTokenCredReq(reqInfo) {
|
||||
return nil, false, nil
|
||||
}
|
||||
@@ -370,7 +381,46 @@ func getReverseProxyClient(baseConfig *rest.Config, cache tokenclient.ExpiringSi
|
||||
return kubeclient.New(kubeclient.WithConfig(impersonationProxyRestConfig))
|
||||
}
|
||||
|
||||
func isAnonymousAuthEnabled(config *rest.Config) (bool, error) {
|
||||
func isRequestForHealthCheck(req *http.Request) bool {
|
||||
if req == nil || req.URL == nil {
|
||||
// Shouldn't really happen but easy enough to handle here.
|
||||
return false
|
||||
}
|
||||
|
||||
path := req.URL.Path
|
||||
|
||||
// See https://kubernetes.io/docs/reference/using-api/health-checks.
|
||||
// Although there are sub-paths for these endpoints, e.g. /healthz/etcd, the sub-paths are not made available
|
||||
// for anonymous auth by GKE when anonymous auth is otherwise disabled, so let's mirror that behavior here.
|
||||
switch path {
|
||||
case "/healthz", "/readyz", "/livez":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// anonAuthEnablement allows us to characterize the most common configurations for anonymous authentication:
|
||||
//
|
||||
// 1. Anonymous auth is disabled for the whole k8s API (e.g. AKS clusters).
|
||||
// 2. Anonymous auth is enabled for the whole k8s API (e.g. GKE clusters before Kubernetes 1.35).
|
||||
// 3. In newer clusters, anonymous auth can be selectively enabled only for certain API paths.
|
||||
// See https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-authenticator-configuration.
|
||||
// Usually this is used to enable anonymous auth only for the three health check endpoints, and disable it for
|
||||
// all other endpoints. This configuration was adpoted by GKE clusters starting with Kube 1.35 (as the default, but
|
||||
// can be overridden by the user during cluster creation to instead allow anon auth for the whole API)
|
||||
// and by EKS clusters starting with Kube 1.32.
|
||||
//
|
||||
// Of course, other configurations of which API paths allow should anonymous auth are possible, but we have no practical
|
||||
// way of auto-detecting them here. We could alternatively add new Pinniped configuration options instead of trying to
|
||||
// auto-detect anonymous authentication enablement here, but that would put extra burdon on the user to configure it
|
||||
// correctly. In practice, its almost always one of the three configurations described above.
|
||||
type anonAuthEnablement struct {
|
||||
HealthCheckEndpointsAllowAnonAuth bool
|
||||
OtherEndpointsAllowAnonAuth bool
|
||||
}
|
||||
|
||||
func isAnonymousAuthEnabled(config *rest.Config) (*anonAuthEnablement, error) {
|
||||
anonymousConfig := kubeclient.SecureAnonymousClientConfig(config)
|
||||
|
||||
// we do not need either of these but RESTClientFor complains if they are not set
|
||||
@@ -380,32 +430,54 @@ func isAnonymousAuthEnabled(config *rest.Config) (bool, error) {
|
||||
// in case anyone looking at audit logs wants to know who is making the anonymous request
|
||||
anonymousConfig.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
|
||||
rc, err := rest.RESTClientFor(anonymousConfig)
|
||||
anonClient, err := rest.RESTClientFor(anonymousConfig)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
healthzAllowsAnonAuth, err := isAnonymousAuthEnabledForEndpoint(anonClient.Get().AbsPath("/healthz"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error from healthz API: %w", err)
|
||||
}
|
||||
|
||||
// As a heuristic to determine if anonymous auth is enabled for all other API endpoints,
|
||||
// we probe one representative endpoint which should exist on all clusters. We assume that
|
||||
// the result found at this endpoint is representative of the result for all non-heath endpoints.
|
||||
otherAPIAllowsAnonAuth, err := isAnonymousAuthEnabledForEndpoint(
|
||||
anonClient.Get().AbsPath("/api/v1/nodes").Param("limit", "1"),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error from v1 nodes API: %w", err)
|
||||
}
|
||||
|
||||
return &anonAuthEnablement{
|
||||
HealthCheckEndpointsAllowAnonAuth: healthzAllowsAnonAuth,
|
||||
OtherEndpointsAllowAnonAuth: otherAPIAllowsAnonAuth,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func isAnonymousAuthEnabledForEndpoint(anonReq *rest.Request) (bool, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
_, errHealthz := rc.Get().AbsPath("/healthz").DoRaw(ctx)
|
||||
_, err := anonReq.DoRaw(ctx)
|
||||
|
||||
switch {
|
||||
// 200 ok on healthz clearly indicates authentication success
|
||||
case errHealthz == nil:
|
||||
// 200 ok clearly indicates authentication success
|
||||
case err == nil:
|
||||
return true, nil
|
||||
|
||||
// we are authenticated but not authorized. anonymous authentication is enabled
|
||||
case apierrors.IsForbidden(errHealthz):
|
||||
// we are authenticated but not authorized: anonymous authentication is enabled at the endpoint
|
||||
case apierrors.IsForbidden(err):
|
||||
return true, nil
|
||||
|
||||
// failure to authenticate will return unauthorized (http misnomer)
|
||||
case apierrors.IsUnauthorized(errHealthz):
|
||||
case apierrors.IsUnauthorized(err):
|
||||
return false, nil
|
||||
|
||||
// any other error is unexpected
|
||||
default:
|
||||
return false, errHealthz
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package impersonator
|
||||
@@ -101,19 +101,21 @@ func TestImpersonator(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
clientCert clientCert
|
||||
clientImpersonateUser rest.ImpersonationConfig
|
||||
clientMutateHeaders func(http.Header)
|
||||
clientNextProtos []string
|
||||
kubeAPIServerStatusCode int
|
||||
kubeAPIServerHealthz http.Handler
|
||||
anonymousAuthDisabled bool
|
||||
noServiceAcctTokenInCache bool // when true, no available service account token for the impersonator to use
|
||||
wantKubeAPIServerRequestHeaders func(credentialID string) http.Header
|
||||
wantError string
|
||||
wantConstructionError string
|
||||
wantAuthorizerAttributes func(credentialID string) []authorizer.AttributesRecord
|
||||
name string
|
||||
clientCert clientCert
|
||||
clientImpersonateUser rest.ImpersonationConfig
|
||||
clientMutateHeaders func(http.Header)
|
||||
clientNextProtos []string
|
||||
kubeAPIServerStatusCode int
|
||||
kubeAPIServerHealthz http.Handler
|
||||
kubeAPIServerNodes http.Handler
|
||||
anonymousAuthForHealthDisabled bool
|
||||
anonymousAuthForOtherAPIsDisabled bool
|
||||
noServiceAcctTokenInCache bool // when true, no available service account token for the impersonator to use
|
||||
wantKubeAPIServerRequestHeaders func(credentialID string) http.Header
|
||||
wantError string
|
||||
wantConstructionError string
|
||||
wantAuthorizerAttributes func(credentialID string) []authorizer.AttributesRecord
|
||||
}{
|
||||
{
|
||||
name: "happy path",
|
||||
@@ -140,7 +142,7 @@ func TestImpersonator(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path with forbidden healthz",
|
||||
name: "happy path with forbidden healthz (anonymous auth for health checks is allowed)",
|
||||
clientCert: newClientCert(t, ca, "test-username", []string{"test-group1", "test-group2"}),
|
||||
kubeAPIServerHealthz: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
@@ -168,13 +170,104 @@ func TestImpersonator(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path with unauthorized healthz",
|
||||
name: "happy path with forbidden nodes (anonymous auth for other APIs is allowed)",
|
||||
clientCert: newClientCert(t, ca, "test-username", []string{"test-group1", "test-group2"}),
|
||||
kubeAPIServerNodes: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
_, _ = w.Write([]byte("no nodes for you"))
|
||||
}),
|
||||
wantKubeAPIServerRequestHeaders: func(credentialID string) http.Header {
|
||||
return http.Header{
|
||||
"Impersonate-User": {"test-username"},
|
||||
"Impersonate-Group": {"test-group1", "test-group2", "system:authenticated"},
|
||||
"Authorization": {"Bearer some-service-account-token"},
|
||||
"User-Agent": {"test-agent"},
|
||||
"Accept": {"application/vnd.kubernetes.protobuf,application/json"},
|
||||
"Accept-Encoding": {"gzip"},
|
||||
"X-Forwarded-For": {"127.0.0.1"},
|
||||
"Impersonate-Extra-Authentication.kubernetes.io%2fcredential-Id": {credentialID},
|
||||
}
|
||||
},
|
||||
wantAuthorizerAttributes: func(credentialID string) []authorizer.AttributesRecord {
|
||||
return []authorizer.AttributesRecord{
|
||||
{
|
||||
User: defaultInfoForTestUsername(credentialID),
|
||||
Verb: "list", Namespace: "", APIGroup: "", APIVersion: "v1", Resource: "namespaces", Subresource: "", Name: "", ResourceRequest: true, Path: "/api/v1/namespaces",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path with unauthorized healthz (anonymous auth for health checks is disallowed)",
|
||||
clientCert: newClientCert(t, ca, "test-username", []string{"test-group1", "test-group2"}),
|
||||
kubeAPIServerHealthz: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
_, _ = w.Write([]byte("no healthz for you"))
|
||||
}),
|
||||
anonymousAuthDisabled: true,
|
||||
anonymousAuthForHealthDisabled: true,
|
||||
wantKubeAPIServerRequestHeaders: func(credentialID string) http.Header {
|
||||
return http.Header{
|
||||
"Impersonate-User": {"test-username"},
|
||||
"Impersonate-Group": {"test-group1", "test-group2", "system:authenticated"},
|
||||
"Authorization": {"Bearer some-service-account-token"},
|
||||
"User-Agent": {"test-agent"},
|
||||
"Accept": {"application/vnd.kubernetes.protobuf,application/json"},
|
||||
"Accept-Encoding": {"gzip"},
|
||||
"X-Forwarded-For": {"127.0.0.1"},
|
||||
"Impersonate-Extra-Authentication.kubernetes.io%2fcredential-Id": {credentialID},
|
||||
}
|
||||
},
|
||||
wantAuthorizerAttributes: func(credentialID string) []authorizer.AttributesRecord {
|
||||
return []authorizer.AttributesRecord{
|
||||
{
|
||||
User: defaultInfoForTestUsername(credentialID),
|
||||
Verb: "list", Namespace: "", APIGroup: "", APIVersion: "v1", Resource: "namespaces", Subresource: "", Name: "", ResourceRequest: true, Path: "/api/v1/namespaces",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path with unauthorized nodes (anonymous auth for other APIs is disallowed)",
|
||||
clientCert: newClientCert(t, ca, "test-username", []string{"test-group1", "test-group2"}),
|
||||
kubeAPIServerNodes: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
_, _ = w.Write([]byte("no nodes for you"))
|
||||
}),
|
||||
anonymousAuthForOtherAPIsDisabled: true,
|
||||
wantKubeAPIServerRequestHeaders: func(credentialID string) http.Header {
|
||||
return http.Header{
|
||||
"Impersonate-User": {"test-username"},
|
||||
"Impersonate-Group": {"test-group1", "test-group2", "system:authenticated"},
|
||||
"Authorization": {"Bearer some-service-account-token"},
|
||||
"User-Agent": {"test-agent"},
|
||||
"Accept": {"application/vnd.kubernetes.protobuf,application/json"},
|
||||
"Accept-Encoding": {"gzip"},
|
||||
"X-Forwarded-For": {"127.0.0.1"},
|
||||
"Impersonate-Extra-Authentication.kubernetes.io%2fcredential-Id": {credentialID},
|
||||
}
|
||||
},
|
||||
wantAuthorizerAttributes: func(credentialID string) []authorizer.AttributesRecord {
|
||||
return []authorizer.AttributesRecord{
|
||||
{
|
||||
User: defaultInfoForTestUsername(credentialID),
|
||||
Verb: "list", Namespace: "", APIGroup: "", APIVersion: "v1", Resource: "namespaces", Subresource: "", Name: "", ResourceRequest: true, Path: "/api/v1/namespaces",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path with unauthorized healthz and nodes (anonymous auth for everything is disallowed)",
|
||||
clientCert: newClientCert(t, ca, "test-username", []string{"test-group1", "test-group2"}),
|
||||
kubeAPIServerHealthz: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
_, _ = w.Write([]byte("no healthz for you"))
|
||||
}),
|
||||
kubeAPIServerNodes: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
_, _ = w.Write([]byte("no nodes for you"))
|
||||
}),
|
||||
anonymousAuthForHealthDisabled: true,
|
||||
anonymousAuthForOtherAPIsDisabled: true,
|
||||
wantKubeAPIServerRequestHeaders: func(credentialID string) http.Header {
|
||||
return http.Header{
|
||||
"Impersonate-User": {"test-username"},
|
||||
@@ -747,7 +840,16 @@ func TestImpersonator(t *testing.T) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = w.Write([]byte("broken"))
|
||||
}),
|
||||
wantConstructionError: `could not detect if anonymous authentication is enabled: an error on the server ("broken") has prevented the request from succeeding`,
|
||||
wantConstructionError: `could not detect if anonymous authentication is enabled: error from healthz API: an error on the server ("broken") has prevented the request from succeeding`,
|
||||
wantAuthorizerAttributes: nil,
|
||||
},
|
||||
{
|
||||
name: "unexpected nodes response",
|
||||
kubeAPIServerNodes: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = w.Write([]byte("broken"))
|
||||
}),
|
||||
wantConstructionError: `could not detect if anonymous authentication is enabled: error from v1 nodes API: an error on the server ("broken") has prevented the request from succeeding`,
|
||||
wantAuthorizerAttributes: nil,
|
||||
},
|
||||
{
|
||||
@@ -832,7 +934,7 @@ func TestImpersonator(t *testing.T) {
|
||||
var testKubeAPIServerSawHeaders http.Header
|
||||
testKubeAPIServer, testKubeAPIServerCA := tlsserver.TestServerIPv4(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
tlsConfigFunc := func(rootCAs *x509.CertPool) *tls.Config {
|
||||
// Requests to get configmaps, flowcontrol requests, and healthz requests
|
||||
// Requests to get configmaps, nodes, flowcontrol requests, and healthz requests
|
||||
// are not done by our http round trippers that specify only one protocol
|
||||
// (either http1.1 or http2, not both).
|
||||
// For all other requests from the impersonator, if it is not an upgrade
|
||||
@@ -844,7 +946,8 @@ func TestImpersonator(t *testing.T) {
|
||||
case "/api/v1/namespaces/kube-system/configmaps",
|
||||
fmt.Sprintf("/apis/flowcontrol.apiserver.k8s.io/%s/prioritylevelconfigurations", priorityLevelConfigurationsVersion),
|
||||
fmt.Sprintf("/apis/flowcontrol.apiserver.k8s.io/%s/flowschemas", flowSchemasVersion),
|
||||
"/healthz":
|
||||
"/healthz",
|
||||
"/api/v1/nodes":
|
||||
default:
|
||||
if !httpstream.IsUpgradeRequest(r) {
|
||||
secure.NextProtos = []string{secure.NextProtos[0]}
|
||||
@@ -900,6 +1003,15 @@ func TestImpersonator(t *testing.T) {
|
||||
_, _ = fmt.Fprint(w, "probed")
|
||||
return
|
||||
|
||||
case "/readyz", "/readyz/etcd", "/livez":
|
||||
require.Equal(t, http.MethodGet, r.Method)
|
||||
|
||||
// match the KAS endpoint's behavior
|
||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
_, _ = fmt.Fprint(w, "ok")
|
||||
return
|
||||
|
||||
case "/healthz":
|
||||
require.Equal(t, http.MethodGet, r.Method)
|
||||
require.Empty(t, r.Header.Get("Authorization"))
|
||||
@@ -916,6 +1028,24 @@ func TestImpersonator(t *testing.T) {
|
||||
_, _ = fmt.Fprint(w, "ok")
|
||||
return
|
||||
|
||||
case "/api/v1/nodes":
|
||||
// In these tests, the test client doesn't call the nodes API through the impersonator,
|
||||
// but the impersonator production code uses the nodes API to probe whether anonymous auth
|
||||
// is enabled or not, similar to what it does with the healthz API.
|
||||
require.Equal(t, http.MethodGet, r.Method)
|
||||
require.Empty(t, r.Header.Get("Authorization"))
|
||||
require.Contains(t, r.Header.Get("User-Agent"), "kubernetes")
|
||||
|
||||
if tt.kubeAPIServerNodes != nil {
|
||||
tt.kubeAPIServerNodes.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// by default just return success
|
||||
w.Header().Add("Content-Type", "application/json; charset=UTF-8")
|
||||
_, _ = fmt.Fprint(w, `{}`)
|
||||
return
|
||||
|
||||
case "/apis/login.concierge.pinniped.dev/v1alpha1/tokencredentialrequests":
|
||||
require.Equal(t, http.MethodPost, r.Method)
|
||||
|
||||
@@ -1142,8 +1272,40 @@ func TestImpersonator(t *testing.T) {
|
||||
rc, err := rest.RESTClientFor(anonymousConfig)
|
||||
require.NoError(t, err)
|
||||
|
||||
// It would be nice to also call /healthz through the impersonator here, but this unit test makes it
|
||||
// difficult because of the expectations that it sets differently for APIs that are expected to be called
|
||||
// by external clients versus those expected to be called by the impersonator itself.
|
||||
// We can test calling /readyz and /livez, but note that calling /healthz should also work the same.
|
||||
readyzBody, errReadyz := rc.Get().AbsPath("/readyz").DoRaw(ctx)
|
||||
if tt.anonymousAuthForHealthDisabled {
|
||||
require.True(t, apierrors.IsUnauthorized(errReadyz), errReadyz)
|
||||
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(readyzBody))
|
||||
} else {
|
||||
require.NoError(t, errReadyz)
|
||||
require.Equal(t, "ok", string(readyzBody))
|
||||
}
|
||||
|
||||
// We don't treat sub-paths of health check endpoints as health check endpoints. Treat sub-paths as "other" endpoints.
|
||||
readyzEtcdBody, errReadyzEtcd := rc.Get().AbsPath("/readyz/etcd").DoRaw(ctx)
|
||||
if tt.anonymousAuthForOtherAPIsDisabled {
|
||||
require.True(t, apierrors.IsUnauthorized(errReadyzEtcd), errReadyzEtcd)
|
||||
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(readyzEtcdBody))
|
||||
} else {
|
||||
require.NoError(t, errReadyzEtcd)
|
||||
require.Equal(t, "ok", string(readyzEtcdBody))
|
||||
}
|
||||
|
||||
livezBody, errLivez := rc.Get().AbsPath("/livez").DoRaw(ctx)
|
||||
if tt.anonymousAuthForHealthDisabled {
|
||||
require.True(t, apierrors.IsUnauthorized(errLivez), errLivez)
|
||||
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(livezBody))
|
||||
} else {
|
||||
require.NoError(t, errLivez)
|
||||
require.Equal(t, "ok", string(livezBody))
|
||||
}
|
||||
|
||||
probeBody, errProbe := rc.Get().AbsPath("/probe").DoRaw(ctx)
|
||||
if tt.anonymousAuthDisabled {
|
||||
if tt.anonymousAuthForOtherAPIsDisabled {
|
||||
require.True(t, apierrors.IsUnauthorized(errProbe), errProbe)
|
||||
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(probeBody))
|
||||
} else {
|
||||
@@ -1151,8 +1313,9 @@ func TestImpersonator(t *testing.T) {
|
||||
require.Equal(t, "probed", string(probeBody))
|
||||
}
|
||||
|
||||
// Fetch other resource that just happens to also be called tokencredentialrequests, but belongs to a different API group/version.
|
||||
notTCRBody, errNotTCR := rc.Get().Resource("tokencredentialrequests").DoRaw(ctx)
|
||||
if tt.anonymousAuthDisabled {
|
||||
if tt.anonymousAuthForOtherAPIsDisabled {
|
||||
require.True(t, apierrors.IsUnauthorized(errNotTCR), errNotTCR)
|
||||
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(notTCRBody))
|
||||
} else {
|
||||
@@ -1161,7 +1324,7 @@ func TestImpersonator(t *testing.T) {
|
||||
}
|
||||
|
||||
ducksBody, errDucks := rc.Get().Resource("ducks").DoRaw(ctx)
|
||||
if tt.anonymousAuthDisabled {
|
||||
if tt.anonymousAuthForOtherAPIsDisabled {
|
||||
require.True(t, apierrors.IsUnauthorized(errDucks), errDucks)
|
||||
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(ducksBody))
|
||||
} else {
|
||||
@@ -1194,8 +1357,24 @@ func TestImpersonator(t *testing.T) {
|
||||
Verb: "create", Namespace: "", APIGroup: "login.concierge.walrus.tld", APIVersion: "v1alpha1", Resource: "tokencredentialrequests", Subresource: "", Name: "", ResourceRequest: true, Path: "/apis/login.concierge.walrus.tld/v1alpha1/tokencredentialrequests",
|
||||
},
|
||||
)
|
||||
if !tt.anonymousAuthDisabled {
|
||||
if !tt.anonymousAuthForHealthDisabled {
|
||||
wantAuthorizerAttributes = append(wantAuthorizerAttributes,
|
||||
authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{Name: "system:anonymous", UID: "", Groups: []string{"system:unauthenticated"}, Extra: nil},
|
||||
Verb: "get", Namespace: "", APIGroup: "", APIVersion: "", Resource: "", Subresource: "", Name: "", ResourceRequest: false, Path: "/readyz",
|
||||
},
|
||||
authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{Name: "system:anonymous", UID: "", Groups: []string{"system:unauthenticated"}, Extra: nil},
|
||||
Verb: "get", Namespace: "", APIGroup: "", APIVersion: "", Resource: "", Subresource: "", Name: "", ResourceRequest: false, Path: "/livez",
|
||||
},
|
||||
)
|
||||
}
|
||||
if !tt.anonymousAuthForOtherAPIsDisabled {
|
||||
wantAuthorizerAttributes = append(wantAuthorizerAttributes,
|
||||
authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{Name: "system:anonymous", UID: "", Groups: []string{"system:unauthenticated"}, Extra: nil},
|
||||
Verb: "get", Namespace: "", APIGroup: "", APIVersion: "", Resource: "", Subresource: "", Name: "", ResourceRequest: false, Path: "/readyz/etcd",
|
||||
},
|
||||
authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{Name: "system:anonymous", UID: "", Groups: []string{"system:unauthenticated"}, Extra: nil},
|
||||
Verb: "get", Namespace: "", APIGroup: "", APIVersion: "", Resource: "", Subresource: "", Name: "", ResourceRequest: false, Path: "/probe",
|
||||
@@ -2262,3 +2441,77 @@ func (r *attributeRecorder) record(attributes authorizer.Attributes) {
|
||||
defer r.lock.Unlock()
|
||||
r.attributes = append(r.attributes, *attributes.(*authorizer.AttributesRecord))
|
||||
}
|
||||
|
||||
func Test_isRequestForHealthCheck(t *testing.T) {
|
||||
tests := []struct {
|
||||
path string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
path: "/healthz",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
path: "/livez",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
path: "/readyz",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
path: "/healthz/anything",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
path: "/livez/anything",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
path: "/readyz/anything",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
path: "/readyz/anything/",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
path: "/healthz/",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
path: "/livez/",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
path: "/readyz/",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
path: "/other",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
path: "/something/else",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.path, func(t *testing.T) {
|
||||
u := url.URL{Path: tt.path}
|
||||
got := isRequestForHealthCheck(&http.Request{URL: &u})
|
||||
require.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("nil req", func(t *testing.T) {
|
||||
got := isRequestForHealthCheck(nil)
|
||||
require.False(t, got)
|
||||
})
|
||||
|
||||
t.Run("nil URL", func(t *testing.T) {
|
||||
got := isRequestForHealthCheck(&http.Request{})
|
||||
require.False(t, got)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package jwtcachefiller implements a controller for filling an authncache.Cache with each
|
||||
@@ -305,7 +305,7 @@ func (c *jwtCacheFillerController) doExpensiveValidations(
|
||||
okSoFar bool,
|
||||
) (*cachedJWTAuthenticator, []*metav1.Condition, []error) {
|
||||
var conditions []*metav1.Condition
|
||||
var errs []error
|
||||
errs := make([]error, 0, 4)
|
||||
|
||||
client := phttp.Default(caBundle.CertPool())
|
||||
client.Timeout = 30 * time.Second // copied from Kube OIDC code
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package webhookcachefiller implements a controller for filling an authncache.Cache with each added/updated WebhookAuthenticator.
|
||||
@@ -256,7 +256,7 @@ func (c *webhookCacheFillerController) doExpensiveValidations(
|
||||
) (*cachedWebhookAuthenticator, []*metav1.Condition, []error) {
|
||||
var newWebhookAuthenticatorForCache *cachedWebhookAuthenticator
|
||||
var conditions []*metav1.Condition
|
||||
var errs []error
|
||||
errs := make([]error, 0, 2)
|
||||
|
||||
conditions, tlsNegotiateErr := c.validateConnection(ctx, caBundle.CertPool(), endpointHostPort, conditions, okSoFar, usingProxyForHost, logger)
|
||||
errs = append(errs, tlsNegotiateErr)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package supervisorconfig
|
||||
@@ -682,7 +682,7 @@ func appendIdentityProvidersFoundCondition(
|
||||
conditions []*metav1.Condition,
|
||||
) []*metav1.Condition {
|
||||
if len(idpNotFoundIndices) != 0 {
|
||||
messages := []string{}
|
||||
messages := make([]string, 0, len(idpNotFoundIndices))
|
||||
for _, idpNotFoundIndex := range idpNotFoundIndices {
|
||||
messages = append(messages, fmt.Sprintf("cannot find resource specified by .spec.identityProviders[%d].objectRef (with name %q)",
|
||||
idpNotFoundIndex, federationDomainIdentityProviders[idpNotFoundIndex].ObjectRef.Name))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package supervisorconfig
|
||||
@@ -2182,7 +2182,7 @@ func makeFederationDomainIdentityProviderComparable(fdi *federationdomainprovide
|
||||
}
|
||||
|
||||
func convertToComparableType(fdis []*federationdomainproviders.FederationDomainIssuer) []*comparableFederationDomainIssuer {
|
||||
result := []*comparableFederationDomainIssuer{}
|
||||
result := make([]*comparableFederationDomainIssuer, 0, len(fdis))
|
||||
for _, fdi := range fdis {
|
||||
identityProviders := fdi.IdentityProviders()
|
||||
comparableFDIs := make([]*comparableFederationDomainIdentityProvider, len(identityProviders))
|
||||
@@ -2217,7 +2217,7 @@ func expectedFederationDomainStatusUpdate(
|
||||
}
|
||||
|
||||
func getFederationDomainStatusUpdates(t *testing.T, actions []coretesting.Action) []*supervisorconfigv1alpha1.FederationDomain {
|
||||
federationDomains := []*supervisorconfigv1alpha1.FederationDomain{}
|
||||
federationDomains := make([]*supervisorconfigv1alpha1.FederationDomain, 0, len(actions))
|
||||
|
||||
for _, action := range actions {
|
||||
updateAction, ok := action.(coretesting.UpdateAction)
|
||||
@@ -2320,7 +2320,7 @@ func TestTransformationPipelinesCanBeTestedForEqualityUsingSourceToMakeTestingEa
|
||||
equalPipeline := idtransform.NewTransformationPipeline()
|
||||
differentPipeline1 := idtransform.NewTransformationPipeline()
|
||||
differentPipeline2 := idtransform.NewTransformationPipeline()
|
||||
expectedSourceList := []any{}
|
||||
expectedSourceList := make([]any, 0, len(transforms))
|
||||
|
||||
for i, transform := range transforms {
|
||||
// Compile and append to a pipeline.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package githubupstreamwatcher implements a controller which watches GitHubIdentityProviders.
|
||||
@@ -310,7 +310,7 @@ func (c *gitHubWatcherController) validateUpstreamAndUpdateConditions(ctx contex
|
||||
*upstreamgithub.Provider, // If validated, returns the config
|
||||
error, // This error will only refer to programmatic errors such as inability to perform a connection probe or dereference a pointer, not configuration errors
|
||||
) {
|
||||
conditions := make([]*metav1.Condition, 0)
|
||||
conditions := make([]*metav1.Condition, 0, 6)
|
||||
applicationErrors := make([]error, 0)
|
||||
|
||||
clientSecretCondition, clientID, clientSecret, clientSecretErr := c.validateClientSecret(upstream.Spec.Client.SecretName)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2024-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package ptls
|
||||
@@ -74,7 +74,7 @@ func TestSetAllowedCiphersForTLSOneDotTwo(t *testing.T) {
|
||||
err := SetUserConfiguredAllowedCipherSuitesForTLSOneDotTwo(userConfiguredAllowedCipherSuites)
|
||||
require.NoError(t, err)
|
||||
stored := getUserConfiguredAllowedCipherSuitesForTLSOneDotTwo()
|
||||
var storedNames []string
|
||||
storedNames := make([]string, 0, len(stored))
|
||||
for _, suite := range stored {
|
||||
storedNames = append(storedNames, suite.Name)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package token
|
||||
@@ -5980,7 +5980,7 @@ func deepCopyRequestForm(r *http.Request) *http.Request {
|
||||
}
|
||||
|
||||
func getMapKeys(m map[string]any) []string {
|
||||
keys := make([]string, 0)
|
||||
keys := make([]string, 0, len(m))
|
||||
for key := range m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package endpointsmanager
|
||||
@@ -110,7 +110,7 @@ func TestManager(t *testing.T) {
|
||||
expectedFlowsJSON, err := json.Marshal(expectedFlows)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedIDPJSONList := []string{}
|
||||
expectedIDPJSONList := make([]string, 0, len(expectedIDPNames))
|
||||
for i := range expectedIDPNames {
|
||||
expectedIDPJSONList = append(expectedIDPJSONList, fmt.Sprintf(`{"name":"%s","type":"%s","flows":%s}`,
|
||||
expectedIDPNames[i], expectedIDPTypes, expectedFlowsJSON))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2023-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2023-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package federationdomainproviders
|
||||
@@ -74,7 +74,7 @@ func NewFederationDomainIdentityProvidersListerFinder(
|
||||
wrappedLister idplister.UpstreamIdentityProvidersLister,
|
||||
) *FederationDomainIdentityProvidersListerFinder {
|
||||
// Create a copy of the input slice so we won't need to worry about the caller accidentally changing it.
|
||||
copyOfFederationDomainIdentityProviders := []*FederationDomainIdentityProvider{}
|
||||
copyOfFederationDomainIdentityProviders := make([]*FederationDomainIdentityProvider, 0, len(federationDomainIssuer.IdentityProviders()))
|
||||
// Create a map and a set for quick lookups of the same data that was passed in via the
|
||||
// federationDomainIssuer parameter.
|
||||
allowedResourceUIDs := sets.New[types.UID]()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2024-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package resolvedoidc
|
||||
@@ -106,11 +106,12 @@ func (p *FederationDomainResolvedOIDCIdentityProvider) UpstreamAuthorizeRedirect
|
||||
Scopes: p.Provider.GetScopes(),
|
||||
}
|
||||
|
||||
authCodeOptions := []oauth2.AuthCodeOption{
|
||||
authCodeOptions := make([]oauth2.AuthCodeOption, 0, 3+len(p.Provider.GetAdditionalAuthcodeParams()))
|
||||
authCodeOptions = append(authCodeOptions,
|
||||
state.Nonce.Param(),
|
||||
state.PKCE.Challenge(),
|
||||
state.PKCE.Method(),
|
||||
}
|
||||
)
|
||||
|
||||
for key, val := range p.Provider.GetAdditionalAuthcodeParams() {
|
||||
authCodeOptions = append(authCodeOptions, oauth2.SetAuthURLParam(key, val))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2024-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package githubclient
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-github/v76/github"
|
||||
"github.com/google/go-github/v83/github"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
"go.pinniped.dev/internal/plog"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2024-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package githubclient
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v76/github"
|
||||
"github.com/google/go-github/v83/github"
|
||||
"github.com/migueleliasweb/go-github-mock/src/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/client-go/util/cert"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package groupsuffix
|
||||
@@ -178,7 +178,7 @@ func Unreplace(baseAPIGroup, apiGroupSuffix string) (string, bool) {
|
||||
// makes sure that the provided apiGroupSuffix is a valid DNS-1123 subdomain with at least one dot,
|
||||
// to match Kubernetes behavior.
|
||||
func Validate(apiGroupSuffix string) error {
|
||||
var errs []error //nolint:prealloc
|
||||
var errs []error
|
||||
|
||||
if len(strings.Split(apiGroupSuffix, ".")) < 2 {
|
||||
errs = append(errs, constable.Error("must contain '.'"))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2023-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2023-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package idtransform defines upstream-to-downstream identity transformations which could be
|
||||
@@ -90,7 +90,7 @@ func (p *TransformationPipeline) Evaluate(ctx context.Context, username string,
|
||||
}
|
||||
|
||||
func (p *TransformationPipeline) Source() []any {
|
||||
result := []any{}
|
||||
result := make([]any, 0, len(p.transforms))
|
||||
for _, transform := range p.transforms {
|
||||
result = append(result, transform.Source())
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2023-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2023-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package idtransform
|
||||
@@ -44,7 +44,7 @@ func (a fakeNilGroupTransformer) Source() any {
|
||||
type fakeAppendStringTransformer struct{}
|
||||
|
||||
func (a fakeAppendStringTransformer) Evaluate(_ctx context.Context, username string, groups []string) (*TransformationResult, error) {
|
||||
newGroups := []string{}
|
||||
newGroups := make([]string, 0, len(groups))
|
||||
for _, group := range groups {
|
||||
newGroups = append(newGroups, group+":transformed")
|
||||
}
|
||||
@@ -78,7 +78,7 @@ func (a fakeDeleteUsernameAndGroupsTransformer) Source() any {
|
||||
type fakeAuthenticationDisallowedTransformer struct{}
|
||||
|
||||
func (a fakeAuthenticationDisallowedTransformer) Evaluate(_ctx context.Context, username string, groups []string) (*TransformationResult, error) {
|
||||
newGroups := []string{}
|
||||
newGroups := make([]string, 0, len(groups))
|
||||
for _, group := range groups {
|
||||
newGroups = append(newGroups, group+":disallowed")
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package apiserver
|
||||
@@ -80,7 +80,7 @@ func (c completedConfig) New() (*PinnipedServer, error) {
|
||||
GenericAPIServer: genericServer,
|
||||
}
|
||||
|
||||
var errs []error //nolint:prealloc
|
||||
var errs []error
|
||||
for _, f := range []func() (schema.GroupVersionResource, rest.Storage){
|
||||
func() (schema.GroupVersionResource, rest.Storage) {
|
||||
clientSecretReqGVR := c.ExtraConfig.ClientSecretSupervisorGroupVersion.WithResource("oidcclientsecretrequests")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2021-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*
|
||||
@@ -113,7 +113,7 @@ func decodeObj(r *http.Request) (runtime.Object, error) {
|
||||
}
|
||||
|
||||
var obj runtime.Object
|
||||
var errs []error //nolint:prealloc
|
||||
var errs []error
|
||||
codecsThatWeUseInOurCode := []runtime.NegotiatedSerializer{
|
||||
kubescheme.Codecs,
|
||||
aggregatorclientscheme.Codecs,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package testutil
|
||||
@@ -36,8 +36,9 @@ const (
|
||||
|
||||
// allDynamicClientScopes returns a slice of all scopes that are supported by the Supervisor for dynamic clients.
|
||||
func allDynamicClientScopes() []supervisorconfigv1alpha1.Scope {
|
||||
scopes := []supervisorconfigv1alpha1.Scope{}
|
||||
for _, s := range strings.Split(AllDynamicClientScopesSpaceSep, " ") {
|
||||
splitOnSpace := strings.Split(AllDynamicClientScopesSpaceSep, " ")
|
||||
scopes := make([]supervisorconfigv1alpha1.Scope, 0, len(splitOnSpace))
|
||||
for _, s := range splitOnSpace {
|
||||
scopes = append(scopes, supervisorconfigv1alpha1.Scope(s))
|
||||
}
|
||||
return scopes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package oidcclient implements a CLI OIDC login flow.
|
||||
@@ -646,7 +646,7 @@ func (h *handlerState) maybePerformPinnipedSupervisorValidations() (idpdiscovery
|
||||
|
||||
if !slices.Contains(supportedIDPTypes, h.upstreamIdentityProviderType) {
|
||||
convertIDPListToQuotedStringList := func() []string {
|
||||
var temp []string
|
||||
temp := make([]string, 0, len(supportedIDPTypes))
|
||||
for _, idpType := range supportedIDPTypes {
|
||||
temp = append(temp, fmt.Sprintf("%q", idpType))
|
||||
}
|
||||
@@ -706,7 +706,7 @@ func (h *handlerState) maybePerformPinnipedSupervisorValidations() (idpdiscovery
|
||||
loginFlow = foundIDP.Flows[0]
|
||||
}
|
||||
|
||||
var authorizeOptions []oauth2.AuthCodeOption
|
||||
authorizeOptions := make([]oauth2.AuthCodeOption, 0, 2)
|
||||
|
||||
authorizeOptions = append(authorizeOptions,
|
||||
oauth2.SetAuthURLParam(oidcapi.AuthorizeUpstreamIDPNameParamName, h.upstreamIdentityProviderName),
|
||||
|
||||
@@ -7,8 +7,8 @@ params:
|
||||
github_url: "https://github.com/vmware/pinniped"
|
||||
slack_url: "https://go.pinniped.dev/community/slack"
|
||||
community_url: "https://go.pinniped.dev/community"
|
||||
latest_version: v0.42.0
|
||||
latest_codegen_version: 1.33
|
||||
latest_version: v0.44.0
|
||||
latest_codegen_version: 1.35
|
||||
pygmentsCodefences: true
|
||||
pygmentsStyle: "pygments"
|
||||
markup:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2021-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# The name of the cluster type.
|
||||
@@ -13,9 +13,13 @@ capabilities:
|
||||
# Will the cluster successfully provision a load balancer if requested?
|
||||
hasExternalLoadBalancerProvider: true
|
||||
|
||||
# Does the cluster allow requests without authentication?
|
||||
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
|
||||
anonymousAuthenticationSupported: false
|
||||
|
||||
# Are LDAP ports on the Internet reachable without interference from network firewalls or proxies?
|
||||
canReachInternetLDAPPorts: true
|
||||
|
||||
# Does the cluster allow requests without authentication?
|
||||
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
|
||||
anonymousAuthentication:
|
||||
healthEndpoints:
|
||||
allowed: false
|
||||
otherEndpoints:
|
||||
allowed: false
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2021-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# The name of the cluster type.
|
||||
@@ -13,9 +13,14 @@ capabilities:
|
||||
# Will the cluster successfully provision a load balancer if requested?
|
||||
hasExternalLoadBalancerProvider: true
|
||||
|
||||
# Does the cluster allow requests without authentication?
|
||||
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
|
||||
anonymousAuthenticationSupported: true
|
||||
|
||||
# Are LDAP ports on the Internet reachable without interference from network firewalls or proxies?
|
||||
canReachInternetLDAPPorts: true
|
||||
|
||||
# Does the cluster allow requests without authentication?
|
||||
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
|
||||
# Amazon disabled anonymous authentication in EKS clusters starting with k8s 1.32.
|
||||
anonymousAuthentication:
|
||||
healthEndpoints:
|
||||
allowed: true
|
||||
otherEndpoints:
|
||||
allowedIfK8sMinorVersionLessThan: 32
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# The name of the cluster type.
|
||||
@@ -13,9 +13,14 @@ capabilities:
|
||||
# Will the cluster successfully provision a load balancer if requested?
|
||||
hasExternalLoadBalancerProvider: true
|
||||
|
||||
# Does the cluster allow requests without authentication?
|
||||
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
|
||||
anonymousAuthenticationSupported: true
|
||||
|
||||
# Are LDAP ports on the Internet reachable without interference from network firewalls or proxies?
|
||||
canReachInternetLDAPPorts: true
|
||||
|
||||
# Does the cluster allow requests without authentication?
|
||||
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
|
||||
# Google disabled anonymous authentication in GKE clusters by default starting with k8s 1.35.
|
||||
anonymousAuthentication:
|
||||
healthEndpoints:
|
||||
allowed: true
|
||||
otherEndpoints:
|
||||
allowedIfK8sMinorVersionLessThan: 35
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# The name of the cluster type.
|
||||
@@ -13,9 +13,13 @@ capabilities:
|
||||
# Will the cluster successfully provision a load balancer if requested?
|
||||
hasExternalLoadBalancerProvider: false
|
||||
|
||||
# Does the cluster allow requests without authentication?
|
||||
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
|
||||
anonymousAuthenticationSupported: true
|
||||
|
||||
# Are LDAP ports on the Internet reachable without interference from network firewalls or proxies?
|
||||
canReachInternetLDAPPorts: true
|
||||
|
||||
# Does the cluster allow requests without authentication?
|
||||
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
|
||||
anonymousAuthentication:
|
||||
healthEndpoints:
|
||||
allowed: true
|
||||
otherEndpoints:
|
||||
allowed: true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# The name of the cluster type.
|
||||
@@ -13,9 +13,13 @@ capabilities:
|
||||
# Will the cluster successfully provision a load balancer if requested?
|
||||
hasExternalLoadBalancerProvider: true
|
||||
|
||||
# Does the cluster allow requests without authentication?
|
||||
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
|
||||
anonymousAuthenticationSupported: true
|
||||
|
||||
# Are LDAP ports on the Internet reachable without interference from network firewalls or proxies?
|
||||
canReachInternetLDAPPorts: true
|
||||
|
||||
# Does the cluster allow requests without authentication?
|
||||
# https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests
|
||||
anonymousAuthentication:
|
||||
healthEndpoints:
|
||||
allowed: true
|
||||
otherEndpoints:
|
||||
allowed: true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package integration
|
||||
@@ -218,7 +218,7 @@ func TestCredentialRequest_Browser(t *testing.T) {
|
||||
// for its localhost listener via --listen-port=env.CLIUpstreamOIDC.CallbackURL.Port() per oidcLoginCommand.
|
||||
// Since ports are global to the process, tests using oidcLoginCommand must be run serially.
|
||||
func TestCredentialRequest_JWTAuthenticatorRulesToDisallowLogin_Browser(t *testing.T) {
|
||||
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported)
|
||||
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
|
||||
|
||||
basicSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: env.CLIUpstreamOIDC.Issuer,
|
||||
@@ -321,7 +321,7 @@ func TestCredentialRequest_JWTAuthenticatorRulesToDisallowLogin_Browser(t *testi
|
||||
|
||||
// TCRs are non-mutating and safe to run in parallel with serial tests, see main_test.go.
|
||||
func TestCredentialRequest_ShouldFailWhenTheAuthenticatorDoesNotExist_Parallel(t *testing.T) {
|
||||
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported)
|
||||
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
t.Cleanup(cancel)
|
||||
@@ -344,7 +344,7 @@ func TestCredentialRequest_ShouldFailWhenTheAuthenticatorDoesNotExist_Parallel(t
|
||||
|
||||
// TCRs are non-mutating and safe to run in parallel with serial tests, see main_test.go.
|
||||
func TestCredentialRequest_ShouldFailWhenTheRequestIsValidButTheTokenDoesNotAuthenticateTheUser_Parallel(t *testing.T) {
|
||||
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported)
|
||||
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
|
||||
|
||||
// Create a testWebhook so we have a legitimate authenticator to pass to the TokenCredentialRequest API.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
@@ -365,7 +365,7 @@ func TestCredentialRequest_ShouldFailWhenTheRequestIsValidButTheTokenDoesNotAuth
|
||||
|
||||
// TCRs are non-mutating and safe to run in parallel with serial tests, see main_test.go.
|
||||
func TestCredentialRequest_ShouldFailWhenRequestDoesNotIncludeToken_Parallel(t *testing.T) {
|
||||
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported)
|
||||
env := testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
|
||||
|
||||
// Create a testWebhook so we have a legitimate authenticator to pass to the TokenCredentialRequest API.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package integration
|
||||
@@ -902,8 +902,8 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
|
||||
whoAmI, err = impersonationProxyAnonymousPinnipedConciergeClient.IdentityV1alpha1().WhoAmIRequests().
|
||||
Create(ctx, &identityv1alpha1.WhoAmIRequest{}, metav1.CreateOptions{})
|
||||
|
||||
// we expect the impersonation proxy to match the behavior of KAS in regards to anonymous requests
|
||||
if env.HasCapability(testlib.AnonymousAuthenticationSupported) {
|
||||
// we expect the impersonation proxy to match the behavior of KAS in regard to anonymous requests
|
||||
if env.HasCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints) {
|
||||
require.NoError(t, err, testlib.Sdump(err))
|
||||
require.Equal(t,
|
||||
expectedWhoAmIRequestResponse(
|
||||
@@ -1409,8 +1409,8 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("anonymous authentication enabled", func(t *testing.T) {
|
||||
testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported)
|
||||
t.Run("anonymous authentication enabled for health checks", func(t *testing.T) {
|
||||
testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForHealthEndpoints)
|
||||
parallelIfNotEKS(t)
|
||||
|
||||
// anonymous auth enabled
|
||||
@@ -1421,11 +1421,50 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
|
||||
t.Run("non-resource request", func(t *testing.T) {
|
||||
parallelIfNotEKS(t)
|
||||
|
||||
healthz, errHealth := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx)
|
||||
require.NoError(t, errHealth, testlib.Sdump(errHealth))
|
||||
require.Equal(t, "ok", string(healthz))
|
||||
})
|
||||
response, err := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx)
|
||||
require.NoError(t, err, testlib.Sdump(err))
|
||||
require.Equal(t, "ok", string(response))
|
||||
|
||||
response, err = impersonationProxyAnonymousRestClient.Get().AbsPath("/readyz").DoRaw(ctx)
|
||||
require.NoError(t, err, testlib.Sdump(err))
|
||||
require.Equal(t, "ok", string(response))
|
||||
|
||||
response, err = impersonationProxyAnonymousRestClient.Get().AbsPath("/livez").DoRaw(ctx)
|
||||
require.NoError(t, err, testlib.Sdump(err))
|
||||
require.Equal(t, "ok", string(response))
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("anonymous authentication disabled for health checks", func(t *testing.T) {
|
||||
testlib.IntegrationEnv(t).WithoutCapability(testlib.AnonymousAuthenticationSupportedForHealthEndpoints)
|
||||
parallelIfNotEKS(t)
|
||||
|
||||
// anonymous auth disabled
|
||||
// - hit the healthz endpoint (non-resource endpoint)
|
||||
// - through the impersonation proxy
|
||||
// - should fail Unauthorized
|
||||
t.Run("non-resource request", func(t *testing.T) {
|
||||
parallelIfNotEKS(t)
|
||||
|
||||
expectedResponse := `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}` + "\n"
|
||||
|
||||
response, err := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx)
|
||||
require.True(t, apierrors.IsUnauthorized(err), testlib.Sdump(err))
|
||||
require.Equal(t, expectedResponse, string(response))
|
||||
|
||||
response, err = impersonationProxyAnonymousRestClient.Get().AbsPath("/readyz").DoRaw(ctx)
|
||||
require.True(t, apierrors.IsUnauthorized(err), testlib.Sdump(err))
|
||||
require.Equal(t, expectedResponse, string(response))
|
||||
|
||||
response, err = impersonationProxyAnonymousRestClient.Get().AbsPath("/livez").DoRaw(ctx)
|
||||
require.True(t, apierrors.IsUnauthorized(err), testlib.Sdump(err))
|
||||
require.Equal(t, expectedResponse, string(response))
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("anonymous authentication enabled for other endpoints", func(t *testing.T) {
|
||||
testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
|
||||
parallelIfNotEKS(t)
|
||||
// - hit the pods endpoint (a resource endpoint)
|
||||
// - through the impersonation proxy
|
||||
// - should fail forbidden
|
||||
@@ -1462,22 +1501,10 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("anonymous authentication disabled", func(t *testing.T) {
|
||||
testlib.IntegrationEnv(t).WithoutCapability(testlib.AnonymousAuthenticationSupported)
|
||||
t.Run("anonymous authentication disabled for other endpoints", func(t *testing.T) {
|
||||
testlib.IntegrationEnv(t).WithoutCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
|
||||
parallelIfNotEKS(t)
|
||||
|
||||
// - hit the healthz endpoint (non-resource endpoint)
|
||||
// - through the impersonation proxy
|
||||
// - should fail unauthorized
|
||||
// - kube api server should reject it
|
||||
t.Run("non-resource request", func(t *testing.T) {
|
||||
parallelIfNotEKS(t)
|
||||
|
||||
healthz, err := impersonationProxyAnonymousRestClient.Get().AbsPath("/healthz").DoRaw(ctx)
|
||||
require.True(t, apierrors.IsUnauthorized(err), testlib.Sdump(err))
|
||||
require.Equal(t, `{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}`+"\n", string(healthz))
|
||||
})
|
||||
|
||||
// - hit the pods endpoint (a resource endpoint)
|
||||
// - through the impersonation proxy
|
||||
// - should fail unauthorized
|
||||
@@ -1491,7 +1518,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
|
||||
require.Equal(t, &corev1.Pod{}, pod)
|
||||
})
|
||||
|
||||
// - request to whoami (pinniped resource endpoing)
|
||||
// - request to whoami (pinniped resource endpoint)
|
||||
// - through the impersonation proxy
|
||||
// - should fail unauthorized
|
||||
// - kube api server should reject it
|
||||
@@ -1696,7 +1723,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
|
||||
}
|
||||
|
||||
expectedAnnotations := func(credentialIssuerSpecAnnotations map[string]string, otherAnnotations map[string]string) map[string]string {
|
||||
credentialIssuerSpecAnnotationKeys := []string{}
|
||||
credentialIssuerSpecAnnotationKeys := make([]string, 0, len(credentialIssuerSpecAnnotations))
|
||||
expectedAnnotations := map[string]string{}
|
||||
// Expect the annotations specified on the CredentialIssuer spec to be present.
|
||||
for k, v := range credentialIssuerSpecAnnotations {
|
||||
@@ -1982,7 +2009,7 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
|
||||
// include an unsuccessful impersonation strategy saying that it was manually configured to be disabled.
|
||||
requireDisabledStrategy(ctx, t, env, adminConciergeClient)
|
||||
|
||||
if !env.HasCapability(testlib.ClusterSigningKeyIsAvailable) && env.HasCapability(testlib.AnonymousAuthenticationSupported) {
|
||||
if !env.HasCapability(testlib.ClusterSigningKeyIsAvailable) && env.HasCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints) {
|
||||
// This cluster does not support the cluster signing key strategy, so now that we've manually disabled the
|
||||
// impersonation strategy, we should be left with no working strategies.
|
||||
// Given that there are no working strategies, a TokenCredentialRequest which would otherwise work should now
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
package integration
|
||||
|
||||
@@ -394,7 +394,7 @@ func maybeNeedsExtraWithSHA256(
|
||||
|
||||
// whoami requests are non-mutating and safe to run in parallel with serial tests, see main_test.go.
|
||||
func TestWhoAmI_Anonymous_Parallel(t *testing.T) {
|
||||
_ = testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupported)
|
||||
_ = testlib.IntegrationEnv(t).WithCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package integration
|
||||
@@ -346,7 +346,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
||||
regexp.QuoteMeta("&sub=") + ".+" +
|
||||
"$"
|
||||
|
||||
tests := []*supervisorLoginTestcase{
|
||||
tests := []*supervisorLoginTestcase{ //nolint:prealloc
|
||||
{
|
||||
name: "oidc with default username and groups claim settings",
|
||||
maybeSkip: skipNever,
|
||||
@@ -2829,7 +2829,7 @@ func supervisorLoginGithubTestcases(
|
||||
|
||||
func wantGroupsInAdditionalClaimsIfGroupsExist(additionalClaims map[string]any, wantGroupsAdditionalClaimName string, wantGroups []string) map[string]any {
|
||||
if len(wantGroups) > 0 {
|
||||
var wantGroupsAnyType []any
|
||||
wantGroupsAnyType := make([]any, 0, len(wantGroups))
|
||||
for _, group := range wantGroups {
|
||||
wantGroupsAnyType = append(wantGroupsAnyType, group)
|
||||
}
|
||||
@@ -2909,7 +2909,7 @@ func conditionsSummaryFromActualConditions(
|
||||
caBundleConfigured bool,
|
||||
expectedLDAPConnectionValidMessage string,
|
||||
) [][]string {
|
||||
conditionsSummary := [][]string{}
|
||||
conditionsSummary := make([][]string, 0, len(conditions))
|
||||
for _, condition := range conditions {
|
||||
conditionsSummary = append(conditionsSummary, []string{condition.Type, string(condition.Status), condition.Reason})
|
||||
t.Logf("Saw identity provider with Status.Condition Type=%s Status=%s Reason=%s Message=%s",
|
||||
@@ -3351,7 +3351,7 @@ func verifyTokenResponse(
|
||||
idTokenClaims := map[string]any{}
|
||||
err = idToken.Claims(&idTokenClaims)
|
||||
require.NoError(t, err)
|
||||
idTokenClaimNames := []string{}
|
||||
idTokenClaimNames := make([]string, 0, len(idTokenClaims))
|
||||
for k := range idTokenClaims {
|
||||
idTokenClaimNames = append(idTokenClaimNames, k)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package integration
|
||||
@@ -1040,11 +1040,11 @@ func TestOIDCClientSecretRequestUnauthenticated_Parallel(t *testing.T) {
|
||||
}, metav1.CreateOptions{})
|
||||
require.Error(t, err)
|
||||
|
||||
if env.KubernetesDistribution == testlib.AKSDistro {
|
||||
// On AKS the error just says "Unauthorized".
|
||||
require.Contains(t, err.Error(), "Unauthorized")
|
||||
} else {
|
||||
if env.HasCapability(testlib.AnonymousAuthenticationSupportedForOtherEndpoints) {
|
||||
// Clusters which allow anonymous auth will give a more detailed error.
|
||||
require.Contains(t, err.Error(), `User "system:anonymous" cannot create resource "oidcclientsecretrequests"`)
|
||||
} else {
|
||||
// On AKS and any other cluster which disallows anonymous auth, the error just says "Unauthorized".
|
||||
require.Contains(t, err.Error(), "Unauthorized")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package testlib
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
@@ -17,16 +18,18 @@ import (
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
|
||||
"go.pinniped.dev/internal/testutil"
|
||||
)
|
||||
|
||||
type Capability string
|
||||
type KubeDistro string
|
||||
|
||||
const (
|
||||
ClusterSigningKeyIsAvailable Capability = "clusterSigningKeyIsAvailable"
|
||||
AnonymousAuthenticationSupported Capability = "anonymousAuthenticationSupported"
|
||||
HasExternalLoadBalancerProvider Capability = "hasExternalLoadBalancerProvider"
|
||||
CanReachInternetLDAPPorts Capability = "canReachInternetLDAPPorts"
|
||||
ClusterSigningKeyIsAvailable Capability = "clusterSigningKeyIsAvailable"
|
||||
HasExternalLoadBalancerProvider Capability = "hasExternalLoadBalancerProvider"
|
||||
CanReachInternetLDAPPorts Capability = "canReachInternetLDAPPorts"
|
||||
AnonymousAuthenticationSupportedForHealthEndpoints Capability = "anonymousAuthenticationSupportedForHealthEndpoints"
|
||||
AnonymousAuthenticationSupportedForOtherEndpoints Capability = "anonymousAuthenticationSupportedForOtherEndpoints"
|
||||
|
||||
KindDistro KubeDistro = "Kind"
|
||||
GKEDistro KubeDistro = "GKE"
|
||||
@@ -35,6 +38,24 @@ const (
|
||||
TKGSDistro KubeDistro = "TKGS"
|
||||
)
|
||||
|
||||
type Capabilities struct {
|
||||
ClusterSigningKeyIsAvailable bool `json:"clusterSigningKeyIsAvailable"`
|
||||
HasExternalLoadBalancerProvider bool `json:"hasExternalLoadBalancerProvider"`
|
||||
CanReachInternetLDAPPorts bool `json:"canReachInternetLDAPPorts"`
|
||||
|
||||
AnonymousAuthentication AnonymousAuthenticationCapabilities `json:"anonymousAuthentication"`
|
||||
}
|
||||
|
||||
type AnonymousAuthenticationCapabilities struct {
|
||||
HealthEndpoints AnonymousAuthenticationEndpointCapability `json:"healthEndpoints"`
|
||||
OtherEndpoints AnonymousAuthenticationEndpointCapability `json:"otherEndpoints"`
|
||||
}
|
||||
|
||||
type AnonymousAuthenticationEndpointCapability struct {
|
||||
Allowed bool `json:"allowed"`
|
||||
AllowedIfK8sMinorVersionLessThan string `json:"allowedIfK8sMinorVersionLessThan"`
|
||||
}
|
||||
|
||||
// TestEnv captures all the external parameters consumed by our integration tests.
|
||||
type TestEnv struct {
|
||||
t *testing.T
|
||||
@@ -50,7 +71,7 @@ type TestEnv struct {
|
||||
SupervisorCustomLabels map[string]string `json:"supervisorCustomLabels"`
|
||||
ConciergeCustomLabels map[string]string `json:"conciergeCustomLabels"`
|
||||
KubernetesDistribution KubeDistro `json:"kubernetesDistribution"`
|
||||
Capabilities map[Capability]bool `json:"capabilities"`
|
||||
Capabilities Capabilities `json:"capabilities"`
|
||||
TestWebhook authenticationv1alpha1.WebhookAuthenticatorSpec `json:"testWebhook"`
|
||||
SupervisorHTTPSAddress string `json:"supervisorHttpsAddress"`
|
||||
SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"`
|
||||
@@ -400,9 +421,34 @@ func loadEnvVars(t *testing.T, result *TestEnv) {
|
||||
|
||||
func (e *TestEnv) HasCapability(cap Capability) bool {
|
||||
e.t.Helper()
|
||||
isCapable, capabilityWasDescribed := e.Capabilities[cap]
|
||||
require.Truef(e.t, capabilityWasDescribed, "the %q capability of the test environment was not described", cap)
|
||||
return isCapable
|
||||
|
||||
switch cap {
|
||||
case AnonymousAuthenticationSupportedForHealthEndpoints:
|
||||
versionLessThan := e.Capabilities.AnonymousAuthentication.HealthEndpoints.AllowedIfK8sMinorVersionLessThan
|
||||
if versionLessThan == "" {
|
||||
return e.Capabilities.AnonymousAuthentication.HealthEndpoints.Allowed
|
||||
}
|
||||
minorVersionNumber, err := strconv.Atoi(versionLessThan)
|
||||
require.NoError(e.t, err, "could not parse minor version number from AnonymousAuthentication HealthEndpoints capability as int")
|
||||
return !testutil.KubeServerMinorVersionAtLeastInclusive(e.t, NewKubernetesClientset(e.t).Discovery(), minorVersionNumber)
|
||||
case AnonymousAuthenticationSupportedForOtherEndpoints:
|
||||
versionLessThan := e.Capabilities.AnonymousAuthentication.OtherEndpoints.AllowedIfK8sMinorVersionLessThan
|
||||
if versionLessThan == "" {
|
||||
return e.Capabilities.AnonymousAuthentication.OtherEndpoints.Allowed
|
||||
}
|
||||
minorVersionNumber, err := strconv.Atoi(versionLessThan)
|
||||
require.NoError(e.t, err, "could not parse minor version number from AnonymousAuthentication OtherEndpoints capability as int")
|
||||
return !testutil.KubeServerMinorVersionAtLeastInclusive(e.t, NewKubernetesClientset(e.t).Discovery(), minorVersionNumber)
|
||||
case ClusterSigningKeyIsAvailable:
|
||||
return e.Capabilities.ClusterSigningKeyIsAvailable
|
||||
case HasExternalLoadBalancerProvider:
|
||||
return e.Capabilities.HasExternalLoadBalancerProvider
|
||||
case CanReachInternetLDAPPorts:
|
||||
return e.Capabilities.CanReachInternetLDAPPorts
|
||||
default:
|
||||
require.Failf(e.t, "unknown capability type", "name: %s", cap)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (e *TestEnv) WithCapability(cap Capability) *TestEnv {
|
||||
|
||||
Reference in New Issue
Block a user