mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 07:20:13 +00:00
more dependencies packages:
pkg/metrics pkg/credentialprovider pkg/security pkg/securitycontext pkg/serviceaccount pkg/storage pkg/fieldpath
This commit is contained in:
parent
f8b36bdd40
commit
4f3d0e3bde
@ -27,7 +27,7 @@ import (
|
||||
"github.com/golang/glog"
|
||||
|
||||
dockertypes "github.com/docker/engine-api/types"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
)
|
||||
|
||||
@ -306,17 +306,17 @@ func (k *unionDockerKeyring) Lookup(image string) ([]LazyAuthConfiguration, bool
|
||||
// MakeDockerKeyring inspects the passedSecrets to see if they contain any DockerConfig secrets. If they do,
|
||||
// then a DockerKeyring is built based on every hit and unioned with the defaultKeyring.
|
||||
// If they do not, then the default keyring is returned
|
||||
func MakeDockerKeyring(passedSecrets []api.Secret, defaultKeyring DockerKeyring) (DockerKeyring, error) {
|
||||
func MakeDockerKeyring(passedSecrets []v1.Secret, defaultKeyring DockerKeyring) (DockerKeyring, error) {
|
||||
passedCredentials := []DockerConfig{}
|
||||
for _, passedSecret := range passedSecrets {
|
||||
if dockerConfigJsonBytes, dockerConfigJsonExists := passedSecret.Data[api.DockerConfigJsonKey]; (passedSecret.Type == api.SecretTypeDockerConfigJson) && dockerConfigJsonExists && (len(dockerConfigJsonBytes) > 0) {
|
||||
if dockerConfigJsonBytes, dockerConfigJsonExists := passedSecret.Data[v1.DockerConfigJsonKey]; (passedSecret.Type == v1.SecretTypeDockerConfigJson) && dockerConfigJsonExists && (len(dockerConfigJsonBytes) > 0) {
|
||||
dockerConfigJson := DockerConfigJson{}
|
||||
if err := json.Unmarshal(dockerConfigJsonBytes, &dockerConfigJson); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
passedCredentials = append(passedCredentials, dockerConfigJson.Auths)
|
||||
} else if dockercfgBytes, dockercfgExists := passedSecret.Data[api.DockerConfigKey]; (passedSecret.Type == api.SecretTypeDockercfg) && dockercfgExists && (len(dockercfgBytes) > 0) {
|
||||
} else if dockercfgBytes, dockercfgExists := passedSecret.Data[v1.DockerConfigKey]; (passedSecret.Type == v1.SecretTypeDockercfg) && dockercfgExists && (len(dockercfgBytes) > 0) {
|
||||
dockercfg := DockerConfig{}
|
||||
if err := json.Unmarshal(dockercfgBytes, &dockercfg); err != nil {
|
||||
return nil, err
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
)
|
||||
|
||||
// formatMap formats map[string]string to a string.
|
||||
@ -65,9 +66,10 @@ func ExtractFieldPathAsString(obj interface{}, fieldPath string) (string, error)
|
||||
return "", fmt.Errorf("Unsupported fieldPath: %v", fieldPath)
|
||||
}
|
||||
|
||||
// TODO: move the functions below to pkg/api/util/resources
|
||||
// ExtractResourceValueByContainerName extracts the value of a resource
|
||||
// by providing container name
|
||||
func ExtractResourceValueByContainerName(fs *api.ResourceFieldSelector, pod *api.Pod, containerName string) (string, error) {
|
||||
func ExtractResourceValueByContainerName(fs *v1.ResourceFieldSelector, pod *v1.Pod, containerName string) (string, error) {
|
||||
container, err := findContainerInPod(pod, containerName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -77,7 +79,7 @@ func ExtractResourceValueByContainerName(fs *api.ResourceFieldSelector, pod *api
|
||||
|
||||
// ExtractResourceValueByContainerNameAndNodeAllocatable extracts the value of a resource
|
||||
// by providing container name and node allocatable
|
||||
func ExtractResourceValueByContainerNameAndNodeAllocatable(fs *api.ResourceFieldSelector, pod *api.Pod, containerName string, nodeAllocatable api.ResourceList) (string, error) {
|
||||
func ExtractResourceValueByContainerNameAndNodeAllocatable(fs *v1.ResourceFieldSelector, pod *v1.Pod, containerName string, nodeAllocatable v1.ResourceList) (string, error) {
|
||||
realContainer, err := findContainerInPod(pod, containerName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -88,7 +90,7 @@ func ExtractResourceValueByContainerNameAndNodeAllocatable(fs *api.ResourceField
|
||||
return "", fmt.Errorf("failed to perform a deep copy of container object: %v", err)
|
||||
}
|
||||
|
||||
container, ok := containerCopy.(*api.Container)
|
||||
container, ok := containerCopy.(*v1.Container)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("unexpected type returned from deep copy of container object")
|
||||
}
|
||||
@ -100,7 +102,32 @@ func ExtractResourceValueByContainerNameAndNodeAllocatable(fs *api.ResourceField
|
||||
|
||||
// ExtractContainerResourceValue extracts the value of a resource
|
||||
// in an already known container
|
||||
func ExtractContainerResourceValue(fs *api.ResourceFieldSelector, container *api.Container) (string, error) {
|
||||
func ExtractContainerResourceValue(fs *v1.ResourceFieldSelector, container *v1.Container) (string, error) {
|
||||
divisor := resource.Quantity{}
|
||||
if divisor.Cmp(fs.Divisor) == 0 {
|
||||
divisor = resource.MustParse("1")
|
||||
} else {
|
||||
divisor = fs.Divisor
|
||||
}
|
||||
|
||||
switch fs.Resource {
|
||||
case "limits.cpu":
|
||||
return convertResourceCPUToString(container.Resources.Limits.Cpu(), divisor)
|
||||
case "limits.memory":
|
||||
return convertResourceMemoryToString(container.Resources.Limits.Memory(), divisor)
|
||||
case "requests.cpu":
|
||||
return convertResourceCPUToString(container.Resources.Requests.Cpu(), divisor)
|
||||
case "requests.memory":
|
||||
return convertResourceMemoryToString(container.Resources.Requests.Memory(), divisor)
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Unsupported container resource : %v", fs.Resource)
|
||||
}
|
||||
|
||||
// TODO: remove this duplicate
|
||||
// InternalExtractContainerResourceValue extracts the value of a resource
|
||||
// in an already known container
|
||||
func InternalExtractContainerResourceValue(fs *api.ResourceFieldSelector, container *api.Container) (string, error) {
|
||||
divisor := resource.Quantity{}
|
||||
if divisor.Cmp(fs.Divisor) == 0 {
|
||||
divisor = resource.MustParse("1")
|
||||
@ -123,7 +150,7 @@ func ExtractContainerResourceValue(fs *api.ResourceFieldSelector, container *api
|
||||
}
|
||||
|
||||
// findContainerInPod finds a container by its name in the provided pod
|
||||
func findContainerInPod(pod *api.Pod, containerName string) (*api.Container, error) {
|
||||
func findContainerInPod(pod *v1.Pod, containerName string) (*v1.Container, error) {
|
||||
for _, container := range pod.Spec.Containers {
|
||||
if container.Name == containerName {
|
||||
return &container, nil
|
||||
@ -148,12 +175,12 @@ func convertResourceMemoryToString(memory *resource.Quantity, divisor resource.Q
|
||||
|
||||
// MergeContainerResourceLimits checks if a limit is applied for
|
||||
// the container, and if not, it sets the limit to the passed resource list.
|
||||
func MergeContainerResourceLimits(container *api.Container,
|
||||
allocatable api.ResourceList) {
|
||||
func MergeContainerResourceLimits(container *v1.Container,
|
||||
allocatable v1.ResourceList) {
|
||||
if container.Resources.Limits == nil {
|
||||
container.Resources.Limits = make(api.ResourceList)
|
||||
container.Resources.Limits = make(v1.ResourceList)
|
||||
}
|
||||
for _, resource := range []api.ResourceName{api.ResourceCPU, api.ResourceMemory} {
|
||||
for _, resource := range []v1.ResourceName{v1.ResourceCPU, v1.ResourceMemory} {
|
||||
if quantity, exists := container.Resources.Limits[resource]; !exists || quantity.IsZero() {
|
||||
if cap, exists := allocatable[resource]; exists {
|
||||
container.Resources.Limits[resource] = *cap.Copy()
|
||||
|
@ -22,8 +22,8 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
)
|
||||
|
||||
func TestExtractFieldPathAsString(t *testing.T) {
|
||||
@ -43,8 +43,8 @@ func TestExtractFieldPathAsString(t *testing.T) {
|
||||
{
|
||||
name: "ok - namespace",
|
||||
fieldPath: "metadata.namespace",
|
||||
obj: &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
obj: &v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Namespace: "object-namespace",
|
||||
},
|
||||
},
|
||||
@ -53,8 +53,8 @@ func TestExtractFieldPathAsString(t *testing.T) {
|
||||
{
|
||||
name: "ok - name",
|
||||
fieldPath: "metadata.name",
|
||||
obj: &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
obj: &v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: "object-name",
|
||||
},
|
||||
},
|
||||
@ -63,8 +63,8 @@ func TestExtractFieldPathAsString(t *testing.T) {
|
||||
{
|
||||
name: "ok - labels",
|
||||
fieldPath: "metadata.labels",
|
||||
obj: &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
obj: &v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Labels: map[string]string{"key": "value"},
|
||||
},
|
||||
},
|
||||
@ -73,8 +73,8 @@ func TestExtractFieldPathAsString(t *testing.T) {
|
||||
{
|
||||
name: "ok - labels bslash n",
|
||||
fieldPath: "metadata.labels",
|
||||
obj: &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
obj: &v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Labels: map[string]string{"key": "value\n"},
|
||||
},
|
||||
},
|
||||
@ -83,8 +83,8 @@ func TestExtractFieldPathAsString(t *testing.T) {
|
||||
{
|
||||
name: "ok - annotations",
|
||||
fieldPath: "metadata.annotations",
|
||||
obj: &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
obj: &v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Annotations: map[string]string{"builder": "john-doe"},
|
||||
},
|
||||
},
|
||||
@ -94,8 +94,8 @@ func TestExtractFieldPathAsString(t *testing.T) {
|
||||
{
|
||||
name: "invalid expression",
|
||||
fieldPath: "metadata.whoops",
|
||||
obj: &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
obj: &v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Namespace: "object-namespace",
|
||||
},
|
||||
},
|
||||
@ -119,26 +119,26 @@ func TestExtractFieldPathAsString(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getPod(cname, cpuRequest, cpuLimit, memoryRequest, memoryLimit string) *api.Pod {
|
||||
resources := api.ResourceRequirements{
|
||||
Limits: make(api.ResourceList),
|
||||
Requests: make(api.ResourceList),
|
||||
func getPod(cname, cpuRequest, cpuLimit, memoryRequest, memoryLimit string) *v1.Pod {
|
||||
resources := v1.ResourceRequirements{
|
||||
Limits: make(v1.ResourceList),
|
||||
Requests: make(v1.ResourceList),
|
||||
}
|
||||
if cpuLimit != "" {
|
||||
resources.Limits[api.ResourceCPU] = resource.MustParse(cpuLimit)
|
||||
resources.Limits[v1.ResourceCPU] = resource.MustParse(cpuLimit)
|
||||
}
|
||||
if memoryLimit != "" {
|
||||
resources.Limits[api.ResourceMemory] = resource.MustParse(memoryLimit)
|
||||
resources.Limits[v1.ResourceMemory] = resource.MustParse(memoryLimit)
|
||||
}
|
||||
if cpuRequest != "" {
|
||||
resources.Requests[api.ResourceCPU] = resource.MustParse(cpuRequest)
|
||||
resources.Requests[v1.ResourceCPU] = resource.MustParse(cpuRequest)
|
||||
}
|
||||
if memoryRequest != "" {
|
||||
resources.Requests[api.ResourceMemory] = resource.MustParse(memoryRequest)
|
||||
resources.Requests[v1.ResourceMemory] = resource.MustParse(memoryRequest)
|
||||
}
|
||||
return &api.Pod{
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
return &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: cname,
|
||||
Resources: resources,
|
||||
@ -150,14 +150,14 @@ func getPod(cname, cpuRequest, cpuLimit, memoryRequest, memoryLimit string) *api
|
||||
|
||||
func TestExtractResourceValue(t *testing.T) {
|
||||
cases := []struct {
|
||||
fs *api.ResourceFieldSelector
|
||||
pod *api.Pod
|
||||
fs *v1.ResourceFieldSelector
|
||||
pod *v1.Pod
|
||||
cName string
|
||||
expectedValue string
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
fs: &api.ResourceFieldSelector{
|
||||
fs: &v1.ResourceFieldSelector{
|
||||
Resource: "limits.cpu",
|
||||
},
|
||||
cName: "foo",
|
||||
@ -165,7 +165,7 @@ func TestExtractResourceValue(t *testing.T) {
|
||||
expectedValue: "9",
|
||||
},
|
||||
{
|
||||
fs: &api.ResourceFieldSelector{
|
||||
fs: &v1.ResourceFieldSelector{
|
||||
Resource: "requests.cpu",
|
||||
},
|
||||
cName: "foo",
|
||||
@ -173,7 +173,7 @@ func TestExtractResourceValue(t *testing.T) {
|
||||
expectedValue: "0",
|
||||
},
|
||||
{
|
||||
fs: &api.ResourceFieldSelector{
|
||||
fs: &v1.ResourceFieldSelector{
|
||||
Resource: "requests.cpu",
|
||||
},
|
||||
cName: "foo",
|
||||
@ -181,7 +181,7 @@ func TestExtractResourceValue(t *testing.T) {
|
||||
expectedValue: "8",
|
||||
},
|
||||
{
|
||||
fs: &api.ResourceFieldSelector{
|
||||
fs: &v1.ResourceFieldSelector{
|
||||
Resource: "requests.cpu",
|
||||
},
|
||||
cName: "foo",
|
||||
@ -189,7 +189,7 @@ func TestExtractResourceValue(t *testing.T) {
|
||||
expectedValue: "1",
|
||||
},
|
||||
{
|
||||
fs: &api.ResourceFieldSelector{
|
||||
fs: &v1.ResourceFieldSelector{
|
||||
Resource: "requests.cpu",
|
||||
Divisor: resource.MustParse("100m"),
|
||||
},
|
||||
@ -198,7 +198,7 @@ func TestExtractResourceValue(t *testing.T) {
|
||||
expectedValue: "12",
|
||||
},
|
||||
{
|
||||
fs: &api.ResourceFieldSelector{
|
||||
fs: &v1.ResourceFieldSelector{
|
||||
Resource: "requests.memory",
|
||||
},
|
||||
cName: "foo",
|
||||
@ -206,7 +206,7 @@ func TestExtractResourceValue(t *testing.T) {
|
||||
expectedValue: "104857600",
|
||||
},
|
||||
{
|
||||
fs: &api.ResourceFieldSelector{
|
||||
fs: &v1.ResourceFieldSelector{
|
||||
Resource: "requests.memory",
|
||||
Divisor: resource.MustParse("1Mi"),
|
||||
},
|
||||
@ -215,7 +215,7 @@ func TestExtractResourceValue(t *testing.T) {
|
||||
expectedValue: "100",
|
||||
},
|
||||
{
|
||||
fs: &api.ResourceFieldSelector{
|
||||
fs: &v1.ResourceFieldSelector{
|
||||
Resource: "limits.memory",
|
||||
},
|
||||
cName: "foo",
|
||||
|
@ -21,7 +21,8 @@ import (
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/master/ports"
|
||||
"k8s.io/kubernetes/pkg/util/system"
|
||||
@ -53,7 +54,7 @@ type MetricsGrabber struct {
|
||||
func NewMetricsGrabber(c clientset.Interface, kubelets bool, scheduler bool, controllers bool, apiServer bool) (*MetricsGrabber, error) {
|
||||
registeredMaster := false
|
||||
masterName := ""
|
||||
nodeList, err := c.Core().Nodes().List(api.ListOptions{})
|
||||
nodeList, err := c.Core().Nodes().List(v1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -61,7 +62,7 @@ func NewMetricsGrabber(c clientset.Interface, kubelets bool, scheduler bool, con
|
||||
glog.Warning("Can't find any Nodes in the API server to grab metrics from")
|
||||
}
|
||||
for _, node := range nodeList.Items {
|
||||
if system.IsMasterNode(&node) {
|
||||
if system.IsMasterNode(node.Name) {
|
||||
registeredMaster = true
|
||||
masterName = node.Name
|
||||
break
|
||||
@ -85,7 +86,7 @@ func NewMetricsGrabber(c clientset.Interface, kubelets bool, scheduler bool, con
|
||||
}
|
||||
|
||||
func (g *MetricsGrabber) GrabFromKubelet(nodeName string) (KubeletMetrics, error) {
|
||||
nodes, err := g.client.Core().Nodes().List(api.ListOptions{FieldSelector: fields.Set{api.ObjectNameField: nodeName}.AsSelector()})
|
||||
nodes, err := g.client.Core().Nodes().List(v1.ListOptions{FieldSelector: fields.Set{api.ObjectNameField: nodeName}.AsSelector().String()})
|
||||
if err != nil {
|
||||
return KubeletMetrics{}, err
|
||||
}
|
||||
@ -166,7 +167,7 @@ func (g *MetricsGrabber) Grab() (MetricsCollection, error) {
|
||||
}
|
||||
if g.grabFromKubelets {
|
||||
result.KubeletMetrics = make(map[string]KubeletMetrics)
|
||||
nodes, err := g.client.Core().Nodes().List(api.ListOptions{})
|
||||
nodes, err := g.client.Core().Nodes().List(v1.ListOptions{})
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
} else {
|
||||
|
@ -19,7 +19,7 @@ package apparmor
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
)
|
||||
|
||||
// TODO: Move these values into the API package.
|
||||
@ -38,7 +38,7 @@ const (
|
||||
)
|
||||
|
||||
// Checks whether app armor is required for pod to be run.
|
||||
func isRequired(pod *api.Pod) bool {
|
||||
func isRequired(pod *v1.Pod) bool {
|
||||
for key := range pod.Annotations {
|
||||
if strings.HasPrefix(key, ContainerAnnotationKeyPrefix) {
|
||||
return true
|
||||
@ -48,7 +48,7 @@ func isRequired(pod *api.Pod) bool {
|
||||
}
|
||||
|
||||
// Returns the name of the profile to use with the container.
|
||||
func GetProfileName(pod *api.Pod, containerName string) string {
|
||||
func GetProfileName(pod *v1.Pod, containerName string) string {
|
||||
return GetProfileNameFromPodAnnotations(pod.Annotations, containerName)
|
||||
}
|
||||
|
||||
@ -59,10 +59,19 @@ func GetProfileNameFromPodAnnotations(annotations map[string]string, containerNa
|
||||
}
|
||||
|
||||
// Sets the name of the profile to use with the container.
|
||||
func SetProfileName(pod *api.Pod, containerName, profileName string) error {
|
||||
func SetProfileName(pod *v1.Pod, containerName, profileName string) error {
|
||||
if pod.Annotations == nil {
|
||||
pod.Annotations = map[string]string{}
|
||||
}
|
||||
pod.Annotations[ContainerAnnotationKeyPrefix+containerName] = profileName
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sets the name of the profile to use with the container.
|
||||
func SetProfileNameFromPodAnnotations(annotations map[string]string, containerName, profileName string) error {
|
||||
if annotations == nil {
|
||||
return nil
|
||||
}
|
||||
annotations[ContainerAnnotationKeyPrefix+containerName] = profileName
|
||||
return nil
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
utilconfig "k8s.io/kubernetes/pkg/util/config"
|
||||
)
|
||||
@ -36,7 +36,7 @@ var isDisabledBuild bool
|
||||
|
||||
// Interface for validating that a pod with with an AppArmor profile can be run by a Node.
|
||||
type Validator interface {
|
||||
Validate(pod *api.Pod) error
|
||||
Validate(pod *v1.Pod) error
|
||||
ValidateHost() error
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ type validator struct {
|
||||
appArmorFS string
|
||||
}
|
||||
|
||||
func (v *validator) Validate(pod *api.Pod) error {
|
||||
func (v *validator) Validate(pod *v1.Pod) error {
|
||||
if !isRequired(pod) {
|
||||
return nil
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@ -133,19 +133,19 @@ func TestValidateValidHost(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test multi-container pod.
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Annotations: map[string]string{
|
||||
ContainerAnnotationKeyPrefix + "init": ProfileNamePrefix + "foo-container",
|
||||
ContainerAnnotationKeyPrefix + "test1": ProfileRuntimeDefault,
|
||||
ContainerAnnotationKeyPrefix + "test2": ProfileNamePrefix + "docker-default",
|
||||
},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
InitContainers: []api.Container{
|
||||
Spec: v1.PodSpec{
|
||||
InitContainers: []v1.Container{
|
||||
{Name: "init"},
|
||||
},
|
||||
Containers: []api.Container{
|
||||
Containers: []v1.Container{
|
||||
{Name: "test1"},
|
||||
{Name: "test2"},
|
||||
{Name: "no-profile"},
|
||||
@ -172,7 +172,7 @@ func TestParseProfileName(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getPodWithProfile(profile string) *api.Pod {
|
||||
func getPodWithProfile(profile string) *v1.Pod {
|
||||
annotations := map[string]string{
|
||||
ContainerAnnotationKeyPrefix + "test": profile,
|
||||
}
|
||||
@ -181,12 +181,12 @@ func getPodWithProfile(profile string) *api.Pod {
|
||||
"foo": "bar",
|
||||
}
|
||||
}
|
||||
return &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
return &v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Annotations: annotations,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "test",
|
||||
},
|
||||
|
@ -92,7 +92,7 @@ func (s *strategy) Validate(pod *api.Pod, container *api.Container) field.ErrorL
|
||||
allErrs := field.ErrorList{}
|
||||
fieldPath := field.NewPath("pod", "metadata", "annotations").Key(apparmor.ContainerAnnotationKeyPrefix + container.Name)
|
||||
|
||||
profile := apparmor.GetProfileName(pod, container.Name)
|
||||
profile := apparmor.GetProfileNameFromPodAnnotations(pod.Annotations, container.Name)
|
||||
if profile == "" {
|
||||
if len(s.allowedProfiles) > 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(fieldPath, "AppArmor profile must be set"))
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/security/apparmor"
|
||||
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp"
|
||||
@ -373,8 +374,11 @@ func TestValidateContainerSecurityContextFailures(t *testing.T) {
|
||||
}
|
||||
|
||||
failNilAppArmorPod := defaultPod()
|
||||
failInvalidAppArmorPod := defaultPod()
|
||||
apparmor.SetProfileName(failInvalidAppArmorPod, defaultContainerName, apparmor.ProfileNamePrefix+"foo")
|
||||
v1FailInvalidAppArmorPod := defaultV1Pod()
|
||||
apparmor.SetProfileName(v1FailInvalidAppArmorPod, defaultContainerName, apparmor.ProfileNamePrefix+"foo")
|
||||
failInvalidAppArmorPod := &api.Pod{}
|
||||
v1.Convert_v1_Pod_To_api_Pod(v1FailInvalidAppArmorPod, failInvalidAppArmorPod, nil)
|
||||
|
||||
failAppArmorPSP := defaultPSP()
|
||||
failAppArmorPSP.Annotations = map[string]string{
|
||||
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault,
|
||||
@ -669,8 +673,10 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
|
||||
appArmorPSP.Annotations = map[string]string{
|
||||
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault,
|
||||
}
|
||||
appArmorPod := defaultPod()
|
||||
apparmor.SetProfileName(appArmorPod, defaultContainerName, apparmor.ProfileRuntimeDefault)
|
||||
v1AppArmorPod := defaultV1Pod()
|
||||
apparmor.SetProfileName(v1AppArmorPod, defaultContainerName, apparmor.ProfileRuntimeDefault)
|
||||
appArmorPod := &api.Pod{}
|
||||
v1.Convert_v1_Pod_To_api_Pod(v1AppArmorPod, appArmorPod, nil)
|
||||
|
||||
privPSP := defaultPSP()
|
||||
privPSP.Spec.Privileged = true
|
||||
@ -930,6 +936,30 @@ func defaultPod() *api.Pod {
|
||||
}
|
||||
}
|
||||
|
||||
func defaultV1Pod() *v1.Pod {
|
||||
var notPriv bool = false
|
||||
return &v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Annotations: map[string]string{},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: &v1.PodSecurityContext{
|
||||
// fill in for test cases
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: defaultContainerName,
|
||||
SecurityContext: &v1.SecurityContext{
|
||||
// expected to be set by defaulting mechanisms
|
||||
Privileged: ¬Priv,
|
||||
// fill in the rest for test cases
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// TestValidateAllowedVolumes will test that for every field of VolumeSource we can create
|
||||
// a pod with that type of volume and deny it, accept it explicitly, or accept it with
|
||||
// the FSTypeAll wildcard.
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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 (
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -26,7 +26,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/auth/authenticator"
|
||||
"k8s.io/kubernetes/pkg/auth/user"
|
||||
|
||||
@ -47,14 +47,14 @@ const (
|
||||
|
||||
// ServiceAccountTokenGetter defines functions to retrieve a named service account and secret
|
||||
type ServiceAccountTokenGetter interface {
|
||||
GetServiceAccount(namespace, name string) (*api.ServiceAccount, error)
|
||||
GetSecret(namespace, name string) (*api.Secret, error)
|
||||
GetServiceAccount(namespace, name string) (*v1.ServiceAccount, error)
|
||||
GetSecret(namespace, name string) (*v1.Secret, error)
|
||||
}
|
||||
|
||||
type TokenGenerator interface {
|
||||
// GenerateToken generates a token which will identify the given ServiceAccount.
|
||||
// The returned token will be stored in the given (and yet-unpersisted) Secret.
|
||||
GenerateToken(serviceAccount api.ServiceAccount, secret api.Secret) (string, error)
|
||||
GenerateToken(serviceAccount v1.ServiceAccount, secret v1.Secret) (string, error)
|
||||
}
|
||||
|
||||
// ReadPrivateKey is a helper function for reading a private key from a PEM-encoded file
|
||||
@ -148,7 +148,7 @@ type jwtTokenGenerator struct {
|
||||
privateKey interface{}
|
||||
}
|
||||
|
||||
func (j *jwtTokenGenerator) GenerateToken(serviceAccount api.ServiceAccount, secret api.Secret) (string, error) {
|
||||
func (j *jwtTokenGenerator) GenerateToken(serviceAccount v1.ServiceAccount, secret v1.Secret) (string, error) {
|
||||
var method jwt.SigningMethod
|
||||
switch privateKey := j.privateKey.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
@ -299,7 +299,7 @@ func (j *jwtTokenAuthenticator) AuthenticateToken(token string) (user.Info, bool
|
||||
glog.V(4).Infof("Could not retrieve token %s/%s for service account %s/%s: %v", namespace, secretName, namespace, serviceAccountName, err)
|
||||
return nil, false, errors.New("Token has been invalidated")
|
||||
}
|
||||
if bytes.Compare(secret.Data[api.ServiceAccountTokenKey], []byte(token)) != 0 {
|
||||
if bytes.Compare(secret.Data[v1.ServiceAccountTokenKey], []byte(token)) != 0 {
|
||||
glog.V(4).Infof("Token contents no longer matches %s/%s for service account %s/%s", namespace, secretName, namespace, serviceAccountName)
|
||||
return nil, false, errors.New("Token does not match server's copy")
|
||||
}
|
||||
|
@ -22,9 +22,9 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/fake"
|
||||
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||
)
|
||||
@ -164,21 +164,21 @@ func TestTokenGenerateAndValidate(t *testing.T) {
|
||||
expectedUserUID := "12345"
|
||||
|
||||
// Related API objects
|
||||
serviceAccount := &api.ServiceAccount{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
serviceAccount := &v1.ServiceAccount{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: "my-service-account",
|
||||
UID: "12345",
|
||||
Namespace: "test",
|
||||
},
|
||||
}
|
||||
rsaSecret := &api.Secret{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
rsaSecret := &v1.Secret{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: "my-rsa-secret",
|
||||
Namespace: "test",
|
||||
},
|
||||
}
|
||||
ecdsaSecret := &api.Secret{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ecdsaSecret := &v1.Secret{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: "my-ecdsa-secret",
|
||||
Namespace: "test",
|
||||
},
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/auth/user"
|
||||
)
|
||||
@ -84,7 +85,28 @@ func UserInfo(namespace, name, uid string) user.Info {
|
||||
}
|
||||
|
||||
// IsServiceAccountToken returns true if the secret is a valid api token for the service account
|
||||
func IsServiceAccountToken(secret *api.Secret, sa *api.ServiceAccount) bool {
|
||||
func IsServiceAccountToken(secret *v1.Secret, sa *v1.ServiceAccount) bool {
|
||||
if secret.Type != v1.SecretTypeServiceAccountToken {
|
||||
return false
|
||||
}
|
||||
|
||||
name := secret.Annotations[v1.ServiceAccountNameKey]
|
||||
uid := secret.Annotations[v1.ServiceAccountUIDKey]
|
||||
if name != sa.Name {
|
||||
// Name must match
|
||||
return false
|
||||
}
|
||||
if len(uid) > 0 && uid != string(sa.UID) {
|
||||
// If UID is specified, it must match
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// TODO: remove the duplicate code
|
||||
// InternalIsServiceAccountToken returns true if the secret is a valid api token for the service account
|
||||
func InternalIsServiceAccountToken(secret *api.Secret, sa *api.ServiceAccount) bool {
|
||||
if secret.Type != api.SecretTypeServiceAccountToken {
|
||||
return false
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
@ -631,7 +632,7 @@ func newCacherListerWatcher(storage Interface, resourcePrefix string, newListFun
|
||||
}
|
||||
|
||||
// Implements cache.ListerWatcher interface.
|
||||
func (lw *cacherListerWatcher) List(options api.ListOptions) (runtime.Object, error) {
|
||||
func (lw *cacherListerWatcher) List(options v1.ListOptions) (runtime.Object, error) {
|
||||
list := lw.newListFunc()
|
||||
if err := lw.storage.List(context.TODO(), lw.resourcePrefix, "", Everything, list); err != nil {
|
||||
return nil, err
|
||||
@ -640,7 +641,7 @@ func (lw *cacherListerWatcher) List(options api.ListOptions) (runtime.Object, er
|
||||
}
|
||||
|
||||
// Implements cache.ListerWatcher interface.
|
||||
func (lw *cacherListerWatcher) Watch(options api.ListOptions) (watch.Interface, error) {
|
||||
func (lw *cacherListerWatcher) Watch(options v1.ListOptions) (watch.Interface, error) {
|
||||
return lw.storage.WatchList(context.TODO(), lw.resourcePrefix, options.ResourceVersion, Everything)
|
||||
}
|
||||
|
||||
|
@ -24,13 +24,14 @@ package testing
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
time "time"
|
||||
|
||||
codec1978 "github.com/ugorji/go/codec"
|
||||
pkg2_api "k8s.io/kubernetes/pkg/api"
|
||||
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
|
||||
pkg3_types "k8s.io/kubernetes/pkg/types"
|
||||
"reflect"
|
||||
"runtime"
|
||||
time "time"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/clock"
|
||||
@ -312,14 +313,14 @@ func TestWaitUntilFreshAndListTimeout(t *testing.T) {
|
||||
}
|
||||
|
||||
type testLW struct {
|
||||
ListFunc func(options api.ListOptions) (runtime.Object, error)
|
||||
WatchFunc func(options api.ListOptions) (watch.Interface, error)
|
||||
ListFunc func(options v1.ListOptions) (runtime.Object, error)
|
||||
WatchFunc func(options v1.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
func (t *testLW) List(options api.ListOptions) (runtime.Object, error) {
|
||||
func (t *testLW) List(options v1.ListOptions) (runtime.Object, error) {
|
||||
return t.ListFunc(options)
|
||||
}
|
||||
func (t *testLW) Watch(options api.ListOptions) (watch.Interface, error) {
|
||||
func (t *testLW) Watch(options v1.ListOptions) (watch.Interface, error) {
|
||||
return t.WatchFunc(options)
|
||||
}
|
||||
|
||||
@ -337,12 +338,12 @@ func TestReflectorForWatchCache(t *testing.T) {
|
||||
}
|
||||
|
||||
lw := &testLW{
|
||||
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
fw := watch.NewFake()
|
||||
go fw.Stop()
|
||||
return fw, nil
|
||||
},
|
||||
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "10"}}, nil
|
||||
},
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user