Bump libs to k8s.io@v0.32.3, add codegen for k8s 1.32, and drop codegen for k8s 1.25

This commit is contained in:
Joshua Casey
2025-01-29 13:52:35 -06:00
committed by Ryan Richard
parent b50da60c84
commit b8e7a64afe
268 changed files with 52778 additions and 2609 deletions

View File

@@ -236,16 +236,30 @@ func validateRequest(ctx context.Context, obj runtime.Object, createValidation r
}
func validateUserInfo(userInfo user.Info) error {
switch {
case len(userInfo.GetName()) == 0:
if len(userInfo.GetName()) == 0 {
return errors.New("empty username is not allowed")
case len(userInfo.GetUID()) != 0:
return errors.New("UIDs are not supported") // certs cannot assert UID
case len(userInfo.GetExtra()) != 0:
return errors.New("extras are not supported") // certs cannot assert extra
default:
}
// certs cannot assert UID
if len(userInfo.GetUID()) != 0 {
return errors.New("UIDs are not supported")
}
// certs cannot assert extras, but starting in K8s 1.32 the authenticator will always provide this information
if len(userInfo.GetExtra()) == 0 { // it's ok for this to be empty...
return nil
}
// ... but if it's not empty, should have only exactly this one key.
if len(userInfo.GetExtra()) > 1 {
return errors.New("extra may have only one key 'authentication.kubernetes.io/credential-id'")
}
_, ok := userInfo.GetExtra()["authentication.kubernetes.io/credential-id"]
if !ok {
return errors.New("extra may have only one key 'authentication.kubernetes.io/credential-id'")
}
return nil
}
func authenticationFailedResponse() *loginapi.TokenCredentialRequest {

View File

@@ -1,4 +1,4 @@
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package credentialrequest
@@ -359,7 +359,7 @@ func TestCreate(t *testing.T) {
"name": "fake-authenticator-name",
},
"reason": "unsupported value in userInfo returned by authenticator",
"err": "extras are not supported",
"err": "extra may have only one key 'authentication.kubernetes.io/credential-id'",
"userInfoExtrasCount": float64(1),
"personalInfo": map[string]any{
"userInfoName": "test-user",
@@ -369,6 +369,113 @@ func TestCreate(t *testing.T) {
}
})
it("CreateSucceedsWithAnUnauthenticatedStatusWhenWebhookReturnsAUserWithTooManyExtra", func() {
req := validCredentialRequest()
requestAuthenticator := mockcredentialrequest.NewMockTokenCredentialRequestAuthenticator(ctrl)
requestAuthenticator.EXPECT().AuthenticateTokenCredentialRequest(gomock.Any(), req).
Return(&user.DefaultInfo{
Name: "test-user",
Groups: []string{"test-group-1", "test-group-2"},
Extra: map[string][]string{
"test-key": {"test-val-1", "test-val-2"},
"authentication.kubernetes.io/credential-id": {"some-value"},
},
}, nil)
storage := NewREST(requestAuthenticator, nil, schema.GroupResource{}, auditLogger)
response, err := callCreate(storage, req)
requireSuccessfulResponseWithAuthenticationFailureMessage(t, err, response)
wantAuditLog = []testutil.WantedAuditLog{
testutil.WantAuditLog("TokenCredentialRequest Token Received", map[string]any{
"auditID": "fake-audit-id",
"tokenID": tokenToHash(req.Spec.Token),
}),
testutil.WantAuditLog("TokenCredentialRequest Unsupported UserInfo", map[string]any{
"auditID": "fake-audit-id",
"authenticator": map[string]any{
"apiGroup": "fake-api-group.com",
"kind": "FakeAuthenticatorKind",
"name": "fake-authenticator-name",
},
"reason": "unsupported value in userInfo returned by authenticator",
"err": "extra may have only one key 'authentication.kubernetes.io/credential-id'",
"userInfoExtrasCount": float64(2),
"personalInfo": map[string]any{
"userInfoName": "test-user",
"userInfoUID": "",
},
}),
}
})
it("CreateSucceedsWhenWebhookReturnsAUserWithValidExtra", func() {
req := validCredentialRequest()
requestAuthenticator := mockcredentialrequest.NewMockTokenCredentialRequestAuthenticator(ctrl)
requestAuthenticator.EXPECT().AuthenticateTokenCredentialRequest(gomock.Any(), req).
Return(&user.DefaultInfo{
Name: "test-user",
Groups: []string{"test-group-1", "test-group-2"},
Extra: map[string][]string{"authentication.kubernetes.io/credential-id": {"test-val-1", "test-val-2"}},
}, nil)
clientCertIssuer := mockissuer.NewMockClientCertIssuer(ctrl)
clientCertIssuer.EXPECT().IssueClientCertPEM(
"test-user",
[]string{"test-group-1", "test-group-2"},
5*time.Minute,
).Return(&cert.PEM{
CertPEM: []byte("test-cert"),
KeyPEM: []byte("test-key"),
NotBefore: fakeNow.Add(-5 * time.Minute),
NotAfter: fakeNow.Add(5 * time.Minute),
}, nil)
storage := NewREST(requestAuthenticator, clientCertIssuer, schema.GroupResource{}, auditLogger)
response, err := callCreate(storage, req)
r.NoError(err)
r.IsType(&loginapi.TokenCredentialRequest{}, response)
r.Equal(response, &loginapi.TokenCredentialRequest{
Status: loginapi.TokenCredentialRequestStatus{
Credential: &loginapi.ClusterCredential{
ExpirationTimestamp: metav1.NewTime(fakeNow.Add(5 * time.Minute).UTC()),
ClientCertificateData: "test-cert",
ClientKeyData: "test-key",
},
},
})
wantAuditLog = []testutil.WantedAuditLog{
testutil.WantAuditLog("TokenCredentialRequest Token Received", map[string]any{
"auditID": "fake-audit-id",
"tokenID": tokenToHash(req.Spec.Token),
}),
testutil.WantAuditLog("TokenCredentialRequest Authenticated User", map[string]any{
"auditID": "fake-audit-id",
"authenticator": map[string]any{
"apiGroup": "fake-api-group.com",
"kind": "FakeAuthenticatorKind",
"name": "fake-authenticator-name",
},
"issuedClientCert": map[string]any{
"notBefore": "2024-09-12T04:20:56Z", // this is fakeNow - 5 minutes in UTC
"notAfter": "2024-09-12T04:30:56Z", // this is fakeNow + 5 minutes in UTC
},
"personalInfo": map[string]any{
"username": "test-user",
"groups": []any{"test-group-1", "test-group-2"},
},
}),
}
})
it("CreateFailsWhenGivenTheWrongInputType", func() {
notACredentialRequest := runtime.Unknown{}
response, err := NewREST(nil, nil, schema.GroupResource{}, auditLogger).Create(