mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-13 21:25:09 +00:00
Update tests to handle RemoteRequestHeaderUID
Signed-off-by: Monis Khan <mok@microsoft.com>
This commit is contained in:
@@ -30,11 +30,14 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/dump"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/apiserver/pkg/authentication/request/headerrequest"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
corev1listers "k8s.io/client-go/listers/core/v1"
|
||||
clienttesting "k8s.io/client-go/testing"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -95,6 +98,7 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
preexistingObjs []runtime.Object
|
||||
expectedConfigMaps map[string]*corev1.ConfigMap
|
||||
expectCreate bool
|
||||
uidGate bool
|
||||
}{
|
||||
{
|
||||
name: "basic",
|
||||
@@ -107,6 +111,32 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
RequestHeaderCA: anotherRandomCAProvider,
|
||||
RequestHeaderAllowedNames: headerrequest.StaticStringSlice{"first", "second"},
|
||||
},
|
||||
expectedConfigMaps: map[string]*corev1.ConfigMap{
|
||||
"extension-apiserver-authentication": {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"client-ca-file": string(someRandomCA),
|
||||
"requestheader-username-headers": `["alfa","bravo","charlie"]`,
|
||||
"requestheader-group-headers": `["delta"]`,
|
||||
"requestheader-extra-headers-prefix": `["echo","foxtrot"]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
"requestheader-allowed-names": `["first","second"]`,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectCreate: true,
|
||||
},
|
||||
{
|
||||
name: "basic with feature gate",
|
||||
clusterAuthInfo: ClusterAuthenticationInfo{
|
||||
ClientCA: someRandomCAProvider,
|
||||
RequestHeaderUsernameHeaders: headerrequest.StaticStringSlice{"alfa", "bravo", "charlie"},
|
||||
RequestHeaderUIDHeaders: headerrequest.StaticStringSlice{"golf", "hotel", "india"},
|
||||
RequestHeaderGroupHeaders: headerrequest.StaticStringSlice{"delta"},
|
||||
RequestHeaderExtraHeaderPrefixes: headerrequest.StaticStringSlice{"echo", "foxtrot"},
|
||||
RequestHeaderCA: anotherRandomCAProvider,
|
||||
RequestHeaderAllowedNames: headerrequest.StaticStringSlice{"first", "second"},
|
||||
},
|
||||
expectedConfigMaps: map[string]*corev1.ConfigMap{
|
||||
"extension-apiserver-authentication": {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
@@ -122,6 +152,7 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expectCreate: true,
|
||||
uidGate: true,
|
||||
},
|
||||
{
|
||||
name: "skip extension-apiserver-authentication",
|
||||
@@ -134,7 +165,6 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-uid-headers": `[]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
@@ -169,7 +199,6 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-uid-headers": `[]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
@@ -205,7 +234,6 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
name: "overwrite extension-apiserver-authentication requestheader",
|
||||
clusterAuthInfo: ClusterAuthenticationInfo{
|
||||
RequestHeaderUsernameHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderUIDHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderGroupHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderExtraHeaderPrefixes: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderCA: anotherRandomCAProvider,
|
||||
@@ -216,7 +244,6 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-uid-headers": `[]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(someRandomCA),
|
||||
@@ -229,7 +256,6 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-uid-headers": `[]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(someRandomCA) + string(anotherRandomCA),
|
||||
@@ -260,7 +286,6 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
name: "skip on no change",
|
||||
clusterAuthInfo: ClusterAuthenticationInfo{
|
||||
RequestHeaderUsernameHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderUIDHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderGroupHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderExtraHeaderPrefixes: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderCA: anotherRandomCAProvider,
|
||||
@@ -271,7 +296,6 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-uid-headers": `[]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
@@ -282,10 +306,126 @@ func TestWriteClientCAs(t *testing.T) {
|
||||
expectedConfigMaps: map[string]*corev1.ConfigMap{},
|
||||
expectCreate: false,
|
||||
},
|
||||
{
|
||||
name: "drop uid without feature gate",
|
||||
clusterAuthInfo: ClusterAuthenticationInfo{
|
||||
RequestHeaderUsernameHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderUIDHeaders: headerrequest.StaticStringSlice{"panda"},
|
||||
RequestHeaderGroupHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderExtraHeaderPrefixes: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderCA: anotherRandomCAProvider,
|
||||
RequestHeaderAllowedNames: headerrequest.StaticStringSlice{},
|
||||
},
|
||||
preexistingObjs: []runtime.Object{
|
||||
&corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-uid-headers": `["snorlax"]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
"requestheader-allowed-names": `[]`,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedConfigMaps: map[string]*corev1.ConfigMap{
|
||||
"extension-apiserver-authentication": {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
"requestheader-allowed-names": `[]`,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectCreate: false,
|
||||
},
|
||||
{
|
||||
name: "add uid with feature gate",
|
||||
clusterAuthInfo: ClusterAuthenticationInfo{
|
||||
RequestHeaderUsernameHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderUIDHeaders: headerrequest.StaticStringSlice{"panda"},
|
||||
RequestHeaderGroupHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderExtraHeaderPrefixes: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderCA: anotherRandomCAProvider,
|
||||
RequestHeaderAllowedNames: headerrequest.StaticStringSlice{},
|
||||
},
|
||||
preexistingObjs: []runtime.Object{
|
||||
&corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
"requestheader-allowed-names": `[]`,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedConfigMaps: map[string]*corev1.ConfigMap{
|
||||
"extension-apiserver-authentication": {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-uid-headers": `["panda"]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
"requestheader-allowed-names": `[]`,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectCreate: false,
|
||||
uidGate: true,
|
||||
},
|
||||
{
|
||||
name: "append uid with feature gate",
|
||||
clusterAuthInfo: ClusterAuthenticationInfo{
|
||||
RequestHeaderUsernameHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderUIDHeaders: headerrequest.StaticStringSlice{"panda"},
|
||||
RequestHeaderGroupHeaders: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderExtraHeaderPrefixes: headerrequest.StaticStringSlice{},
|
||||
RequestHeaderCA: anotherRandomCAProvider,
|
||||
RequestHeaderAllowedNames: headerrequest.StaticStringSlice{},
|
||||
},
|
||||
preexistingObjs: []runtime.Object{
|
||||
&corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-uid-headers": `["snorlax"]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
"requestheader-allowed-names": `[]`,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedConfigMaps: map[string]*corev1.ConfigMap{
|
||||
"extension-apiserver-authentication": {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-uid-headers": `["snorlax","panda"]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
"requestheader-allowed-names": `[]`,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectCreate: false,
|
||||
uidGate: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RemoteRequestHeaderUID, test.uidGate)
|
||||
|
||||
client := fake.NewSimpleClientset(test.preexistingObjs...)
|
||||
configMapIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
for _, obj := range test.preexistingObjs {
|
||||
@@ -341,7 +481,6 @@ func TestWriteConfigMapDeleted(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
|
||||
Data: map[string]string{
|
||||
"requestheader-username-headers": `[]`,
|
||||
"requestheader-uid-headers": `[]`,
|
||||
"requestheader-group-headers": `[]`,
|
||||
"requestheader-extra-headers-prefix": `[]`,
|
||||
"requestheader-client-ca-file": string(anotherRandomCA),
|
||||
|
@@ -99,7 +99,7 @@ func SetFeatureGateEmulationVersionDuringTest(tb TB, gate featuregate.FeatureGat
|
||||
detectParallelOverrideCleanup := detectParallelOverrideEmulationVersion(tb, ver)
|
||||
originalEmuVer := gate.(featuregate.MutableVersionedFeatureGate).EmulationVersion()
|
||||
if err := gate.(featuregate.MutableVersionedFeatureGate).SetEmulationVersion(ver); err != nil {
|
||||
tb.Fatalf("failed to set emulation version to %s during test", ver.String())
|
||||
tb.Fatalf("failed to set emulation version to %s during test: %v", ver.String(), err)
|
||||
}
|
||||
tb.Cleanup(func() {
|
||||
tb.Helper()
|
||||
|
@@ -35,35 +35,33 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"k8s.io/apiserver/pkg/audit"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||
"k8s.io/client-go/transport"
|
||||
|
||||
"golang.org/x/net/websocket"
|
||||
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
"go.opentelemetry.io/otel/sdk/trace/tracetest"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"golang.org/x/net/websocket"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/apimachinery/pkg/util/proxy"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apiserver/pkg/audit"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/apiserver/pkg/endpoints/filters"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||
"k8s.io/apiserver/pkg/server/egressselector"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol"
|
||||
apiserverproxyutil "k8s.io/apiserver/pkg/util/proxy"
|
||||
"k8s.io/client-go/transport"
|
||||
"k8s.io/component-base/featuregate"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/component-base/metrics"
|
||||
"k8s.io/component-base/metrics/legacyregistry"
|
||||
apiregistration "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
|
||||
"k8s.io/utils/pointer"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
@@ -145,7 +143,7 @@ func TestProxyHandler(t *testing.T) {
|
||||
apiService: &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Service: &apiregistration.ServiceReference{Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Port: ptr.To[int32](443)},
|
||||
Group: "foo",
|
||||
Version: "v1",
|
||||
},
|
||||
@@ -168,7 +166,7 @@ func TestProxyHandler(t *testing.T) {
|
||||
apiService: &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Service: &apiregistration.ServiceReference{Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Port: ptr.To[int32](443)},
|
||||
Group: "foo",
|
||||
Version: "v1",
|
||||
InsecureSkipTLSVerify: true,
|
||||
@@ -201,7 +199,7 @@ func TestProxyHandler(t *testing.T) {
|
||||
apiService: &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Service: &apiregistration.ServiceReference{Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Port: ptr.To[int32](443)},
|
||||
Group: "foo",
|
||||
Version: "v1",
|
||||
InsecureSkipTLSVerify: true,
|
||||
@@ -236,7 +234,7 @@ func TestProxyHandler(t *testing.T) {
|
||||
apiService: &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: ptr.To[int32](443)},
|
||||
Group: "foo",
|
||||
Version: "v1",
|
||||
CABundle: testCACrt,
|
||||
@@ -269,7 +267,7 @@ func TestProxyHandler(t *testing.T) {
|
||||
apiService: &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: ptr.To[int32](443)},
|
||||
Group: "foo",
|
||||
Version: "v1",
|
||||
CABundle: testCACrt,
|
||||
@@ -304,7 +302,7 @@ func TestProxyHandler(t *testing.T) {
|
||||
apiService: &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: ptr.To[int32](443)},
|
||||
Group: "foo",
|
||||
Version: "v1",
|
||||
CABundle: testCACrt,
|
||||
@@ -328,7 +326,7 @@ func TestProxyHandler(t *testing.T) {
|
||||
apiService: &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Service: &apiregistration.ServiceReference{Name: "bad-service", Namespace: "test-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "bad-service", Namespace: "test-ns", Port: ptr.To[int32](443)},
|
||||
Group: "foo",
|
||||
Version: "v1",
|
||||
CABundle: testCACrt,
|
||||
@@ -351,7 +349,7 @@ func TestProxyHandler(t *testing.T) {
|
||||
apiService: &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Service: &apiregistration.ServiceReference{Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Port: ptr.To[int32](443)},
|
||||
Group: "foo",
|
||||
Version: "v1",
|
||||
},
|
||||
@@ -373,7 +371,7 @@ func TestProxyHandler(t *testing.T) {
|
||||
apiService: &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: ptr.To[int32](443)},
|
||||
Group: "foo",
|
||||
Version: "v1",
|
||||
CABundle: testCACrt,
|
||||
@@ -511,6 +509,8 @@ func newBrokenDialerAndSelector() (*mockEgressDialer, *egressselector.EgressSele
|
||||
}
|
||||
|
||||
func TestProxyUpgrade(t *testing.T) {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RemoteRequestHeaderUID, true)
|
||||
|
||||
upgradeUser := "upgradeUser"
|
||||
upgradeUID := "upgradeUser-UID"
|
||||
testcases := map[string]struct {
|
||||
@@ -525,7 +525,7 @@ func TestProxyUpgrade(t *testing.T) {
|
||||
CABundle: testCACrt,
|
||||
Group: "mygroup",
|
||||
Version: "v1",
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: ptr.To[int32](443)},
|
||||
},
|
||||
Status: apiregistration.APIServiceStatus{
|
||||
Conditions: []apiregistration.APIServiceCondition{
|
||||
@@ -542,7 +542,7 @@ func TestProxyUpgrade(t *testing.T) {
|
||||
InsecureSkipTLSVerify: true,
|
||||
Group: "mygroup",
|
||||
Version: "v1",
|
||||
Service: &apiregistration.ServiceReference{Name: "invalid-service", Namespace: "invalid-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "invalid-service", Namespace: "invalid-ns", Port: ptr.To[int32](443)},
|
||||
},
|
||||
Status: apiregistration.APIServiceStatus{
|
||||
Conditions: []apiregistration.APIServiceCondition{
|
||||
@@ -559,7 +559,7 @@ func TestProxyUpgrade(t *testing.T) {
|
||||
CABundle: testCACrt,
|
||||
Group: "mygroup",
|
||||
Version: "v1",
|
||||
Service: &apiregistration.ServiceReference{Name: "invalid-service", Namespace: "invalid-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "invalid-service", Namespace: "invalid-ns", Port: ptr.To[int32](443)},
|
||||
},
|
||||
Status: apiregistration.APIServiceStatus{
|
||||
Conditions: []apiregistration.APIServiceCondition{
|
||||
@@ -576,7 +576,7 @@ func TestProxyUpgrade(t *testing.T) {
|
||||
CABundle: testCACrt,
|
||||
Group: "mygroup",
|
||||
Version: "v1",
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: ptr.To[int32](443)},
|
||||
},
|
||||
Status: apiregistration.APIServiceStatus{
|
||||
Conditions: []apiregistration.APIServiceCondition{
|
||||
@@ -594,7 +594,7 @@ func TestProxyUpgrade(t *testing.T) {
|
||||
CABundle: testCACrt,
|
||||
Group: "mygroup",
|
||||
Version: "v1",
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service", Namespace: "test-ns", Port: ptr.To[int32](443)},
|
||||
},
|
||||
Status: apiregistration.APIServiceStatus{
|
||||
Conditions: []apiregistration.APIServiceCondition{
|
||||
@@ -1075,7 +1075,7 @@ func TestProxyCertReload(t *testing.T) {
|
||||
apiService := &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service2", Namespace: "test-ns", Port: pointer.Int32Ptr(443)},
|
||||
Service: &apiregistration.ServiceReference{Name: "test-service2", Namespace: "test-ns", Port: ptr.To[int32](443)},
|
||||
Group: "foo",
|
||||
Version: "v1",
|
||||
CABundle: backendCaCertificate(), // used to validate backendCertificate()
|
||||
|
@@ -27,7 +27,7 @@ import (
|
||||
func main() {
|
||||
ctx := genericapiserver.SetupSignalContext()
|
||||
options := server.NewWardleServerOptions(os.Stdout, os.Stderr)
|
||||
cmd := server.NewCommandStartWardleServer(ctx, options)
|
||||
cmd := server.NewCommandStartWardleServer(ctx, options, false)
|
||||
code := cli.Run(cmd)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
@@ -90,12 +90,15 @@ func NewWardleServerOptions(out, errOut io.Writer) *WardleServerOptions {
|
||||
|
||||
// NewCommandStartWardleServer provides a CLI handler for 'start master' command
|
||||
// with a default WardleServerOptions.
|
||||
func NewCommandStartWardleServer(ctx context.Context, defaults *WardleServerOptions) *cobra.Command {
|
||||
func NewCommandStartWardleServer(ctx context.Context, defaults *WardleServerOptions, skipDefaultComponentGlobalsRegistrySet bool) *cobra.Command {
|
||||
o := *defaults
|
||||
cmd := &cobra.Command{
|
||||
Short: "Launch a wardle API server",
|
||||
Long: "Launch a wardle API server",
|
||||
PersistentPreRunE: func(*cobra.Command, []string) error {
|
||||
if skipDefaultComponentGlobalsRegistrySet {
|
||||
return nil
|
||||
}
|
||||
return featuregate.DefaultComponentGlobalsRegistry.Set()
|
||||
},
|
||||
RunE: func(c *cobra.Command, args []string) error {
|
||||
|
@@ -1058,6 +1058,12 @@
|
||||
lockToDefault: true
|
||||
preRelease: GA
|
||||
version: "1.29"
|
||||
- name: RemoteRequestHeaderUID
|
||||
versionedSpecs:
|
||||
- default: false
|
||||
lockToDefault: false
|
||||
preRelease: Alpha
|
||||
version: "1.32"
|
||||
- name: ResilientWatchCacheInitialization
|
||||
versionedSpecs:
|
||||
- default: true
|
||||
|
@@ -27,11 +27,14 @@ import (
|
||||
|
||||
authnv1 "k8s.io/api/authentication/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
"k8s.io/client-go/util/keyutil"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
||||
"k8s.io/kubernetes/test/integration/framework"
|
||||
testutils "k8s.io/kubernetes/test/utils"
|
||||
@@ -39,6 +42,8 @@ import (
|
||||
)
|
||||
|
||||
func TestAuthnToKAS(t *testing.T) {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RemoteRequestHeaderUID, true)
|
||||
|
||||
tCtx := ktesting.Init(t)
|
||||
|
||||
frontProxyCA, frontProxyClient, frontProxyKey, err := newTestCAWithClient(
|
||||
|
@@ -45,8 +45,10 @@ import (
|
||||
"k8s.io/apiserver/pkg/authentication/serviceaccount"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||
genericapiserveroptions "k8s.io/apiserver/pkg/server/options"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
client "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
@@ -54,6 +56,7 @@ import (
|
||||
"k8s.io/client-go/transport"
|
||||
"k8s.io/client-go/util/cert"
|
||||
"k8s.io/component-base/featuregate"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
utilversion "k8s.io/component-base/version"
|
||||
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
|
||||
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
|
||||
@@ -260,6 +263,7 @@ func TestFrontProxyConfig(t *testing.T) {
|
||||
testFrontProxyConfig(t, false)
|
||||
})
|
||||
t.Run("WithUID", func(t *testing.T) {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RemoteRequestHeaderUID, true)
|
||||
testFrontProxyConfig(t, true)
|
||||
})
|
||||
}
|
||||
@@ -282,7 +286,7 @@ func testFrontProxyConfig(t *testing.T, withUID bool) {
|
||||
kubeBinaryVersion := sampleserver.WardleVersionToKubeVersion(version.MustParse(wardleBinaryVersion)).String()
|
||||
|
||||
// start up the KAS and prepare the options for the wardle API server
|
||||
testKAS, wardleOptions, wardlePort := prepareAggregatedWardleAPIServer(ctx, t, testNamespace, kubeBinaryVersion, wardleBinaryVersion, extraKASFlags)
|
||||
testKAS, wardleOptions, wardlePort := prepareAggregatedWardleAPIServer(ctx, t, testNamespace, kubeBinaryVersion, wardleBinaryVersion, extraKASFlags, withUID)
|
||||
kubeConfig := getKubeConfig(testKAS)
|
||||
|
||||
// create the SA that we will use to query the aggregated API
|
||||
@@ -337,12 +341,12 @@ func testFrontProxyConfig(t *testing.T, withUID bool) {
|
||||
transport.WrapperFunc(func(rt http.RoundTripper) http.RoundTripper {
|
||||
return roundTripperFunc(func(req *http.Request) (*http.Response, error) {
|
||||
gotUser, ok := genericapirequest.UserFrom(req.Context())
|
||||
if !ok || gotUser.GetName() == "system:anonymous" {
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("got an unauthenticated request")
|
||||
}
|
||||
|
||||
// this is likely the KAS checking the OpenAPI endpoints
|
||||
if gotUser.GetName() == "system:anonymous" || gotUser.GetName() == "system:aggregator" {
|
||||
if gotUser.GetName() == "system:anonymous" || gotUser.GetName() == "system:aggregator" || gotUser.GetName() == "system:kube-aggregator" {
|
||||
return rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
@@ -368,7 +372,7 @@ func testFrontProxyConfig(t *testing.T, withUID bool) {
|
||||
wardleCertDir, _ := os.MkdirTemp("", "test-integration-wardle-server")
|
||||
defer os.RemoveAll(wardleCertDir)
|
||||
|
||||
runPreparedWardleServer(ctx, t, wardleOptions, wardleCertDir, wardlePort, false, true, wardleBinaryVersion, kubeConfig)
|
||||
runPreparedWardleServer(ctx, t, wardleOptions, wardleCertDir, wardlePort, false, true, wardleBinaryVersion, kubeConfig, withUID)
|
||||
waitForWardleAPIServiceReady(ctx, t, kubeConfig, wardleCertDir, testNamespace)
|
||||
|
||||
// get the wardle API client using our SA token
|
||||
@@ -401,13 +405,13 @@ func testAggregatedAPIServer(t *testing.T, setWardleFeatureGate, banFlunder bool
|
||||
// each wardle binary is bundled with a specific kube binary.
|
||||
kubeBinaryVersion := sampleserver.WardleVersionToKubeVersion(version.MustParse(wardleBinaryVersion)).String()
|
||||
|
||||
testKAS, wardleOptions, wardlePort := prepareAggregatedWardleAPIServer(ctx, t, testNamespace, kubeBinaryVersion, wardleBinaryVersion, nil)
|
||||
testKAS, wardleOptions, wardlePort := prepareAggregatedWardleAPIServer(ctx, t, testNamespace, kubeBinaryVersion, wardleBinaryVersion, nil, false)
|
||||
kubeClientConfig := getKubeConfig(testKAS)
|
||||
|
||||
wardleCertDir, _ := os.MkdirTemp("", "test-integration-wardle-server")
|
||||
defer os.RemoveAll(wardleCertDir)
|
||||
|
||||
directWardleClientConfig := runPreparedWardleServer(ctx, t, wardleOptions, wardleCertDir, wardlePort, setWardleFeatureGate, banFlunder, wardleEmulationVersion, kubeClientConfig)
|
||||
directWardleClientConfig := runPreparedWardleServer(ctx, t, wardleOptions, wardleCertDir, wardlePort, setWardleFeatureGate, banFlunder, wardleEmulationVersion, kubeClientConfig, false)
|
||||
|
||||
// now we're finally ready to test. These are what's run by default now
|
||||
wardleDirectClient := client.NewForConfigOrDie(directWardleClientConfig)
|
||||
@@ -681,7 +685,7 @@ func TestAggregatedAPIServerRejectRedirectResponse(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func prepareAggregatedWardleAPIServer(ctx context.Context, t *testing.T, namespace, kubebinaryVersion, wardleBinaryVersion string, kubeAPIServerFlags []string) (*kastesting.TestServer, *sampleserver.WardleServerOptions, int) {
|
||||
func prepareAggregatedWardleAPIServer(ctx context.Context, t *testing.T, namespace, kubebinaryVersion, wardleBinaryVersion string, kubeAPIServerFlags []string, withUID bool) (*kastesting.TestServer, *sampleserver.WardleServerOptions, int) {
|
||||
// makes the kube-apiserver very responsive. it's normally a minute
|
||||
dynamiccertificates.FileRefreshDuration = 1 * time.Second
|
||||
|
||||
@@ -693,6 +697,11 @@ func prepareAggregatedWardleAPIServer(ctx context.Context, t *testing.T, namespa
|
||||
// endpoints cannot have loopback IPs so we need to override the resolver itself
|
||||
t.Cleanup(app.SetServiceResolverForTests(staticURLServiceResolver(fmt.Sprintf("https://127.0.0.1:%d", wardlePort))))
|
||||
|
||||
// TODO figure out how to actually make BinaryVersion/EmulationVersion work with Wardle and KAS at the same time when Alpha FG are being set
|
||||
if withUID {
|
||||
kubebinaryVersion = ""
|
||||
}
|
||||
|
||||
testServer := kastesting.StartTestServerOrDie(t,
|
||||
&kastesting.TestServerInstanceOptions{
|
||||
EnableCertAuth: true,
|
||||
@@ -751,6 +760,7 @@ func runPreparedWardleServer(
|
||||
banFlunder bool,
|
||||
emulationVersion string,
|
||||
kubeConfig *rest.Config,
|
||||
withUID bool,
|
||||
) *rest.Config {
|
||||
|
||||
// start the wardle server to prove we can aggregate it
|
||||
@@ -769,7 +779,8 @@ func runPreparedWardleServer(
|
||||
if flunderBanningFeatureGate {
|
||||
args = append(args, "--feature-gates", fmt.Sprintf("wardle:BanFlunder=%v", banFlunder))
|
||||
}
|
||||
wardleCmd := sampleserver.NewCommandStartWardleServer(ctx, wardleOptions)
|
||||
// TODO figure out how to actually make BinaryVersion/EmulationVersion work with Wardle and KAS at the same time when Alpha FG are being set
|
||||
wardleCmd := sampleserver.NewCommandStartWardleServer(ctx, wardleOptions, withUID)
|
||||
wardleCmd.SetArgs(args)
|
||||
if err := wardleCmd.Execute(); err != nil {
|
||||
t.Error(err)
|
||||
|
Reference in New Issue
Block a user