mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-04 18:52:38 +00:00
Validate and populate metadata fields in token request
This commit is contained in:
@@ -29,6 +29,7 @@ import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -126,7 +127,11 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
instanceConfig, _, closeFn := framework.RunAnAPIServer(controlPlaneConfig)
|
||||
defer closeFn()
|
||||
|
||||
cs, err := clientset.NewForConfig(instanceConfig.GenericAPIServer.LoopbackClientConfig)
|
||||
warningHandler := &recordingWarningHandler{}
|
||||
|
||||
configWithWarningHandler := rest.CopyConfig(instanceConfig.GenericAPIServer.LoopbackClientConfig)
|
||||
configWithWarningHandler.WarningHandler = warningHandler
|
||||
cs, err := clientset.NewForConfig(configWithWarningHandler)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
@@ -182,16 +187,42 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
warningHandler.clear()
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err == nil {
|
||||
t.Fatalf("expected err creating token for nonexistant svcacct but got: %#v", resp)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
sa, delSvcAcct := createDeleteSvcAcct(t, cs, sa)
|
||||
defer delSvcAcct()
|
||||
|
||||
treqWithBadName := treq.DeepCopy()
|
||||
treqWithBadName.Name = "invalid-name"
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treqWithBadName, metav1.CreateOptions{}); err == nil || !strings.Contains(err.Error(), "must match the service account name") {
|
||||
t.Fatalf("expected err creating token with mismatched name but got: %#v", resp)
|
||||
}
|
||||
|
||||
treqWithBadNamespace := treq.DeepCopy()
|
||||
treqWithBadNamespace.Namespace = "invalid-namespace"
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treqWithBadNamespace, metav1.CreateOptions{}); err == nil || !strings.Contains(err.Error(), "must match the service account namespace") {
|
||||
t.Fatalf("expected err creating token with mismatched namespace but got: %#v", resp)
|
||||
}
|
||||
|
||||
warningHandler.clear()
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
if treq.Name != sa.Name {
|
||||
t.Errorf("expected name=%s, got %s", sa.Name, treq.Name)
|
||||
}
|
||||
if treq.Namespace != sa.Namespace {
|
||||
t.Errorf("expected namespace=%s, got %s", sa.Namespace, treq.Namespace)
|
||||
}
|
||||
if treq.CreationTimestamp.IsZero() {
|
||||
t.Errorf("expected non-zero creation timestamp")
|
||||
}
|
||||
|
||||
checkPayload(t, treq.Status.Token, `"system:serviceaccount:myns:test-svcacct"`, "sub")
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
@@ -220,34 +251,44 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
warningHandler.clear()
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err == nil {
|
||||
t.Fatalf("expected err creating token for nonexistant svcacct but got: %#v", resp)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
sa, del := createDeleteSvcAcct(t, cs, sa)
|
||||
defer del()
|
||||
|
||||
warningHandler.clear()
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err == nil {
|
||||
t.Fatalf("expected err creating token bound to nonexistant pod but got: %#v", resp)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
pod, delPod := createDeletePod(t, cs, pod)
|
||||
defer delPod()
|
||||
|
||||
// right uid
|
||||
treq.Spec.BoundObjectRef.UID = pod.UID
|
||||
warningHandler.clear()
|
||||
if _, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
// wrong uid
|
||||
treq.Spec.BoundObjectRef.UID = wrongUID
|
||||
warningHandler.clear()
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err == nil {
|
||||
t.Fatalf("expected err creating token bound to pod with wrong uid but got: %#v", resp)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
// no uid
|
||||
treq.Spec.BoundObjectRef.UID = noUID
|
||||
warningHandler.clear()
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
checkPayload(t, treq.Status.Token, `"system:serviceaccount:myns:test-svcacct"`, "sub")
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
@@ -283,34 +324,44 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
warningHandler.clear()
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err == nil {
|
||||
t.Fatalf("expected err creating token for nonexistant svcacct but got: %#v", resp)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
sa, del := createDeleteSvcAcct(t, cs, sa)
|
||||
defer del()
|
||||
|
||||
warningHandler.clear()
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err == nil {
|
||||
t.Fatalf("expected err creating token bound to nonexistant secret but got: %#v", resp)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
secret, delSecret := createDeleteSecret(t, cs, secret)
|
||||
defer delSecret()
|
||||
|
||||
// right uid
|
||||
treq.Spec.BoundObjectRef.UID = secret.UID
|
||||
warningHandler.clear()
|
||||
if _, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
// wrong uid
|
||||
treq.Spec.BoundObjectRef.UID = wrongUID
|
||||
warningHandler.clear()
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err == nil {
|
||||
t.Fatalf("expected err creating token bound to secret with wrong uid but got: %#v", resp)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
// no uid
|
||||
treq.Spec.BoundObjectRef.UID = noUID
|
||||
warningHandler.clear()
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
checkPayload(t, treq.Status.Token, `"system:serviceaccount:myns:test-svcacct"`, "sub")
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
@@ -341,9 +392,11 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
_, del = createDeletePod(t, cs, otherpod)
|
||||
defer del()
|
||||
|
||||
warningHandler.clear()
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err == nil {
|
||||
t.Fatalf("expected err but got: %#v", resp)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
})
|
||||
|
||||
t.Run("expired token", func(t *testing.T) {
|
||||
@@ -356,10 +409,12 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
sa, del := createDeleteSvcAcct(t, cs, sa)
|
||||
defer del()
|
||||
|
||||
warningHandler.clear()
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
doTokenReview(t, cs, treq, false)
|
||||
|
||||
@@ -405,10 +460,12 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
defer delPod()
|
||||
treq.Spec.BoundObjectRef.UID = pod.UID
|
||||
|
||||
warningHandler.clear()
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
doTokenReview(t, cs, treq, false)
|
||||
|
||||
@@ -459,10 +516,12 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
defer delPod()
|
||||
treq.Spec.BoundObjectRef.UID = pod.UID
|
||||
|
||||
warningHandler.clear()
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
// Give some tolerance to avoid flakiness since we are using real time.
|
||||
var leeway int64 = 10
|
||||
@@ -499,10 +558,12 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
sa, del := createDeleteSvcAcct(t, cs, sa)
|
||||
defer del()
|
||||
|
||||
warningHandler.clear()
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
doTokenReview(t, cs, treq, true)
|
||||
})
|
||||
@@ -515,10 +576,12 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
sa, del := createDeleteSvcAcct(t, cs, sa)
|
||||
defer del()
|
||||
|
||||
warningHandler.clear()
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
|
||||
@@ -543,9 +606,11 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
defer originalDelPod()
|
||||
|
||||
treq.Spec.BoundObjectRef.UID = originalPod.UID
|
||||
warningHandler.clear()
|
||||
if treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
checkPayload(t, treq.Status.Token, `"system:serviceaccount:myns:test-svcacct"`, "sub")
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
@@ -584,9 +649,11 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
defer originalDelSecret()
|
||||
|
||||
treq.Spec.BoundObjectRef.UID = originalSecret.UID
|
||||
warningHandler.clear()
|
||||
if treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
checkPayload(t, treq.Status.Token, `"system:serviceaccount:myns:test-svcacct"`, "sub")
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
@@ -627,9 +694,11 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
defer originalDelSecret()
|
||||
|
||||
treq.Spec.BoundObjectRef.UID = originalSecret.UID
|
||||
warningHandler.clear()
|
||||
if treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
|
||||
checkPayload(t, treq.Status.Token, `"system:serviceaccount:myns:test-svcacct"`, "sub")
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
@@ -671,9 +740,11 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
defer originalDelSecret()
|
||||
|
||||
treq.Spec.BoundObjectRef.UID = originalSecret.UID
|
||||
warningHandler.clear()
|
||||
if treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(context.TODO(), sa.Name, treq, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, []string{fmt.Sprintf("requested expiration of %d seconds shortened to %d seconds", tooLongExpirationTime, maxExpirationSeconds)})
|
||||
|
||||
checkPayload(t, treq.Status.Token, `"system:serviceaccount:myns:test-svcacct"`, "sub")
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
@@ -698,6 +769,7 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
defer del()
|
||||
|
||||
t.Log("get token")
|
||||
warningHandler.clear()
|
||||
tokenRequest, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(
|
||||
context.TODO(),
|
||||
sa.Name,
|
||||
@@ -709,6 +781,7 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error creating token: %v", err)
|
||||
}
|
||||
warningHandler.assertEqual(t, nil)
|
||||
token := tokenRequest.Status.Token
|
||||
if token == "" {
|
||||
t.Fatal("no token")
|
||||
@@ -972,3 +1045,29 @@ func (f *fakeIndexer) GetByKey(key string) (interface{}, bool, error) {
|
||||
obj, err := f.get(namespace, name)
|
||||
return obj, err == nil, err
|
||||
}
|
||||
|
||||
type recordingWarningHandler struct {
|
||||
warnings []string
|
||||
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func (r *recordingWarningHandler) HandleWarningHeader(code int, agent string, message string) {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
r.warnings = append(r.warnings, message)
|
||||
}
|
||||
|
||||
func (r *recordingWarningHandler) clear() {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
r.warnings = nil
|
||||
}
|
||||
func (r *recordingWarningHandler) assertEqual(t *testing.T, expected []string) {
|
||||
t.Helper()
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
if !reflect.DeepEqual(r.warnings, expected) {
|
||||
t.Errorf("expected\n\t%v\ngot\n\t%v", expected, r.warnings)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user