Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
ca696fef
Unverified
Commit
ca696fef
authored
Nov 16, 2018
by
k8s-ci-robot
Committed by
GitHub
Nov 16, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #69848 from mikedanese/projadmission
migrate service account volume to a projected volume when BoundServiceAccountTokenVolumes are enabled
parents
9bd9bf71
1244ee66
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
287 additions
and
32 deletions
+287
-32
typha-horizontal-autoscaler-deployment.yaml
...cy-controller/typha-horizontal-autoscaler-deployment.yaml
+3
-0
heapster-controller.yaml
...addons/cluster-monitoring/google/heapster-controller.yaml
+3
-0
heapster-controller-combined.yaml
...nitoring/googleinfluxdb/heapster-controller-combined.yaml
+3
-0
heapster-controller.yaml
...dons/cluster-monitoring/influxdb/heapster-controller.yaml
+3
-0
heapster-controller.yaml
...s/cluster-monitoring/stackdriver/heapster-controller.yaml
+3
-0
heapster-controller.yaml
...ns/cluster-monitoring/standalone/heapster-controller.yaml
+3
-0
dns-horizontal-autoscaler.yaml
.../dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml
+3
-0
kube-dns.yaml.base
cluster/addons/dns/kube-dns/kube-dns.yaml.base
+3
-0
kube-dns.yaml.in
cluster/addons/dns/kube-dns/kube-dns.yaml.in
+3
-0
kube-dns.yaml.sed
cluster/addons/dns/kube-dns/kube-dns.yaml.sed
+3
-0
event-exporter-psp.yaml
...s/fluentd-gcp/podsecuritypolicies/event-exporter-psp.yaml
+1
-0
fluentd-gcp-psp.yaml
...dons/fluentd-gcp/podsecuritypolicies/fluentd-gcp-psp.yaml
+1
-0
persistent-volume-binder.yaml
.../addons/podsecuritypolicies/persistent-volume-binder.yaml
+1
-0
unprivileged-addon.yaml
...er/gce/addons/podsecuritypolicies/unprivileged-addon.yaml
+1
-0
BUILD
plugin/pkg/admission/serviceaccount/BUILD
+4
-0
admission.go
plugin/pkg/admission/serviceaccount/admission.go
+83
-17
admission_test.go
plugin/pkg/admission/serviceaccount/admission_test.go
+166
-15
No files found.
cluster/addons/calico-policy-controller/typha-horizontal-autoscaler-deployment.yaml
View file @
ca696fef
...
...
@@ -17,6 +17,9 @@ spec:
scheduler.alpha.kubernetes.io/critical-pod
:
'
'
spec
:
priorityClassName
:
system-cluster-critical
securityContext
:
supplementalGroups
:
[
65534
]
fsGroup
:
65534
containers
:
-
image
:
k8s.gcr.io/cluster-proportional-autoscaler-amd64:1.1.2-r2
name
:
autoscaler
...
...
cluster/addons/cluster-monitoring/google/heapster-controller.yaml
View file @
ca696fef
...
...
@@ -59,6 +59,9 @@ spec:
seccomp.security.alpha.kubernetes.io/pod
:
'
docker/default'
spec
:
priorityClassName
:
system-cluster-critical
securityContext
:
supplementalGroups
:
[
65534
]
fsGroup
:
65534
containers
:
-
image
:
k8s.gcr.io/heapster-amd64:v1.6.0-beta.1
name
:
heapster
...
...
cluster/addons/cluster-monitoring/googleinfluxdb/heapster-controller-combined.yaml
View file @
ca696fef
...
...
@@ -59,6 +59,9 @@ spec:
seccomp.security.alpha.kubernetes.io/pod
:
'
docker/default'
spec
:
priorityClassName
:
system-cluster-critical
securityContext
:
supplementalGroups
:
[
65534
]
fsGroup
:
65534
containers
:
-
image
:
k8s.gcr.io/heapster-amd64:v1.6.0-beta.1
name
:
heapster
...
...
cluster/addons/cluster-monitoring/influxdb/heapster-controller.yaml
View file @
ca696fef
...
...
@@ -59,6 +59,9 @@ spec:
seccomp.security.alpha.kubernetes.io/pod
:
'
docker/default'
spec
:
priorityClassName
:
system-cluster-critical
securityContext
:
supplementalGroups
:
[
65534
]
fsGroup
:
65534
containers
:
-
image
:
k8s.gcr.io/heapster-amd64:v1.6.0-beta.1
name
:
heapster
...
...
cluster/addons/cluster-monitoring/stackdriver/heapster-controller.yaml
View file @
ca696fef
...
...
@@ -46,6 +46,9 @@ spec:
seccomp.security.alpha.kubernetes.io/pod
:
'
docker/default'
spec
:
priorityClassName
:
system-cluster-critical
securityContext
:
supplementalGroups
:
[
65534
]
fsGroup
:
65534
containers
:
-
image
:
k8s.gcr.io/heapster-amd64:v1.6.0-beta.1
name
:
heapster
...
...
cluster/addons/cluster-monitoring/standalone/heapster-controller.yaml
View file @
ca696fef
...
...
@@ -46,6 +46,9 @@ spec:
seccomp.security.alpha.kubernetes.io/pod
:
'
docker/default'
spec
:
priorityClassName
:
system-cluster-critical
securityContext
:
supplementalGroups
:
[
65534
]
fsGroup
:
65534
containers
:
-
image
:
k8s.gcr.io/heapster-amd64:v1.6.0-beta.1
name
:
heapster
...
...
cluster/addons/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml
View file @
ca696fef
...
...
@@ -80,6 +80,9 @@ spec:
seccomp.security.alpha.kubernetes.io/pod
:
'
docker/default'
spec
:
priorityClassName
:
system-cluster-critical
securityContext
:
supplementalGroups
:
[
65534
]
fsGroup
:
65534
containers
:
-
name
:
autoscaler
image
:
k8s.gcr.io/cluster-proportional-autoscaler-amd64:1.3.0
...
...
cluster/addons/dns/kube-dns/kube-dns.yaml.base
View file @
ca696fef
...
...
@@ -86,6 +86,9 @@ spec:
seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
spec:
priorityClassName: system-cluster-critical
securityContext:
supplementalGroups: [ 65534 ]
fsGroup: 65534
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
...
...
cluster/addons/dns/kube-dns/kube-dns.yaml.in
View file @
ca696fef
...
...
@@ -86,6 +86,9 @@ spec:
seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
spec:
priorityClassName: system-cluster-critical
securityContext:
supplementalGroups: [ 65534 ]
fsGroup: 65534
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
...
...
cluster/addons/dns/kube-dns/kube-dns.yaml.sed
View file @
ca696fef
...
...
@@ -86,6 +86,9 @@ spec:
s
e
ccomp
.
s
e
curity.alpha.kub
e
r
n
ete
s
.
io/pod: 'docker/default'
spec:
priorityClassName: system-cluster-critical
securityContext:
supplementalGroups:
[
65534
]
fsGroup: 65534
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
...
...
cluster/addons/fluentd-gcp/podsecuritypolicies/event-exporter-psp.yaml
View file @
ca696fef
...
...
@@ -19,6 +19,7 @@ spec:
volumes
:
-
'
hostPath'
-
'
secret'
-
'
projected'
# TODO: This only needs a hostPath to read /etc/ssl/certs,
# but it should be able to just include these in the image.
allowedHostPaths
:
...
...
cluster/addons/fluentd-gcp/podsecuritypolicies/fluentd-gcp-psp.yaml
View file @
ca696fef
...
...
@@ -20,6 +20,7 @@ spec:
-
'
configMap'
-
'
hostPath'
-
'
secret'
-
'
projected'
allowedHostPaths
:
-
pathPrefix
:
/var/log
-
pathPrefix
:
/var/lib/docker/containers
...
...
cluster/gce/addons/podsecuritypolicies/persistent-volume-binder.yaml
View file @
ca696fef
...
...
@@ -15,6 +15,7 @@ spec:
volumes
:
-
'
nfs'
-
'
secret'
# Required for service account credentials.
-
'
projected'
hostNetwork
:
false
hostIPC
:
false
hostPID
:
false
...
...
cluster/gce/addons/podsecuritypolicies/unprivileged-addon.yaml
View file @
ca696fef
...
...
@@ -39,6 +39,7 @@ spec:
-
'
emptyDir'
-
'
configMap'
-
'
secret'
-
'
projected'
hostNetwork
:
false
hostIPC
:
false
hostPID
:
false
...
...
plugin/pkg/admission/serviceaccount/BUILD
View file @
ca696fef
...
...
@@ -16,6 +16,7 @@ go_library(
deps = [
"//pkg/api/pod:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubeapiserver/admission/util:go_default_library",
"//pkg/serviceaccount:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
...
...
@@ -27,6 +28,7 @@ go_library(
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
...
...
@@ -40,12 +42,14 @@ go_test(
deps = [
"//pkg/apis/core:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubelet/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
...
...
plugin/pkg/admission/serviceaccount/admission.go
View file @
ca696fef
...
...
@@ -21,6 +21,7 @@ import (
"io"
"math/rand"
"strconv"
"strings"
"time"
corev1
"k8s.io/api/core/v1"
...
...
@@ -32,28 +33,34 @@ import (
"k8s.io/apiserver/pkg/admission"
genericadmissioninitializer
"k8s.io/apiserver/pkg/admission/initializer"
"k8s.io/apiserver/pkg/storage/names"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
corev1listers
"k8s.io/client-go/listers/core/v1"
podutil
"k8s.io/kubernetes/pkg/api/pod"
api
"k8s.io/kubernetes/pkg/apis/core"
kubefeatures
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/kubeapiserver/admission/util"
"k8s.io/kubernetes/pkg/serviceaccount"
)
// DefaultServiceAccountName is the name of the default service account to set on pods which do not specify a service account
const
DefaultServiceAccountName
=
"default"
const
(
// DefaultServiceAccountName is the name of the default service account to set on pods which do not specify a service account
DefaultServiceAccountName
=
"default"
// EnforceMountableSecretsAnnotation is a default annotation that indicates that a service account should enforce mountable secrets.
// The value must be true to have this annotation take effect
const
EnforceMountableSecretsAnnotation
=
"kubernetes.io/enforce-mountable-secrets"
// EnforceMountableSecretsAnnotation is a default annotation that indicates that a service account should enforce mountable secrets.
// The value must be true to have this annotation take effect
EnforceMountableSecretsAnnotation
=
"kubernetes.io/enforce-mountable-secrets"
// DefaultAPITokenMountPath is the path that ServiceAccountToken secrets are automounted to.
// The token file would then be accessible at /var/run/secrets/kubernetes.io/serviceaccount
const
DefaultAPITokenMountPath
=
"/var/run/secrets/kubernetes.io/serviceaccount"
ServiceAccountVolumeName
=
"kube-api-access"
// PluginName is the name of this admission plugin
const
PluginName
=
"ServiceAccount"
// DefaultAPITokenMountPath is the path that ServiceAccountToken secrets are automounted to.
// The token file would then be accessible at /var/run/secrets/kubernetes.io/serviceaccount
DefaultAPITokenMountPath
=
"/var/run/secrets/kubernetes.io/serviceaccount"
// PluginName is the name of this admission plugin
PluginName
=
"ServiceAccount"
)
// Register registers a plugin
func
Register
(
plugins
*
admission
.
Plugins
)
{
...
...
@@ -79,6 +86,10 @@ type serviceAccount struct {
serviceAccountLister
corev1listers
.
ServiceAccountLister
secretLister
corev1listers
.
SecretLister
generateName
func
(
string
)
string
featureGate
utilfeature
.
FeatureGate
}
var
_
admission
.
MutationInterface
=
&
serviceAccount
{}
...
...
@@ -101,6 +112,10 @@ func NewServiceAccount() *serviceAccount {
MountServiceAccountToken
:
true
,
// Reject pod creation until a service account token is available
RequireAPIToken
:
true
,
generateName
:
names
.
SimpleNameGenerator
.
GenerateName
,
featureGate
:
utilfeature
.
DefaultFeatureGate
,
}
}
...
...
@@ -434,7 +449,8 @@ func (s *serviceAccount) mountServiceAccountToken(serviceAccount *corev1.Service
allVolumeNames
:=
sets
.
NewString
()
for
_
,
volume
:=
range
pod
.
Spec
.
Volumes
{
allVolumeNames
.
Insert
(
volume
.
Name
)
if
volume
.
Secret
!=
nil
&&
volume
.
Secret
.
SecretName
==
serviceAccountToken
{
if
(
!
s
.
featureGate
.
Enabled
(
kubefeatures
.
BoundServiceAccountTokenVolume
)
&&
volume
.
Secret
!=
nil
&&
volume
.
Secret
.
SecretName
==
serviceAccountToken
)
||
(
s
.
featureGate
.
Enabled
(
kubefeatures
.
BoundServiceAccountTokenVolume
)
&&
strings
.
HasPrefix
(
volume
.
Name
,
ServiceAccountVolumeName
+
"-"
))
{
tokenVolumeName
=
volume
.
Name
hasTokenVolume
=
true
break
...
...
@@ -443,10 +459,14 @@ func (s *serviceAccount) mountServiceAccountToken(serviceAccount *corev1.Service
// Determine a volume name for the ServiceAccountTokenSecret in case we need it
if
len
(
tokenVolumeName
)
==
0
{
if
s
.
featureGate
.
Enabled
(
kubefeatures
.
BoundServiceAccountTokenVolume
)
{
tokenVolumeName
=
s
.
generateName
(
ServiceAccountVolumeName
+
"-"
)
}
else
{
// Try naming the volume the same as the serviceAccountToken, and uniquify if needed
tokenVolumeName
=
serviceAccountToken
if
allVolumeNames
.
Has
(
tokenVolumeName
)
{
tokenVolumeName
=
names
.
SimpleNameGenerator
.
GenerateName
(
fmt
.
Sprintf
(
"%s-"
,
serviceAccountToken
))
tokenVolumeName
=
s
.
generateName
(
fmt
.
Sprintf
(
"%s-"
,
serviceAccountToken
))
}
}
}
...
...
@@ -490,15 +510,61 @@ func (s *serviceAccount) mountServiceAccountToken(serviceAccount *corev1.Service
// Add the volume if a container needs it
if
!
hasTokenVolume
&&
needsTokenVolume
{
volume
:=
api
.
Volume
{
pod
.
Spec
.
Volumes
=
append
(
pod
.
Spec
.
Volumes
,
s
.
createVolume
(
tokenVolumeName
,
serviceAccountToken
))
}
return
nil
}
func
(
s
*
serviceAccount
)
createVolume
(
tokenVolumeName
,
secretName
string
)
api
.
Volume
{
if
s
.
featureGate
.
Enabled
(
kubefeatures
.
BoundServiceAccountTokenVolume
)
{
return
api
.
Volume
{
Name
:
tokenVolumeName
,
VolumeSource
:
api
.
VolumeSource
{
Secret
:
&
api
.
SecretVolumeSource
{
SecretName
:
serviceAccountToken
,
Projected
:
&
api
.
ProjectedVolumeSource
{
Sources
:
[]
api
.
VolumeProjection
{
{
ServiceAccountToken
:
&
api
.
ServiceAccountTokenProjection
{
Path
:
"token"
,
ExpirationSeconds
:
60
*
60
,
},
},
{
ConfigMap
:
&
api
.
ConfigMapProjection
{
LocalObjectReference
:
api
.
LocalObjectReference
{
Name
:
"kube-root-ca.crt"
,
},
Items
:
[]
api
.
KeyToPath
{
{
Key
:
"ca.crt"
,
Path
:
"ca.crt"
,
},
},
},
},
{
DownwardAPI
:
&
api
.
DownwardAPIProjection
{
Items
:
[]
api
.
DownwardAPIVolumeFile
{
{
Path
:
"namespace"
,
FieldRef
:
&
api
.
ObjectFieldSelector
{
APIVersion
:
"v1"
,
FieldPath
:
"metadata.namespace"
,
},
},
},
},
},
},
},
},
}
pod
.
Spec
.
Volumes
=
append
(
pod
.
Spec
.
Volumes
,
volume
)
}
return
nil
return
api
.
Volume
{
Name
:
tokenVolumeName
,
VolumeSource
:
api
.
VolumeSource
{
Secret
:
&
api
.
SecretVolumeSource
{
SecretName
:
secretName
,
},
},
}
}
plugin/pkg/admission/serviceaccount/admission_test.go
View file @
ca696fef
...
...
@@ -28,15 +28,31 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apiserver/pkg/admission"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
corev1listers
"k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
api
"k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/controller"
kubefeatures
"k8s.io/kubernetes/pkg/features"
kubelet
"k8s.io/kubernetes/pkg/kubelet/types"
)
var
(
deprecationDisabledFeature
=
utilfeature
.
NewFeatureGate
()
deprecationEnabledFeature
=
utilfeature
.
NewFeatureGate
()
)
func
init
()
{
if
err
:=
deprecationDisabledFeature
.
Add
(
map
[
utilfeature
.
Feature
]
utilfeature
.
FeatureSpec
{
kubefeatures
.
BoundServiceAccountTokenVolume
:
{
Default
:
false
}});
err
!=
nil
{
panic
(
err
)
}
if
err
:=
deprecationEnabledFeature
.
Add
(
map
[
utilfeature
.
Feature
]
utilfeature
.
FeatureSpec
{
kubefeatures
.
BoundServiceAccountTokenVolume
:
{
Default
:
true
}});
err
!=
nil
{
panic
(
err
)
}
}
func
TestIgnoresNonCreate
(
t
*
testing
.
T
)
{
for
_
,
op
:=
range
[]
admission
.
Operation
{
admission
.
Delete
,
admission
.
Connect
}
{
handler
:=
NewServiceAccount
()
...
...
@@ -267,29 +283,30 @@ func TestDeniesInvalidServiceAccount(t *testing.T) {
}
func
TestAutomountsAPIToken
(
t
*
testing
.
T
)
{
testBoundServiceAccountTokenVolumePhases
(
t
,
func
(
t
*
testing
.
T
,
applyFeatures
func
(
*
serviceAccount
)
*
serviceAccount
)
{
admit
:=
applyFeatures
(
NewServiceAccount
())
informerFactory
:=
informers
.
NewSharedInformerFactory
(
nil
,
controller
.
NoResyncPeriodFunc
())
admit
.
SetExternalKubeInformerFactory
(
informerFactory
)
admit
.
generateName
=
testGenerateName
admit
.
MountServiceAccountToken
=
true
admit
.
RequireAPIToken
=
true
ns
:=
"myns"
tokenName
:=
"token-name"
serviceAccountName
:=
DefaultServiceAccountName
serviceAccountUID
:=
"12345"
expectedVolume
:=
api
.
Volume
{
Name
:
tokenName
,
VolumeSource
:
api
.
VolumeSource
{
Secret
:
&
api
.
SecretVolumeSource
{
SecretName
:
tokenName
},
},
tokenName
:=
"token-name"
if
admit
.
featureGate
.
Enabled
(
kubefeatures
.
BoundServiceAccountTokenVolume
)
{
tokenName
=
generatedVolumeName
}
expectedVolume
:=
admit
.
createVolume
(
tokenName
,
tokenName
)
expectedVolumeMount
:=
api
.
VolumeMount
{
Name
:
tokenName
,
ReadOnly
:
true
,
MountPath
:
DefaultAPITokenMountPath
,
}
admit
:=
NewServiceAccount
()
informerFactory
:=
informers
.
NewSharedInformerFactory
(
nil
,
controller
.
NoResyncPeriodFunc
())
admit
.
SetExternalKubeInformerFactory
(
informerFactory
)
admit
.
MountServiceAccountToken
=
true
admit
.
RequireAPIToken
=
true
// Add the default service account for the ns with a token into the cache
informerFactory
.
Core
()
.
V1
()
.
ServiceAccounts
()
.
Informer
()
.
GetStore
()
.
Add
(
&
corev1
.
ServiceAccount
{
ObjectMeta
:
metav1
.
ObjectMeta
{
...
...
@@ -420,9 +437,11 @@ func TestAutomountsAPIToken(t *testing.T) {
if
!
reflect
.
DeepEqual
(
expectedVolumeMount
,
pod
.
Spec
.
InitContainers
[
0
]
.
VolumeMounts
[
0
])
{
t
.
Fatalf
(
"Expected
\n\t
%#v
\n
got
\n\t
%#v"
,
expectedVolumeMount
,
pod
.
Spec
.
InitContainers
[
0
]
.
VolumeMounts
[
0
])
}
})
}
func
TestRespectsExistingMount
(
t
*
testing
.
T
)
{
testBoundServiceAccountTokenVolumePhases
(
t
,
func
(
t
*
testing
.
T
,
applyFeatures
func
(
*
serviceAccount
)
*
serviceAccount
)
{
ns
:=
"myns"
tokenName
:=
"token-name"
serviceAccountName
:=
DefaultServiceAccountName
...
...
@@ -434,7 +453,7 @@ func TestRespectsExistingMount(t *testing.T) {
MountPath
:
DefaultAPITokenMountPath
,
}
admit
:=
NewServiceAccount
(
)
admit
:=
applyFeatures
(
NewServiceAccount
()
)
informerFactory
:=
informers
.
NewSharedInformerFactory
(
nil
,
controller
.
NoResyncPeriodFunc
())
admit
.
SetExternalKubeInformerFactory
(
informerFactory
)
admit
.
MountServiceAccountToken
=
true
...
...
@@ -527,6 +546,7 @@ func TestRespectsExistingMount(t *testing.T) {
if
!
reflect
.
DeepEqual
(
expectedVolumeMount
,
pod
.
Spec
.
InitContainers
[
0
]
.
VolumeMounts
[
0
])
{
t
.
Fatalf
(
"Expected
\n\t
%#v
\n
got
\n\t
%#v"
,
expectedVolumeMount
,
pod
.
Spec
.
InitContainers
[
0
]
.
VolumeMounts
[
0
])
}
})
}
func
TestAllowsReferencedSecret
(
t
*
testing
.
T
)
{
...
...
@@ -950,7 +970,8 @@ func newSecret(secretType corev1.SecretType, namespace, name, serviceAccountName
}
func
TestGetServiceAccountTokens
(
t
*
testing
.
T
)
{
admit
:=
NewServiceAccount
()
testBoundServiceAccountTokenVolumePhases
(
t
,
func
(
t
*
testing
.
T
,
applyFeatures
func
(
*
serviceAccount
)
*
serviceAccount
)
{
admit
:=
applyFeatures
(
NewServiceAccount
())
indexer
:=
cache
.
NewIndexer
(
cache
.
MetaNamespaceKeyFunc
,
cache
.
Indexers
{})
admit
.
secretLister
=
corev1listers
.
NewSecretLister
(
indexer
)
...
...
@@ -989,4 +1010,134 @@ func TestGetServiceAccountTokens(t *testing.T) {
if
e
,
a
:=
matchingSAToken
.
Name
,
tokens
[
0
]
.
Name
;
e
!=
a
{
t
.
Errorf
(
"expected token %s, got %s"
,
e
,
a
)
}
})
}
func
TestAutomountIsBackwardsCompatible
(
t
*
testing
.
T
)
{
ns
:=
"myns"
tokenName
:=
"token-name"
serviceAccountName
:=
DefaultServiceAccountName
serviceAccountUID
:=
"12345"
defaultTokenName
:=
"default-token-abc123"
expectedVolume
:=
api
.
Volume
{
Name
:
defaultTokenName
,
VolumeSource
:
api
.
VolumeSource
{
Secret
:
&
api
.
SecretVolumeSource
{
SecretName
:
defaultTokenName
,
},
},
}
expectedVolumeMount
:=
api
.
VolumeMount
{
Name
:
defaultTokenName
,
ReadOnly
:
true
,
MountPath
:
DefaultAPITokenMountPath
,
}
admit
:=
NewServiceAccount
()
admit
.
generateName
=
testGenerateName
admit
.
featureGate
=
deprecationEnabledFeature
informerFactory
:=
informers
.
NewSharedInformerFactory
(
nil
,
controller
.
NoResyncPeriodFunc
())
admit
.
SetExternalKubeInformerFactory
(
informerFactory
)
admit
.
MountServiceAccountToken
=
true
admit
.
RequireAPIToken
=
true
// Add the default service account for the ns with a token into the cache
informerFactory
.
Core
()
.
V1
()
.
ServiceAccounts
()
.
Informer
()
.
GetStore
()
.
Add
(
&
corev1
.
ServiceAccount
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
serviceAccountName
,
Namespace
:
ns
,
UID
:
types
.
UID
(
serviceAccountUID
),
},
Secrets
:
[]
corev1
.
ObjectReference
{
{
Name
:
tokenName
},
},
})
// Add a token for the service account into the cache
informerFactory
.
Core
()
.
V1
()
.
Secrets
()
.
Informer
()
.
GetStore
()
.
Add
(
&
corev1
.
Secret
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
tokenName
,
Namespace
:
ns
,
Annotations
:
map
[
string
]
string
{
corev1
.
ServiceAccountNameKey
:
serviceAccountName
,
corev1
.
ServiceAccountUIDKey
:
serviceAccountUID
,
},
},
Type
:
corev1
.
SecretTypeServiceAccountToken
,
Data
:
map
[
string
][]
byte
{
api
.
ServiceAccountTokenKey
:
[]
byte
(
"token-data"
),
},
})
pod
:=
&
api
.
Pod
{
Spec
:
api
.
PodSpec
{
Containers
:
[]
api
.
Container
{
{
Name
:
"c-1"
,
VolumeMounts
:
[]
api
.
VolumeMount
{
{
Name
:
defaultTokenName
,
MountPath
:
DefaultAPITokenMountPath
,
ReadOnly
:
true
,
},
},
},
},
Volumes
:
[]
api
.
Volume
{
{
Name
:
defaultTokenName
,
VolumeSource
:
api
.
VolumeSource
{
Secret
:
&
api
.
SecretVolumeSource
{
SecretName
:
defaultTokenName
,
},
},
},
},
},
}
attrs
:=
admission
.
NewAttributesRecord
(
pod
,
nil
,
api
.
Kind
(
"Pod"
)
.
WithVersion
(
"version"
),
ns
,
"myname"
,
api
.
Resource
(
"pods"
)
.
WithVersion
(
"version"
),
""
,
admission
.
Create
,
false
,
nil
)
err
:=
admit
.
Admit
(
attrs
)
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
if
pod
.
Spec
.
ServiceAccountName
!=
DefaultServiceAccountName
{
t
.
Errorf
(
"Expected service account %s assigned, got %s"
,
DefaultServiceAccountName
,
pod
.
Spec
.
ServiceAccountName
)
}
_
=
expectedVolume
_
=
expectedVolumeMount
if
len
(
pod
.
Spec
.
Volumes
)
!=
1
{
t
.
Fatalf
(
"Expected 1 volume, got %d"
,
len
(
pod
.
Spec
.
Volumes
))
}
if
!
reflect
.
DeepEqual
(
expectedVolume
,
pod
.
Spec
.
Volumes
[
0
])
{
t
.
Fatalf
(
"Expected
\n\t
%#v
\n
got
\n\t
%#v"
,
expectedVolume
,
pod
.
Spec
.
Volumes
[
0
])
}
if
len
(
pod
.
Spec
.
Containers
[
0
]
.
VolumeMounts
)
!=
1
{
t
.
Fatalf
(
"Expected 1 volume mount, got %d"
,
len
(
pod
.
Spec
.
Containers
[
0
]
.
VolumeMounts
))
}
if
!
reflect
.
DeepEqual
(
expectedVolumeMount
,
pod
.
Spec
.
Containers
[
0
]
.
VolumeMounts
[
0
])
{
t
.
Fatalf
(
"Expected
\n\t
%#v
\n
got
\n\t
%#v"
,
expectedVolumeMount
,
pod
.
Spec
.
Containers
[
0
]
.
VolumeMounts
[
0
])
}
}
func
testGenerateName
(
n
string
)
string
{
return
n
+
"abc123"
}
var
generatedVolumeName
=
testGenerateName
(
ServiceAccountVolumeName
+
"-"
)
func
testBoundServiceAccountTokenVolumePhases
(
t
*
testing
.
T
,
f
func
(
*
testing
.
T
,
func
(
*
serviceAccount
)
*
serviceAccount
))
{
t
.
Run
(
"BoundServiceAccountTokenVolume disabled"
,
func
(
t
*
testing
.
T
)
{
f
(
t
,
func
(
s
*
serviceAccount
)
*
serviceAccount
{
s
.
featureGate
=
deprecationDisabledFeature
return
s
})
})
t
.
Run
(
"BoundServiceAccountTokenVolume enabled"
,
func
(
t
*
testing
.
T
)
{
f
(
t
,
func
(
s
*
serviceAccount
)
*
serviceAccount
{
s
.
featureGate
=
deprecationEnabledFeature
return
s
})
})
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment