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
This commit is contained in:
parent
97bcc9760f
commit
0731ac5d3a
|
@ -0,0 +1,135 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cat <<'EOF' > {{ .Values.conf.chroot_mnt_path | quote }}/tmp/perm_host.sh
|
||||||
|
{{ include "divingbell.shcommon" . }}
|
||||||
|
|
||||||
|
backup_path='/var/divingbell/perm'
|
||||||
|
|
||||||
|
[ ! -d "${backup_path}" ] && mkdir -p "${backup_path}"
|
||||||
|
|
||||||
|
write_test "${backup_path}"
|
||||||
|
|
||||||
|
add_perm(){
|
||||||
|
# accepts $path, $owner, $group, $permissions
|
||||||
|
local path="${1}"
|
||||||
|
|
||||||
|
for i in ${path}; do
|
||||||
|
add_single_perm $i ${2} ${3} ${4}
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
add_single_perm(){
|
||||||
|
# accepts $path, $owner, $group, $permissions
|
||||||
|
local path="${1}"
|
||||||
|
local owner="${2}"
|
||||||
|
local group="${3}"
|
||||||
|
local permissions="${4}"
|
||||||
|
|
||||||
|
# check if file exists
|
||||||
|
[ -e $path ] || return 1
|
||||||
|
# if set -e is set the entire script will exit
|
||||||
|
|
||||||
|
# construct backup name
|
||||||
|
local file_name=$(systemd-escape $path)
|
||||||
|
local backup_file="${backup_path}/${file_name}"
|
||||||
|
# check if backup exists
|
||||||
|
if [ ! -e ${backup_file} ]; then
|
||||||
|
# Try reading the current permissions and owner
|
||||||
|
local o_owner="$(stat -c %U ${path})"
|
||||||
|
local o_group="$(stat -c %G ${path})"
|
||||||
|
local o_permissions="$(stat -c %a ${path})"
|
||||||
|
|
||||||
|
# write restore script/data
|
||||||
|
# design decision:
|
||||||
|
# we could write complete script to restore originals
|
||||||
|
# but for security reasons write only data
|
||||||
|
# otherwise we would execute _any_ script from backup dir
|
||||||
|
|
||||||
|
# chmod o_permissions path
|
||||||
|
echo "$o_permissions $path"> ${backup_file}
|
||||||
|
# chown o_owner:o_group path
|
||||||
|
echo "$o_owner:$o_group $path">> ${backup_file}
|
||||||
|
|
||||||
|
log.DEBUG ${backup_file}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# apply permissions
|
||||||
|
chmod ${permissions} ${path}
|
||||||
|
# apply owner and group
|
||||||
|
chown ${owner}:${group} ${path}
|
||||||
|
|
||||||
|
# notice applied perm
|
||||||
|
applied_perm="${applied_perm}${file_name}"$'\n'
|
||||||
|
# ("${file_name}"$'\n')
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{{- range $perm := .Values.conf.perm }}
|
||||||
|
add_perm {{ $perm.path | squote }} {{ $perm.owner | squote }} {{ $perm.group | squote }} {{ $perm.permissions | squote }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
log.INFO "Applied: ${applied_perm}"
|
||||||
|
|
||||||
|
# Revert
|
||||||
|
prev_files="$(find "${backup_path}" -type f)"
|
||||||
|
if [ -n "${prev_files}" ]; then
|
||||||
|
basename -a ${prev_files} | sort > /tmp/prev_perm
|
||||||
|
echo "${applied_perm}" | sort > /tmp/curr_perm
|
||||||
|
log.DEBUG /tmp/prev_perm
|
||||||
|
log.DEBUG /tmp/curr_perm
|
||||||
|
revert_list="$(comm -23 /tmp/prev_perm /tmp/curr_perm)"
|
||||||
|
IFS=$'\n'
|
||||||
|
for o_perm in ${revert_list}; do
|
||||||
|
first=1
|
||||||
|
while IFS=' ' read -r a1 a2; do
|
||||||
|
if [ "$first" -eq 1 ]; then
|
||||||
|
$(chmod $a1 $a2)
|
||||||
|
first=0
|
||||||
|
else
|
||||||
|
$(chown $a1 $a2)
|
||||||
|
fi
|
||||||
|
done < "${backup_path}/${o_perm}"
|
||||||
|
|
||||||
|
rm "${backup_path}/${o_perm}"
|
||||||
|
log.INFO "Reverted permissions and owner: ${backup_path}/${o_perm}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${curr_settings}" ]; then
|
||||||
|
log.INFO 'All permissions successfully applied on this node.'
|
||||||
|
else
|
||||||
|
log.WARN 'No permissions overrides defined for this node.'
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod 755 {{ .Values.conf.chroot_mnt_path | quote }}/tmp/perm_host.sh
|
||||||
|
chroot {{ .Values.conf.chroot_mnt_path | quote }} /tmp/perm_host.sh
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
echo 'INFO Putting the daemon to sleep.'
|
||||||
|
|
||||||
|
while [ 1 ]; do
|
||||||
|
sleep 300
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,71 @@
|
||||||
|
{{/*
|
||||||
|
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{- define "divingbell.daemonset.perm" }}
|
||||||
|
{{- $daemonset := index . 0 }}
|
||||||
|
{{- $secretName := index . 1 }}
|
||||||
|
{{- $envAll := index . 2 }}
|
||||||
|
{{- with $envAll }}
|
||||||
|
---
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
name: {{ $daemonset }}
|
||||||
|
annotations:
|
||||||
|
{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
|
||||||
|
spec:
|
||||||
|
{{ tuple $envAll $daemonset | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
{{ list $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
|
||||||
|
spec:
|
||||||
|
hostNetwork: true
|
||||||
|
hostPID: true
|
||||||
|
hostIPC: true
|
||||||
|
containers:
|
||||||
|
- name: {{ $daemonset }}
|
||||||
|
image: {{ .Values.images.divingbell }}
|
||||||
|
imagePullPolicy: {{ .Values.images.pull_policy }}
|
||||||
|
{{ tuple $envAll $envAll.Values.pod.resources.perm | include "helm-toolkit.snippets.kubernetes_resources" | indent 8 }}
|
||||||
|
command:
|
||||||
|
- /tmp/{{ $daemonset }}.sh
|
||||||
|
volumeMounts:
|
||||||
|
- name: rootfs-{{ $daemonset }}
|
||||||
|
mountPath: {{ .Values.conf.chroot_mnt_path }}
|
||||||
|
- name: {{ $secretName }}
|
||||||
|
mountPath: /tmp/{{ $daemonset }}.sh
|
||||||
|
subPath: {{ $daemonset }}
|
||||||
|
readOnly: true
|
||||||
|
securityContext:
|
||||||
|
privileged: true
|
||||||
|
volumes:
|
||||||
|
- name: rootfs-{{ $daemonset }}
|
||||||
|
hostPath:
|
||||||
|
path: /
|
||||||
|
- name: {{ $secretName }}
|
||||||
|
secret:
|
||||||
|
secretName: {{ $secretName }}
|
||||||
|
defaultMode: 0555
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.manifests.daemonset_perm }}
|
||||||
|
{{- $daemonset := "perm" }}
|
||||||
|
{{- $secretName := "divingbell-perm" }}
|
||||||
|
{{- $daemonset_yaml := list $daemonset $secretName . | include "divingbell.daemonset.perm" | toString | fromYaml }}
|
||||||
|
{{- $secret_include := "divingbell.secret.perm" }}
|
||||||
|
{{- list $daemonset $daemonset_yaml $secret_include $secretName . | include "helm-toolkit.utils.daemonset_overrides" }}
|
||||||
|
{{- end }}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{{/*
|
||||||
|
Copyright 2018 The Openstack-Helm Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{- define "divingbell.secret.perm" }}
|
||||||
|
{{- $secretName := index . 0 }}
|
||||||
|
{{- $envAll := index . 1 }}
|
||||||
|
{{- with $envAll }}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ $secretName }}
|
||||||
|
data:
|
||||||
|
perm: {{ tuple "bin/_perm.sh.tpl" . | include "helm-toolkit.utils.template" | b64enc }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
|
@ -31,6 +31,47 @@ conf:
|
||||||
- telnetd-ssl
|
- telnetd-ssl
|
||||||
- nis
|
- nis
|
||||||
- ntpdate
|
- ntpdate
|
||||||
|
# perm:
|
||||||
|
# -
|
||||||
|
# path: '/boot/System.map-*'
|
||||||
|
# owner: 'root'
|
||||||
|
# group: 'root'
|
||||||
|
# permissions: '0640'
|
||||||
|
# -
|
||||||
|
# path: '/etc/shadow'
|
||||||
|
# owner: 'root'
|
||||||
|
# group: 'shadow'
|
||||||
|
# permissions: '0640'
|
||||||
|
# -
|
||||||
|
# path: '/etc/gshadow'
|
||||||
|
# owner: 'root'
|
||||||
|
# group: 'shadow'
|
||||||
|
# permissions: '0640'
|
||||||
|
# -
|
||||||
|
# path: '/etc/passwd'
|
||||||
|
# owner: 'root'
|
||||||
|
# group: 'root'
|
||||||
|
# permissions: '0644'
|
||||||
|
# -
|
||||||
|
# path: '/etc/group'
|
||||||
|
# owner: 'root'
|
||||||
|
# group: 'root'
|
||||||
|
# permissions: '0644'
|
||||||
|
# -
|
||||||
|
# path: '/var/log/kern.log'
|
||||||
|
# owner: 'syslog'
|
||||||
|
# group: 'adm'
|
||||||
|
# permissions: '0640'
|
||||||
|
# -
|
||||||
|
# path: '/var/log/auth.log'
|
||||||
|
# owner: 'syslog'
|
||||||
|
# group: 'adm'
|
||||||
|
# permissions: '0640'
|
||||||
|
# -
|
||||||
|
# path: '/var/log/syslog'
|
||||||
|
# owner: 'syslog'
|
||||||
|
# group: 'adm'
|
||||||
|
# permissions: '0640'
|
||||||
|
|
||||||
## data.values.conf.sysctl
|
## data.values.conf.sysctl
|
||||||
# sysctl:
|
# sysctl:
|
||||||
|
@ -76,6 +117,10 @@ pod:
|
||||||
enabled: true
|
enabled: true
|
||||||
min_ready_seconds: 0
|
min_ready_seconds: 0
|
||||||
max_unavailable: 100%
|
max_unavailable: 100%
|
||||||
|
perm:
|
||||||
|
enabled: true
|
||||||
|
min_ready_seconds: 0
|
||||||
|
max_unavailable: 100%
|
||||||
resources:
|
resources:
|
||||||
enabled: false
|
enabled: false
|
||||||
ethtool:
|
ethtool:
|
||||||
|
@ -113,6 +158,13 @@ pod:
|
||||||
requests:
|
requests:
|
||||||
memory: "128Mi"
|
memory: "128Mi"
|
||||||
cpu: "100m"
|
cpu: "100m"
|
||||||
|
perm:
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
requests:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "100m"
|
||||||
apt:
|
apt:
|
||||||
limits:
|
limits:
|
||||||
memory: "128Mi"
|
memory: "128Mi"
|
||||||
|
@ -128,3 +180,4 @@ manifests:
|
||||||
daemonset_sysctl: true
|
daemonset_sysctl: true
|
||||||
daemonset_limits: true
|
daemonset_limits: true
|
||||||
daemonset_apt: true
|
daemonset_apt: true
|
||||||
|
daemonset_perm: true
|
||||||
|
|
|
@ -353,6 +353,88 @@ test_limits(){
|
||||||
echo "[SUCCESS] test range loop for limits passed successfully" >> "${TEST_RESULTS}"
|
echo "[SUCCESS] test range loop for limits passed successfully" >> "${TEST_RESULTS}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_test_perm_value(){
|
||||||
|
local file=${1}
|
||||||
|
local owner=${2}
|
||||||
|
local group=${3}
|
||||||
|
local perm=${4}
|
||||||
|
local r_owner="$(stat -c %U ${file})"
|
||||||
|
local r_group="$(stat -c %G ${file})"
|
||||||
|
local r_perm="$(stat -c %a ${file})"
|
||||||
|
[ "${perm}"=="${r_perm}" ] && echo "+" || (echo "File ${file} permissions ${r_perm} but expected ${perm}"; exit 1)
|
||||||
|
[ "${owner}"=="${r_owner}" ] && echo "+" || (echo "File ${file} owner ${r_owner} but expected ${owner}"; exit 1)
|
||||||
|
[ "${group}"=="${r_group}" ] && echo "+" || (echo "File ${file} group ${r_group} but expected ${group}"; exit 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
_perm_init_one(){
|
||||||
|
local file=${1}
|
||||||
|
local user=${file##*.}
|
||||||
|
useradd ${user} -U
|
||||||
|
chmod 777 ${file}
|
||||||
|
chown ${user}:${user} ${file}
|
||||||
|
echo ${file}
|
||||||
|
}
|
||||||
|
|
||||||
|
_make_p_temp(){
|
||||||
|
echo $(mktemp "${TMPDIR:-/tmp}/${0##*/}.XXXXXX")
|
||||||
|
}
|
||||||
|
|
||||||
|
_perm_init(){
|
||||||
|
# global vars!
|
||||||
|
p_test_file1=$(_perm_init_one $(_make_p_temp))
|
||||||
|
p_test_file2=$(_perm_init_one $(_make_p_temp))
|
||||||
|
}
|
||||||
|
|
||||||
|
_perm_teardown_one(){
|
||||||
|
local file=${1}
|
||||||
|
local user=${file##*.}
|
||||||
|
deluser ${user} -q
|
||||||
|
rm -f ${file}
|
||||||
|
}
|
||||||
|
|
||||||
|
_perm_teardown(){
|
||||||
|
# global vars!
|
||||||
|
_perm_teardown_one ${p_test_file1}
|
||||||
|
unset p_test_file1
|
||||||
|
_perm_teardown_one ${p_test_file2}
|
||||||
|
unset p_test_file2
|
||||||
|
}
|
||||||
|
|
||||||
|
test_perm(){
|
||||||
|
_perm_init
|
||||||
|
local overrides_yaml=${LOGS_SUBDIR}/${FUNCNAME}.yaml
|
||||||
|
echo "conf:
|
||||||
|
perm:
|
||||||
|
-
|
||||||
|
path: ${p_test_file1}
|
||||||
|
owner: 'root'
|
||||||
|
group: 'shadow'
|
||||||
|
permissions: '0640'
|
||||||
|
-
|
||||||
|
path: ${p_test_file2}
|
||||||
|
owner: 'root'
|
||||||
|
group: 'shadow'
|
||||||
|
permissions: '0640'" > "${overrides_yaml}"
|
||||||
|
install_base "--values=${overrides_yaml}"
|
||||||
|
get_container_status perm
|
||||||
|
_test_perm_value ${p_test_file1} root shadow 640
|
||||||
|
_test_perm_value ${p_test_file2} root shadow 640
|
||||||
|
echo "[SUCCESS] Positive test for perm passed successfully" >> "${TEST_RESULTS}"
|
||||||
|
echo "conf:
|
||||||
|
perm:
|
||||||
|
-
|
||||||
|
path: ${p_test_file1}
|
||||||
|
owner: 'root'
|
||||||
|
group: 'shadow'
|
||||||
|
permissions: '0640'" > "${overrides_yaml}"
|
||||||
|
install_base "--values=${overrides_yaml}"
|
||||||
|
get_container_status perm
|
||||||
|
_test_perm_value ${p_test_file1} root shadow 640
|
||||||
|
_test_perm_value ${p_test_file2} ${p_test_file2##*.} ${p_test_file2##*.} 777
|
||||||
|
echo "[SUCCESS] Backup test for perm passed successfully" >> "${TEST_RESULTS}"
|
||||||
|
_perm_teardown
|
||||||
|
}
|
||||||
|
|
||||||
_test_if_mounted_positive(){
|
_test_if_mounted_positive(){
|
||||||
mountpoint "${1}" || (echo "Expect ${1} to be mounted, but was not"; exit 1)
|
mountpoint "${1}" || (echo "Expect ${1} to be mounted, but was not"; exit 1)
|
||||||
df -h | grep "${1}" | grep "${2}" ||
|
df -h | grep "${1}" | grep "${2}" ||
|
||||||
|
@ -971,9 +1053,9 @@ test_overrides(){
|
||||||
|
|
||||||
# Compare against expected number of generated daemonsets
|
# Compare against expected number of generated daemonsets
|
||||||
daemonset_count="$(echo "${tc_output}" | grep 'kind: DaemonSet' | wc -l)"
|
daemonset_count="$(echo "${tc_output}" | grep 'kind: DaemonSet' | wc -l)"
|
||||||
if [ "${daemonset_count}" != "14" ]; then
|
if [ "${daemonset_count}" != "15" ]; then
|
||||||
echo '[FAILURE] overrides test 1 failed' >> "${TEST_RESULTS}"
|
echo '[FAILURE] overrides test 1 failed' >> "${TEST_RESULTS}"
|
||||||
echo "Expected 14 daemonsets; got '${daemonset_count}'" >> "${TEST_RESULTS}"
|
echo "Expected 15 daemonsets; got '${daemonset_count}'" >> "${TEST_RESULTS}"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo '[SUCCESS] overrides test 1 passed successfully' >> "${TEST_RESULTS}"
|
echo '[SUCCESS] overrides test 1 passed successfully' >> "${TEST_RESULTS}"
|
||||||
|
@ -1153,6 +1235,7 @@ if [[ -z $SKIP_BASE_TESTS ]]; then
|
||||||
install_base
|
install_base
|
||||||
test_sysctl
|
test_sysctl
|
||||||
test_limits
|
test_limits
|
||||||
|
test_perm
|
||||||
test_mounts
|
test_mounts
|
||||||
test_ethtool
|
test_ethtool
|
||||||
test_uamlite
|
test_uamlite
|
||||||
|
|
Loading…
Reference in New Issue