diff --git a/salt/common/tools/sbin/so-soc-restart b/salt/common/tools/sbin/so-soc-restart index 9d252e2c1..0a678de96 100755 --- a/salt/common/tools/sbin/so-soc-restart +++ b/salt/common/tools/sbin/so-soc-restart @@ -9,4 +9,5 @@ . /usr/sbin/so-common +pkill salt-relay.sh /usr/sbin/so-restart soc $1 diff --git a/salt/common/tools/sbin/so-user b/salt/common/tools/sbin/so-user index 81bfa0d76..0a287aa7c 100755 --- a/salt/common/tools/sbin/so-user +++ b/salt/common/tools/sbin/so-user @@ -11,29 +11,120 @@ source $(dirname $0)/so-common DEFAULT_ROLE=analyst -if [[ $# -lt 1 || $# -gt 3 ]]; then - echo "Usage: $0 [email] [role]" - echo "" - echo " where is one of the following:" - echo "" - echo " list: Lists all user email addresses currently defined in the identity system" - echo " add: Adds a new user to the identity system; requires 'email' parameter, while 'role' parameter is optional and defaults to $DEFAULT_ROLE" - echo " addrole: Grants a role to an existing user; requires 'email' and 'role' parameters" - echo " delrole: Removes a role from an existing user; requires 'email' and 'role' parameters" - echo " update: Updates a user's password and disables MFA; requires 'email' parameter" - echo " enable: Enables a user; requires 'email' parameter" - echo " disable: Disables a user; requires 'email' parameter" - echo " validate: Validates that the given email address and password are acceptable; requires 'email' parameter" - echo " valemail: Validates that the given email address is acceptable; requires 'email' parameter" - echo " valpass: Validates that a password is acceptable" - echo "" - echo " Note that the password can be piped into STDIN to avoid prompting for it" +function usage() { + cat < [supporting parameters]" + + where is one of the following:" + + list: Lists all user email addresses currently defined in the identity system" + + add: Adds a new user to the identity system" + Required parameters: " + --email " + Optional parameters: " + --role (defaults to $DEFAULT_ROLE)" + --firstName (defaults to blank)" + --lastName (defaults to blank)" + --note (defaults to blank)" + --skip-sync (defers the Elastic sync until the next scheduled time) + + addrole: Grants a role to an existing user" + Required parameters: " + --email " + --role " + Optional parameters: " + --skip-sync (defers the Elastic sync until the next scheduled time) + + delrole: Removes a role from an existing user" + Required parameters: " + --email " + --role " + Optional parameters: " + --skip-sync (defers the Elastic sync until the next scheduled time) + + password: Updates a user's password and disables MFA" + Required parameters: " + --email " + Optional parameters: " + --skip-sync (defers the Elastic sync until the next scheduled time) + + profile: Updates a user's profile information" + Required parameters: " + --email " + Optional parameters: " + --role (defaults to $DEFAULT_ROLE)" + --firstName (defaults to blank)" + --lastName (defaults to blank)" + --note (defaults to blank)" + + enable: Enables a user" + Required parameters: " + --email " + Optional parameters: " + --skip-sync (defers the Elastic sync until the next scheduled time) + + disable: Disables a user" + Required parameters: " + --email " + Optional parameters: " + --skip-sync (defers the Elastic sync until the next scheduled time) + + validate: Validates that the given email address and password are acceptable" + Required parameters: " + --email " + + valemail: Validates that the given email address is acceptable; requires 'email' parameter" + Required parameters: " + --email " + + valpass: Validates that a password is acceptable" + + Note that the password can be piped into STDIN to avoid prompting for it" +USAGE_EOF exit 1 +} + +if [[ $# -lt 1 || $1 == --help || $1 == -h || $1 == -? || $1 == --h ]]; then + usage fi operation=$1 -email=$2 -role=$3 +shift + +while [[ $# -gt 0 ]]; do + param=$1 + shift + case "$param" in + --email) + email=$1 + shift + ;; + --role) + role=$1 + shift + ;; + --firstName) + firstName=$1 + shift + ;; + --lastName) + lastName=$1 + shift + ;; + --note) + note=$1 + shift + ;; + --skip-sync) + SKIP_SYNC=1 + ;; + *) + echo "Encountered unexpected parameter: $param" + usage + ;; + esac +done kratosUrl=${KRATOS_URL:-http://127.0.0.1:4434/admin} databasePath=${KRATOS_DB_PATH:-/opt/so/conf/kratos/db/db.sqlite} @@ -213,6 +304,8 @@ function syncElasticSystemRole() { } function syncElastic() { + [[ -n $SKIP_SYNC ]] && return + echo "Syncing users and roles between SOC and Elastic..." usersTmpFile="${elasticUsersFile}.tmp" @@ -277,9 +370,9 @@ function syncElastic() { mv "${rolesTmpFile}" "${elasticRolesFile}" if [[ -z "$SKIP_STATE_APPLY" ]]; then - echo "Elastic state will be re-applied to affected minions. This may take several minutes..." + echo "Elastic state will be re-applied to affected minions. This will run in the background and may take several minutes to complete." echo "Applying elastic state to elastic minions at $(date)" >> /opt/so/log/soc/sync.log 2>&1 - salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-searchnode or G@role:so-heavynode' state.apply elasticsearch queue=True >> /opt/so/log/soc/sync.log 2>&1 + salt --async -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-searchnode or G@role:so-heavynode' state.apply elasticsearch queue=True >> /opt/so/log/soc/sync.log 2>&1 fi else echo "Newly generated users/roles files are incomplete; aborting." @@ -369,11 +462,19 @@ function adjustUserRole() { function createUser() { email=$1 role=$2 + firstName=$3 + lastName=$4 + note=$5 now=$(date -u +%FT%TZ) addUserJson=$(cat < "${SOC_PIPE}") + else + log "Unsuccessful command execution: $response ($exit_code)" + $(echo "false" > "${SOC_PIPE}") + fi +} + +function manage_salt() { + request=$1 + op=$(echo "$request" | jq -r .operation) + minion=$(echo "$request" | jq -r .minion) + if [[ -s $minion || "$minion" == "null" ]]; then + minion=$(cat /etc/salt/minion | grep "id:" | awk '{print $2}' | sed "s/'//g") + fi + + case "$op" in + state) + log "Performing '$op' for '$state' on minion '$minion'" + state=$(echo "$request" | jq -r .state) + response=$(salt --async "$minion" state.apply "$state" queue=True) + exit_code=$? + ;; + highstate) + log "Performing '$op' on minion $minion" + response=$(salt --async "$minion" state.highstate queue=True) + exit_code=$? + ;; + activejobs) + log "Querying active salt jobs" + response=$(salt-run jobs.active -out json -l quiet) + $(echo "$response" > "${SOC_PIPE}") + return + ;; + *) + response="Unsupported salt operation: $op" + exit_code=1 + ;; + esac + + if [[ exit_code -eq 0 ]]; then + log "Successful command execution" + $(echo "true" > "${SOC_PIPE}") + else + log "Unsuccessful command execution: $response ($exit_code)" + $(echo "false" > "${SOC_PIPE}") + fi +} + while true; do log "Listening for request" request=$(cat ${SOC_PIPE}) if [[ "$request" != "" ]]; then - log "Received request: ${request}" - case "$request" in + command=$(echo "$request" | jq -r .command) + log "Received request; command=${command}" + case "$command" in list-minions) list_minions ;; - manage-minion*) - manage_minion ${request} + manage-minion) + manage_minion "${request}" + ;; + manage-user) + manage_user "${request}" + ;; + manage-salt) + manage_salt "${request}" ;; *) - log "Unsupported command: $request" + log "Unsupported command: $command" $(echo "false" > "${SOC_PIPE}") + ;; esac # allow remote reader to get a clean reader before we try to read again on next loop diff --git a/setup/so-functions b/setup/so-functions index 5a0e35be0..7dfa7b047 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -69,7 +69,7 @@ add_web_user() { { info "Attempting to add administrator user for web interface..."; export SKIP_STATE_APPLY=true - echo "$WEBPASSWD1" | /usr/sbin/so-user add "$WEBUSER" "superuser"; + echo "$WEBPASSWD1" | /usr/sbin/so-user add --email "$WEBUSER" --role "superuser"; unset SKIP_STATE_APPLY info "Add user result: $?"; } >> "/root/so-user-add.log" 2>&1 @@ -550,7 +550,7 @@ collect_so_allow() { collect_webuser_inputs() { whiptail_create_web_user - while ! so-user valemail "$WEBUSER" >> "$setup_log" 2>&1; do + while ! so-user valemail --email "$WEBUSER" >> "$setup_log" 2>&1; do whiptail_invalid_user_warning whiptail_create_web_user "$WEBUSER" done