summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskovaleff <sk607s@att.com>2018-10-31 18:22:39 -0700
committerskovaleff <sk607s@att.com>2018-11-27 09:08:11 -0800
commit0731ac5d3a2d4c63dab0b9f519f403b6548bcce0 (patch)
treeb7a8ff20ba6fcdf926755980651812727f5e5d3c
parent97bcc9760ff1c88a4243ce561e4d72d7d408dd94 (diff)
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
Notes
Notes (review): Code-Review+2: Matt McEuen <matt.mceuen@att.com> Code-Review+2: Scott Hussey <sthussey@att.com> Workflow+1: Scott Hussey <sthussey@att.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Tue, 27 Nov 2018 20:45:27 +0000 Reviewed-on: https://review.openstack.org/614665 Project: openstack/airship-divingbell Branch: refs/heads/master
-rw-r--r--divingbell/templates/bin/_perm.sh.tpl135
-rw-r--r--divingbell/templates/daemonset-perm.yaml71
-rw-r--r--divingbell/templates/secret-perm.yaml29
-rw-r--r--divingbell/values.yaml53
-rwxr-xr-xtools/gate/scripts/020-test-divingbell.sh87
5 files changed, 373 insertions, 2 deletions
diff --git a/divingbell/templates/bin/_perm.sh.tpl b/divingbell/templates/bin/_perm.sh.tpl
new file mode 100644
index 0000000..6aac03e
--- /dev/null
+++ b/divingbell/templates/bin/_perm.sh.tpl
@@ -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
19set -e
20
21cat <<'EOF' > {{ .Values.conf.chroot_mnt_path | quote }}/tmp/perm_host.sh
22{{ include "divingbell.shcommon" . }}
23
24backup_path='/var/divingbell/perm'
25
26[ ! -d "${backup_path}" ] && mkdir -p "${backup_path}"
27
28write_test "${backup_path}"
29
30add_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
39add_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 }}
86add_perm {{ $perm.path | squote }} {{ $perm.owner | squote }} {{ $perm.group | squote }} {{ $perm.permissions | squote }}
87{{- end }}
88
89log.INFO "Applied: ${applied_perm}"
90
91# Revert
92prev_files="$(find "${backup_path}" -type f)"
93if [ -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
114fi
115
116if [ -n "${curr_settings}" ]; then
117 log.INFO 'All permissions successfully applied on this node.'
118else
119 log.WARN 'No permissions overrides defined for this node.'
120fi
121
122exit 0
123EOF
124
125chmod 755 {{ .Values.conf.chroot_mnt_path | quote }}/tmp/perm_host.sh
126chroot {{ .Values.conf.chroot_mnt_path | quote }} /tmp/perm_host.sh
127
128sleep 1
129echo 'INFO Putting the daemon to sleep.'
130
131while [ 1 ]; do
132 sleep 300
133done
134
135exit 0
diff --git a/divingbell/templates/daemonset-perm.yaml b/divingbell/templates/daemonset-perm.yaml
new file mode 100644
index 0000000..6c31c71
--- /dev/null
+++ b/divingbell/templates/daemonset-perm.yaml
@@ -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---
23apiVersion: extensions/v1beta1
24kind: DaemonSet
25metadata:
26 name: {{ $daemonset }}
27 annotations:
28 {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
29spec:
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 }}
diff --git a/divingbell/templates/secret-perm.yaml b/divingbell/templates/secret-perm.yaml
new file mode 100644
index 0000000..e1edbfa
--- /dev/null
+++ b/divingbell/templates/secret-perm.yaml
@@ -0,0 +1,29 @@
1{{/*
2Copyright 2018 The Openstack-Helm Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/}}
16
17{{- define "divingbell.secret.perm" }}
18{{- $secretName := index . 0 }}
19{{- $envAll := index . 1 }}
20{{- with $envAll }}
21---
22apiVersion: v1
23kind: Secret
24metadata:
25 name: {{ $secretName }}
26data:
27 perm: {{ tuple "bin/_perm.sh.tpl" . | include "helm-toolkit.utils.template" | b64enc }}
28{{- end }}
29{{- end }}
diff --git a/divingbell/values.yaml b/divingbell/values.yaml
index eab75d4..d8351f5 100644
--- a/divingbell/values.yaml
+++ b/divingbell/values.yaml
@@ -31,6 +31,47 @@ conf:
31 - telnetd-ssl 31 - telnetd-ssl
32 - nis 32 - nis
33 - ntpdate 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## data.values.conf.sysctl 76## data.values.conf.sysctl
36# sysctl: 77# sysctl:
@@ -76,6 +117,10 @@ pod:
76 enabled: true 117 enabled: true
77 min_ready_seconds: 0 118 min_ready_seconds: 0
78 max_unavailable: 100% 119 max_unavailable: 100%
120 perm:
121 enabled: true
122 min_ready_seconds: 0
123 max_unavailable: 100%
79 resources: 124 resources:
80 enabled: false 125 enabled: false
81 ethtool: 126 ethtool:
@@ -113,6 +158,13 @@ pod:
113 requests: 158 requests:
114 memory: "128Mi" 159 memory: "128Mi"
115 cpu: "100m" 160 cpu: "100m"
161 perm:
162 limits:
163 memory: "128Mi"
164 cpu: "100m"
165 requests:
166 memory: "128Mi"
167 cpu: "100m"
116 apt: 168 apt:
117 limits: 169 limits:
118 memory: "128Mi" 170 memory: "128Mi"
@@ -128,3 +180,4 @@ manifests:
128 daemonset_sysctl: true 180 daemonset_sysctl: true
129 daemonset_limits: true 181 daemonset_limits: true
130 daemonset_apt: true 182 daemonset_apt: true
183 daemonset_perm: true
diff --git a/tools/gate/scripts/020-test-divingbell.sh b/tools/gate/scripts/020-test-divingbell.sh
index b4cf74d..d766108 100755
--- a/tools/gate/scripts/020-test-divingbell.sh
+++ b/tools/gate/scripts/020-test-divingbell.sh
@@ -353,6 +353,88 @@ test_limits(){
353 echo "[SUCCESS] test range loop for limits passed successfully" >> "${TEST_RESULTS}" 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
403test_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_test_if_mounted_positive(){ 438_test_if_mounted_positive(){
357 mountpoint "${1}" || (echo "Expect ${1} to be mounted, but was not"; exit 1) 439 mountpoint "${1}" || (echo "Expect ${1} to be mounted, but was not"; exit 1)
358 df -h | grep "${1}" | grep "${2}" || 440 df -h | grep "${1}" | grep "${2}" ||
@@ -971,9 +1053,9 @@ test_overrides(){
971 1053
972 # Compare against expected number of generated daemonsets 1054 # Compare against expected number of generated daemonsets
973 daemonset_count="$(echo "${tc_output}" | grep 'kind: DaemonSet' | wc -l)" 1055 daemonset_count="$(echo "${tc_output}" | grep 'kind: DaemonSet' | wc -l)"
974 if [ "${daemonset_count}" != "14" ]; then 1056 if [ "${daemonset_count}" != "15" ]; then
975 echo '[FAILURE] overrides test 1 failed' >> "${TEST_RESULTS}" 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 exit 1 1059 exit 1
978 else 1060 else
979 echo '[SUCCESS] overrides test 1 passed successfully' >> "${TEST_RESULTS}" 1061 echo '[SUCCESS] overrides test 1 passed successfully' >> "${TEST_RESULTS}"
@@ -1153,6 +1235,7 @@ if [[ -z $SKIP_BASE_TESTS ]]; then
1153 install_base 1235 install_base
1154 test_sysctl 1236 test_sysctl
1155 test_limits 1237 test_limits
1238 test_perm
1156 test_mounts 1239 test_mounts
1157 test_ethtool 1240 test_ethtool
1158 test_uamlite 1241 test_uamlite