Skip to content

Commit d0fe42e

Browse files
authored
Add support for structured authentication (#995)
* Initial support for structured-auth Signed-off-by: Fabian Ruff <fabian.ruff@sap.com> * add structured authenitcation configuration This commit adds a new field “authenticationConfiguration” to the kluster spec that allowing to provide the content of the —authentication-configuration config file. The ground controller reconciles any changes to the api and updates a configmap that is referenced in the apiserver deployment. As any changes to the configfile are automatically picked up by the apiserver this changes to the kluster spec become effective within a minute. Signed-off-by: Fabian Ruff <fabian.ruff@sap.com> * incorporate code-review feedback Signed-off-by: Fabian Ruff <fabian.ruff@sap.com> --------- Signed-off-by: Fabian Ruff <fabian.ruff@sap.com>
1 parent 0bdf260 commit d0fe42e

File tree

11 files changed

+309
-7
lines changed

11 files changed

+309
-7
lines changed

.golangci.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ run:
22
timeout: 5m
33
linters:
44
enable:
5-
- copyloopvar
65
- gci
76
- gofmt
87
disable:

charts/kube-master/templates/api.yaml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ spec:
140140
path: config.yaml
141141
- key: admission-kubeconfig
142142
path: kubeconfig
143+
{{- end }}
144+
{{- if (semverCompare ">= 1.30" .Values.version.kubernetes) }}
145+
- name: auth-config
146+
configMap:
147+
name: {{ include "master.fullname" . }}-auth
148+
items:
149+
- key: config.yaml
150+
path: config.yaml
143151
{{- end }}
144152
initContainers:
145153
- name: etcd-wait
@@ -268,7 +276,9 @@ spec:
268276
{{- if .Values.api.corsAllowedOrigins }}
269277
- --cors-allowed-origins={{ .Values.api.corsAllowedOrigins }}
270278
{{- end }}
271-
{{ if or .Values.dex.enabled .Values.api.oidc.issuerURL }}
279+
{{ if (semverCompare ">= 1.30" .Values.version.kubernetes)}}
280+
- --authentication-config=/etc/kubernetes/auth/config.yaml
281+
{{ else if or .Values.dex.enabled .Values.api.oidc.issuerURL }}
272282
- --oidc-issuer-url={{ default (printf "https://%s" (include "dex.url" .)) .Values.api.oidc.issuerURL }}
273283
- --oidc-client-id={{ .Values.api.oidc.clientID }}
274284
- --oidc-groups-claim={{ .Values.api.oidc.groupsClaim }}
@@ -318,6 +328,11 @@ spec:
318328
- mountPath: /etc/kubernetes/admission
319329
name: admission-config
320330
readOnly: true
331+
{{- end }}
332+
{{- if (semverCompare ">= 1.30" .Values.version.kubernetes) }}
333+
- mountPath: /etc/kubernetes/auth
334+
name: auth-config
335+
readOnly: true
321336
{{- end }}
322337
livenessProbe:
323338
{{- if .Values.etcd.backup.enabled }}

go.mod

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ require (
5353
k8s.io/api v0.32.2
5454
k8s.io/apiextensions-apiserver v0.32.2
5555
k8s.io/apimachinery v0.32.2
56+
k8s.io/apiserver v0.32.2
5657
k8s.io/client-go v0.32.2
5758
k8s.io/cluster-bootstrap v0.32.1
5859
k8s.io/klog v1.0.0
@@ -62,10 +63,12 @@ require (
6263

6364
require (
6465
al.essio.dev/pkg/shellescape v1.5.1 // indirect
66+
cel.dev/expr v0.18.0 // indirect
6567
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
6668
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
6769
github.com/MakeNowJust/heredoc v1.0.0 // indirect
6870
github.com/Masterminds/squirrel v1.5.4 // indirect
71+
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
6972
github.com/aws/aws-sdk-go v1.55.5 // indirect
7073
github.com/beorn7/perks v1.0.1 // indirect
7174
github.com/blang/semver/v4 v4.0.0 // indirect
@@ -112,6 +115,7 @@ require (
112115
github.com/gogo/protobuf v1.3.2 // indirect
113116
github.com/golang/protobuf v1.5.4 // indirect
114117
github.com/google/btree v1.0.1 // indirect
118+
github.com/google/cel-go v0.22.0 // indirect
115119
github.com/google/gnostic-models v0.6.8 // indirect
116120
github.com/google/go-cmp v0.6.0 // indirect
117121
github.com/google/gofuzz v1.2.0 // indirect
@@ -165,6 +169,7 @@ require (
165169
github.com/shopspring/decimal v1.4.0 // indirect
166170
github.com/sirupsen/logrus v1.9.3 // indirect
167171
github.com/spf13/cast v1.7.0 // indirect
172+
github.com/stoewer/go-strcase v1.3.0 // indirect
168173
github.com/stretchr/objx v0.5.2 // indirect
169174
github.com/vincent-petithory/dataurl v1.0.0 // indirect
170175
github.com/x448/float16 v0.8.4 // indirect
@@ -177,17 +182,18 @@ require (
177182
go.opentelemetry.io/otel v1.28.0 // indirect
178183
go.opentelemetry.io/otel/metric v1.28.0 // indirect
179184
go.opentelemetry.io/otel/trace v1.28.0 // indirect
185+
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
180186
golang.org/x/sync v0.12.0 // indirect
181187
golang.org/x/term v0.30.0 // indirect
182188
golang.org/x/text v0.23.0 // indirect
183189
golang.org/x/time v0.7.0 // indirect
190+
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect
184191
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect
185192
google.golang.org/grpc v1.65.0 // indirect
186193
google.golang.org/protobuf v1.35.2 // indirect
187194
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
188195
gopkg.in/inf.v0 v0.9.1 // indirect
189196
gopkg.in/yaml.v3 v3.0.1 // indirect
190-
k8s.io/apiserver v0.32.2 // indirect
191197
k8s.io/cli-runtime v0.32.2 // indirect
192198
k8s.io/component-base v0.32.2 // indirect
193199
k8s.io/klog/v2 v2.130.1 // indirect

go.sum

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho=
22
al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
3+
cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo=
4+
cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
35
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
46
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
57
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
@@ -42,6 +44,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
4244
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
4345
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
4446
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
47+
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
48+
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
4549
github.com/aokoli/goutils v1.1.1 h1:/hA+Ywo3AxoDZY5ZMnkiEkUvkK4BPp927ax110KCqqg=
4650
github.com/aokoli/goutils v1.1.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=
4751
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
@@ -272,6 +276,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
272276
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
273277
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
274278
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
279+
github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g=
280+
github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
275281
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
276282
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
277283
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -587,18 +593,25 @@ github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
587593
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
588594
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
589595
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
596+
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
597+
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
590598
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
591599
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
592600
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
593601
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
594602
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
603+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
604+
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
595605
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
596606
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
597607
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
598608
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
599609
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
600610
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
601611
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
612+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
613+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
614+
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
602615
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
603616
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
604617
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -671,6 +684,8 @@ golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0
671684
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
672685
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
673686
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
687+
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
688+
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
674689
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
675690
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
676691
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -799,6 +814,8 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn
799814
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
800815
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
801816
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
817+
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw=
818+
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
802819
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs=
803820
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
804821
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package models
2+
3+
import (
4+
"context"
5+
"net/http"
6+
7+
"github.com/go-openapi/errors"
8+
"github.com/go-openapi/strfmt"
9+
"k8s.io/apimachinery/pkg/runtime"
10+
"k8s.io/apimachinery/pkg/runtime/serializer"
11+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
12+
"k8s.io/apiserver/pkg/apis/apiserver"
13+
apiserverv1alpha1 "k8s.io/apiserver/pkg/apis/apiserver/v1alpha1"
14+
apiserverv1beta1 "k8s.io/apiserver/pkg/apis/apiserver/v1beta1"
15+
apiservervalidation "k8s.io/apiserver/pkg/apis/apiserver/validation"
16+
authenticationcel "k8s.io/apiserver/pkg/authentication/cel"
17+
)
18+
19+
var decoder runtime.Decoder
20+
21+
func init() {
22+
scheme := runtime.NewScheme()
23+
schemeBuilder := runtime.NewSchemeBuilder(apiserverv1beta1.AddToScheme, apiserverv1alpha1.AddToScheme, apiserver.AddToScheme)
24+
utilruntime.Must(schemeBuilder.AddToScheme(scheme))
25+
decoder = serializer.NewCodecFactory(scheme).UniversalDecoder()
26+
}
27+
28+
// AuthenticationConfiguration is a custom string type
29+
type AuthenticationConfiguration string
30+
31+
// Validate ensures that the AuthenticationConfiguration fulfills the go-swagger validation interface
32+
func (a AuthenticationConfiguration) Validate(formats strfmt.Registry) error {
33+
if a == "" {
34+
return nil // empty is valid
35+
}
36+
obj, schemaVersion, err := decoder.Decode([]byte(a), nil, nil)
37+
if err != nil {
38+
return errors.New(http.StatusBadRequest, "failed to decode authenticationConfiguration: %s", err)
39+
}
40+
41+
authenticationConfig, ok := obj.(*apiserver.AuthenticationConfiguration)
42+
if !ok {
43+
return errors.New(http.StatusBadRequest, "failed to cast authenticationConfiguration type: %v", schemaVersion)
44+
}
45+
46+
if errList := apiservervalidation.ValidateAuthenticationConfiguration(authenticationcel.NewDefaultCompiler(), authenticationConfig, nil); len(errList) != 0 {
47+
return errors.New(http.StatusBadRequest, "invalid authenticationConfiguration: %v", errList)
48+
}
49+
// Add additional validation logic here if needed
50+
return nil
51+
}
52+
53+
// ContextValidate validates the AuthenticationConfiguration based on the context it is used in
54+
func (a AuthenticationConfiguration) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
55+
// Add context-specific validation logic here if needed
56+
return nil
57+
}

pkg/api/models/kluster_spec.go

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/api/models/o_id_c.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/api/rest/api_test.go

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ func TestCreateCluster(t *testing.T) {
147147
assert.Contains(t, string(body), "nase")
148148
}
149149

150-
//Ensure specifying a different router doesn't obverlap
150+
//Ensure specifying a different router doesn't overlap
151151
req = createRequest("POST", "/api/v1/clusters", `{"name": "ohr", "spec": { "openstack": { "routerID":"routerB"}}}`)
152152
code, _, body = result(handler, req)
153153
assert.Equal(t, 201, code, "specifying a different router should not conflict. response: %s", string(body))
@@ -169,7 +169,7 @@ func TestCreateCluster(t *testing.T) {
169169
assert.Contains(t, string(body), "CIDR")
170170
}
171171

172-
//Ensure specifying a different router doesn't obverlap
172+
//Ensure specifying an empty clusterCIDR does not fail
173173
req = createRequest("POST", "/api/v1/clusters", `{"name": "nocidr", "spec": { "clusterCIDR": "", "noCloud": true, "serviceCIDR":"5.5.5.5/24"}}`)
174174

175175
code, _, body = result(handler, req)
@@ -180,6 +180,73 @@ func TestCreateCluster(t *testing.T) {
180180

181181
}
182182

183+
func TestAuthenticationConfigurationValidation(t *testing.T) {
184+
handler, _, cancel := createTestHandler(t)
185+
defer cancel()
186+
//Ensure invalid authentication configuration is rejected
187+
invalidAuthConfig, err := json.Marshal(models.Kluster{
188+
Name: "auth",
189+
Spec: models.KlusterSpec{
190+
AuthenticationConfiguration: models.AuthenticationConfiguration(`
191+
apiVersion: apiserver.config.k8s.io/v1beta1
192+
kind: AuthenticationConfiguration
193+
jwt:
194+
- issuer:
195+
url: https://issuer1.example.com
196+
audiences:
197+
- audience1
198+
- audience2
199+
audienceMatchPolicy: MatchAny
200+
`),
201+
},
202+
})
203+
assert.NoError(t, err, "failed to marshal authentication configuration")
204+
req := createRequest("POST", "/api/v1/clusters", string(invalidAuthConfig))
205+
code, _, body := result(handler, req)
206+
assert.Equal(t, 400, code, "invalid authentication configuration should be rejected. response: %s, %s", string(body))
207+
208+
validAuthConfig, err := json.Marshal(models.Kluster{
209+
Name: "auth",
210+
Spec: models.KlusterSpec{
211+
AuthenticationConfiguration: models.AuthenticationConfiguration(`
212+
apiVersion: apiserver.config.k8s.io/v1beta1
213+
kind: AuthenticationConfiguration
214+
jwt:
215+
- issuer:
216+
url: https://issuer1.example.com
217+
audiences:
218+
- audience1
219+
- audience2
220+
audienceMatchPolicy: MatchAny
221+
claimMappings:
222+
username:
223+
expression: 'claims.username'
224+
groups:
225+
expression: 'claims.groups'
226+
`),
227+
},
228+
})
229+
assert.NoError(t, err, "failed to marshal authentication configuration")
230+
req = createRequest("POST", "/api/v1/clusters", string(validAuthConfig))
231+
code, _, body = result(handler, req)
232+
assert.Equal(t, 201, code, "valid authentication configuration should be accepted. response: %s", string(body))
233+
234+
emptyAuthConfig, err := json.Marshal(models.Kluster{
235+
Name: "emptyauth",
236+
Spec: models.KlusterSpec{
237+
ClusterCIDR: swag.String("100.101.0.0/16"),
238+
AuthenticationConfiguration: models.AuthenticationConfiguration(`
239+
apiVersion: apiserver.config.k8s.io/v1beta1
240+
kind: AuthenticationConfiguration
241+
`),
242+
},
243+
})
244+
assert.NoError(t, err, "failed to marshal authentication configuration")
245+
req = createRequest("POST", "/api/v1/clusters", string(emptyAuthConfig))
246+
code, _, body = result(handler, req)
247+
assert.Equal(t, 201, code, "empty authentication configuration is valid. response: %s", string(body))
248+
}
249+
183250
func TestClusterShow(t *testing.T) {
184251
kluster := kubernikusv1.Kluster{
185252
ObjectMeta: metav1.ObjectMeta{
@@ -484,5 +551,4 @@ func TestClusterBootstrapConfig(t *testing.T) {
484551
ClusterDomain: "example.com",
485552
RotateCertificates: true,
486553
}, config)
487-
488554
}

0 commit comments

Comments
 (0)