mirror of https://github.com/k3s-io/k3s
Merge pull request #71007 from mikedanese/allowdefault
TokenRequestProjections should allow API server to default empty audiencepull/58/head
commit
5a84dffc75
|
@ -11,15 +11,22 @@ go_test(
|
|||
srcs = ["projected_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/authentication/v1:go_default_library",
|
||||
"//pkg/apis/core/v1:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/emptydir:go_default_library",
|
||||
"//pkg/volume/testing:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//staging/src/k8s.io/api/authentication/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -326,11 +326,14 @@ func (s *projectedVolumeMounter) collectData() (map[string]volumeutil.FileProjec
|
|||
continue
|
||||
}
|
||||
tp := source.ServiceAccountToken
|
||||
|
||||
var auds []string
|
||||
if len(tp.Audience) != 0 {
|
||||
auds = []string{tp.Audience}
|
||||
}
|
||||
tr, err := s.plugin.getServiceAccountToken(s.pod.Namespace, s.pod.Spec.ServiceAccountName, &authenticationv1.TokenRequest{
|
||||
Spec: authenticationv1.TokenRequestSpec{
|
||||
Audiences: []string{
|
||||
tp.Audience,
|
||||
},
|
||||
Audiences: auds,
|
||||
ExpirationSeconds: tp.ExpirationSeconds,
|
||||
BoundObjectRef: &authenticationv1.BoundObjectReference{
|
||||
APIVersion: "v1",
|
||||
|
|
|
@ -25,11 +25,18 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
authenticationv1 "k8s.io/api/authentication/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
clitesting "k8s.io/client-go/testing"
|
||||
pkgauthenticationv1 "k8s.io/kubernetes/pkg/apis/authentication/v1"
|
||||
pkgcorev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/emptydir"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
|
@ -699,6 +706,113 @@ func TestCollectDataWithDownwardAPI(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCollectDataWithServiceAccountToken(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
utilruntime.Must(pkgauthenticationv1.RegisterDefaults(scheme))
|
||||
utilruntime.Must(pkgcorev1.RegisterDefaults(scheme))
|
||||
|
||||
minute := int64(60)
|
||||
cases := []struct {
|
||||
name string
|
||||
svcacct string
|
||||
audience string
|
||||
expiration *int64
|
||||
path string
|
||||
|
||||
payload map[string]util.FileProjection
|
||||
}{
|
||||
{
|
||||
name: "test good service account",
|
||||
audience: "https://example.com",
|
||||
path: "token",
|
||||
expiration: &minute,
|
||||
|
||||
payload: map[string]util.FileProjection{
|
||||
"token": {Data: []byte("test_projected_namespace:foo:60:[https://example.com]"), Mode: 0600},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "test good service account other path",
|
||||
audience: "https://example.com",
|
||||
path: "other-token",
|
||||
expiration: &minute,
|
||||
|
||||
payload: map[string]util.FileProjection{
|
||||
"other-token": {Data: []byte("test_projected_namespace:foo:60:[https://example.com]"), Mode: 0600},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "test good service account defaults audience",
|
||||
path: "token",
|
||||
expiration: &minute,
|
||||
|
||||
payload: map[string]util.FileProjection{
|
||||
"token": {Data: []byte("test_projected_namespace:foo:60:[https://api]"), Mode: 0600},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "test good service account defaults expiration",
|
||||
audience: "https://example.com",
|
||||
path: "token",
|
||||
|
||||
payload: map[string]util.FileProjection{
|
||||
"token": {Data: []byte("test_projected_namespace:foo:3600:[https://example.com]"), Mode: 0600},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
testNamespace := "test_projected_namespace"
|
||||
source := makeProjection(tc.name, 0600, "serviceAccountToken")
|
||||
source.Sources[0].ServiceAccountToken.Audience = tc.audience
|
||||
source.Sources[0].ServiceAccountToken.ExpirationSeconds = tc.expiration
|
||||
source.Sources[0].ServiceAccountToken.Path = tc.path
|
||||
|
||||
testPodUID := types.UID("test_pod_uid")
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, UID: testPodUID},
|
||||
Spec: v1.PodSpec{ServiceAccountName: "foo"},
|
||||
}
|
||||
scheme.Default(pod)
|
||||
|
||||
client := &fake.Clientset{}
|
||||
client.AddReactor("create", "serviceaccounts", clitesting.ReactionFunc(func(action clitesting.Action) (bool, runtime.Object, error) {
|
||||
tr := action.(clitesting.CreateAction).GetObject().(*authenticationv1.TokenRequest)
|
||||
scheme.Default(tr)
|
||||
if len(tr.Spec.Audiences) == 0 {
|
||||
tr.Spec.Audiences = []string{"https://api"}
|
||||
}
|
||||
tr.Status.Token = fmt.Sprintf("%v:%v:%d:%v", action.GetNamespace(), "foo", *tr.Spec.ExpirationSeconds, tr.Spec.Audiences)
|
||||
return true, tr, nil
|
||||
}))
|
||||
|
||||
_, host := newTestHost(t, client)
|
||||
|
||||
var myVolumeMounter = projectedVolumeMounter{
|
||||
projectedVolume: &projectedVolume{
|
||||
sources: source.Sources,
|
||||
podUID: pod.UID,
|
||||
plugin: &projectedPlugin{
|
||||
host: host,
|
||||
getServiceAccountToken: host.GetServiceAccountTokenFunc(),
|
||||
},
|
||||
},
|
||||
source: *source,
|
||||
pod: pod,
|
||||
}
|
||||
|
||||
actualPayload, err := myVolumeMounter.collectData()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected failure making payload: %v", err)
|
||||
}
|
||||
if e, a := tc.payload, actualPayload; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expected and actual payload do not match:\n%s", diff.ObjectReflectDiff(e, a))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newTestHost(t *testing.T, clientset clientset.Interface) (string, volume.VolumeHost) {
|
||||
tempDir, err := ioutil.TempDir("/tmp", "projected_volume_test.")
|
||||
if err != nil {
|
||||
|
@ -1113,6 +1227,10 @@ func makeProjection(name string, defaultMode int32, kind string) *v1.ProjectedVo
|
|||
item = v1.VolumeProjection{
|
||||
DownwardAPI: &v1.DownwardAPIProjection{},
|
||||
}
|
||||
case "serviceAccountToken":
|
||||
item = v1.VolumeProjection{
|
||||
ServiceAccountToken: &v1.ServiceAccountTokenProjection{},
|
||||
}
|
||||
}
|
||||
|
||||
return &v1.ProjectedVolumeSource{
|
||||
|
|
Loading…
Reference in New Issue