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
135
divingbell/templates/bin/_perm.sh.tpl
Normal file
135
divingbell/templates/bin/_perm.sh.tpl
Normal file
@ -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
|
71
divingbell/templates/daemonset-perm.yaml
Normal file
71
divingbell/templates/daemonset-perm.yaml
Normal file
@ -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 }}
|
29
divingbell/templates/secret-perm.yaml
Normal file
29
divingbell/templates/secret-perm.yaml
Normal file
@ -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
|
||||
- nis
|
||||
- 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
|
||||
# sysctl:
|
||||
@ -76,6 +117,10 @@ pod:
|
||||
enabled: true
|
||||
min_ready_seconds: 0
|
||||
max_unavailable: 100%
|
||||
perm:
|
||||
enabled: true
|
||||
min_ready_seconds: 0
|
||||
max_unavailable: 100%
|
||||
resources:
|
||||
enabled: false
|
||||
ethtool:
|
||||
@ -113,6 +158,13 @@ pod:
|
||||
requests:
|
||||
memory: "128Mi"
|
||||
cpu: "100m"
|
||||
perm:
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "100m"
|
||||
requests:
|
||||
memory: "128Mi"
|
||||
cpu: "100m"
|
||||
apt:
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
@ -128,3 +180,4 @@ manifests:
|
||||
daemonset_sysctl: true
|
||||
daemonset_limits: true
|
||||
daemonset_apt: true
|
||||
daemonset_perm: true
|
||||
|
@ -353,6 +353,88 @@ test_limits(){
|
||||
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(){
|
||||
mountpoint "${1}" || (echo "Expect ${1} to be mounted, but was not"; exit 1)
|
||||
df -h | grep "${1}" | grep "${2}" ||
|
||||
@ -971,9 +1053,9 @@ test_overrides(){
|
||||
|
||||
# Compare against expected number of generated daemonsets
|
||||
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 "Expected 14 daemonsets; got '${daemonset_count}'" >> "${TEST_RESULTS}"
|
||||
echo "Expected 15 daemonsets; got '${daemonset_count}'" >> "${TEST_RESULTS}"
|
||||
exit 1
|
||||
else
|
||||
echo '[SUCCESS] overrides test 1 passed successfully' >> "${TEST_RESULTS}"
|
||||
@ -1153,6 +1235,7 @@ if [[ -z $SKIP_BASE_TESTS ]]; then
|
||||
install_base
|
||||
test_sysctl
|
||||
test_limits
|
||||
test_perm
|
||||
test_mounts
|
||||
test_ethtool
|
||||
test_uamlite
|
||||
|
Loading…
x
Reference in New Issue
Block a user