forked from LaconicNetwork/kompose
Feat support security fsgroup (#1613)
* feat: support security context fsgroup Signed-off-by: AhmedGrati <ahmedgrati1999@gmail.com> * test: add unit test to security group fsgroup Signed-off-by: AhmedGrati <ahmedgrati1999@gmail.com> * test: add functional test to security group fsgroup Signed-off-by: AhmedGrati <ahmedgrati1999@gmail.com> * docs: add documentation of the new label of security group fsgroup Signed-off-by: AhmedGrati <ahmedgrati1999@gmail.com> --------- Signed-off-by: AhmedGrati <ahmedgrati1999@gmail.com>
This commit is contained in:
parent
ce1294a604
commit
8f0a6684ca
@ -201,6 +201,7 @@ The currently supported options are:
|
|||||||
| kompose.service.healthcheck.liveness.http_get_port | kubernetes liveness httpGet port |
|
| kompose.service.healthcheck.liveness.http_get_port | kubernetes liveness httpGet port |
|
||||||
| kompose.service.healthcheck.liveness.tcp_port | kubernetes liveness tcpSocket port |
|
| kompose.service.healthcheck.liveness.tcp_port | kubernetes liveness tcpSocket port |
|
||||||
| kompose.service.external-traffic-policy | 'cluster', 'local', '' | |
|
| 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.
|
**Note**: `kompose.service.type` label should be defined with `ports` only (except for headless service), otherwise `kompose` will fail.
|
||||||
|
|
||||||
@ -431,6 +432,20 @@ services:
|
|||||||
kompose.service.external-traffic-policy: local
|
kompose.service.external-traffic-policy: local
|
||||||
kompose.service.type: loadbalancer
|
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
|
## 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.
|
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.
|
||||||
|
|||||||
@ -149,6 +149,7 @@ type ServiceConfig struct {
|
|||||||
Dockerfile string `compose:"dockerfile"`
|
Dockerfile string `compose:"dockerfile"`
|
||||||
Replicas int `compose:"replicas"`
|
Replicas int `compose:"replicas"`
|
||||||
GroupAdd []int64 `compose:"group_add"`
|
GroupAdd []int64 `compose:"group_add"`
|
||||||
|
FsGroup int64 `compose:"kompose.security-context.fsgroup"`
|
||||||
Volumes []Volumes `compose:""`
|
Volumes []Volumes `compose:""`
|
||||||
Secrets []types.ServiceSecretConfig
|
Secrets []types.ServiceSecretConfig
|
||||||
HealthChecks HealthChecks `compose:""`
|
HealthChecks HealthChecks `compose:""`
|
||||||
|
|||||||
@ -705,6 +705,8 @@ func parseKomposeLabels(labels map[string]string, serviceConfig *kobject.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
serviceConfig.ServiceExternalTrafficPolicy = serviceExternalTypeTrafficPolicy
|
serviceConfig.ServiceExternalTrafficPolicy = serviceExternalTypeTrafficPolicy
|
||||||
|
case LabelSecurityContextFsGroup:
|
||||||
|
serviceConfig.FsGroup = cast.ToInt64(value)
|
||||||
case LabelServiceExpose:
|
case LabelServiceExpose:
|
||||||
serviceConfig.ExposeService = strings.Trim(strings.ToLower(value), " ,")
|
serviceConfig.ExposeService = strings.Trim(strings.ToLower(value), " ,")
|
||||||
case LabelNodePortPort:
|
case LabelNodePortPort:
|
||||||
|
|||||||
@ -79,6 +79,8 @@ const (
|
|||||||
|
|
||||||
// ServiceTypeHeadless ...
|
// ServiceTypeHeadless ...
|
||||||
ServiceTypeHeadless = "Headless"
|
ServiceTypeHeadless = "Headless"
|
||||||
|
// LabelSecurityContextFsGroup defines the pod FsGroup
|
||||||
|
LabelSecurityContextFsGroup = "kompose.security-context.fsgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
// load environment variables from compose file
|
// load environment variables from compose file
|
||||||
|
|||||||
@ -549,6 +549,11 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
|
|||||||
podSecurityContext.SupplementalGroups = service.GroupAdd
|
podSecurityContext.SupplementalGroups = service.GroupAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set Security Context FsGroup
|
||||||
|
if service.FsGroup != 0 {
|
||||||
|
podSecurityContext.FSGroup = &service.FsGroup
|
||||||
|
}
|
||||||
|
|
||||||
// Setup security context
|
// Setup security context
|
||||||
securityContext := &api.SecurityContext{}
|
securityContext := &api.SecurityContext{}
|
||||||
if service.Privileged {
|
if service.Privileged {
|
||||||
|
|||||||
@ -51,6 +51,7 @@ func newServiceConfig() kobject.ServiceConfig {
|
|||||||
VolList: []string{"/tmp/volume"},
|
VolList: []string{"/tmp/volume"},
|
||||||
Network: []string{"network1", "network2"}, // supported
|
Network: []string{"network1", "network2"}, // supported
|
||||||
Labels: nil,
|
Labels: nil,
|
||||||
|
FsGroup: 1001,
|
||||||
Annotations: map[string]string{"abc": "def"},
|
Annotations: map[string]string{"abc": "def"},
|
||||||
CPUQuota: 1, // not supported
|
CPUQuota: 1, // not supported
|
||||||
CapAdd: []string{"cap_add"},
|
CapAdd: []string{"cap_add"},
|
||||||
@ -209,6 +210,9 @@ func checkPodTemplate(config kobject.ServiceConfig, template api.PodTemplateSpec
|
|||||||
if config.Privileged == privilegedNilOrFalse(template) {
|
if config.Privileged == privilegedNilOrFalse(template) {
|
||||||
return fmt.Errorf("Found different template privileged: %#v vs. %#v", config.Privileged, template.Spec.Containers[0].SecurityContext)
|
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 {
|
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)
|
return fmt.Errorf("Found different values for stdin: %#v vs. %#v", config.Stdin, template.Spec.Containers[0].Stdin)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -128,6 +128,11 @@ func SecurityContext(name string, service kobject.ServiceConfig) PodSpecOption {
|
|||||||
podSecurityContext.SupplementalGroups = service.GroupAdd
|
podSecurityContext.SupplementalGroups = service.GroupAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set Pod FsGroup
|
||||||
|
if service.FsGroup != 0 {
|
||||||
|
podSecurityContext.FSGroup = &service.FsGroup
|
||||||
|
}
|
||||||
|
|
||||||
// Setup security context
|
// Setup security context
|
||||||
securityContext := &api.SecurityContext{}
|
securityContext := &api.SecurityContext{}
|
||||||
if service.Privileged {
|
if service.Privileged {
|
||||||
|
|||||||
@ -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"
|
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 "$k8s_cmd" "$k8s_output"
|
||||||
convert::expect_success_and_warning "$os_cmd" "$os_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
script/test/fixtures/fsgroup/docker-compose.yaml
vendored
Normal file
14
script/test/fixtures/fsgroup/docker-compose.yaml
vendored
Normal file
@ -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: dumb_pgadmin_user@email.com
|
||||||
|
PGADMIN_DEFAULT_PASSWORD: pgadmin_password
|
||||||
|
volumes:
|
||||||
|
- pgadmin-data:/var/lib/pgadmin
|
||||||
79
script/test/fixtures/fsgroup/output-k8s.yaml
vendored
Normal file
79
script/test/fixtures/fsgroup/output-k8s.yaml
vendored
Normal file
@ -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: dumb_pgadmin_user@email.com
|
||||||
|
- 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
script/test/fixtures/fsgroup/output-os.yaml
vendored
Normal file
102
script/test/fixtures/fsgroup/output-os.yaml
vendored
Normal file
@ -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: dumb_pgadmin_user@email.com
|
||||||
|
- 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: {}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user