Browse Source

Add ability to control owner:group and permissions

via new module 'perm'

1) DaemonSet
2) Secret (instead of old ConfigMap)
3) Include module /bin/_perm.sh.tpl
4) Commented example in values.yaml
5) Demo: https://asciinema.org/a/209509
6) Increased # of expected DaemonSets
7) Rebased after a few merges
8) Addressing comments
9) Migrated from ConfigMap to Secret
10) Got rid of 'eval'
11) Test
12) Demo for host targeting: https://asciinema.org/a/213125

Change-Id: Ia3181dcb7fc1ccc7422c635b010000f6d3fbcf4d
skovaleff 5 months ago
parent
commit
0731ac5d3a

+ 135
- 0
divingbell/templates/bin/_perm.sh.tpl View File

@@ -0,0 +1,135 @@
1
+#!/bin/bash
2
+
3
+{{/*
4
+# Copyright 2018 AT&T Intellectual Property.  All other rights reserved.
5
+#
6
+# Licensed under the Apache License, Version 2.0 (the "License");
7
+# you may not use this file except in compliance with the License.
8
+# You may obtain a copy of the License at
9
+#
10
+#     http://www.apache.org/licenses/LICENSE-2.0
11
+#
12
+# Unless required by applicable law or agreed to in writing, software
13
+# distributed under the License is distributed on an "AS IS" BASIS,
14
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+# See the License for the specific language governing permissions and
16
+# limitations under the License.
17
+*/}}
18
+
19
+set -e
20
+
21
+cat <<'EOF' > {{ .Values.conf.chroot_mnt_path | quote }}/tmp/perm_host.sh
22
+{{ include "divingbell.shcommon" . }}
23
+
24
+backup_path='/var/divingbell/perm'
25
+
26
+[ ! -d "${backup_path}" ] && mkdir -p "${backup_path}"
27
+
28
+write_test "${backup_path}"
29
+
30
+add_perm(){
31
+# accepts $path, $owner, $group, $permissions
32
+  local path="${1}"
33
+
34
+  for i in ${path}; do
35
+    add_single_perm $i ${2} ${3} ${4}
36
+  done
37
+}
38
+
39
+add_single_perm(){
40
+# accepts $path, $owner, $group, $permissions
41
+  local path="${1}"
42
+  local owner="${2}"
43
+  local group="${3}"
44
+  local permissions="${4}"
45
+
46
+  # check if file exists
47
+  [ -e $path ] || return 1
48
+  # if set -e is set the entire script will exit
49
+
50
+  # construct backup name
51
+  local file_name=$(systemd-escape $path)
52
+  local backup_file="${backup_path}/${file_name}"
53
+  # check if backup exists
54
+  if [ ! -e ${backup_file} ]; then
55
+      # Try reading the current permissions and owner
56
+      local o_owner="$(stat -c %U ${path})"
57
+      local o_group="$(stat -c %G ${path})"
58
+      local o_permissions="$(stat -c %a ${path})"
59
+
60
+      # write restore script/data
61
+      # design decision:
62
+      # we could write complete script to restore originals
63
+      # but for security reasons write only data
64
+      # otherwise we would execute _any_ script from backup dir
65
+
66
+      # chmod o_permissions path
67
+      echo "$o_permissions $path"> ${backup_file}
68
+      # chown o_owner:o_group path
69
+      echo "$o_owner:$o_group $path">> ${backup_file}
70
+
71
+      log.DEBUG ${backup_file}
72
+  fi
73
+
74
+  # apply permissions
75
+  chmod ${permissions} ${path}
76
+  # apply owner and group
77
+  chown ${owner}:${group} ${path}
78
+
79
+  # notice applied perm
80
+  applied_perm="${applied_perm}${file_name}"$'\n'
81
+  # ("${file_name}"$'\n')
82
+
83
+}
84
+
85
+{{- range $perm := .Values.conf.perm }}
86
+add_perm {{ $perm.path | squote }} {{ $perm.owner | squote }} {{ $perm.group | squote }} {{ $perm.permissions | squote }}
87
+{{- end }}
88
+
89
+log.INFO "Applied: ${applied_perm}"
90
+
91
+# Revert
92
+prev_files="$(find "${backup_path}" -type f)"
93
+if [ -n "${prev_files}" ]; then
94
+  basename -a ${prev_files} | sort > /tmp/prev_perm
95
+  echo "${applied_perm}" | sort > /tmp/curr_perm
96
+  log.DEBUG /tmp/prev_perm
97
+  log.DEBUG /tmp/curr_perm
98
+  revert_list="$(comm -23 /tmp/prev_perm /tmp/curr_perm)"
99
+  IFS=$'\n'
100
+  for o_perm in ${revert_list}; do
101
+    first=1
102
+    while IFS=' ' read -r a1 a2; do
103
+      if [ "$first" -eq 1 ]; then
104
+        $(chmod $a1 $a2)
105
+        first=0
106
+      else
107
+        $(chown $a1 $a2)
108
+      fi
109
+    done < "${backup_path}/${o_perm}"
110
+
111
+    rm "${backup_path}/${o_perm}"
112
+    log.INFO "Reverted permissions and owner: ${backup_path}/${o_perm}"
113
+  done
114
+fi
115
+
116
+if [ -n "${curr_settings}" ]; then
117
+  log.INFO 'All permissions successfully applied on this node.'
118
+else
119
+  log.WARN 'No permissions overrides defined for this node.'
120
+fi
121
+
122
+exit 0
123
+EOF
124
+
125
+chmod 755 {{ .Values.conf.chroot_mnt_path | quote }}/tmp/perm_host.sh
126
+chroot {{ .Values.conf.chroot_mnt_path | quote }} /tmp/perm_host.sh
127
+
128
+sleep 1
129
+echo 'INFO Putting the daemon to sleep.'
130
+
131
+while [ 1 ]; do
132
+  sleep 300
133
+done
134
+
135
+exit 0

+ 71
- 0
divingbell/templates/daemonset-perm.yaml View File

@@ -0,0 +1,71 @@
1
+{{/*
2
+# Copyright 2017 AT&T Intellectual Property.  All other rights reserved.
3
+#
4
+# Licensed under the Apache License, Version 2.0 (the "License");
5
+# you may not use this file except in compliance with the License.
6
+# You may obtain a copy of the License at
7
+#
8
+#     http://www.apache.org/licenses/LICENSE-2.0
9
+#
10
+# Unless required by applicable law or agreed to in writing, software
11
+# distributed under the License is distributed on an "AS IS" BASIS,
12
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+# See the License for the specific language governing permissions and
14
+# limitations under the License.
15
+*/}}
16
+
17
+{{- define "divingbell.daemonset.perm" }}
18
+  {{- $daemonset := index . 0 }}
19
+  {{- $secretName := index . 1 }}
20
+  {{- $envAll := index . 2 }}
21
+  {{- with $envAll }}
22
+---
23
+apiVersion: extensions/v1beta1
24
+kind: DaemonSet
25
+metadata:
26
+  name: {{ $daemonset }}
27
+  annotations:
28
+    {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
29
+spec:
30
+{{ tuple $envAll $daemonset | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }}
31
+  template:
32
+    metadata:
33
+      labels:
34
+{{ list $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
35
+    spec:
36
+      hostNetwork: true
37
+      hostPID: true
38
+      hostIPC: true
39
+      containers:
40
+      - name: {{ $daemonset }}
41
+        image: {{ .Values.images.divingbell }}
42
+        imagePullPolicy: {{ .Values.images.pull_policy }}
43
+{{ tuple $envAll $envAll.Values.pod.resources.perm | include "helm-toolkit.snippets.kubernetes_resources" | indent 8 }}
44
+        command:
45
+        - /tmp/{{ $daemonset }}.sh
46
+        volumeMounts:
47
+        - name: rootfs-{{ $daemonset }}
48
+          mountPath: {{ .Values.conf.chroot_mnt_path }}
49
+        - name: {{ $secretName }}
50
+          mountPath: /tmp/{{ $daemonset }}.sh
51
+          subPath: {{ $daemonset }}
52
+          readOnly: true
53
+        securityContext:
54
+          privileged: true
55
+      volumes:
56
+      - name: rootfs-{{ $daemonset }}
57
+        hostPath:
58
+          path: /
59
+      - name: {{ $secretName }}
60
+        secret:
61
+          secretName: {{ $secretName }}
62
+          defaultMode: 0555
63
+  {{- end }}
64
+{{- end }}
65
+{{- if .Values.manifests.daemonset_perm }}
66
+{{- $daemonset := "perm" }}
67
+{{- $secretName := "divingbell-perm" }}
68
+{{- $daemonset_yaml := list $daemonset $secretName . | include "divingbell.daemonset.perm" | toString | fromYaml }}
69
+{{- $secret_include := "divingbell.secret.perm" }}
70
+{{- list $daemonset $daemonset_yaml $secret_include $secretName . | include "helm-toolkit.utils.daemonset_overrides" }}
71
+{{- end }}

+ 29
- 0
divingbell/templates/secret-perm.yaml View File

@@ -0,0 +1,29 @@
1
+{{/*
2
+Copyright 2018 The Openstack-Helm Authors.
3
+
4
+Licensed under the Apache License, Version 2.0 (the "License");
5
+you may not use this file except in compliance with the License.
6
+You may obtain a copy of the License at
7
+
8
+   http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+Unless required by applicable law or agreed to in writing, software
11
+distributed under the License is distributed on an "AS IS" BASIS,
12
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+See the License for the specific language governing permissions and
14
+limitations under the License.
15
+*/}}
16
+
17
+{{- define "divingbell.secret.perm" }}
18
+{{- $secretName := index . 0 }}
19
+{{- $envAll := index . 1 }}
20
+{{- with $envAll }}
21
+---
22
+apiVersion: v1
23
+kind: Secret
24
+metadata:
25
+  name: {{ $secretName }}
26
+data:
27
+  perm: {{ tuple "bin/_perm.sh.tpl" . | include "helm-toolkit.utils.template" | b64enc }}
28
+{{- end }}
29
+{{- end }}

+ 53
- 0
divingbell/values.yaml View File

@@ -31,6 +31,47 @@ conf:
31 31
     - telnetd-ssl
32 32
     - nis
33 33
     - ntpdate
34
+#  perm:
35
+#    -
36
+#      path: '/boot/System.map-*'
37
+#      owner: 'root'
38
+#      group: 'root'
39
+#      permissions: '0640'
40
+#    -
41
+#      path: '/etc/shadow'
42
+#      owner: 'root'
43
+#      group: 'shadow'
44
+#      permissions: '0640'
45
+#    -
46
+#      path: '/etc/gshadow'
47
+#      owner: 'root'
48
+#      group: 'shadow'
49
+#      permissions: '0640'
50
+#    -
51
+#      path: '/etc/passwd'
52
+#      owner: 'root'
53
+#      group: 'root'
54
+#      permissions: '0644'
55
+#    -
56
+#      path: '/etc/group'
57
+#      owner: 'root'
58
+#      group: 'root'
59
+#      permissions: '0644'
60
+#    -
61
+#      path: '/var/log/kern.log'
62
+#      owner: 'syslog'
63
+#      group: 'adm'
64
+#      permissions: '0640'
65
+#    -
66
+#      path: '/var/log/auth.log'
67
+#      owner: 'syslog'
68
+#      group: 'adm'
69
+#      permissions: '0640'
70
+#    -
71
+#      path: '/var/log/syslog'
72
+#      owner: 'syslog'
73
+#      group: 'adm'
74
+#      permissions: '0640'
34 75
 
35 76
 ##  data.values.conf.sysctl
36 77
 #  sysctl:
@@ -76,6 +117,10 @@ pod:
76 117
           enabled: true
77 118
           min_ready_seconds: 0
78 119
           max_unavailable: 100%
120
+        perm:
121
+          enabled: true
122
+          min_ready_seconds: 0
123
+          max_unavailable: 100%
79 124
   resources:
80 125
     enabled: false
81 126
     ethtool:
@@ -113,6 +158,13 @@ pod:
113 158
       requests:
114 159
         memory: "128Mi"
115 160
         cpu: "100m"
161
+    perm:
162
+      limits:
163
+        memory: "128Mi"
164
+        cpu: "100m"
165
+      requests:
166
+        memory: "128Mi"
167
+        cpu: "100m"
116 168
     apt:
117 169
       limits:
118 170
         memory: "128Mi"
@@ -128,3 +180,4 @@ manifests:
128 180
   daemonset_sysctl: true
129 181
   daemonset_limits: true
130 182
   daemonset_apt: true
183
+  daemonset_perm: true

+ 85
- 2
tools/gate/scripts/020-test-divingbell.sh View File

@@ -353,6 +353,88 @@ test_limits(){
353 353
   echo "[SUCCESS] test range loop for limits passed successfully" >> "${TEST_RESULTS}"
354 354
 }
355 355
 
356
+_test_perm_value(){
357
+  local file=${1}
358
+  local owner=${2}
359
+  local group=${3}
360
+  local perm=${4}
361
+  local r_owner="$(stat -c %U ${file})"
362
+  local r_group="$(stat -c %G ${file})"
363
+  local r_perm="$(stat -c %a ${file})"
364
+  [ "${perm}"=="${r_perm}" ] && echo "+" || (echo "File ${file} permissions ${r_perm} but expected ${perm}"; exit 1)
365
+  [ "${owner}"=="${r_owner}" ] && echo "+" || (echo "File ${file} owner ${r_owner} but expected ${owner}"; exit 1)
366
+  [ "${group}"=="${r_group}" ] && echo "+" || (echo "File ${file} group ${r_group} but expected ${group}"; exit 1)
367
+}
368
+
369
+_perm_init_one(){
370
+  local file=${1}
371
+  local user=${file##*.}
372
+  useradd ${user} -U
373
+  chmod 777 ${file}
374
+  chown ${user}:${user} ${file}
375
+  echo ${file}
376
+}
377
+
378
+_make_p_temp(){
379
+  echo $(mktemp "${TMPDIR:-/tmp}/${0##*/}.XXXXXX")
380
+}
381
+
382
+_perm_init(){
383
+  # global vars!
384
+  p_test_file1=$(_perm_init_one $(_make_p_temp))
385
+  p_test_file2=$(_perm_init_one $(_make_p_temp))
386
+}
387
+
388
+_perm_teardown_one(){
389
+  local file=${1}
390
+  local user=${file##*.}
391
+  deluser ${user} -q
392
+  rm -f ${file}
393
+}
394
+
395
+_perm_teardown(){
396
+  # global vars!
397
+  _perm_teardown_one ${p_test_file1}
398
+  unset p_test_file1
399
+  _perm_teardown_one ${p_test_file2}
400
+  unset p_test_file2
401
+}
402
+
403
+test_perm(){
404
+  _perm_init
405
+  local overrides_yaml=${LOGS_SUBDIR}/${FUNCNAME}.yaml
406
+  echo "conf:
407
+  perm:
408
+    -
409
+      path: ${p_test_file1}
410
+      owner: 'root'
411
+      group: 'shadow'
412
+      permissions: '0640'
413
+    -
414
+      path: ${p_test_file2}
415
+      owner: 'root'
416
+      group: 'shadow'
417
+      permissions: '0640'" > "${overrides_yaml}"
418
+  install_base "--values=${overrides_yaml}"
419
+  get_container_status perm
420
+  _test_perm_value ${p_test_file1} root shadow 640
421
+  _test_perm_value ${p_test_file2} root shadow 640
422
+  echo "[SUCCESS] Positive test for perm passed successfully" >> "${TEST_RESULTS}"
423
+  echo "conf:
424
+  perm:
425
+    -
426
+      path: ${p_test_file1}
427
+      owner: 'root'
428
+      group: 'shadow'
429
+      permissions: '0640'" > "${overrides_yaml}"
430
+  install_base "--values=${overrides_yaml}"
431
+  get_container_status perm
432
+  _test_perm_value ${p_test_file1} root shadow 640
433
+  _test_perm_value ${p_test_file2} ${p_test_file2##*.} ${p_test_file2##*.} 777
434
+  echo "[SUCCESS] Backup test for perm passed successfully" >> "${TEST_RESULTS}"
435
+  _perm_teardown
436
+}
437
+
356 438
 _test_if_mounted_positive(){
357 439
   mountpoint "${1}" || (echo "Expect ${1} to be mounted, but was not"; exit 1)
358 440
   df -h | grep "${1}" | grep "${2}" ||
@@ -971,9 +1053,9 @@ test_overrides(){
971 1053
 
972 1054
   # Compare against expected number of generated daemonsets
973 1055
   daemonset_count="$(echo "${tc_output}" | grep 'kind: DaemonSet' | wc -l)"
974
-  if [ "${daemonset_count}" != "14" ]; then
1056
+  if [ "${daemonset_count}" != "15" ]; then
975 1057
     echo '[FAILURE] overrides test 1 failed' >> "${TEST_RESULTS}"
976
-    echo "Expected 14 daemonsets; got '${daemonset_count}'" >> "${TEST_RESULTS}"
1058
+    echo "Expected 15 daemonsets; got '${daemonset_count}'" >> "${TEST_RESULTS}"
977 1059
     exit 1
978 1060
   else
979 1061
     echo '[SUCCESS] overrides test 1 passed successfully' >> "${TEST_RESULTS}"
@@ -1153,6 +1235,7 @@ if [[ -z $SKIP_BASE_TESTS ]]; then
1153 1235
   install_base
1154 1236
   test_sysctl
1155 1237
   test_limits
1238
+  test_perm
1156 1239
   test_mounts
1157 1240
   test_ethtool
1158 1241
   test_uamlite

Loading…
Cancel
Save