mirror of
https://github.com/rancher/steve.git
synced 2025-05-11 09:24:20 +00:00
changing permission for kubeconfig file inside the shell pod (#166)
* changing permission for kubeconfig file inside the shell pod * creating unit tests for the changes done
This commit is contained in:
parent
9b00eb3a7f
commit
46e3638cd8
pkg/podimpersonation
@ -512,10 +512,12 @@ func (s *PodImpersonation) adminKubeConfig(user user.Info, role *rbacv1.ClusterR
|
||||
|
||||
func (s *PodImpersonation) augmentPod(pod *v1.Pod, sa *v1.ServiceAccount, secret *v1.Secret, imageOverride string) *v1.Pod {
|
||||
var (
|
||||
zero = int64(0)
|
||||
t = true
|
||||
f = false
|
||||
m = int32(420)
|
||||
zero = int64(0)
|
||||
t = true
|
||||
f = false
|
||||
m = int32(0o644)
|
||||
m2 = int32(0o600)
|
||||
shellUser = 1000
|
||||
)
|
||||
|
||||
pod = pod.DeepCopy()
|
||||
@ -535,11 +537,18 @@ func (s *PodImpersonation) augmentPod(pod *v1.Pod, sa *v1.ServiceAccount, secret
|
||||
},
|
||||
v1.Volume{
|
||||
Name: "user-kubeconfig",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
EmptyDir: &v1.EmptyDirVolumeSource{},
|
||||
},
|
||||
},
|
||||
v1.Volume{
|
||||
Name: "user-kube-configmap",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
ConfigMap: &v1.ConfigMapVolumeSource{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: s.userConfigName(),
|
||||
},
|
||||
DefaultMode: &m2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -553,15 +562,45 @@ func (s *PodImpersonation) augmentPod(pod *v1.Pod, sa *v1.ServiceAccount, secret
|
||||
},
|
||||
})
|
||||
|
||||
image := imageOverride
|
||||
if image == "" {
|
||||
image = s.imageName()
|
||||
}
|
||||
|
||||
for i, container := range pod.Spec.Containers {
|
||||
for _, envvar := range container.Env {
|
||||
if envvar.Name != "KUBECONFIG" {
|
||||
continue
|
||||
}
|
||||
|
||||
//This mounts two volumes, one configMap and one emptyDir.
|
||||
//The reason for this is that we need to change the permissions on the kubeconfig file
|
||||
//and, since a configMap volume is always read-only, we need an emptyDir volume as well.
|
||||
vmount := v1.VolumeMount{
|
||||
Name: "user-kubeconfig",
|
||||
MountPath: "/tmp/.kube",
|
||||
}
|
||||
cfgVMount := v1.VolumeMount{
|
||||
Name: "user-kube-configmap",
|
||||
MountPath: "/home/.kube/config",
|
||||
SubPath: "config",
|
||||
}
|
||||
|
||||
pod.Spec.InitContainers = append(pod.Spec.InitContainers, v1.Container{
|
||||
Name: "init-kubeconfig-volume",
|
||||
Image: image,
|
||||
Command: []string{"sh", "-c", fmt.Sprintf("cp %s %s && chown %d %s/config", cfgVMount.MountPath, vmount.MountPath, shellUser, vmount.MountPath)},
|
||||
ImagePullPolicy: v1.PullIfNotPresent,
|
||||
SecurityContext: &v1.SecurityContext{
|
||||
RunAsUser: &zero,
|
||||
RunAsGroup: &zero,
|
||||
},
|
||||
VolumeMounts: []v1.VolumeMount{cfgVMount, vmount},
|
||||
},
|
||||
)
|
||||
|
||||
pod.Spec.Containers[i].VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{
|
||||
Name: "user-kubeconfig",
|
||||
ReadOnly: true,
|
||||
MountPath: envvar.Value,
|
||||
SubPath: "config",
|
||||
})
|
||||
@ -569,11 +608,6 @@ func (s *PodImpersonation) augmentPod(pod *v1.Pod, sa *v1.ServiceAccount, secret
|
||||
}
|
||||
}
|
||||
|
||||
image := imageOverride
|
||||
if image == "" {
|
||||
image = s.imageName()
|
||||
}
|
||||
|
||||
pod.Spec.Containers = append(pod.Spec.Containers, v1.Container{
|
||||
Name: "proxy",
|
||||
Image: image,
|
||||
|
91
pkg/podimpersonation/podimpersonation_test.go
Normal file
91
pkg/podimpersonation/podimpersonation_test.go
Normal file
@ -0,0 +1,91 @@
|
||||
package podimpersonation
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestAugmentPod(t *testing.T) {
|
||||
var (
|
||||
zero = int64(0)
|
||||
)
|
||||
testCases := []struct {
|
||||
name string
|
||||
imageOverride string
|
||||
envVars []v1.EnvVar
|
||||
}{
|
||||
{
|
||||
name: "Should mount volume to container, create an init container and use regular image",
|
||||
imageOverride: "",
|
||||
envVars: []v1.EnvVar{{Name: "KUBECONFIG", Value: ".kube/config"}},
|
||||
},
|
||||
{
|
||||
name: "Should mount volume to container, create an init container and use overridden image",
|
||||
imageOverride: "rancher/notShell:v1.0.0",
|
||||
envVars: []v1.EnvVar{{Name: "KUBECONFIG", Value: ".kube/config"}},
|
||||
},
|
||||
{
|
||||
name: "Should not create init container if there's no KUBECONFIG envVar",
|
||||
imageOverride: "",
|
||||
envVars: []v1.EnvVar{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
p := newPod(tc.envVars)
|
||||
impersonator := New("", nil, time.Minute, func() string { return "rancher/shell:v0.1.22" })
|
||||
pod := impersonator.augmentPod(p, nil, &v1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "s"}}, tc.imageOverride)
|
||||
|
||||
assert.Len(t, pod.Spec.Volumes, len(p.Spec.Volumes)+4, "expected four new volumes")
|
||||
if len(tc.envVars) != 0 {
|
||||
assert.Len(t, pod.Spec.Containers[0].VolumeMounts, len(p.Spec.Containers[0].VolumeMounts)+1, "expected kubeconfig volume to be mounted")
|
||||
assert.Len(t, pod.Spec.InitContainers, len(p.Spec.InitContainers)+1, "expected an init container to be created")
|
||||
if tc.imageOverride != "" {
|
||||
assert.Equal(t, pod.Spec.InitContainers[len(pod.Spec.InitContainers)-1].Image, tc.imageOverride, "expected image to be the one received as parameter")
|
||||
} else {
|
||||
assert.Equal(t, pod.Spec.InitContainers[len(pod.Spec.InitContainers)-1].Image, impersonator.imageName(), "expected image to be the impersonator image")
|
||||
}
|
||||
assert.Equal(t, pod.Spec.InitContainers[len(pod.Spec.InitContainers)-1].SecurityContext.RunAsUser, &zero, "expected init container to run as user zero")
|
||||
assert.Equal(t, pod.Spec.InitContainers[len(pod.Spec.InitContainers)-1].SecurityContext.RunAsGroup, &zero, "expected init container to run as group zero")
|
||||
} else {
|
||||
assert.Len(t, pod.Spec.InitContainers, len(p.Spec.InitContainers), "expected no init container to be created")
|
||||
}
|
||||
assert.Equal(t, pod.Spec.Containers[len(pod.Spec.Containers)-1].Name, "proxy", "expected the container proxy to be created")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newPod(env []v1.EnvVar) *v1.Pod {
|
||||
return &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Volumes: []v1.Volume{{
|
||||
Name: "volume1",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
ConfigMap: &v1.ConfigMapVolumeSource{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: "cfgMap",
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "shell",
|
||||
Image: "rancher/shell:v0.1.22",
|
||||
Env: env,
|
||||
VolumeMounts: []v1.VolumeMount{{
|
||||
Name: "volume1",
|
||||
MountPath: "/home/vol",
|
||||
}},
|
||||
},
|
||||
},
|
||||
ServiceAccountName: "svc-account-1",
|
||||
AutomountServiceAccountToken: nil,
|
||||
SecurityContext: nil,
|
||||
},
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user