mirror of https://github.com/k3s-io/k3s
Merge pull request #72688 from liggitt/token-test
Update service account token mount testpull/564/head
commit
6a8ad537a7
|
@ -25,6 +25,7 @@ go_library(
|
||||||
"//pkg/security/podsecuritypolicy/util:go_default_library",
|
"//pkg/security/podsecuritypolicy/util:go_default_library",
|
||||||
"//plugin/pkg/admission/serviceaccount:go_default_library",
|
"//plugin/pkg/admission/serviceaccount:go_default_library",
|
||||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/api/authentication/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/batch/v1:go_default_library",
|
"//staging/src/k8s.io/api/batch/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
@ -37,6 +38,7 @@ go_library(
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/apis/audit:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/apis/audit:go_default_library",
|
||||||
|
|
|
@ -18,11 +18,14 @@ package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
authenticationv1 "k8s.io/api/authentication/v1"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/uuid"
|
"k8s.io/apimachinery/pkg/util/uuid"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"
|
"k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"
|
||||||
|
@ -163,23 +166,25 @@ var _ = SIGDescribe("ServiceAccounts", func() {
|
||||||
Account mount path MUST be auto mounted to the Container.
|
Account mount path MUST be auto mounted to the Container.
|
||||||
*/
|
*/
|
||||||
framework.ConformanceIt("should mount an API token into pods ", func() {
|
framework.ConformanceIt("should mount an API token into pods ", func() {
|
||||||
var tokenContent string
|
|
||||||
var rootCAContent string
|
var rootCAContent string
|
||||||
|
|
||||||
|
sa, err := f.ClientSet.CoreV1().ServiceAccounts(f.Namespace.Name).Create(&v1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "mount-test"}})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
// Standard get, update retry loop
|
// Standard get, update retry loop
|
||||||
framework.ExpectNoError(wait.Poll(time.Millisecond*500, framework.ServiceAccountProvisionTimeout, func() (bool, error) {
|
framework.ExpectNoError(wait.Poll(time.Millisecond*500, framework.ServiceAccountProvisionTimeout, func() (bool, error) {
|
||||||
By("getting the auto-created API token")
|
By("getting the auto-created API token")
|
||||||
sa, err := f.ClientSet.CoreV1().ServiceAccounts(f.Namespace.Name).Get("default", metav1.GetOptions{})
|
sa, err := f.ClientSet.CoreV1().ServiceAccounts(f.Namespace.Name).Get("mount-test", metav1.GetOptions{})
|
||||||
if apierrors.IsNotFound(err) {
|
if apierrors.IsNotFound(err) {
|
||||||
framework.Logf("default service account was not found")
|
framework.Logf("mount-test service account was not found")
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Logf("error getting default service account: %v", err)
|
framework.Logf("error getting mount-test service account: %v", err)
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if len(sa.Secrets) == 0 {
|
if len(sa.Secrets) == 0 {
|
||||||
framework.Logf("default service account has no secret references")
|
framework.Logf("mount-test service account has no secret references")
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
for _, secretRef := range sa.Secrets {
|
for _, secretRef := range sa.Secrets {
|
||||||
|
@ -189,7 +194,6 @@ var _ = SIGDescribe("ServiceAccounts", func() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if secret.Type == v1.SecretTypeServiceAccountToken {
|
if secret.Type == v1.SecretTypeServiceAccountToken {
|
||||||
tokenContent = string(secret.Data[v1.ServiceAccountTokenKey])
|
|
||||||
rootCAContent = string(secret.Data[v1.ServiceAccountRootCAKey])
|
rootCAContent = string(secret.Data[v1.ServiceAccountRootCAKey])
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
@ -199,49 +203,46 @@ var _ = SIGDescribe("ServiceAccounts", func() {
|
||||||
return false, nil
|
return false, nil
|
||||||
}))
|
}))
|
||||||
|
|
||||||
pod := &v1.Pod{
|
zero := int64(0)
|
||||||
|
pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(&v1.Pod{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
GenerateName: "pod-service-account-" + string(uuid.NewUUID()) + "-",
|
Name: "pod-service-account-" + string(uuid.NewUUID()),
|
||||||
},
|
},
|
||||||
Spec: v1.PodSpec{
|
Spec: v1.PodSpec{
|
||||||
Containers: []v1.Container{
|
ServiceAccountName: sa.Name,
|
||||||
{
|
Containers: []v1.Container{{
|
||||||
Name: "token-test",
|
Name: "test",
|
||||||
Image: mountImage,
|
Image: imageutils.GetE2EImage(imageutils.BusyBox),
|
||||||
Args: []string{
|
Command: []string{"sleep", "100000"}, // run and pause
|
||||||
fmt.Sprintf("--file_content=%s/%s", serviceaccount.DefaultAPITokenMountPath, v1.ServiceAccountTokenKey),
|
}},
|
||||||
},
|
TerminationGracePeriodSeconds: &zero, // terminate quickly when deleted
|
||||||
},
|
RestartPolicy: v1.RestartPolicyNever, // never restart
|
||||||
{
|
|
||||||
Name: "root-ca-test",
|
|
||||||
Image: mountImage,
|
|
||||||
Args: []string{
|
|
||||||
fmt.Sprintf("--file_content=%s/%s", serviceaccount.DefaultAPITokenMountPath, v1.ServiceAccountRootCAKey),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
RestartPolicy: v1.RestartPolicyNever,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.Spec.Containers = append(pod.Spec.Containers, v1.Container{
|
|
||||||
Name: "namespace-test",
|
|
||||||
Image: mountImage,
|
|
||||||
Args: []string{
|
|
||||||
fmt.Sprintf("--file_content=%s/%s", serviceaccount.DefaultAPITokenMountPath, v1.ServiceAccountNamespaceKey),
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
framework.ExpectNoError(framework.WaitForPodRunningInNamespace(f.ClientSet, pod))
|
||||||
|
|
||||||
f.TestContainerOutput("consume service account token", pod, 0, []string{
|
mountedToken, err := f.ReadFileViaContainer(pod.Name, pod.Spec.Containers[0].Name, path.Join(serviceaccount.DefaultAPITokenMountPath, v1.ServiceAccountTokenKey))
|
||||||
fmt.Sprintf(`content of file "%s/%s": %s`, serviceaccount.DefaultAPITokenMountPath, v1.ServiceAccountTokenKey, tokenContent),
|
framework.ExpectNoError(err)
|
||||||
})
|
mountedCA, err := f.ReadFileViaContainer(pod.Name, pod.Spec.Containers[0].Name, path.Join(serviceaccount.DefaultAPITokenMountPath, v1.ServiceAccountRootCAKey))
|
||||||
f.TestContainerOutput("consume service account root CA", pod, 1, []string{
|
framework.ExpectNoError(err)
|
||||||
fmt.Sprintf(`content of file "%s/%s": %s`, serviceaccount.DefaultAPITokenMountPath, v1.ServiceAccountRootCAKey, rootCAContent),
|
mountedNamespace, err := f.ReadFileViaContainer(pod.Name, pod.Spec.Containers[0].Name, path.Join(serviceaccount.DefaultAPITokenMountPath, v1.ServiceAccountNamespaceKey))
|
||||||
})
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
f.TestContainerOutput("consume service account namespace", pod, 2, []string{
|
// CA and namespace should be identical
|
||||||
fmt.Sprintf(`content of file "%s/%s": %s`, serviceaccount.DefaultAPITokenMountPath, v1.ServiceAccountNamespaceKey, f.Namespace.Name),
|
Expect(mountedCA).To(Equal(rootCAContent))
|
||||||
})
|
Expect(mountedNamespace).To(Equal(f.Namespace.Name))
|
||||||
|
// Token should be a valid credential that identifies the pod's service account
|
||||||
|
tokenReview := &authenticationv1.TokenReview{Spec: authenticationv1.TokenReviewSpec{Token: mountedToken}}
|
||||||
|
tokenReview, err = f.ClientSet.AuthenticationV1().TokenReviews().Create(tokenReview)
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
Expect(tokenReview.Status.Authenticated).To(Equal(true))
|
||||||
|
Expect(tokenReview.Status.Error).To(Equal(""))
|
||||||
|
Expect(tokenReview.Status.User.Username).To(Equal("system:serviceaccount:" + f.Namespace.Name + ":" + sa.Name))
|
||||||
|
groups := sets.NewString(tokenReview.Status.User.Groups...)
|
||||||
|
Expect(groups.Has("system:authenticated")).To(Equal(true), fmt.Sprintf("expected system:authenticated group, had %v", groups.List()))
|
||||||
|
Expect(groups.Has("system:serviceaccounts")).To(Equal(true), fmt.Sprintf("expected system:serviceaccounts group, had %v", groups.List()))
|
||||||
|
Expect(groups.Has("system:serviceaccounts:"+f.Namespace.Name)).To(Equal(true), fmt.Sprintf("expected system:serviceaccounts:"+f.Namespace.Name+" group, had %v", groups.List()))
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue