diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..4444152 --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1,23 @@ +# Check shellcheck wiki at: +# https://github.com/koalaman/shellcheck/wiki/SCXXXX + +# Redirections are performed by the current shell before sudo is started. +disable=SC2024 + +# foo appears unused. Verify it or export it. +disable=SC2034 + +# Double quote array expansions to avoid re-splitting elements. +disable=SC2068 + +# Argument mixes string and array. +disable=SC2145 + +# Declare and assign separately to avoid masking return values. +disable=SC2155 + +# This redirection doesn't have a command. +disable=SC2188 + +# This is a file redirection. +disable=SC2210 \ No newline at end of file diff --git a/README.md b/README.md index 355fc86..b8e78ec 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ [![SaltStack][saltstack_badge]][saltstack_release_notes] [![Ubuntu Image][ubuntu_badge]][ubuntu_hub_docker] +[![Docker Build Status][docker_build_badge]][docker_hub] +[![CodeFactor][codefactor_badge]][codefactor_score] # SaltStack Master v3000.3_1 @@ -380,3 +382,9 @@ Where `salt-service` is one of: `salt-master` os `salt-api` (if `SALT_API_SERVIC [ubuntu_badge]: https://img.shields.io/badge/ubuntu-bionic--20200403-E95420.svg?style=flat-square&logo=Ubuntu [ubuntu_hub_docker]: https://hub.docker.com/_/ubuntu/ "Ubuntu Image" + +[docker_build_badge]: https://img.shields.io/docker/build/cdalvaro/saltstack-master?logo=docker&style=flat-square +[docker_hub]: https://hub.docker.com/r/cdalvaro/saltstack-master/builds + +[codefactor_badge]: https://www.codefactor.io/repository/github/cdalvaro/saltstack-master/badge?style=flat-square +[codefactor_score]: https://www.codefactor.io/repository/github/cdalvaro/saltstack-master \ No newline at end of file diff --git a/assets/build/functions.sh b/assets/build/functions.sh index a8a7bf6..300ddea 100755 --- a/assets/build/functions.sh +++ b/assets/build/functions.sh @@ -5,9 +5,9 @@ set -e # Execute a command as SALT_USER function exec_as_salt() { - if [[ $(whoami) == ${SALT_USER} ]]; then + if [[ $(whoami) == "${SALT_USER}" ]]; then $@ else - sudo -HEu ${SALT_USER} "$@" + sudo -HEu "${SALT_USER}" "$@" fi } diff --git a/assets/build/install.sh b/assets/build/install.sh index 78a2cba..94f6951 100755 --- a/assets/build/install.sh +++ b/assets/build/install.sh @@ -2,39 +2,41 @@ set -e -source ${SALT_BUILD_DIR}/functions.sh +source "${SALT_BUILD_DIR}/functions.sh" # Install build dependencies echo "Installing dependencies ..." -BUILD_DEPENDENCIES="cmake gcc g++ make \ - libhttp-parser-dev libssl-dev zlib1g-dev \ - libcurl4-openssl-dev libffi-dev swig" +BUILD_DEPENDENCIES=( + cmake gcc g++ make \ + libhttp-parser-dev libssl-dev zlib1g-dev \ + libcurl4-openssl-dev libffi-dev swig \ +) apt-get update -DEBIAN_FRONTEND=noninteractive apt-get install --yes --quiet --no-install-recommends ${BUILD_DEPENDENCIES} +DEBIAN_FRONTEND=noninteractive apt-get install --yes --quiet --no-install-recommends "${BUILD_DEPENDENCIES[@]}" # Create salt user echo "Creating ${SALT_USER} user ..." -useradd -d ${SALT_HOME} -ms /bin/bash -U -G root,sudo,shadow ${SALT_USER} +useradd -d "${SALT_HOME}" -ms /bin/bash -U -G root,sudo,shadow "${SALT_USER}" # Set PATH -exec_as_salt cat >> ${SALT_HOME}/.profile <> "${SALT_HOME}/.profile" <> /etc/ssh/ssh_config -echo " LogLevel ERROR" >> /etc/ssh/ssh_config -echo "# IdentityFile salt_ssh_key" >> /etc/ssh/ssh_config +{ + echo " UserKnownHostsFile /dev/null" + echo " LogLevel ERROR" + echo "# IdentityFile salt_ssh_key" +} >> /etc/ssh/ssh_config # Configure logrotate echo "Configuring logrotate ..." diff --git a/assets/runtime/functions.sh b/assets/runtime/functions.sh index b7699d0..216ef9a 100755 --- a/assets/runtime/functions.sh +++ b/assets/runtime/functions.sh @@ -1,36 +1,36 @@ #!/usr/bin/env bash set -e -source ${SALT_RUNTIME_DIR}/env-defaults.sh +source "${SALT_RUNTIME_DIR}/env-defaults.sh" # Execute a command as SALT_USER function exec_as_salt() { - if [[ $(whoami) == ${SALT_USER} ]]; then + if [[ $(whoami) == "${SALT_USER}" ]]; then $@ else - sudo -HEu ${SALT_USER} "$@" + sudo -HEu "${SALT_USER}" "$@" fi } # Log error function log_error() { - (>2& echo "ERROR: $@") + (>2& echo "ERROR: $*") } # Map salt user with host user function map_uidgid() { - USERMAP_ORIG_UID=$(id -u ${SALT_USER}) - USERMAP_ORIG_GID=$(id -g ${SALT_USER}) + USERMAP_ORIG_UID=$(id -u "${SALT_USER}") + USERMAP_ORIG_GID=$(id -g "${SALT_USER}") USERMAP_GID=${USERMAP_GID:-${USERMAP_UID:-$USERMAP_ORIG_GID}} USERMAP_UID=${USERMAP_UID:-$USERMAP_ORIG_UID} - if [[ ${USERMAP_UID} != ${USERMAP_ORIG_UID} ]] || [[ ${USERMAP_GID} != ${USERMAP_ORIG_GID} ]]; then + if [[ "${USERMAP_UID}" != "${USERMAP_ORIG_UID}" ]] || [[ "${USERMAP_GID}" != "${USERMAP_ORIG_GID}" ]]; then echo "Mapping UID and GID for ${SALT_USER}:${SALT_USER} to ${USERMAP_UID}:${USERMAP_GID} ..." - groupmod -o -g ${USERMAP_GID} ${SALT_USER} + groupmod -o -g "${USERMAP_GID}" "${SALT_USER}" sed -i -e "s|:${USERMAP_ORIG_UID}:${USERMAP_GID}:|:${USERMAP_UID}:${USERMAP_GID}:|" /etc/passwd - find ${SALT_HOME} -path ${SALT_DATA_DIR}/\* \( ! -uid ${USERMAP_ORIG_UID} -o ! -gid ${USERMAP_ORIG_GID} \) -print0 | xargs -0 chown -h ${SALT_USER}: ${SALT_HOME} + find "${SALT_HOME}" -path "${SALT_DATA_DIR}/*" \( ! -uid "${USERMAP_ORIG_UID}" -o ! -gid "${USERMAP_ORIG_GID}" \) -print0 | xargs -0 chown -h "${SALT_USER}": "${SALT_HOME}" fi } @@ -42,25 +42,25 @@ function update_template() local FILE=${1?missing argument} shift - [[ ! -f ${FILE} ]] && return 1 + [[ ! -f "${FILE}" ]] && return 1 - local VARIABLES=($@) - local USR=$(stat -c %U ${FILE}) + local VARIABLES=( "$@" ) + local USR=$(stat -c %U "${FILE}") local tmp_file=$(mktemp) - cp -a "${FILE}" ${tmp_file} + cp -a "${FILE}" "${tmp_file}" local variables - for variable in ${VARIABLES[@]}; do - sed -ri "s|[{}]{2}$variable[}]{2}|\${$variable}|g" ${tmp_file} + for variable in "${VARIABLES[@]}"; do + sed -ri "s|[{}]{2}${variable}[}]{2}|\${${variable}}|g" "${tmp_file}" done # Replace placeholders ( - export ${VARIABLES[@]} - local IFS=":"; sudo -HEu ${USR} envsubst "${VARIABLES[*]/#/$}" < ${tmp_file} > ${FILE} + export "${VARIABLES[@]}" + local IFS=":"; sudo -HEu "${USR}" envsubst "${VARIABLES[*]/#/$}" < "${tmp_file}" > "${FILE}" ) - rm -f ${tmp_file} + rm -f "${tmp_file}" } # This function configures containers timezone @@ -69,14 +69,14 @@ function configure_timezone() echo "Configuring container timezone ..." # Perform sanity check of provided timezone value - if [ -e /usr/share/zoneinfo/${TIMEZONE} ]; then + if [ -e "/usr/share/zoneinfo/${TIMEZONE}" ]; then echo "Setting TimeZone -> ${TIMEZONE} ..." # Set localtime - ln -snf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime + ln -snf "/usr/share/zoneinfo/${TIMEZONE}" /etc/localtime # Set timezone - echo ${TIMEZONE} > /etc/timezone + echo "${TIMEZONE}" > /etc/timezone else echo "Timezone: '${TIMEZONE}' is not valid. Check available timezones at: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones" return 1 @@ -88,39 +88,40 @@ function gen_signed_keys() { local key_name=${1:-master} - mkdir -p ${SALT_KEYS_DIR}/generated/ - GENERATED_KEYS_DIR=$(mktemp -d -p ${SALT_KEYS_DIR}/generated/ -t ${key_name}.XXXXX) + mkdir -p "${SALT_KEYS_DIR}/generated/" + GENERATED_KEYS_DIR=$(mktemp -d -p "${SALT_KEYS_DIR}/generated/" -t "${key_name}.XXXXX") - salt-key --gen-keys ${key_name} --gen-keys-dir ${GENERATED_KEYS_DIR} > /dev/null 2>&1 - salt-key --gen-signature --auto-create --pub ${GENERATED_KEYS_DIR}/${key_name}.pub --signature-path ${GENERATED_KEYS_DIR} > /dev/null 2>&1 + salt-key --gen-keys "${key_name}" --gen-keys-dir "${GENERATED_KEYS_DIR}" > /dev/null 2>&1 + salt-key --gen-signature --auto-create --pub "${GENERATED_KEYS_DIR}/${key_name}.pub" --signature-path "${GENERATED_KEYS_DIR}" > /dev/null 2>&1 - echo -n ${GENERATED_KEYS_DIR} + echo -n "${GENERATED_KEYS_DIR}" } # This function repairs keys permissions and creates keys if neaded function setup_salt_keys() { echo "Setting up salt keys ..." - if [ ! -f ${SALT_KEYS_DIR}/master.pem ]; then + if [ ! -f "${SALT_KEYS_DIR}/master.pem" ]; then echo "Generating keys ..." - salt-key --gen-keys master --gen-keys-dir ${SALT_KEYS_DIR} + salt-key --gen-keys master --gen-keys-dir "${SALT_KEYS_DIR}" fi - if [ ! -f "${SALT_KEYS_DIR}/${SALT_MASTER_SIGN_KEY_NAME}.pem" ] && [ ${SALT_MASTER_SIGN_PUBKEY} == True ]; then + if [ ! -f "${SALT_KEYS_DIR}/${SALT_MASTER_SIGN_KEY_NAME}.pem" ] && [ "${SALT_MASTER_SIGN_PUBKEY}" == True ]; then echo "Generating signed keys ..." - salt-key --gen-signature --auto-create --pub ${SALT_KEYS_DIR}/master.pub --signature-path ${SALT_KEYS_DIR} + salt-key --gen-signature --auto-create --pub "${SALT_KEYS_DIR}/master.pub" --signature-path "${SALT_KEYS_DIR}" fi - for pub_key in $(find ${SALT_KEYS_DIR} -maxdepth 1 -type f); do - if [[ ${pub_key} =~ .*\.pem$ ]]; then - chmod 400 ${pub_key} + while IFS= read -r -d '' pub_key + do + if [[ "${pub_key}" =~ .*\.pem$ ]]; then + chmod 400 "${pub_key}" else - chmod 644 ${pub_key} + chmod 644 "${pub_key}" fi - done + done < <(find "${SALT_KEYS_DIR}" -maxdepth 1 -type f -print0) - find ${SALT_KEYS_DIR}/minions* -maxdepth 1 -type f -exec chmod 644 {} \; - find ${SALT_HOME} -path ${SALT_KEYS_DIR}/\* -prune -o -print0 | xargs -0 chown -h ${SALT_USER}: + find "${SALT_KEYS_DIR}/minions"* -maxdepth 1 -type f -exec chmod 644 {} \; + find "${SALT_HOME}" -path "${SALT_KEYS_DIR}/*" -prune -o -print0 | xargs -0 chown -h "${SALT_USER}": } # This function configures ssh keys @@ -147,10 +148,10 @@ function configure_salt_master() echo "Configuring salt-master service ..." # https://docs.saltstack.com/en/latest/ref/configuration/master.html - exec_as_salt cp -p ${SALT_RUNTIME_DIR}/config/master.yml ${SALT_ROOT_DIR}/master + exec_as_salt cp -p "${SALT_RUNTIME_DIR}/config/master.yml" "${SALT_ROOT_DIR}/master" # Update main configuration - update_template ${SALT_ROOT_DIR}/master \ + update_template "${SALT_ROOT_DIR}/master" \ SALT_USER \ SALT_LOG_LEVEL \ SALT_LEVEL_LOGFILE \ @@ -161,7 +162,7 @@ function configure_salt_master() SALT_KEYS_DIR # Update keys configuration - update_template ${SALT_ROOT_DIR}/master \ + update_template "${SALT_ROOT_DIR}/master" \ SALT_MASTER_SIGN_PUBKEY \ SALT_MASTER_SIGN_KEY_NAME \ SALT_MASTER_PUBKEY_SIGNATURE \ @@ -175,18 +176,18 @@ function configure_salt_api() if [[ -n "${SALT_API_USER}" ]]; then - if [[ ${SALT_API_USER} == ${SALT_USER} ]]; then - log_error "SALT_API_USER cannot be the same as ${SALT_USER}" + if [[ ${SALT_API_USER} == "${SALT_USER}" ]]; then + log_error "SALT_API_USER cannot be the same as '${SALT_USER}'" return 1 fi if [[ -z "${SALT_API_USER_PASS}" ]]; then - log_error "SALT_API_USER_PASS env variable must be set to create ${SALT_API_USER} user" + log_error "SALT_API_USER_PASS env variable must be set to create '${SALT_API_USER}' user" return 2 fi - echo "Creating ${SALT_API_USER} user for salt-api ..." - adduser --quiet --disabled-password --gecos "Salt API" ${SALT_API_USER} + echo "Creating '${SALT_API_USER}' user for salt-api ..." + adduser --quiet --disabled-password --gecos "Salt API" "${SALT_API_USER}" echo "${SALT_API_USER}:${SALT_API_USER_PASS}" | chpasswd unset SALT_API_USER_PASS fi @@ -194,10 +195,10 @@ function configure_salt_api() echo "Configuring salt-api service ..." CERTS_PATH=/etc/pki - rm -rf ${CERTS_PATH}/tls/certs/* - salt-call --local tls.create_self_signed_cert cacert_path=${CERTS_PATH} CN=docker-salt-master + rm -rf "${CERTS_PATH}/tls/certs/*" + salt-call --local tls.create_self_signed_cert cacert_path="${CERTS_PATH}" CN=docker-salt-master - cat >> ${SALT_ROOT_DIR}/master <> "${SALT_ROOT_DIR}/master" <