Revision 808edc81
Added by Benoît PECCATTE about 8 years ago
share/commands/remote-run | ||
---|---|---|
# @man +
|
||
# @man *Arguments*:
|
||
# @man +
|
||
# @man *node*: IP or hostname of the target node
|
||
# @man *node*: IP or hostname of the target node or 'all' for all nodes of the server
|
||
# @man +
|
||
# @man *Options*:
|
||
# @man +
|
||
... | ... | |
# @man *-m*: run the agent with multiline output
|
||
# @man +
|
||
# @man *-D*: define a class for this run
|
||
# @man +
|
||
# @man *-a*: run the agent on all known nodes
|
||
# @man +
|
||
# @man *-g*: run the agent on all nodes of the group UUID given in parameter
|
||
# @man +
|
||
# @man *-j*: run this number of jobs in parallel
|
||
# @man +
|
||
# @man *-t*: provide an alternate token for group query (default from ~/.rudder)
|
||
# @man +
|
||
# @man *-u*: provide an alternate url for group query (default from ~/.rudder)
|
||
# @man +
|
||
# @man *-C*: provide an alternate config section in ~/.rudder for group query (default to first found)
|
||
|
||
|
||
. "${BASEDIR}/../lib/cfengine_parsing.sh"
|
||
. "${BASEDIR}/../lib/api_call.sh"
|
||
|
||
PORT=5309
|
||
LOOP="xargs -I{}"
|
||
MULTIHOST=1
|
||
|
||
while getopts "iIvdqwrRmcb:D:" opt; do
|
||
# Check for js presence
|
||
need_jq() {
|
||
if ! type jq >/dev/null 2>/dev/null
|
||
then
|
||
echo "ERROR: 'jq' must be installed to query hosts from server" 1>&2
|
||
exit 2
|
||
fi
|
||
}
|
||
|
||
while getopts "iIvdqwrRmcb:D:j:at:u:C:" opt; do
|
||
case $opt in
|
||
i|I)
|
||
VERBOSITY="-I ${DEBUG_CLASS}"
|
||
... | ... | |
D)
|
||
CLASS="-D ${OPTARG}"
|
||
;;
|
||
j)
|
||
if ! type parallel >/dev/null 2>/dev/null
|
||
then
|
||
echo "ERROR: 'parallel' must be installed to run multiple jobs in parallel" 1>&2
|
||
exit 2
|
||
fi
|
||
LOOP="parallel --jobs ${OPTARG}"
|
||
;;
|
||
g)
|
||
need_jq
|
||
GROUP="${OPTARG}"
|
||
;;
|
||
a)
|
||
need_jq
|
||
ALL="true"
|
||
;;
|
||
t)
|
||
TOKEN="${OPTARG}"
|
||
;;
|
||
u)
|
||
URL="${OPTARG}"
|
||
;;
|
||
C)
|
||
CONFID="${OPTARG}"
|
||
;;
|
||
esac
|
||
# to keep the argument as $1
|
||
shift `expr ${OPTIND} - 1`
|
||
done
|
||
|
||
PORT=5309
|
||
NODE="$1"
|
||
if [ -z "${NODE}" ]
|
||
# Define node list method
|
||
if [ -n "${ALL}" ]
|
||
then
|
||
NODELIST="get_all_hostnames"
|
||
elif [ -n "${GROUP}" ]
|
||
then
|
||
NODELIST="get_group_hostids ${GROUP}"
|
||
elif [ -z "$1" ]
|
||
then
|
||
echo "Usage rudder remote run <node_ip_or_name>"
|
||
exit 1
|
||
else
|
||
NODELIST="echo $*"
|
||
fi
|
||
|
||
"${RUDDER_VAR}/cfengine-community/bin/cf-runagent" -H "${NODE}:${PORT}" ${VERBOSITY} ${COLOR} | eval ${PRETTY}
|
||
# get all hosts on server
|
||
get_all_hostnames() {
|
||
full_api_call "/api/nodes" "${URL}" "${CONFID}" "${TOKEN}" | jq '.data.nodes[].hostname' | sed -e 's/"\(.*\)"/\1/'
|
||
}
|
||
|
||
# get all hosts in a given group
|
||
get_group_hostids() {
|
||
for id in $(full_api_call "/api/groups/$1" "${URL}" "${CONFID}" "${TOKEN}" | jq '.data.groups[0].nodeIds[]')
|
||
do
|
||
full_api_call "/api/nodes/${id}" "${URL}" "${CONFID}" "${TOKEN}" | jq '.data.nodes[0].hostname'
|
||
done | sed -e 's/"\(.*\)"/\1/'
|
||
}
|
||
|
||
# Aggregate everything
|
||
${NODELIST} | ${LOOP} "${RUDDER_VAR}/cfengine-community/bin/cf-runagent" -H "{}:${PORT}" ${VERBOSITY} ${COLOR} | eval ${PRETTY}
|
share/lib/api_call.sh | ||
---|---|---|
if type curl >/dev/null 2>/dev/null
|
||
then
|
||
DOWNLOAD_COMMAND="curl --silent --show-error --insecure --location --proxy ''"
|
||
HEADER_OPT="--header"
|
||
else
|
||
DOWNLOAD_COMMAND="wget --quiet --no-check-certificate --no-proxy -O -"
|
||
HEADER_OPT="--header"
|
||
fi
|
||
|
||
# This functions tests if the API call returns "OK"
|
||
... | ... | |
then
|
||
printf "${WHITE}${curl_command}${NORMAL}\n"
|
||
fi
|
||
result=`eval ${curl_command}`
|
||
result=`eval ${DOWNLOAD_COMMAND} \"${url}\"`
|
||
code=$?
|
||
if [ ${code} -eq 0 ] && [ "${result}" = "OK" ]
|
||
then
|
||
... | ... | |
exit 1
|
||
fi
|
||
}
|
||
|
||
# retrieve one entry from ~/.rudder
|
||
_get_conf() {
|
||
conf="$1"
|
||
name="$2"
|
||
conffile=~/.rudder
|
||
[ -f "${conffile}" ] || return
|
||
[ -z "${conf}" ] && conf=".*"
|
||
# extract inifile section | extract value
|
||
sed -n "/^\\[${conf}\\]$/,/^\\[.*\\]$/p" "${conffile}" | sed -n "/^${name} *= */s/^${name} *= *//p"
|
||
}
|
||
|
||
# This function calls the api with a token
|
||
full_api_call() {
|
||
api="$1"
|
||
url="$2"
|
||
conf="$3"
|
||
token="$4"
|
||
|
||
if [ -z "${url}" ]
|
||
then
|
||
url=`_get_conf "${conf}" "url"`
|
||
if [ -z "${url}" ]
|
||
then
|
||
host=`cat /var/rudder/cfengine-community/policy_server.dat 2>/dev/null`
|
||
[ -z "${host}" ] && host="localhost"
|
||
url="https://${host}/rudder"
|
||
fi
|
||
fi
|
||
|
||
[ -z "${token}" ] && token=`_get_conf "${conf}" "token"`
|
||
if [ -z "${token}" ]
|
||
then
|
||
echo "A token is mandatory to query the server"
|
||
exit 1
|
||
fi
|
||
eval ${DOWNLOAD_COMMAND} ${HEADER_OPT} "\"X-API-Token: ${token}\"" ${HEADER_OPT} "\"Content-Type: application/json;charset=utf-8\"" ${HEADER_OPT} "\"X-API-Version: latest\"" \"${url}${api}\"
|
||
}
|
||
|
share/lib/cfengine_parsing.sh | ||
---|---|---|
QUIET=0
|
||
# Display full strings
|
||
FULL_STRINGS=0
|
||
# Prefix lines with hostname
|
||
MULTIHOST=0
|
||
|
||
UUID=$(cat /opt/rudder/etc/uuid.hive 2>/dev/null)
|
||
[ $? -ne 0 ] && UUID="Not yet configured"
|
||
|
||
VERSION=`"${BASEDIR}/agent-version"`
|
||
|
||
PRETTY="awk -v info=\"\${DISPLAY_INFO}\" -v full_strings=\"\${FULL_STRINGS}\" -v summary_only=\"\${SUMMARY_ONLY}\" -v quiet=\"\${QUIET}\" -v multiline=\"\${MULTILINE}\" \
|
||
PRETTY="awk -v info=\"\${DISPLAY_INFO}\" -v full_strings=\"\${FULL_STRINGS}\" -v summary_only=\"\${SUMMARY_ONLY}\" -v quiet=\"\${QUIET}\" -v multiline=\"\${MULTILINE}\" -v multihost=\"\${MULTIHOST}\" \
|
||
-v green=\"\${GREEN}\" -v darkgreen=\"\${DARKGREEN}\" -v red=\"\${RED}\" -v yellow=\"\${YELLOW}\" -v magenta=\"\${MAGENTA}\" -v normal=\"\${NORMAL}\" -v white=\"\${WHITE}\" -v cyan=\"\${CYAN}\" \
|
||
-f ${PRETTY_FILTER}"
|
share/lib/reports.awk | ||
---|---|---|
# Do not display "None" keys
|
||
$8 = "";
|
||
}
|
||
if (match($1, /.*> ->/))
|
||
{
|
||
hostname=substr($1, RSTART, RLENGTH-4);
|
||
}
|
||
|
||
{
|
||
if (!summary_only)
|
||
... | ... | |
if (!header_printed)
|
||
{
|
||
header_printed = 1;
|
||
printf "%s%-8.8s %-25.25s %-25.25s %-18.18s %s%s\n", white, "Result", "Technique", "Component", "Key", "Message", normal;
|
||
if(multihost)
|
||
{
|
||
printf "%s%-10.10s %-8.8s %-25.25s %-25.25s %-18.18s %s%s\n", white, "Hostname", "Result", "Technique", "Component", "Key", "Message", normal;
|
||
}
|
||
else
|
||
{
|
||
printf "%s%-8.8s %-25.25s %-25.25s %-18.18s %s%s\n", white, "Result", "Technique", "Component", "Key", "Message", normal;
|
||
}
|
||
}
|
||
|
||
if(multihost)
|
||
{
|
||
printf "%s%-10.10s ", normal, hostname;
|
||
}
|
||
|
||
printf "%s%-8.8s%s ", color, result, normal;
|
||
|
||
if (full_strings)
|
Also available in: Unified diff
Fixes #8187: rudder remote-run should allow running for a group of nodes