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.
306 lines
8.6 KiB
306 lines
8.6 KiB
#!/bin/bash
|
|
# Purpose: check/validate YAML config files (syntax, encoding, ...)
|
|
################################################################################
|
|
|
|
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/}"
|
|
SCHEMAS="${SCHEMAS:-/usr/share/ngcp-ngcpcfg/schemas/}"
|
|
|
|
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
|
|
|
|
usage() {
|
|
printf "ngcpcfg build -- supported command line options:
|
|
|
|
--ignore-branch-check - do not fail build if branch doesn't match 'master'
|
|
--ignore-shared-storage-check - skip check of shared storage\n\n"
|
|
}
|
|
|
|
CHECK_BRANCH=true
|
|
CHECK_SHARED_STORAGE=true
|
|
while [ -n "${1:-}" ] ; do
|
|
case "$1" in
|
|
*--ignore-branch-check*) CHECK_BRANCH=false ; shift ;;
|
|
*--ignore-shared-storage-check*) CHECK_SHARED_STORAGE=false ; shift ;;
|
|
*--help*) usage ; exit 0 ;;
|
|
*) break ;;
|
|
esac
|
|
done
|
|
|
|
check_branch() {
|
|
if ! $CHECK_BRANCH ; then
|
|
log_info "Option --ignore-branch-check is enabled, not checking for branch 'master'."
|
|
return 0
|
|
fi
|
|
|
|
local current_branch
|
|
current_branch=$(compare_active_branch 'master')
|
|
if [ "$current_branch" = 'master' ] ; then
|
|
log_debug "Current branch is 'master', continuing."
|
|
else
|
|
log_error "branch '$current_branch' in '$NGCPCTL_MAIN' active - please switch to branch 'master' before continuing."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_origin() {
|
|
if ! type -p execute_check_shared_storage &>/dev/null ; then
|
|
log_debug "Skipping check_origin, does not look like PRO/CARRIER system."
|
|
return 0
|
|
fi
|
|
|
|
if [ "${NO_CHECK_ORIGIN:-}" = "1" ] ; then
|
|
log_debug "Skipping check_origin (NO_CHECK_ORIGIN=1)."
|
|
return 0
|
|
fi
|
|
|
|
log_debug "check_origin"
|
|
|
|
log_debug "cd ${NGCPCTL_MAIN}"
|
|
cd "${NGCPCTL_MAIN}"
|
|
|
|
local mgmtnode
|
|
mgmtnode="${MGMTNODE:-$(cat /etc/ngcp_mgmt_node)}"
|
|
local expected_origin="${mgmtnode}:/mnt/glusterfs/ngcpcfg-share"
|
|
if [ -n "${NGCPCTL_SHARE:-}" ] ; then
|
|
expected_origin="${mgmtnode}:${NGCPCTL_SHARE}"
|
|
log_debug "NGCPCTL_SHARE is set, using it for expected_origin ['${expected_origin}']"
|
|
else
|
|
log_debug "NGCPCTL_SHARE is unset, using default ['${expected_origin}'] setting for expected_origin"
|
|
fi
|
|
|
|
local actual_origin
|
|
actual_origin="$(git remote get-url origin)"
|
|
if [ "${actual_origin}" = "${expected_origin}" ] ; then
|
|
log_debug "Current remote origin looks as expected [${expected_origin}]."
|
|
else
|
|
log_error "Remote origin of ngcpcfg is '$actual_origin', expected: '${expected_origin}'."
|
|
log_error "NOTE: execute \`cd $NGCPCTL_MAIN ; git remote set-url origin '${expected_origin}'\` to adjust setting."
|
|
log_error "NOTE: perform \`ngcpcfg clean --all\` to recreate local master branch from remote."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_yaml() {
|
|
local schema="$1"
|
|
local config="$2"
|
|
|
|
if ! pkwalify -s -m 'YAML::XS' -f "${schema}" "${config}" >/dev/null 2>&1 ; then
|
|
log_error "Invalid schema detected for ${config}"
|
|
pkwalify -m 'YAML::XS' -f "${schema}" "${config}" >&2 || true
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
check_multi_site() {
|
|
log_debug "Checking multi-site support"
|
|
if ! command -v ngcp-site >/dev/null; then
|
|
log_debug "Skipping check due to missing ngcp-site"
|
|
return 0
|
|
fi
|
|
|
|
if ! error=$( { ngcp-site >/dev/null; } 2>&1 ); then
|
|
log_error "Configuration problem with multi-site setup."
|
|
log_error "${error}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_config_encoding() {
|
|
log_debug "Checking encoding for $config_files"
|
|
for f in $config_files ; do
|
|
if [ -r "$f" ] && ! file -L "$f" | grep -qe "UTF-8" -qe "ASCII" ; then
|
|
log_error "Encoding check of ${f} fails: neither ASCII nor UTF-8."
|
|
log_error "Please convert ${f} to UTF-8."
|
|
log_info
|
|
log_info "NOTE:"
|
|
log_info "* Check encoding via:"
|
|
log_info " # file ${f}"
|
|
log_info "* To convert ISO-8859/latin1 to UTF-8 execute:"
|
|
log_info " # iconv -f latin1 -t utf8 < ${f} > ${f}.tmp && mv ${f}.tmp ${f}"
|
|
exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
check_config_syntax() {
|
|
log_debug "Checking for valid YAML syntax for $config_files"
|
|
for f in $config_files ; do
|
|
if [ -r "$f" ] ; then
|
|
# use YAML::XS for checking
|
|
log_debug "Validating main YAML syntax of ${f}"
|
|
if ! "${HELPER}/validate-yml" "${f}" 2>/dev/null ; then
|
|
log_error "Invalid file syntax in ${f}:"
|
|
"${HELPER}/validate-yml" "${f}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
check_configs() {
|
|
check_config_encoding
|
|
check_config_syntax
|
|
}
|
|
|
|
validate_config() {
|
|
local rc=0
|
|
log_debug "Validating schema for main YAML files"
|
|
|
|
for f in $config_files ; do
|
|
local name
|
|
name="$(basename "${f}")"
|
|
|
|
if [ "$name" = 'network.yml' ]; then
|
|
if ! ngcp-network-validator --network-file="$f"; then
|
|
log_error "Invalid schema detected for ${f}"
|
|
rc=1
|
|
fi
|
|
if ! ngcp-instances-validator --network-file="$f"; then
|
|
log_error "Invalid schema detected for instances connections"
|
|
rc=1
|
|
fi
|
|
else
|
|
local schema
|
|
|
|
case "${name}" in
|
|
sites.yml|instances.yml)
|
|
if ! [ -e "${f}" ]; then
|
|
continue
|
|
fi
|
|
|
|
schema="${SCHEMAS}/${name}"
|
|
;;
|
|
*)
|
|
schema="/usr/share/ngcp-cfg-schema/validate/${name}"
|
|
;;
|
|
esac
|
|
|
|
if ! [ -f "${schema}" ] ; then
|
|
continue
|
|
fi
|
|
|
|
local config_type
|
|
config_type=$(basename "${name}" .yml)
|
|
|
|
local c
|
|
local c_cleanup=false
|
|
case "${config_type}" in
|
|
config|constants)
|
|
c_cleanup=true
|
|
c="$(mktemp -t "ngcpcfg-check-${config_type}.XXXXXXXXXX.yml")"
|
|
"${SCRIPTS}/cat" "${config_type}" >"$c"
|
|
;;
|
|
*)
|
|
c="$f"
|
|
;;
|
|
esac
|
|
|
|
if ! check_yaml "${schema}" "$c"; then
|
|
rc=1
|
|
fi
|
|
if ${c_cleanup}; then
|
|
rm -f "$c"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [ "$rc" = "0" ] ; then
|
|
log_info "yml configs were validated successfully"
|
|
else
|
|
if [ -n "${NO_VALIDATE:-}" ] ; then
|
|
log_info "DANGEROUS ZONE: invalid configs detected, continue anyway due to option '--no-validate'"
|
|
else
|
|
log_error "Aborted, please fix issue(s) above and repeat."
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
check_configs_conflicts() {
|
|
log_debug "Checking merge conflicts in ngcp configs:"
|
|
if grep -rP --exclude-dir='.git' --exclude='*.dpkg-*' \
|
|
'^>>>>>>> [0-9a-fA-F]+' /etc/ngcp-config/ >/dev/null 2>&1
|
|
then
|
|
log_error "ERROR: ngcp configs with Git merge conflicts found:"
|
|
grep -rP --exclude-dir='.git' --exclude='*.dpkg-*' \
|
|
'^>>>>>>> [0-9a-fA-F]+' /etc/ngcp-config/ >&2
|
|
exit 1
|
|
else
|
|
log_debug "No ngcp configs with merge conflicts found."
|
|
fi
|
|
}
|
|
|
|
check_shared_storage() {
|
|
if ! ${CHECK_SHARED_STORAGE} ; then
|
|
log_info "Option --ignore-shared-storage-check is enabled, skipping."
|
|
return 0
|
|
fi
|
|
|
|
# ensure there are no outstanding pull actions,
|
|
# unless --no-action-failure is used (ignore then)
|
|
if ! type -p execute_check_shared_storage &>/dev/null ; then
|
|
log_debug "execute_check_shared_storage not available"
|
|
return 0
|
|
fi
|
|
|
|
log_debug "execute_check_shared_storage function, action pull"
|
|
if [ "${NO_ACTION_FAILURE:-}" = "1" ] ; then
|
|
if execute_check_shared_storage pull ; then
|
|
log_debug "No outstanding pull actions identified (NO_ACTION_FAILURE=1)."
|
|
else
|
|
log_info "Ignoring outstanding pull actions as --no-action-failure option is enabled."
|
|
fi
|
|
|
|
return 0
|
|
fi
|
|
|
|
execute_check_shared_storage pull && RC=0 || RC=$?
|
|
if [ "$RC" = "0" ] ; then
|
|
log_debug "No outstanding pull actions identified (NO_ACTION_FAILURE unset)."
|
|
else
|
|
log_info "Outstanding pull actions have been identified (see ACTION_NEEDED), exiting."
|
|
log_info "TIP: '--no-action-failure' forces execution within 'apply' anyway (use with care!)."
|
|
return "$RC"
|
|
fi
|
|
}
|
|
|
|
if [ "$*" = "" ] ; then
|
|
SITES_FILE="${SITES_FILE:-${NGCPCTL_MAIN}/sites.yml}"
|
|
INSTANCES_FILE="${INSTANCES_FILE:-${NGCPCTL_MAIN}/instances.yml}"
|
|
config_files="${NGCPCTL_CONFIG:-} ${NODE_CONFIG:-} ${PAIR_CONFIG:-} ${HOST_CONFIG:-} ${LOCAL_CONFIG:-} ${MAINTENANCE_CONFIG:-} ${NETWORK_CONFIG:-} ${EXTRA_CONFIG_FILES[*]} ${CONSTANTS_CONFIG:-} ${SITES_FILE:-} ${INSTANCES_FILE:-}"
|
|
else
|
|
config_files="$*"
|
|
fi
|
|
|
|
check_branch
|
|
|
|
check_origin
|
|
|
|
check_multi_site
|
|
|
|
check_configs
|
|
if "${VALIDATE_SCHEMA:-false}" || [ "${VALIDATE:-0}" = "1" ] ; then
|
|
validate_config
|
|
fi
|
|
check_configs_conflicts
|
|
|
|
check_shared_storage || exit $?
|
|
|
|
log_info "configs were checked successfully"
|
|
exit 0
|
|
|
|
## END OF FILE #################################################################
|