mirror of
https://github.com/rancher/steve.git
synced 2025-08-17 22:06:28 +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
@ -515,7 +515,9 @@ func (s *PodImpersonation) augmentPod(pod *v1.Pod, sa *v1.ServiceAccount, secret
|
|||||||
zero = int64(0)
|
zero = int64(0)
|
||||||
t = true
|
t = true
|
||||||
f = false
|
f = false
|
||||||
m = int32(420)
|
m = int32(0o644)
|
||||||
|
m2 = int32(0o600)
|
||||||
|
shellUser = 1000
|
||||||
)
|
)
|
||||||
|
|
||||||
pod = pod.DeepCopy()
|
pod = pod.DeepCopy()
|
||||||
@ -535,11 +537,18 @@ func (s *PodImpersonation) augmentPod(pod *v1.Pod, sa *v1.ServiceAccount, secret
|
|||||||
},
|
},
|
||||||
v1.Volume{
|
v1.Volume{
|
||||||
Name: "user-kubeconfig",
|
Name: "user-kubeconfig",
|
||||||
|
VolumeSource: v1.VolumeSource{
|
||||||
|
EmptyDir: &v1.EmptyDirVolumeSource{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
v1.Volume{
|
||||||
|
Name: "user-kube-configmap",
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeSource: v1.VolumeSource{
|
||||||
ConfigMap: &v1.ConfigMapVolumeSource{
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
||||||
LocalObjectReference: v1.LocalObjectReference{
|
LocalObjectReference: v1.LocalObjectReference{
|
||||||
Name: s.userConfigName(),
|
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 i, container := range pod.Spec.Containers {
|
||||||
for _, envvar := range container.Env {
|
for _, envvar := range container.Env {
|
||||||
if envvar.Name != "KUBECONFIG" {
|
if envvar.Name != "KUBECONFIG" {
|
||||||
continue
|
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{
|
pod.Spec.Containers[i].VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{
|
||||||
Name: "user-kubeconfig",
|
Name: "user-kubeconfig",
|
||||||
ReadOnly: true,
|
|
||||||
MountPath: envvar.Value,
|
MountPath: envvar.Value,
|
||||||
SubPath: "config",
|
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{
|
pod.Spec.Containers = append(pod.Spec.Containers, v1.Container{
|
||||||
Name: "proxy",
|
Name: "proxy",
|
||||||
Image: image,
|
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