Skip to content

Commit

Permalink
Merge pull request #71432 from mikedanese/automated-cherry-pick-of-#7…
Browse files Browse the repository at this point in the history
…1007-upstream-release-1.12

Automated cherry pick of #71007 into upstream release 1.12
  • Loading branch information
k8s-ci-robot committed Nov 28, 2018
2 parents 24f67a6 + eac3227 commit bcc3642
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 3 deletions.
7 changes: 7 additions & 0 deletions pkg/volume/projected/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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/empty_dir: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",
],
)

Expand Down
9 changes: 6 additions & 3 deletions pkg/volume/projected/projected.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,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",
Expand Down
118 changes: 118 additions & 0 deletions pkg/volume/projected/projected_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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/empty_dir"
volumetest "k8s.io/kubernetes/pkg/volume/testing"
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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{
Expand Down

0 comments on commit bcc3642

Please sign in to comment.