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:
Kubernetes Submit Queue 2018-02-24 19:30:56 -08:00 committed by GitHub
commit 15e34b13c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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)
}
}
}