mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Merge pull request #60324 from mikedanese/id-test1
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. integration: refactor, cleanup, and add more tests for TokenRequest ref #58790 ```release-note NONE ```
This commit is contained in:
commit
15e34b13c4
@ -25,6 +25,7 @@ import (
|
||||
authenticationv1 "k8s.io/api/authentication/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
|
||||
@ -63,103 +64,162 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
sa := &v1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
|
||||
tr1 := &authenticationv1.TokenRequest{
|
||||
Spec: authenticationv1.TokenRequestSpec{
|
||||
Audiences: []string{"aud"},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = cs.CoreV1().ServiceAccounts(sa.Namespace).Create(sa)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
tr1, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, tr1)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
checkPayload(t, tr1.Status.Token, `"system:serviceaccount:default:test"`, "sub")
|
||||
checkPayload(t, tr1.Status.Token, `["aud"]`, "aud")
|
||||
checkPayload(t, tr1.Status.Token, "null", "kubernetes.io", "pod")
|
||||
checkPayload(t, tr1.Status.Token, "null", "kubernetes.io", "secret")
|
||||
checkPayload(t, tr1.Status.Token, `"default"`, "kubernetes.io", "namespace")
|
||||
checkPayload(t, tr1.Status.Token, `"test"`, "kubernetes.io", "serviceaccount", "name")
|
||||
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-pod",
|
||||
Namespace: sa.Namespace,
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ServiceAccountName: sa.Name,
|
||||
Containers: []v1.Container{{Name: "test-container", Image: "nginx"}},
|
||||
},
|
||||
}
|
||||
_, err = cs.CoreV1().Pods(pod.Namespace).Create(pod)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
tr2 := &authenticationv1.TokenRequest{
|
||||
Spec: authenticationv1.TokenRequestSpec{
|
||||
Audiences: []string{"aud"},
|
||||
BoundObjectRef: &authenticationv1.BoundObjectReference{
|
||||
Kind: "Pod",
|
||||
APIVersion: "v1",
|
||||
Name: pod.Name,
|
||||
var (
|
||||
sa = &v1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-svcacct",
|
||||
Namespace: "myns",
|
||||
},
|
||||
},
|
||||
}
|
||||
tr2, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, tr2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
checkPayload(t, tr2.Status.Token, `"system:serviceaccount:default:test"`, "sub")
|
||||
checkPayload(t, tr2.Status.Token, `["aud"]`, "aud")
|
||||
checkPayload(t, tr2.Status.Token, `"test-pod"`, "kubernetes.io", "pod", "name")
|
||||
checkPayload(t, tr2.Status.Token, "null", "kubernetes.io", "secret")
|
||||
checkPayload(t, tr2.Status.Token, `"default"`, "kubernetes.io", "namespace")
|
||||
checkPayload(t, tr2.Status.Token, `"test"`, "kubernetes.io", "serviceaccount", "name")
|
||||
|
||||
secret := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-secret",
|
||||
Namespace: sa.Namespace,
|
||||
},
|
||||
}
|
||||
_, err = cs.CoreV1().Secrets(secret.Namespace).Create(secret)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
tr3 := &authenticationv1.TokenRequest{
|
||||
Spec: authenticationv1.TokenRequestSpec{
|
||||
Audiences: []string{"aud"},
|
||||
BoundObjectRef: &authenticationv1.BoundObjectReference{
|
||||
Kind: "Secret",
|
||||
APIVersion: "v1",
|
||||
Name: secret.Name,
|
||||
}
|
||||
pod = &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-pod",
|
||||
Namespace: sa.Namespace,
|
||||
},
|
||||
},
|
||||
}
|
||||
tr3, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, tr3)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
Spec: v1.PodSpec{
|
||||
ServiceAccountName: sa.Name,
|
||||
Containers: []v1.Container{{Name: "test-container", Image: "nginx"}},
|
||||
},
|
||||
}
|
||||
secret = &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-secret",
|
||||
Namespace: sa.Namespace,
|
||||
},
|
||||
}
|
||||
|
||||
checkPayload(t, tr2.Status.Token, `"system:serviceaccount:default:test"`, "sub")
|
||||
checkPayload(t, tr2.Status.Token, `["aud"]`, "aud")
|
||||
checkPayload(t, tr2.Status.Token, `"test-pod"`, "kubernetes.io", "pod", "name")
|
||||
checkPayload(t, tr2.Status.Token, `null`, "kubernetes.io", "secret")
|
||||
checkPayload(t, tr2.Status.Token, `"default"`, "kubernetes.io", "namespace")
|
||||
checkPayload(t, tr2.Status.Token, `"test"`, "kubernetes.io", "serviceaccount", "name")
|
||||
one = int64(1)
|
||||
wrongUID = types.UID("wrong")
|
||||
noUID = types.UID("")
|
||||
)
|
||||
|
||||
t.Run("bound to service account", func(t *testing.T) {
|
||||
treq := &authenticationv1.TokenRequest{
|
||||
Spec: authenticationv1.TokenRequestSpec{
|
||||
Audiences: []string{"api"},
|
||||
ExpirationSeconds: &one,
|
||||
},
|
||||
}
|
||||
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq); err == nil {
|
||||
t.Fatalf("expected err creating token for nonexistant svcacct but got: %#v", resp)
|
||||
}
|
||||
sa, del := createDeleteSvcAcct(t, cs, sa)
|
||||
defer del()
|
||||
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
checkPayload(t, treq.Status.Token, `"system:serviceaccount:myns:test-svcacct"`, "sub")
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
checkPayload(t, treq.Status.Token, "null", "kubernetes.io", "pod")
|
||||
checkPayload(t, treq.Status.Token, "null", "kubernetes.io", "secret")
|
||||
checkPayload(t, treq.Status.Token, `"myns"`, "kubernetes.io", "namespace")
|
||||
checkPayload(t, treq.Status.Token, `"test-svcacct"`, "kubernetes.io", "serviceaccount", "name")
|
||||
})
|
||||
|
||||
t.Run("bound to service account and pod", func(t *testing.T) {
|
||||
treq := &authenticationv1.TokenRequest{
|
||||
Spec: authenticationv1.TokenRequestSpec{
|
||||
Audiences: []string{"api"},
|
||||
ExpirationSeconds: &one,
|
||||
BoundObjectRef: &authenticationv1.BoundObjectReference{
|
||||
Kind: "Pod",
|
||||
APIVersion: "v1",
|
||||
Name: pod.Name,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq); err == nil {
|
||||
t.Fatalf("expected err creating token for nonexistant svcacct but got: %#v", resp)
|
||||
}
|
||||
sa, del := createDeleteSvcAcct(t, cs, sa)
|
||||
defer del()
|
||||
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq); err == nil {
|
||||
t.Fatalf("expected err creating token bound to nonexistant pod but got: %#v", resp)
|
||||
}
|
||||
pod, del := createDeletePod(t, cs, pod)
|
||||
defer del()
|
||||
|
||||
// right uid
|
||||
treq.Spec.BoundObjectRef.UID = pod.UID
|
||||
if _, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
// wrong uid
|
||||
treq.Spec.BoundObjectRef.UID = wrongUID
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq); err == nil {
|
||||
t.Fatalf("expected err creating token bound to pod with wrong uid but got: %#v", resp)
|
||||
}
|
||||
// no uid
|
||||
treq.Spec.BoundObjectRef.UID = noUID
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
checkPayload(t, treq.Status.Token, `"system:serviceaccount:myns:test-svcacct"`, "sub")
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
checkPayload(t, treq.Status.Token, `"test-pod"`, "kubernetes.io", "pod", "name")
|
||||
checkPayload(t, treq.Status.Token, "null", "kubernetes.io", "secret")
|
||||
checkPayload(t, treq.Status.Token, `"myns"`, "kubernetes.io", "namespace")
|
||||
checkPayload(t, treq.Status.Token, `"test-svcacct"`, "kubernetes.io", "serviceaccount", "name")
|
||||
})
|
||||
|
||||
t.Run("bound to service account and secret", func(t *testing.T) {
|
||||
treq := &authenticationv1.TokenRequest{
|
||||
Spec: authenticationv1.TokenRequestSpec{
|
||||
Audiences: []string{"api"},
|
||||
ExpirationSeconds: &one,
|
||||
BoundObjectRef: &authenticationv1.BoundObjectReference{
|
||||
Kind: "Secret",
|
||||
APIVersion: "v1",
|
||||
Name: secret.Name,
|
||||
UID: secret.UID,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq); err == nil {
|
||||
t.Fatalf("expected err creating token for nonexistant svcacct but got: %#v", resp)
|
||||
}
|
||||
sa, del := createDeleteSvcAcct(t, cs, sa)
|
||||
defer del()
|
||||
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq); err == nil {
|
||||
t.Fatalf("expected err creating token bound to nonexistant secret but got: %#v", resp)
|
||||
}
|
||||
secret, del := createDeleteSecret(t, cs, secret)
|
||||
defer del()
|
||||
|
||||
// right uid
|
||||
treq.Spec.BoundObjectRef.UID = secret.UID
|
||||
if _, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
// wrong uid
|
||||
treq.Spec.BoundObjectRef.UID = wrongUID
|
||||
if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq); err == nil {
|
||||
t.Fatalf("expected err creating token bound to secret with wrong uid but got: %#v", resp)
|
||||
}
|
||||
// no uid
|
||||
treq.Spec.BoundObjectRef.UID = noUID
|
||||
treq, err = cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
checkPayload(t, treq.Status.Token, `"system:serviceaccount:myns:test-svcacct"`, "sub")
|
||||
checkPayload(t, treq.Status.Token, `["api"]`, "aud")
|
||||
checkPayload(t, treq.Status.Token, `null`, "kubernetes.io", "pod")
|
||||
checkPayload(t, treq.Status.Token, `"test-secret"`, "kubernetes.io", "secret", "name")
|
||||
checkPayload(t, treq.Status.Token, `"myns"`, "kubernetes.io", "namespace")
|
||||
checkPayload(t, treq.Status.Token, `"test-svcacct"`, "kubernetes.io", "serviceaccount", "name")
|
||||
})
|
||||
}
|
||||
|
||||
func checkPayload(t *testing.T, tok string, want string, parts ...string) {
|
||||
@ -199,3 +259,45 @@ func getPayload(t *testing.T, b string) string {
|
||||
}
|
||||
return string(payload)
|
||||
}
|
||||
|
||||
func createDeleteSvcAcct(t *testing.T, cs clientset.Interface, sa *v1.ServiceAccount) (*v1.ServiceAccount, func()) {
|
||||
t.Helper()
|
||||
sa, err := cs.CoreV1().ServiceAccounts(sa.Namespace).Create(sa)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
return sa, func() {
|
||||
t.Helper()
|
||||
if err := cs.CoreV1().ServiceAccounts(sa.Namespace).Delete(sa.Name, nil); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createDeletePod(t *testing.T, cs clientset.Interface, pod *v1.Pod) (*v1.Pod, func()) {
|
||||
t.Helper()
|
||||
pod, err := cs.CoreV1().Pods(pod.Namespace).Create(pod)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
return pod, func() {
|
||||
t.Helper()
|
||||
if err := cs.CoreV1().Pods(pod.Namespace).Delete(pod.Name, nil); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createDeleteSecret(t *testing.T, cs clientset.Interface, sec *v1.Secret) (*v1.Secret, func()) {
|
||||
t.Helper()
|
||||
sec, err := cs.CoreV1().Secrets(sec.Namespace).Create(sec)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
return sec, func() {
|
||||
t.Helper()
|
||||
if err := cs.CoreV1().Secrets(sec.Namespace).Delete(sec.Name, nil); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user