From 3916eb9f6002aab1d56498cea61ea3c5cdcbc6aa Mon Sep 17 00:00:00 2001 From: gitlawr Date: Fri, 28 Apr 2017 14:41:06 +0800 Subject: [PATCH] Fixes #575 This commit Add support for cap_add & cap_drop which maps to Pod.Spec.Container.SecurityContext.Capabilities.Add/Drop Added unit tests for ConfigCapabilities function Updated conversion.md on support for these keys --- docs/conversion.md | 2 +- pkg/loader/compose/compose.go | 2 -- pkg/transformer/kubernetes/k8sutils.go | 8 ++++++ pkg/transformer/kubernetes/kubernetes.go | 16 +++++++++++ pkg/transformer/kubernetes/kubernetes_test.go | 27 ++++++++++++++++--- 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/docs/conversion.md b/docs/conversion.md index f02ff9a3..8e2f5524 100644 --- a/docs/conversion.md +++ b/docs/conversion.md @@ -6,7 +6,7 @@ This document outlines all the conversion details regarding `docker-compose.yaml |-------------------|---------|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------| | __SERVICE__ | | | | | | build | | Y | OpenShift: [BuildConfig](https://docs.openshift.com/enterprise/3.1/dev_guide/builds.html#defining-a-buildconfig) | Converts, but local builds are not yet supported. See issue [97](https://github.com/kubernetes-incubator/kompose/issues/97) | -| cap_add, cap_drop | | N | | | +| cap_add, cap_drop | | Y | [Pod.Spec.Container.SecurityContext.Capabilities.Add/Drop](https://kubernetes.io/docs/api-reference/v1.6/#capabilities-v1-core) | | | command | | Y | [Pod.Spec.Container.Command](https://kubernetes.io/docs/api-reference/v1/definitions/#_v1_container) | | | cgroup_parent | | N | | No compatibility with Kubernetes / OpenShift. Limited use-cases with Docker. | | container_name | | Y | Mapped to both [Metadata.Name](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/identifiers.md) and [Deployment.Spec.Containers.Name](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/identifiers.md) | | diff --git a/pkg/loader/compose/compose.go b/pkg/loader/compose/compose.go index 8b1a6ef8..542f5c31 100644 --- a/pkg/loader/compose/compose.go +++ b/pkg/loader/compose/compose.go @@ -51,8 +51,6 @@ func checkUnsupportedKey(composeProject *project.Project) []string { // to make sure that unsupported key is not going to be reported twice // by keeping record if already saw this key in another service var unsupportedKey = map[string]bool{ - "CapAdd": false, - "CapDrop": false, "CgroupParent": false, "CPUSet": false, "CPUShares": false, diff --git a/pkg/transformer/kubernetes/k8sutils.go b/pkg/transformer/kubernetes/k8sutils.go index 257c95ae..2cb001bb 100644 --- a/pkg/transformer/kubernetes/k8sutils.go +++ b/pkg/transformer/kubernetes/k8sutils.go @@ -361,6 +361,9 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic // Configure the container ports. ports := k.ConfigPorts(name, service) + // Configure capabilities + capabilities := k.ConfigCapabilities(service) + // Configure annotations annotations := transformer.ConfigAnnotations(service) @@ -401,6 +404,11 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic } + //set capabilities if it is not empty + if len(capabilities.Add) > 0 || len(capabilities.Drop) > 0 { + securityContext.Capabilities = capabilities + } + // update template only if securityContext is not empty if *securityContext != (api.SecurityContext{}) { template.Spec.Containers[0].SecurityContext = securityContext diff --git a/pkg/transformer/kubernetes/kubernetes.go b/pkg/transformer/kubernetes/kubernetes.go index 16e83950..04a76eda 100644 --- a/pkg/transformer/kubernetes/kubernetes.go +++ b/pkg/transformer/kubernetes/kubernetes.go @@ -331,6 +331,22 @@ func (k *Kubernetes) ConfigServicePorts(name string, service kobject.ServiceConf return servicePorts } +//ConfigCapabilities configure POSIX capabilities that can be added or removed to a container +func (k *Kubernetes) ConfigCapabilities(service kobject.ServiceConfig) *api.Capabilities { + capsAdd := []api.Capability{} + capsDrop := []api.Capability{} + for _, capAdd := range service.CapAdd { + capsAdd = append(capsAdd, api.Capability(capAdd)) + } + for _, capDrop := range service.CapDrop { + capsDrop = append(capsDrop, api.Capability(capDrop)) + } + return &api.Capabilities{ + Add: capsAdd, + Drop: capsDrop, + } +} + // ConfigTmpfs configure the tmpfs. func (k *Kubernetes) ConfigTmpfs(name string, service kobject.ServiceConfig) ([]api.VolumeMount, []api.Volume) { //initializing volumemounts and volumes diff --git a/pkg/transformer/kubernetes/kubernetes_test.go b/pkg/transformer/kubernetes/kubernetes_test.go index 01d1d212..19e8fc77 100644 --- a/pkg/transformer/kubernetes/kubernetes_test.go +++ b/pkg/transformer/kubernetes/kubernetes_test.go @@ -45,10 +45,10 @@ func newServiceConfig() kobject.ServiceConfig { Network: []string{"network1", "network2"}, // not supported Labels: nil, Annotations: map[string]string{"abc": "def"}, - CPUQuota: 1, // not supported - CapAdd: []string{"cap_add"}, // not supported - CapDrop: []string{"cap_drop"}, // not supported - Expose: []string{"expose"}, // not supported + CPUQuota: 1, // not supported + CapAdd: []string{"cap_add"}, + CapDrop: []string{"cap_drop"}, + Expose: []string{"expose"}, // not supported Privileged: true, Restart: "always", Stdin: true, @@ -509,3 +509,22 @@ func TestConfigTmpfs(t *testing.T) { } } + +func TestConfigCapabilities(t *testing.T) { + testCases := map[string]struct { + service kobject.ServiceConfig + result api.Capabilities + }{ + "ConfigCapsWithAddDrop": {kobject.ServiceConfig{CapAdd: []string{"CHOWN", "SETUID"}, CapDrop: []string{"KILL"}}, api.Capabilities{Add: []api.Capability{api.Capability("CHOWN"), api.Capability("SETUID")}, Drop: []api.Capability{api.Capability("KILL")}}}, + "ConfigCapsNoAddDrop": {kobject.ServiceConfig{CapAdd: nil, CapDrop: nil}, api.Capabilities{Add: []api.Capability{}, Drop: []api.Capability{}}}, + } + + k := Kubernetes{} + for name, test := range testCases { + t.Log("Test case:", name) + result := k.ConfigCapabilities(test.service) + if !reflect.DeepEqual(result.Add, test.result.Add) || !reflect.DeepEqual(result.Drop, test.result.Drop) { + t.Errorf("Not expected result for ConfigCapabilities") + } + } +}