more dependencies packages:

pkg/metrics
pkg/credentialprovider
pkg/security
pkg/securitycontext
pkg/serviceaccount
pkg/storage
pkg/fieldpath
This commit is contained in:
Chao Xu
2016-11-18 13:26:53 -08:00
parent f8b36bdd40
commit 4f3d0e3bde
21 changed files with 352 additions and 176 deletions

View File

@@ -18,16 +18,17 @@ package securitycontext
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
dockercontainer "github.com/docker/engine-api/types/container"
)
// ValidSecurityContextWithContainerDefaults creates a valid security context provider based on
// empty container defaults. Used for testing.
func ValidSecurityContextWithContainerDefaults() *api.SecurityContext {
func ValidSecurityContextWithContainerDefaults() *v1.SecurityContext {
priv := false
return &api.SecurityContext{
Capabilities: &api.Capabilities{},
return &v1.SecurityContext{
Capabilities: &v1.Capabilities{},
Privileged: &priv,
}
}
@@ -39,7 +40,17 @@ func NewFakeSecurityContextProvider() SecurityContextProvider {
type FakeSecurityContextProvider struct{}
func (p FakeSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, container *api.Container, config *dockercontainer.Config) {
func (p FakeSecurityContextProvider) ModifyContainerConfig(pod *v1.Pod, container *v1.Container, config *dockercontainer.Config) {
}
func (p FakeSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *dockercontainer.HostConfig, supplementalGids []int64) {
func (p FakeSecurityContextProvider) ModifyHostConfig(pod *v1.Pod, container *v1.Container, hostConfig *dockercontainer.HostConfig, supplementalGids []int64) {
}
// ValidInternalSecurityContextWithContainerDefaults creates a valid security context provider based on
// empty container defaults. Used for testing.
func ValidInternalSecurityContextWithContainerDefaults() *api.SecurityContext {
priv := false
return &api.SecurityContext{
Capabilities: &api.Capabilities{},
Privileged: &priv,
}
}

View File

@@ -20,7 +20,8 @@ import (
"fmt"
"strconv"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/kubelet/leaky"
dockercontainer "github.com/docker/engine-api/types/container"
@@ -37,7 +38,7 @@ type SimpleSecurityContextProvider struct{}
// ModifyContainerConfig is called before the Docker createContainer call.
// The security context provider can make changes to the Config with which
// the container is created.
func (p SimpleSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, container *api.Container, config *dockercontainer.Config) {
func (p SimpleSecurityContextProvider) ModifyContainerConfig(pod *v1.Pod, container *v1.Container, config *dockercontainer.Config) {
effectiveSC := DetermineEffectiveSecurityContext(pod, container)
if effectiveSC == nil {
return
@@ -50,7 +51,7 @@ func (p SimpleSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, conta
// ModifyHostConfig is called before the Docker runContainer call. The
// security context provider can make changes to the HostConfig, affecting
// security options, whether the container is privileged, volume binds, etc.
func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *dockercontainer.HostConfig, supplementalGids []int64) {
func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *v1.Pod, container *v1.Container, hostConfig *dockercontainer.HostConfig, supplementalGids []int64) {
// Apply supplemental groups
if container.Name != leaky.PodInfraContainerName {
// TODO: We skip application of supplemental groups to the
@@ -96,7 +97,7 @@ func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container
}
// ModifySecurityOptions adds SELinux options to config.
func ModifySecurityOptions(config []string, selinuxOpts *api.SELinuxOptions) []string {
func ModifySecurityOptions(config []string, selinuxOpts *v1.SELinuxOptions) []string {
config = modifySecurityOption(config, DockerLabelUser, selinuxOpts.User)
config = modifySecurityOption(config, DockerLabelRole, selinuxOpts.Role)
config = modifySecurityOption(config, DockerLabelType, selinuxOpts.Type)
@@ -115,7 +116,7 @@ func modifySecurityOption(config []string, name, value string) []string {
}
// MakeCapabilities creates string slices from Capability slices
func MakeCapabilities(capAdd []api.Capability, capDrop []api.Capability) ([]string, []string) {
func MakeCapabilities(capAdd []v1.Capability, capDrop []v1.Capability) ([]string, []string) {
var (
addCaps []string
dropCaps []string
@@ -129,7 +130,7 @@ func MakeCapabilities(capAdd []api.Capability, capDrop []api.Capability) ([]stri
return addCaps, dropCaps
}
func DetermineEffectiveSecurityContext(pod *api.Pod, container *api.Container) *api.SecurityContext {
func DetermineEffectiveSecurityContext(pod *v1.Pod, container *v1.Container) *v1.SecurityContext {
effectiveSc := securityContextFromPodSecurityContext(pod)
containerSc := container.SecurityContext
@@ -143,6 +144,78 @@ func DetermineEffectiveSecurityContext(pod *api.Pod, container *api.Container) *
return containerSc
}
if containerSc.SELinuxOptions != nil {
effectiveSc.SELinuxOptions = new(v1.SELinuxOptions)
*effectiveSc.SELinuxOptions = *containerSc.SELinuxOptions
}
if containerSc.Capabilities != nil {
effectiveSc.Capabilities = new(v1.Capabilities)
*effectiveSc.Capabilities = *containerSc.Capabilities
}
if containerSc.Privileged != nil {
effectiveSc.Privileged = new(bool)
*effectiveSc.Privileged = *containerSc.Privileged
}
if containerSc.RunAsUser != nil {
effectiveSc.RunAsUser = new(int64)
*effectiveSc.RunAsUser = *containerSc.RunAsUser
}
if containerSc.RunAsNonRoot != nil {
effectiveSc.RunAsNonRoot = new(bool)
*effectiveSc.RunAsNonRoot = *containerSc.RunAsNonRoot
}
if containerSc.ReadOnlyRootFilesystem != nil {
effectiveSc.ReadOnlyRootFilesystem = new(bool)
*effectiveSc.ReadOnlyRootFilesystem = *containerSc.ReadOnlyRootFilesystem
}
return effectiveSc
}
func securityContextFromPodSecurityContext(pod *v1.Pod) *v1.SecurityContext {
if pod.Spec.SecurityContext == nil {
return nil
}
synthesized := &v1.SecurityContext{}
if pod.Spec.SecurityContext.SELinuxOptions != nil {
synthesized.SELinuxOptions = &v1.SELinuxOptions{}
*synthesized.SELinuxOptions = *pod.Spec.SecurityContext.SELinuxOptions
}
if pod.Spec.SecurityContext.RunAsUser != nil {
synthesized.RunAsUser = new(int64)
*synthesized.RunAsUser = *pod.Spec.SecurityContext.RunAsUser
}
if pod.Spec.SecurityContext.RunAsNonRoot != nil {
synthesized.RunAsNonRoot = new(bool)
*synthesized.RunAsNonRoot = *pod.Spec.SecurityContext.RunAsNonRoot
}
return synthesized
}
// TODO: remove the duplicate code
func InternalDetermineEffectiveSecurityContext(pod *api.Pod, container *api.Container) *api.SecurityContext {
effectiveSc := internalSecurityContextFromPodSecurityContext(pod)
containerSc := container.SecurityContext
if effectiveSc == nil && containerSc == nil {
return nil
}
if effectiveSc != nil && containerSc == nil {
return effectiveSc
}
if effectiveSc == nil && containerSc != nil {
return containerSc
}
if containerSc.SELinuxOptions != nil {
effectiveSc.SELinuxOptions = new(api.SELinuxOptions)
*effectiveSc.SELinuxOptions = *containerSc.SELinuxOptions
@@ -176,7 +249,7 @@ func DetermineEffectiveSecurityContext(pod *api.Pod, container *api.Container) *
return effectiveSc
}
func securityContextFromPodSecurityContext(pod *api.Pod) *api.SecurityContext {
func internalSecurityContextFromPodSecurityContext(pod *api.Pod) *api.SecurityContext {
if pod.Spec.SecurityContext == nil {
return nil
}

View File

@@ -23,8 +23,8 @@ import (
"testing"
dockercontainer "github.com/docker/engine-api/types/container"
"k8s.io/kubernetes/pkg/api"
apitesting "k8s.io/kubernetes/pkg/api/testing"
"k8s.io/kubernetes/pkg/api/v1"
)
func TestModifyContainerConfig(t *testing.T) {
@@ -33,13 +33,13 @@ func TestModifyContainerConfig(t *testing.T) {
cases := []struct {
name string
podSc *api.PodSecurityContext
sc *api.SecurityContext
podSc *v1.PodSecurityContext
sc *v1.SecurityContext
expected *dockercontainer.Config
}{
{
name: "container.SecurityContext.RunAsUser set",
sc: &api.SecurityContext{
sc: &v1.SecurityContext{
RunAsUser: &uid,
},
expected: &dockercontainer.Config{
@@ -48,12 +48,12 @@ func TestModifyContainerConfig(t *testing.T) {
},
{
name: "no RunAsUser value set",
sc: &api.SecurityContext{},
sc: &v1.SecurityContext{},
expected: &dockercontainer.Config{},
},
{
name: "pod.Spec.SecurityContext.RunAsUser set",
podSc: &api.PodSecurityContext{
podSc: &v1.PodSecurityContext{
RunAsUser: &uid,
},
expected: &dockercontainer.Config{
@@ -62,10 +62,10 @@ func TestModifyContainerConfig(t *testing.T) {
},
{
name: "container.SecurityContext.RunAsUser overrides pod.Spec.SecurityContext.RunAsUser",
podSc: &api.PodSecurityContext{
podSc: &v1.PodSecurityContext{
RunAsUser: &uid,
},
sc: &api.SecurityContext{
sc: &v1.SecurityContext{
RunAsUser: &overrideUid,
},
expected: &dockercontainer.Config{
@@ -75,9 +75,9 @@ func TestModifyContainerConfig(t *testing.T) {
}
provider := NewSimpleSecurityContextProvider()
dummyContainer := &api.Container{}
dummyContainer := &v1.Container{}
for _, tc := range cases {
pod := &api.Pod{Spec: api.PodSpec{SecurityContext: tc.podSc}}
pod := &v1.Pod{Spec: v1.PodSpec{SecurityContext: tc.podSc}}
dummyContainer.SecurityContext = tc.sc
dockerCfg := &dockercontainer.Config{}
@@ -91,7 +91,7 @@ func TestModifyContainerConfig(t *testing.T) {
func TestModifyHostConfig(t *testing.T) {
priv := true
setPrivSC := &api.SecurityContext{}
setPrivSC := &v1.SecurityContext{}
setPrivSC.Privileged = &priv
setPrivHC := &dockercontainer.HostConfig{
Privileged: true,
@@ -115,8 +115,8 @@ func TestModifyHostConfig(t *testing.T) {
cases := []struct {
name string
podSc *api.PodSecurityContext
sc *api.SecurityContext
podSc *v1.PodSecurityContext
sc *v1.SecurityContext
expected *dockercontainer.HostConfig
}{
{
@@ -131,21 +131,21 @@ func TestModifyHostConfig(t *testing.T) {
},
{
name: "container.SecurityContext.Capabilities",
sc: &api.SecurityContext{
sc: &v1.SecurityContext{
Capabilities: inputCapabilities(),
},
expected: setCapsHC,
},
{
name: "container.SecurityContext.SELinuxOptions",
sc: &api.SecurityContext{
sc: &v1.SecurityContext{
SELinuxOptions: inputSELinuxOptions(),
},
expected: setSELinuxHC,
},
{
name: "pod.Spec.SecurityContext.SELinuxOptions",
podSc: &api.PodSecurityContext{
podSc: &v1.PodSecurityContext{
SELinuxOptions: inputSELinuxOptions(),
},
expected: setSELinuxHC,
@@ -159,10 +159,10 @@ func TestModifyHostConfig(t *testing.T) {
}
provider := NewSimpleSecurityContextProvider()
dummyContainer := &api.Container{}
dummyContainer := &v1.Container{}
for _, tc := range cases {
pod := &api.Pod{Spec: api.PodSpec{SecurityContext: tc.podSc}}
pod := &v1.Pod{Spec: v1.PodSpec{SecurityContext: tc.podSc}}
dummyContainer.SecurityContext = tc.sc
dockerCfg := &dockercontainer.HostConfig{}
@@ -175,7 +175,7 @@ func TestModifyHostConfig(t *testing.T) {
}
func TestModifyHostConfigPodSecurityContext(t *testing.T) {
supplementalGroupsSC := &api.PodSecurityContext{}
supplementalGroupsSC := &v1.PodSecurityContext{}
supplementalGroupsSC.SupplementalGroups = []int64{2222}
supplementalGroupHC := fullValidHostConfig()
supplementalGroupHC.GroupAdd = []string{"2222"}
@@ -189,7 +189,7 @@ func TestModifyHostConfigPodSecurityContext(t *testing.T) {
extraSupplementalGroup := []int64{1234}
testCases := map[string]struct {
securityContext *api.PodSecurityContext
securityContext *v1.PodSecurityContext
expected *dockercontainer.HostConfig
extraSupplementalGroups []int64
}{
@@ -204,12 +204,12 @@ func TestModifyHostConfigPodSecurityContext(t *testing.T) {
extraSupplementalGroups: nil,
},
"FSGroup": {
securityContext: &api.PodSecurityContext{FSGroup: &fsGroup},
securityContext: &v1.PodSecurityContext{FSGroup: &fsGroup},
expected: fsGroupHC,
extraSupplementalGroups: nil,
},
"FSGroup + SupplementalGroups": {
securityContext: &api.PodSecurityContext{
securityContext: &v1.PodSecurityContext{
SupplementalGroups: []int64{2222},
FSGroup: &fsGroup,
},
@@ -229,10 +229,10 @@ func TestModifyHostConfigPodSecurityContext(t *testing.T) {
}
provider := NewSimpleSecurityContextProvider()
dummyContainer := &api.Container{}
dummyContainer := &v1.Container{}
dummyContainer.SecurityContext = fullValidSecurityContext()
dummyPod := &api.Pod{
Spec: apitesting.DeepEqualSafePodSpec(),
dummyPod := &v1.Pod{
Spec: apitesting.V1DeepEqualSafePodSpec(),
}
for k, v := range testCases {
@@ -277,9 +277,9 @@ func TestModifySecurityOption(t *testing.T) {
}
}
func overridePodSecurityContext() *api.PodSecurityContext {
return &api.PodSecurityContext{
SELinuxOptions: &api.SELinuxOptions{
func overridePodSecurityContext() *v1.PodSecurityContext {
return &v1.PodSecurityContext{
SELinuxOptions: &v1.SELinuxOptions{
User: "user2",
Role: "role2",
Type: "type2",
@@ -288,30 +288,30 @@ func overridePodSecurityContext() *api.PodSecurityContext {
}
}
func fullValidPodSecurityContext() *api.PodSecurityContext {
return &api.PodSecurityContext{
func fullValidPodSecurityContext() *v1.PodSecurityContext {
return &v1.PodSecurityContext{
SELinuxOptions: inputSELinuxOptions(),
}
}
func fullValidSecurityContext() *api.SecurityContext {
func fullValidSecurityContext() *v1.SecurityContext {
priv := true
return &api.SecurityContext{
return &v1.SecurityContext{
Privileged: &priv,
Capabilities: inputCapabilities(),
SELinuxOptions: inputSELinuxOptions(),
}
}
func inputCapabilities() *api.Capabilities {
return &api.Capabilities{
Add: []api.Capability{"addCapA", "addCapB"},
Drop: []api.Capability{"dropCapA", "dropCapB"},
func inputCapabilities() *v1.Capabilities {
return &v1.Capabilities{
Add: []v1.Capability{"addCapA", "addCapB"},
Drop: []v1.Capability{"dropCapA", "dropCapB"},
}
}
func inputSELinuxOptions() *api.SELinuxOptions {
return &api.SELinuxOptions{
func inputSELinuxOptions() *v1.SELinuxOptions {
return &v1.SELinuxOptions{
User: "user",
Role: "role",
Type: "type",

View File

@@ -17,7 +17,7 @@ limitations under the License.
package securitycontext
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
dockercontainer "github.com/docker/engine-api/types/container"
)
@@ -26,7 +26,7 @@ type SecurityContextProvider interface {
// ModifyContainerConfig is called before the Docker createContainer call.
// The security context provider can make changes to the Config with which
// the container is created.
ModifyContainerConfig(pod *api.Pod, container *api.Container, config *dockercontainer.Config)
ModifyContainerConfig(pod *v1.Pod, container *v1.Container, config *dockercontainer.Config)
// ModifyHostConfig is called before the Docker createContainer call.
// The security context provider can make changes to the HostConfig, affecting
@@ -37,7 +37,7 @@ type SecurityContextProvider interface {
// - pod: the pod to modify the docker hostconfig for
// - container: the container to modify the hostconfig for
// - supplementalGids: additional supplemental GIDs associated with the pod's volumes
ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *dockercontainer.HostConfig, supplementalGids []int64)
ModifyHostConfig(pod *v1.Pod, container *v1.Container, hostConfig *dockercontainer.HostConfig, supplementalGids []int64)
}
const (

View File

@@ -20,12 +20,12 @@ import (
"fmt"
"strings"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
)
// HasPrivilegedRequest returns the value of SecurityContext.Privileged, taking into account
// the possibility of nils
func HasPrivilegedRequest(container *api.Container) bool {
func HasPrivilegedRequest(container *v1.Container) bool {
if container.SecurityContext == nil {
return false
}
@@ -37,7 +37,7 @@ func HasPrivilegedRequest(container *api.Container) bool {
// HasCapabilitiesRequest returns true if Adds or Drops are defined in the security context
// capabilities, taking into account nils
func HasCapabilitiesRequest(container *api.Container) bool {
func HasCapabilitiesRequest(container *v1.Container) bool {
if container.SecurityContext == nil {
return false
}
@@ -52,14 +52,14 @@ const expectedSELinuxFields = 4
// ParseSELinuxOptions parses a string containing a full SELinux context
// (user, role, type, and level) into an SELinuxOptions object. If the
// context is malformed, an error is returned.
func ParseSELinuxOptions(context string) (*api.SELinuxOptions, error) {
func ParseSELinuxOptions(context string) (*v1.SELinuxOptions, error) {
fields := strings.SplitN(context, ":", expectedSELinuxFields)
if len(fields) != expectedSELinuxFields {
return nil, fmt.Errorf("expected %v fields in selinux; got %v (context: %v)", expectedSELinuxFields, len(fields), context)
}
return &api.SELinuxOptions{
return &v1.SELinuxOptions{
User: fields[0],
Role: fields[1],
Type: fields[2],
@@ -68,7 +68,7 @@ func ParseSELinuxOptions(context string) (*api.SELinuxOptions, error) {
}
// HasNonRootUID returns true if the runAsUser is set and is greater than 0.
func HasRootUID(container *api.Container) bool {
func HasRootUID(container *v1.Container) bool {
if container.SecurityContext == nil {
return false
}
@@ -79,11 +79,11 @@ func HasRootUID(container *api.Container) bool {
}
// HasRunAsUser determines if the sc's runAsUser field is set.
func HasRunAsUser(container *api.Container) bool {
func HasRunAsUser(container *v1.Container) bool {
return container.SecurityContext != nil && container.SecurityContext.RunAsUser != nil
}
// HasRootRunAsUser returns true if the run as user is set and it is set to 0.
func HasRootRunAsUser(container *api.Container) bool {
func HasRootRunAsUser(container *v1.Container) bool {
return HasRunAsUser(container) && HasRootUID(container)
}

View File

@@ -19,19 +19,19 @@ package securitycontext
import (
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
)
func TestParseSELinuxOptions(t *testing.T) {
cases := []struct {
name string
input string
expected *api.SELinuxOptions
expected *v1.SELinuxOptions
}{
{
name: "simple",
input: "user_t:role_t:type_t:s0",
expected: &api.SELinuxOptions{
expected: &v1.SELinuxOptions{
User: "user_t",
Role: "role_t",
Type: "type_t",
@@ -41,7 +41,7 @@ func TestParseSELinuxOptions(t *testing.T) {
{
name: "simple + categories",
input: "user_t:role_t:type_t:s0:c0",
expected: &api.SELinuxOptions{
expected: &v1.SELinuxOptions{
User: "user_t",
Role: "role_t",
Type: "type_t",
@@ -69,7 +69,7 @@ func TestParseSELinuxOptions(t *testing.T) {
}
}
func compareContexts(name string, ex, ac *api.SELinuxOptions, t *testing.T) {
func compareContexts(name string, ex, ac *v1.SELinuxOptions, t *testing.T) {
if e, a := ex.User, ac.User; e != a {
t.Errorf("%v: expected user: %v, got: %v", name, e, a)
}
@@ -84,8 +84,8 @@ func compareContexts(name string, ex, ac *api.SELinuxOptions, t *testing.T) {
}
}
func containerWithUser(ptr *int64) *api.Container {
return &api.Container{SecurityContext: &api.SecurityContext{RunAsUser: ptr}}
func containerWithUser(ptr *int64) *v1.Container {
return &v1.Container{SecurityContext: &v1.SecurityContext{RunAsUser: ptr}}
}
func TestHaRootUID(t *testing.T) {
@@ -93,11 +93,11 @@ func TestHaRootUID(t *testing.T) {
var root int64 = 0
tests := map[string]struct {
container *api.Container
container *v1.Container
expect bool
}{
"nil sc": {
container: &api.Container{SecurityContext: nil},
container: &v1.Container{SecurityContext: nil},
},
"nil runAsuser": {
container: containerWithUser(nil),
@@ -123,11 +123,11 @@ func TestHasRunAsUser(t *testing.T) {
var runAsUser int64 = 0
tests := map[string]struct {
container *api.Container
container *v1.Container
expect bool
}{
"nil sc": {
container: &api.Container{SecurityContext: nil},
container: &v1.Container{SecurityContext: nil},
},
"nil runAsUser": {
container: containerWithUser(nil),
@@ -151,11 +151,11 @@ func TestHasRootRunAsUser(t *testing.T) {
var root int64 = 0
tests := map[string]struct {
container *api.Container
container *v1.Container
expect bool
}{
"nil sc": {
container: &api.Container{SecurityContext: nil},
container: &v1.Container{SecurityContext: nil},
},
"nil runAsuser": {
container: containerWithUser(nil),