mirror of https://github.com/sipwise/ngcpcfg.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
4.2 KiB
170 lines
4.2 KiB
#!/bin/bash
|
|
# Purpose: set config value
|
|
################################################################################
|
|
|
|
set -e
|
|
set -u
|
|
|
|
# support testsuite
|
|
FUNCTIONS="${FUNCTIONS:-/usr/share/ngcp-ngcpcfg/functions/}"
|
|
HELPER="${HELPER:-/usr/share/ngcp-ngcpcfg/helper/}"
|
|
SCRIPTS="${SCRIPTS:-/usr/share/ngcp-ngcpcfg/scripts/}"
|
|
|
|
if ! [ -r "${FUNCTIONS}"/main ] ; then
|
|
printf "Error: %s/main could not be read. Exiting.\n" "${FUNCTIONS}">&2
|
|
exit 1
|
|
fi
|
|
|
|
# shellcheck disable=SC1090
|
|
. "${FUNCTIONS}"/main
|
|
|
|
## functions {{{
|
|
help() {
|
|
echo "Usage: ngcpcfg set [<options>] <file> <key>"
|
|
echo "Example: ngcpcfg set /etc/ngcp-config/config.yml general.maintenance=yes"
|
|
echo "Options:"
|
|
echo " --diff: show difference(s) for the applied changes"
|
|
}
|
|
|
|
## }}}
|
|
|
|
RC=0
|
|
b_show_diff=false
|
|
|
|
while [ -n "${1:-}" ]; do
|
|
case "$1" in
|
|
--diff)
|
|
b_show_diff=true
|
|
shift
|
|
;;
|
|
--*)
|
|
log_error "unsupported option '$1'. Exiting."
|
|
help >&2
|
|
exit 1
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ "${#:-}" != "2" ]; then
|
|
help >&2
|
|
exit 1
|
|
fi
|
|
|
|
file="$1"
|
|
data="$2"
|
|
|
|
[ -f "${file}" ] || (log_error "missing ${file}. Exiting." ; exit 1)
|
|
[ -z "${data}" ] && (log_error "missing data to set. Exiting." ; exit 1)
|
|
|
|
# Check whether we should use different permissions when creating the file.
|
|
CREATEFILE=no
|
|
if [ ! -f "${file}" ]; then
|
|
CREATEFILE=yes
|
|
if [ "${file}" = "${NETWORK_CONFIG:-}" ]; then
|
|
MODE="${NETWORK_CONFIG_CHMOD}"
|
|
USER="${NETWORK_CONFIG_USER}"
|
|
GROUP="${NETWORK_CONFIG_GROUP}"
|
|
else
|
|
MODE="${CONFIG_CHMOD}"
|
|
USER="${CONFIG_USER}"
|
|
GROUP="${CONFIG_GROUP}"
|
|
fi
|
|
fi
|
|
|
|
log_debug "Received data: ${data}"
|
|
option="${data%%=*}"
|
|
value="${data#*=}"
|
|
log_debug "Parsed option: ${option}"
|
|
log_debug "Parsed value: ${value}"
|
|
|
|
[ -z "${option}" ] && ( log_error "missing option to set. Exiting." ; exit 1)
|
|
[ -z "${value}" ] && ( log_error "missing value to set. Exiting." ; exit 1)
|
|
log_debug "Saving option '${option}' value '${value}' into '${file}'"
|
|
|
|
if [[ ${value} =~ ^\'.*\'$ ]] ; then
|
|
log_debug "\$value is already quoted."
|
|
elif [[ ${value} =~ ^[0-9]*$ ]] ; then
|
|
log_debug "Not quoting \$value for integers."
|
|
elif [[ ${value} =~ ^\[.*\]$ ]] ; then
|
|
log_debug "Not quoting \$value for arrays."
|
|
elif [[ ${value} =~ ^\{.*\}$ ]] ; then
|
|
log_debug "Not quoting \$value for hashes."
|
|
else
|
|
log_debug "Quoting \$value to prevent further Perl errors."
|
|
value="\"${value}\""
|
|
fi
|
|
|
|
tmp=$(mktemp -t ngcpcfg-set.XXXXXXXXXX)
|
|
log_debug "Temporary perl file: ${tmp}"
|
|
|
|
cat > "${tmp}" << EOF
|
|
use strict;
|
|
use warnings;
|
|
use YAML::XS;
|
|
my \$file="${file}";
|
|
my \$yaml = YAML::XS::LoadFile("\$file");
|
|
my \$valref = \\\$yaml;
|
|
|
|
for my \$component (split(/\\./, "${option}")) {
|
|
if (ref(\$valref) eq 'SCALAR' && defined(\$\$valref)) {
|
|
print STDERR ("Key resolved to a SCALAR at '\$component'; cannot continue.\n");
|
|
exit(1);
|
|
}
|
|
elsif (\$component =~ /^\\d+\$/ && (!defined(\$\$valref) || ref(\$\$valref) eq 'ARRAY')) {
|
|
\$valref = \\\$\$valref->[\$component];
|
|
}
|
|
elsif (\$component eq 'APPEND' && ref(\$\$valref) eq 'ARRAY') {
|
|
\$valref = \\\$\$valref->[\$#{\$\$valref}+1];
|
|
}
|
|
elsif (!defined(\$\$valref) || ref(\$\$valref) eq 'HASH') {
|
|
\$valref = \\\$\$valref->{\$component};
|
|
}
|
|
else {
|
|
print STDERR ("Key resolved to a " . ref(\$\$valref) . " reference; refusing to overwrite.\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
if (!defined(\$\$valref) || ref(\$valref) eq 'SCALAR') {
|
|
\$\$valref = ${value};
|
|
}
|
|
elsif (ref(\$\$valref) eq 'ARRAY' && ref(${value}) eq 'ARRAY') {
|
|
\$\$valref = ${value};
|
|
}
|
|
elsif (ref(\$\$valref) eq 'HASH' && ref(${value}) eq 'HASH') {
|
|
\$\$valref = ${value};
|
|
}
|
|
else {
|
|
print STDERR ("Key resolved to a " . ref(\$\$valref) . " reference; refusing to overwrite.\n");
|
|
exit(1);
|
|
}
|
|
|
|
YAML::XS::DumpFile(\$file, \$yaml);
|
|
EOF
|
|
|
|
log_debug "perl -wCSD \"${tmp}\" || RC=$?"
|
|
perl -wCSD "${tmp}" || RC=$?
|
|
|
|
if [ "${CREATEFILE}" = "yes" ]; then
|
|
chmod "${MODE}" "${file}"
|
|
chown "${USER}" "${file}"
|
|
chgrp "${GROUP}" "${file}"
|
|
fi
|
|
|
|
if [ "${RC}" = "0" ] && "${b_show_diff:-false}"; then
|
|
log_debug "${SCRIPTS}/diff || true"
|
|
"${SCRIPTS}"/diff || true
|
|
fi
|
|
|
|
if [ -n "${DEBUG:-}" ] ; then
|
|
log_debug "Not removing temporary file ${tmp}"
|
|
else
|
|
rm -f "${tmp}"
|
|
fi
|
|
|
|
exit ${RC}
|
|
|
|
## END OF FILE #################################################################
|