|
| 1 | +#!/bin/bash |
| 2 | +USER_CONFIG="$HOME/.appdynamics/adc/config.sh" |
| 3 | +GLOBAL_CONFIG="/etc/appdynamics/adc/config.sh" |
| 4 | +CONFIG_CONTROLLER_COOKIE_LOCATION="/tmp/appdynamics-controller-cookie.txt" |
| 5 | +# Configure default output verbosity. May contain a combination of the following strings: |
| 6 | +# - debug |
| 7 | +# - error |
| 8 | +# - warn |
| 9 | +# - info |
| 10 | +# - output (msg to stdout) |
| 11 | +# An empty string silents all output |
| 12 | +CONFIG_OUTPUT_VERBOSITY="error,output" |
| 13 | +GLOBAL_COMMANDS="" |
| 14 | +GLOBAL_HELP="" |
| 15 | +SCRIPTNAME=$0 |
| 16 | +# register namespace_command help |
| 17 | +function register { |
| 18 | + GLOBAL_COMMANDS="$GLOBAL_COMMANDS $1" |
| 19 | + GLOBAL_HELP="$GLOBAL_HELP\n$@" |
| 20 | +} |
| 21 | +COLOR_WARNING="\033[0;33m" |
| 22 | +COLOR_INFO="\039[0;33m" |
| 23 | +COLOR_ERROR="\033[0;31m" |
| 24 | +COLOR_DEBUG="\033[0;35m" |
| 25 | +COLOR_RESET="\033[0m" |
| 26 | +function debug { |
| 27 | + if [ "${CONFIG_OUTPUT_VERBOSITY/debug}" != "$CONFIG_OUTPUT_VERBOSITY" ]; then |
| 28 | + echo -e "${COLOR_DEBUG}DEBUG: $@${COLOR_RESET}" |
| 29 | + fi |
| 30 | +} |
| 31 | +function error { |
| 32 | + if [ "${CONFIG_OUTPUT_VERBOSITY/error}" != "$CONFIG_OUTPUT_VERBOSITY" ]; then |
| 33 | + echo -e "${COLOR_ERROR}ERROR: $@${COLOR_RESET}" |
| 34 | + fi |
| 35 | +} |
| 36 | +function warning { |
| 37 | + if [ "${CONFIG_OUTPUT_VERBOSITY/warning}" != "$CONFIG_OUTPUT_VERBOSITY" ]; then |
| 38 | + echo -e "${COLOR_WARNING}WARNING: $@${COLOR_RESET}" |
| 39 | + fi |
| 40 | +} |
| 41 | +function info { |
| 42 | + if [ "${CONFIG_OUTPUT_VERBOSITY/info}" != "$CONFIG_OUTPUT_VERBOSITY" ]; then |
| 43 | + echo -e "${COLOR_INFO}INFO: $@${COLOR_RESET}" |
| 44 | + fi |
| 45 | +} |
| 46 | +function output { |
| 47 | + if [ "${CONFIG_OUTPUT_VERBOSITY}" != "" ]; then |
| 48 | + echo -e "$@" |
| 49 | + fi |
| 50 | +} |
| 51 | +function httpClient { |
| 52 | + curl "$@" |
| 53 | +} |
| 54 | +SHIFTS=0 |
| 55 | +declare -i SHIFTS |
| 56 | +function shiftOptInd { |
| 57 | + SHIFTS=$OPTIND |
| 58 | + SHIFTS=${SHIFTS}-1 |
| 59 | + OPTIND=0 |
| 60 | + return $SHIFTS |
| 61 | +} |
| 62 | +function global_self-setup { |
| 63 | + echo "Self Setup" |
| 64 | + exit 0 |
| 65 | +} |
| 66 | +register _self-setup Initialize the adc configuration file |
| 67 | +function _help { |
| 68 | + COMMAND_RESULT="Usage: $SCRIPTNAME <namespace> <command>\n" |
| 69 | + COMMAND_RESULT="${COMMAND_RESULT}\nTo execute a action, provide a namespace and a command, e.g. \"dbmon list\" to list all database collectors.\nFinally the following commands in the global namespace can be called directly:\n" |
| 70 | + local NAMESPACE="" |
| 71 | + local SORTED=`echo -en "$GLOBAL_HELP" | sort` |
| 72 | + OLD_IFS=$IFS |
| 73 | + IFS=$'\n' |
| 74 | + for LINE in $SORTED; do |
| 75 | + NEW_NAMESPACE=${LINE%%_*} |
| 76 | + if [ "$NEW_NAMESPACE" != "$NAMESPACE" ] |
| 77 | + then |
| 78 | + COMMAND_RESULT="${COMMAND_RESULT}\n$NEW_NAMESPACE\n" |
| 79 | + NAMESPACE=$NEW_NAMESPACE |
| 80 | + fi |
| 81 | + COMMAND=${LINE##*_} |
| 82 | + COMMAND_RESULT="${COMMAND_RESULT}\t${COMMAND%% *}\t\t${COMMAND#* }\n" |
| 83 | + done |
| 84 | + IFS=$OLD_IFS |
| 85 | +} |
| 86 | +register _help Display the global usage information |
| 87 | +CONTROLLER_LOGIN_STATUS=0 |
| 88 | +function controller_login { |
| 89 | + debug "Login at $CONFIG_CONTROLLER_HOST with $CONFIG_CONTROLLER_CREDENTIALS" |
| 90 | + LOGIN_RESPONSE=$(httpClient -sI -c $CONFIG_CONTROLLER_COOKIE_LOCATION --user $CONFIG_CONTROLLER_CREDENTIALS $CONFIG_CONTROLLER_HOST/controller/auth?action=login) |
| 91 | + debug "RESPONSE: ${LOGIN_RESPONSE}" |
| 92 | + if [[ "${LOGIN_RESPONSE/200 OK}" != "$LOGIN_RESPONSE" ]]; then |
| 93 | + COMMAND_RESULT="Controller Login Successful" |
| 94 | + CONTROLLER_LOGIN_STATUS=1 |
| 95 | + else |
| 96 | + COMMAND_RESULT="Controller Login Error! Please check hostname and credentials" |
| 97 | + CONTROLLER_LOGIN_STATUS=0 |
| 98 | + fi |
| 99 | + XCSRFTOKEN=$(tail -1 $CONFIG_CONTROLLER_COOKIE_LOCATION | awk 'NF>1{print $NF}') |
| 100 | + debug "XCSRFTOKEN: $XCSRFTOKEN" |
| 101 | +} |
| 102 | +register controller_login Login to your controller |
| 103 | +function controller_call { |
| 104 | + debug "Calling $CONFIG_CONTROLLER_HOST" |
| 105 | + local METHOD="GET" |
| 106 | + while getopts "X:d:" opt "$@"; |
| 107 | + do |
| 108 | + case "${opt}" in |
| 109 | + X) |
| 110 | + METHOD=${OPTARG} |
| 111 | + ;; |
| 112 | + d) |
| 113 | + PAYLOAD=${OPTARG} |
| 114 | + ;; |
| 115 | + esac |
| 116 | + done |
| 117 | + |
| 118 | + shiftOptInd |
| 119 | + shift $SHIFTS |
| 120 | + ENDPOINT=$@ |
| 121 | + |
| 122 | + controller_login |
| 123 | + # Debug the COMMAND_RESULT from controller_login |
| 124 | + debug $COMMAND_RESULT |
| 125 | + if [ $CONTROLLER_LOGIN_STATUS -eq 1 ]; then |
| 126 | + COMMAND_RESULT=$(httpClient -s -b $CONFIG_CONTROLLER_COOKIE_LOCATION \ |
| 127 | + -X $METHOD\ |
| 128 | + -H "X-CSRF-TOKEN: $XCSRFTOKEN" \ |
| 129 | + -H "Content-Type: application/json;charset=UTF-8" \ |
| 130 | + -H "Accept: application/json, text/plain, */*"\ |
| 131 | + -d "$PAYLOAD" \ |
| 132 | + $CONFIG_CONTROLLER_HOST$ENDPOINT) |
| 133 | + else |
| 134 | + COMMAND_RESULT="Controller Login Error! Please check hostname and credentials" |
| 135 | + fi |
| 136 | +} |
| 137 | +register controller_call Send a custom HTTP call to a controller |
| 138 | +function dbmon_create { |
| 139 | + echo "Stub" |
| 140 | +} |
| 141 | +register dbmon_create Create a new database collector |
| 142 | +function timerange_create { |
| 143 | + while getopts "s:e:" opt "$@"; |
| 144 | + do |
| 145 | + case "${opt}" in |
| 146 | + s) |
| 147 | + START_TIME=${OPTARG} |
| 148 | + ;; |
| 149 | + e) |
| 150 | + END_TIME=${OPTARG} |
| 151 | + ;; |
| 152 | + esac |
| 153 | + done; |
| 154 | + shiftOptInd |
| 155 | + shift $SHIFTS |
| 156 | + TIMERANGE_NAME=$@ |
| 157 | + controller_call -X POST -d "{\"name\":\"$TIMERANGE_NAME\",\"timeRange\":{\"type\":\"BETWEEN_TIMES\",\"durationInMinutes\":0,\"startTime\":$START_TIME,\"endTime\":$END_TIME}}" /controller/restui/user/createCustomRange |
| 158 | +} |
| 159 | +register timerange_create Create a custom time range |
| 160 | +function dashboard_list { |
| 161 | + controller_call -X GET /controller/restui/dashboards/getAllDashboardsByType/false |
| 162 | +} |
| 163 | +register dashboard_list List all dashboards available on the controller |
| 164 | +function dashboard_export { |
| 165 | + local DASHBOARD_ID=$@ |
| 166 | + if [[ $DASHBOARD_ID =~ ^[0-9]+$ ]]; then |
| 167 | + controller_call -X GET /controller/CustomDashboardImportExportServlet?dashboardId=$@ |
| 168 | + else |
| 169 | + COMMAND_RESULT="" |
| 170 | + error "This is not a number: '$DASHBOARD_ID'" |
| 171 | + fi |
| 172 | +} |
| 173 | +register dashboard_export Export a specific dashboard |
| 174 | +function dashboard_delete { |
| 175 | + local DASHBOARD_ID=$@ |
| 176 | + if [[ $DASHBOARD_ID =~ ^[0-9]+$ ]]; then |
| 177 | + controller_call -X POST -d "[$DASHBOARD_ID]" /controller/restui/dashboards/deleteDashboards |
| 178 | + else |
| 179 | + COMMAND_RESULT="" |
| 180 | + error "This is not a number: '$DASHBOARD_ID'" |
| 181 | + fi |
| 182 | +} |
| 183 | +register dashboard_delete Delete a specific dashboard |
| 184 | +if [ -f "${GLOBAL_CONFIG}" ]; then |
| 185 | + debug "Sourcing global config from ${GLOBAL_CONFIG} " |
| 186 | + . ${GLOBAL_CONFIG} |
| 187 | +else |
| 188 | + warning "File ${GLOBAL_CONFIG} not found!" |
| 189 | +fi |
| 190 | +if [ -f "${USER_CONFIG}" ]; then |
| 191 | + debug "Sourcing user config from ${USER_CONFIG} " |
| 192 | + . ${USER_CONFIG} |
| 193 | +else |
| 194 | + warning "File ${USER_CONFIG} not found!" |
| 195 | +fi |
| 196 | +# Parse global options |
| 197 | +while getopts "H:C:D:" opt; |
| 198 | +do |
| 199 | + case "${opt}" in |
| 200 | + H) |
| 201 | + CONFIG_CONTROLLER_HOST=${OPTARG} |
| 202 | + debug "Set CONFIG_CONTROLLER_HOST=${CONFIG_CONTROLLER_HOST}" |
| 203 | + ;; |
| 204 | + C) |
| 205 | + CONFIG_CONTROLLER_CREDENTIALS=${OPTARG} |
| 206 | + debug "Set CONFIG_CONTROLLER_CREDENTIALS=${CONFIG_CONTROLLER_CREDENTIALS}" |
| 207 | + ;; |
| 208 | + J) |
| 209 | + CONFIG_CONTROLLER_COOKIE_LOCATION=${OPTARG} |
| 210 | + debug "Set CONFIG_CONTROLLER_COOKIE_LOCATION=${CONFIG_CONTROLLER_COOKIE_LOCATION}" |
| 211 | + ;; |
| 212 | + D) |
| 213 | + CONFIG_OUTPUT_VERBOSITY=${OPTARG} |
| 214 | + debug "Set CONFIG_OUTPUT_VERBOSITY=${CONFIG_OUTPUT_VERBOSITY}" |
| 215 | + esac |
| 216 | +done |
| 217 | +shiftOptInd |
| 218 | +shift $SHIFTS |
| 219 | +debug "CONFIG_CONTROLLER_HOST=$CONFIG_CONTROLLER_HOST" |
| 220 | +debug "CONFIG_CONTROLLER_CREDENTIALS=$CONFIG_CONTROLLER_CREDENTIALS" |
| 221 | +debug "CONFIG_CONTROLLER_COOKIE_LOCATION=$CONFIG_CONTROLLER_COOKIE_LOCATION" |
| 222 | +debug "CONFIG_OUTPUT_VERBOSITY=$CONFIG_OUTPUT_VERBOSITY" |
| 223 | +NAMESPACE=$1 |
| 224 | +COMMAND_RESULT="Unknown command" |
| 225 | +# Check if the namespace is used |
| 226 | +if [ "${GLOBAL_COMMANDS/${NAMESPACE}_}" != "$GLOBAL_COMMANDS" ] ; then |
| 227 | + debug "_${NAMESPACE} has commands" |
| 228 | + COMMAND=$2 |
| 229 | + if [ "${GLOBAL_COMMANDS/${NAMESPACE}_${COMMAND}}" != "$GLOBAL_COMMANDS" ] ; then |
| 230 | + debug "${NAMESPACE}_${COMMAND} is a valid command" |
| 231 | + shift 2 |
| 232 | + ${NAMESPACE}_${COMMAND} $@ |
| 233 | + fi |
| 234 | +# Check if this is a global command |
| 235 | +elif [ "${GLOBAL_COMMANDS/_${NAMESPACE}}" != "$GLOBAL_COMMANDS" ] ; then |
| 236 | + debug "_${NAMESPACE} found as global command" |
| 237 | + shift 1 |
| 238 | + _${NAMESPACE} $@ |
| 239 | +fi |
| 240 | +if [ "$COMMAND_RESULT" != "" ]; then |
| 241 | + output $COMMAND_RESULT |
| 242 | +fi |
| 243 | +debug END |
0 commit comments