Skip to content

Commit

Permalink
Feat support security fsgroup (#1613)
Browse files Browse the repository at this point in the history
* feat: support security context fsgroup

Signed-off-by: AhmedGrati <[email protected]>

* test: add unit test to security group fsgroup

Signed-off-by: AhmedGrati <[email protected]>

* test: add functional test to security group fsgroup

Signed-off-by: AhmedGrati <[email protected]>

* docs: add documentation of the new label of security group fsgroup

Signed-off-by: AhmedGrati <[email protected]>

---------

Signed-off-by: AhmedGrati <[email protected]>
  • Loading branch information
AhmedGrati authored Apr 5, 2023
1 parent ce1294a commit 8f0a668
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 0 deletions.
15 changes: 15 additions & 0 deletions docs/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ The currently supported options are:
| kompose.service.healthcheck.liveness.http_get_port | kubernetes liveness httpGet port |
| kompose.service.healthcheck.liveness.tcp_port | kubernetes liveness tcpSocket port |
| kompose.service.external-traffic-policy | 'cluster', 'local', '' | |
| kompose.security-context.fsgroup | kubernetes pod security group fsgroup | |

**Note**: `kompose.service.type` label should be defined with `ports` only (except for headless service), otherwise `kompose` will fail.

Expand Down Expand Up @@ -431,6 +432,20 @@ services:
kompose.service.external-traffic-policy: local
kompose.service.type: loadbalancer
```

- `kompose.security-context.fsgroup` defines Kubernetes Pod [security context FsGroup.](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/).

For example:

```yaml
version: '3.8'
services:
pgadmin:
image: nginx
labels:
kompose.security-context.fsgroup: 1001
```
## Restart

If you want to create normal pods without controller you can use `restart` construct of docker-compose to define that. Follow table below to see what happens on the `restart` value.
Expand Down
1 change: 1 addition & 0 deletions pkg/kobject/kobject.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ type ServiceConfig struct {
Dockerfile string `compose:"dockerfile"`
Replicas int `compose:"replicas"`
GroupAdd []int64 `compose:"group_add"`
FsGroup int64 `compose:"kompose.security-context.fsgroup"`
Volumes []Volumes `compose:""`
Secrets []types.ServiceSecretConfig
HealthChecks HealthChecks `compose:""`
Expand Down
2 changes: 2 additions & 0 deletions pkg/loader/compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,8 @@ func parseKomposeLabels(labels map[string]string, serviceConfig *kobject.Service
}

serviceConfig.ServiceExternalTrafficPolicy = serviceExternalTypeTrafficPolicy
case LabelSecurityContextFsGroup:
serviceConfig.FsGroup = cast.ToInt64(value)
case LabelServiceExpose:
serviceConfig.ExposeService = strings.Trim(strings.ToLower(value), " ,")
case LabelNodePortPort:
Expand Down
2 changes: 2 additions & 0 deletions pkg/loader/compose/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ const (

// ServiceTypeHeadless ...
ServiceTypeHeadless = "Headless"
// LabelSecurityContextFsGroup defines the pod FsGroup
LabelSecurityContextFsGroup = "kompose.security-context.fsgroup"
)

// load environment variables from compose file
Expand Down
5 changes: 5 additions & 0 deletions pkg/transformer/kubernetes/k8sutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,11 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
podSecurityContext.SupplementalGroups = service.GroupAdd
}

//set Security Context FsGroup
if service.FsGroup != 0 {
podSecurityContext.FSGroup = &service.FsGroup
}

// Setup security context
securityContext := &api.SecurityContext{}
if service.Privileged {
Expand Down
4 changes: 4 additions & 0 deletions pkg/transformer/kubernetes/kubernetes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func newServiceConfig() kobject.ServiceConfig {
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // supported
Labels: nil,
FsGroup: 1001,
Annotations: map[string]string{"abc": "def"},
CPUQuota: 1, // not supported
CapAdd: []string{"cap_add"},
Expand Down Expand Up @@ -209,6 +210,9 @@ func checkPodTemplate(config kobject.ServiceConfig, template api.PodTemplateSpec
if config.Privileged == privilegedNilOrFalse(template) {
return fmt.Errorf("Found different template privileged: %#v vs. %#v", config.Privileged, template.Spec.Containers[0].SecurityContext)
}
if config.FsGroup != *template.Spec.SecurityContext.FSGroup {
return fmt.Errorf("Found different pod security context fs group values: %#v vs. %#v", config.FsGroup, *template.Spec.SecurityContext.FSGroup)
}
if config.Stdin != template.Spec.Containers[0].Stdin {
return fmt.Errorf("Found different values for stdin: %#v vs. %#v", config.Stdin, template.Spec.Containers[0].Stdin)
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/transformer/kubernetes/podspec.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ func SecurityContext(name string, service kobject.ServiceConfig) PodSpecOption {
podSecurityContext.SupplementalGroups = service.GroupAdd
}

//set Pod FsGroup
if service.FsGroup != 0 {
podSecurityContext.FSGroup = &service.FsGroup
}

// Setup security context
securityContext := &api.SecurityContext{}
if service.Privileged {
Expand Down
8 changes: 8 additions & 0 deletions script/test/cmd/tests_new.sh
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,11 @@ os_cmd="kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/exter
os_output="$KOMPOSE_ROOT/script/test/fixtures/external-traffic-policy/output-os-v2.yaml"
convert::expect_success_and_warning "$k8s_cmd" "$k8s_output"
convert::expect_success_and_warning "$os_cmd" "$os_output"

# Test Pod security context fs group
k8s_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/fsgroup/docker-compose.yaml convert --stdout --with-kompose-annotation=false"
k8s_output="$KOMPOSE_ROOT/script/test/fixtures/fsgroup/output-k8s.yaml"
os_cmd="kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/fsgroup/docker-compose.yaml convert --stdout --with-kompose-annotation=false"
os_output="$KOMPOSE_ROOT/script/test/fixtures/fsgroup/output-os.yaml"
convert::expect_success_and_warning "$k8s_cmd" "$k8s_output"
convert::expect_success "$os_cmd" "$os_output"
14 changes: 14 additions & 0 deletions script/test/fixtures/fsgroup/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: '3.8'
volumes:
pgadmin-data:

services:
pgadmin:
labels:
kompose.security-context.fsgroup: 1001
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: [email protected]
PGADMIN_DEFAULT_PASSWORD: pgadmin_password
volumes:
- pgadmin-data:/var/lib/pgadmin
79 changes: 79 additions & 0 deletions script/test/fixtures/fsgroup/output-k8s.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.security-context.fsgroup: "1001"
creationTimestamp: null
labels:
io.kompose.service: pgadmin
name: pgadmin
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: pgadmin
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.security-context.fsgroup: "1001"
creationTimestamp: null
labels:
io.kompose.network/fsgroup-default: "true"
io.kompose.service: pgadmin
spec:
containers:
- env:
- name: PGADMIN_DEFAULT_EMAIL
value: [email protected]
- name: PGADMIN_DEFAULT_PASSWORD
value: pgadmin_password
image: dpage/pgadmin4
name: pgadmin
resources: {}
volumeMounts:
- mountPath: /var/lib/pgadmin
name: pgadmin-data
restartPolicy: Always
securityContext:
fsGroup: 1001
volumes:
- name: pgadmin-data
persistentVolumeClaim:
claimName: pgadmin-data
status: {}

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: pgadmin-data
name: pgadmin-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
creationTimestamp: null
name: fsgroup-default
spec:
ingress:
- from:
- podSelector:
matchLabels:
io.kompose.network/fsgroup-default: "true"
podSelector:
matchLabels:
io.kompose.network/fsgroup-default: "true"

102 changes: 102 additions & 0 deletions script/test/fixtures/fsgroup/output-os.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
apiVersion: v1
kind: DeploymentConfig
metadata:
annotations:
kompose.security-context.fsgroup: "1001"
creationTimestamp: null
labels:
io.kompose.service: pgadmin
name: pgadmin
spec:
replicas: 1
selector:
io.kompose.service: pgadmin
strategy:
resources: {}
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
io.kompose.network/fsgroup-default: "true"
io.kompose.service: pgadmin
spec:
containers:
- env:
- name: PGADMIN_DEFAULT_EMAIL
value: [email protected]
- name: PGADMIN_DEFAULT_PASSWORD
value: pgadmin_password
image: ' '
name: pgadmin
resources: {}
volumeMounts:
- mountPath: /var/lib/pgadmin
name: pgadmin-data
restartPolicy: Always
securityContext:
fsGroup: 1001
volumes:
- name: pgadmin-data
persistentVolumeClaim:
claimName: pgadmin-data
test: false
triggers:
- type: ConfigChange
- imageChangeParams:
automatic: true
containerNames:
- pgadmin
from:
kind: ImageStreamTag
name: pgadmin:latest
type: ImageChange
status:
availableReplicas: 0
latestVersion: 0
observedGeneration: 0
replicas: 0
unavailableReplicas: 0
updatedReplicas: 0

---
apiVersion: v1
kind: ImageStream
metadata:
creationTimestamp: null
labels:
io.kompose.service: pgadmin
name: pgadmin
spec:
lookupPolicy:
local: false
tags:
- annotations: null
from:
kind: DockerImage
name: dpage/pgadmin4
generation: null
importPolicy: {}
name: latest
referencePolicy:
type: ""
status:
dockerImageRepository: ""

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: pgadmin-data
name: pgadmin-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}

0 comments on commit 8f0a668

Please sign in to comment.