Skip to content

Commit 988982a

Browse files
authored
Merge pull request kubernetes#88048 from mtaufen/provider-info-e2etest
Add e2e test for validating JWTs as OIDC tokens
2 parents ab40772 + aee9fde commit 988982a

File tree

3 files changed

+105
-2
lines changed

3 files changed

+105
-2
lines changed

cluster/gce/config-test.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,9 @@ ROTATE_CERTIFICATES="${ROTATE_CERTIFICATES:-}"
517517
# into kube-controller-manager via `--concurrent-service-syncs`
518518
CONCURRENT_SERVICE_SYNCS="${CONCURRENT_SERVICE_SYNCS:-}"
519519

520-
SERVICEACCOUNT_ISSUER="https://kubernetes.io/${CLUSTER_NAME}"
520+
# The value kubernetes.default.svc is only usable in Pods and should only be
521+
# set for tests. DO NOT COPY THIS VALUE FOR PRODUCTION CLUSTERS.
522+
SERVICEACCOUNT_ISSUER="https://kubernetes.default.svc"
521523

522524
# Optional: Enable Node termination Handler for Preemptible and GPU VMs.
523525
# https://github.com/GoogleCloudPlatform/k8s-node-termination-handler

test/e2e/auth/service_accounts.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
authenticationv1 "k8s.io/api/authentication/v1"
2828
v1 "k8s.io/api/core/v1"
29+
rbacv1 "k8s.io/api/rbac/v1"
2930
apierrors "k8s.io/apimachinery/pkg/api/errors"
3031
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3132
"k8s.io/apimachinery/pkg/util/sets"
@@ -520,6 +521,106 @@ var _ = SIGDescribe("ServiceAccounts", func() {
520521
framework.Failf("Unexpected error: %v\n%s", err, logs)
521522
}
522523
})
524+
525+
ginkgo.It("should support OIDC discovery of service account issuer [Feature:ServiceAccountIssuerDiscovery]", func() {
526+
// Allow the test pod access to the OIDC discovery non-resource URLs.
527+
// The role should have already been automatically created as part of the
528+
// bootstrap policy, but not the role binding.
529+
const clusterRoleName = "system:service-account-issuer-discovery"
530+
crbName := fmt.Sprintf("%s-%s", f.Namespace.Name, clusterRoleName)
531+
if _, err := f.ClientSet.RbacV1().ClusterRoleBindings().Create(
532+
context.TODO(),
533+
&rbacv1.ClusterRoleBinding{
534+
ObjectMeta: metav1.ObjectMeta{
535+
Name: crbName,
536+
},
537+
Subjects: []rbacv1.Subject{
538+
{
539+
Kind: rbacv1.ServiceAccountKind,
540+
APIGroup: "",
541+
Name: "default",
542+
Namespace: f.Namespace.Name,
543+
},
544+
},
545+
RoleRef: rbacv1.RoleRef{
546+
Name: clusterRoleName,
547+
APIGroup: rbacv1.GroupName,
548+
Kind: "ClusterRole",
549+
},
550+
},
551+
metav1.CreateOptions{}); err != nil && !apierrors.IsAlreadyExists(err) {
552+
framework.Failf("Unexpected err creating ClusterRoleBinding %s: %v", crbName, err)
553+
}
554+
555+
// Create the pod with tokens.
556+
tokenPath := "/var/run/secrets/tokens"
557+
tokenName := "sa-token"
558+
audience := "oidc-discovery-test"
559+
tenMin := int64(10 * 60)
560+
561+
pod := &v1.Pod{
562+
ObjectMeta: metav1.ObjectMeta{Name: "oidc-discovery-validator"},
563+
Spec: v1.PodSpec{
564+
Containers: []v1.Container{{
565+
Name: "oidc-discovery-validator",
566+
Image: imageutils.GetE2EImage(imageutils.Agnhost),
567+
Args: []string{
568+
"test-service-account-issuer-discovery",
569+
"--in-cluster-discovery",
570+
"--token-path", path.Join(tokenPath, tokenName),
571+
"--audience", audience,
572+
},
573+
VolumeMounts: []v1.VolumeMount{{
574+
MountPath: tokenPath,
575+
Name: tokenName,
576+
ReadOnly: true,
577+
}},
578+
}},
579+
RestartPolicy: v1.RestartPolicyNever,
580+
ServiceAccountName: "default",
581+
Volumes: []v1.Volume{{
582+
Name: tokenName,
583+
VolumeSource: v1.VolumeSource{
584+
Projected: &v1.ProjectedVolumeSource{
585+
Sources: []v1.VolumeProjection{
586+
{
587+
ServiceAccountToken: &v1.ServiceAccountTokenProjection{
588+
Path: tokenName,
589+
ExpirationSeconds: &tenMin,
590+
Audience: audience,
591+
},
592+
},
593+
},
594+
},
595+
},
596+
}},
597+
},
598+
}
599+
pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(context.TODO(), pod, metav1.CreateOptions{})
600+
framework.ExpectNoError(err)
601+
602+
framework.Logf("created pod")
603+
podErr := e2epod.WaitForPodSuccessInNamespace(f.ClientSet, pod.Name, f.Namespace.Name)
604+
605+
// Get the logs before calling ExpectNoError, so we can debug any errors.
606+
var logs string
607+
if err := wait.Poll(30*time.Second, 2*time.Minute, func() (done bool, err error) {
608+
framework.Logf("polling logs")
609+
logs, err = e2epod.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, pod.Spec.Containers[0].Name)
610+
if err != nil {
611+
framework.Logf("Error pulling logs: %v", err)
612+
return false, nil
613+
}
614+
return true, nil
615+
}); err != nil {
616+
framework.Failf("Unexpected error getting pod logs: %v\n%s", err, logs)
617+
} else {
618+
framework.Logf("Pod logs: \n%v", logs)
619+
}
620+
621+
framework.ExpectNoError(podErr)
622+
framework.Logf("completed pod")
623+
})
523624
})
524625

525626
var reportLogsParser = regexp.MustCompile("([a-zA-Z0-9-_]*)=([a-zA-Z0-9-_]*)$")

test/utils/image/manifest.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ const (
205205

206206
func initImageConfigs() map[int]Config {
207207
configs := map[int]Config{}
208-
configs[Agnhost] = Config{promoterE2eRegistry, "agnhost", "2.10"}
208+
configs[Agnhost] = Config{promoterE2eRegistry, "agnhost", "2.12"}
209209
configs[AgnhostPrivate] = Config{PrivateRegistry, "agnhost", "2.6"}
210210
configs[AuthenticatedAlpine] = Config{gcAuthenticatedRegistry, "alpine", "3.7"}
211211
configs[AuthenticatedWindowsNanoServer] = Config{gcAuthenticatedRegistry, "windows-nanoserver", "v1"}

0 commit comments

Comments
 (0)