├── .gitignore ├── Makefile ├── .travis.yml ├── contrib ├── samples │ ├── my-informations.sh │ ├── list-domains.sh │ └── post-domain-TXT-record.sh ├── test │ └── jsonshlib_test.sh ├── README.md ├── ovh-api-lib.sh └── jsonsh-lib.sh ├── README.md └── ovh-api-bash-client.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .ovhApplication* 2 | .ovhConsumerKey* 3 | libs/ 4 | profile/ 5 | contrib/test/*.json 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | LIBS_FOLDER = "./libs/" 2 | 3 | install: 4 | curl -Ls -o $(LIBS_FOLDER)/JSON.sh --create-dirs https://github.com/dominictarr/JSON.sh/raw/master/JSON.sh 5 | chmod +x $(LIBS_FOLDER)/* 6 | 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | language: bash 4 | 5 | services: 6 | - docker 7 | 8 | before_install: 9 | - docker pull koalaman/shellcheck 10 | 11 | script: 12 | - docker run -v $(pwd):/scripts koalaman/shellcheck /scripts/ovh-api-bash-client.sh 13 | 14 | matrix: 15 | fast_finish: true 16 | 17 | -------------------------------------------------------------------------------- /contrib/samples/my-informations.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | HERE=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) 3 | source ${HERE}/../ovh-api-lib.sh || exit 1 4 | 5 | OvhRequestApi /me 6 | 7 | if [ ${OVHAPI_HTTP_STATUS} -ne 200 ]; then 8 | echo "profile error:" 9 | getJSONValues 10 | exit 11 | fi 12 | 13 | echo "-- all fields --" 14 | getJSONValues 15 | echo "-- only some fields --" 16 | getJSONValue "email" 17 | getJSONValue "currency.code" 18 | getJSONValue "currency.symbol" 19 | -------------------------------------------------------------------------------- /contrib/samples/list-domains.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | HERE=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) 3 | source ${HERE}/../ovh-api-lib.sh || exit 1 4 | 5 | OvhRequestApi /me 6 | 7 | if [ ${OVHAPI_HTTP_STATUS} -ne 200 ]; then 8 | echo "profile error:" 9 | getJSONValues 10 | exit 11 | fi 12 | 13 | OvhRequestApi "/domain" 14 | 15 | if [ "${OVHAPI_HTTP_STATUS}" -eq 200 ]; then 16 | domains=($(getJSONValues)) 17 | echo "number of domains=${#domains[@]}" 18 | 19 | # for example, only list for first domain 20 | #for domain in "${domains[@]}" 21 | for domain in "${domains[0]}" 22 | do 23 | echo -e "\n== informations about ${domain} ==" 24 | OvhRequestApi "/domain/${domain}" 25 | echo "-- single value --" 26 | # key can be passed with/without double quote 27 | getJSONValue lastUpdate 28 | getJSONValue '"transferLockStatus"' 29 | echo "-- get all values --" 30 | getJSONValues 31 | done 32 | else 33 | getJSONValues 34 | fi 35 | -------------------------------------------------------------------------------- /contrib/samples/post-domain-TXT-record.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | HERE=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) 3 | source ${HERE}/../ovh-api-lib.sh || exit 1 4 | 5 | OvhRequestApi /me 6 | 7 | if [ ${OVHAPI_HTTP_STATUS} -ne 200 ]; then 8 | echo "profile error:" 9 | getJSONValues 10 | exit 11 | fi 12 | 13 | if [ -z "${OVH_DOMAIN}" ]; then 14 | echo -e "please set one of your domains with :\nOVH_DOMAIN=your_domain.tld" 15 | echo -e "choose in :\n" 16 | 17 | OvhRequestApi "/domain" 18 | getJSONValues 19 | exit 1 20 | fi 21 | 22 | txt_field="ovhapilib" 23 | 24 | txt_value="test1: text with space and quo't'es" 25 | 26 | # avoid backslashes :-) : 27 | CUSTOMDATA=$(cat < : the API URL to call, for example /domains (default is /me) 45 | --method : the HTTP method to use, for example POST (default is GET) 46 | --data : the data body to send with the request 47 | --target : the target API [CA|EU|US] (default is EU) 48 | --init : to initialize the consumer key, and manage custom access rules file 49 | --initApp : to initialize the API application 50 | --list-profile : list available profiles in ~/.ovh-api-bash-client/profile directory 51 | --profile 52 | * default : from ~/.ovh-api-bash-client/profile directory 53 | * : from ~/.ovh-api-bash-client/profile/ directory 54 | ``` 55 | 56 | Usage 57 | ----- 58 | 59 | ### Just some examples: 60 | 61 | To make a basic call on GET `/me` just run: 62 | 63 | ``` 64 | ./ovh-api-bash-client.sh 65 | ``` 66 | 67 | To retrieve your domain list, run: 68 | 69 | ``` 70 | ./ovh-api-bash-client.sh --url "/domain" 71 | ``` 72 | 73 | To activate the monitoring on your dedicated server, run: 74 | 75 | ``` 76 | ./ovh-api-bash-client.sh --method PUT --url "/dedicated/server/ns00000.ovh.net" --data '{"monitoring": true}' 77 | ``` 78 | 79 | To create a Consumer key for different account or usage (profile is created if missing) 80 | 81 | ``` 82 | ./ovh-api-bash-client.sh --profile demo1 --init 83 | ./ovh-api-bash-client.sh --profile demo2 --init 84 | ``` 85 | 86 | Embedded lib for external scripts 87 | --------------------------------- 88 | 89 | See **contrib/** directory 90 | -------------------------------------------------------------------------------- /contrib/test/jsonshlib_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | HERE=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) 3 | 4 | JSONSH_DIR=${HERE}/../../libs/ 5 | source ${HERE}/../../contrib/jsonsh-lib.sh || exit 1 6 | 7 | # optional output separator 8 | JSONSH_SEPARATOR="\t:\t" 9 | 10 | _pause() 11 | { 12 | echo -e "\n== $1 ==\n" 13 | read -p "-- Press ENTER --" 14 | } 15 | 16 | _pause "demo file" 17 | JSON=$(cat <&2 31 | fi 32 | } 33 | 34 | # to override profile, define value in the variable OVHAPI_BASHCLIENT_PROFILE 35 | # to override target, define value in the variable OVHAPI_TARGET 36 | # OvhRequestApi url [method] [post_data] 37 | # 38 | # default method: get 39 | # return response code in OVHAPI_HTTP_STATUS and content in OVHAPI_HTTP_RESPONSE 40 | OvhRequestApi() 41 | { 42 | local url=$1 43 | local method=$2 44 | local data=$3 45 | 46 | local client_response= 47 | local cmd_profile= 48 | local cmd=("${OVHAPI_BASHCLIENT_BIN}") 49 | 50 | ## construct arguments array 51 | if [ -n "${OVHAPI_BASHCLIENT_PROFILE}" ]; then 52 | cmd+=(--profile "${OVHAPI_BASHCLIENT_PROFILE}") 53 | fi 54 | cmd_profile=${cmd[*]} 55 | 56 | if [ -n "${url}" ]; then 57 | cmd+=(--url "${url}") 58 | fi 59 | 60 | if [ -n "${method}" ]; then 61 | cmd+=(--method "${method}") 62 | fi 63 | 64 | if [ -n "${OVHAPI_TARGET}" ]; then 65 | cmd+=(--target "${OVHAPI_TARGET}") 66 | fi 67 | 68 | if [ "${method}" == "POST" ] || [ "${method}" == "PUT" ]; then 69 | # double-quote data content for bash input 70 | data=$(printf "%q" "${data}") 71 | cmd+=(--data "${data}") 72 | fi 73 | 74 | _ovhapilib_echo_debug "command: ${cmd[*]}" 75 | 76 | # best way found to correctly pass quoted arguments to a command called from a function 77 | client_response=$(echo "${cmd[*]}" | bash) 78 | 79 | OVHAPI_HTTP_STATUS=$(echo "${client_response}" | cut -d ' ' -f1) 80 | OVHAPI_HTTP_RESPONSE="$(echo "${client_response}" | cut -d ' ' -f2-)" 81 | 82 | # catch profile error 83 | if [[ ! ${OVHAPI_HTTP_STATUS} =~ ^[0-9]+$ ]] && [[ ${OVHAPI_HTTP_RESPONSE} == *$'\n'* ]]; then 84 | OVHAPI_HTTP_STATUS=500 85 | OVHAPI_HTTP_RESPONSE=$(cat </dev/null)" ) 16 | 17 | # can be overrided 18 | JSONSH_DIR=${JSONSH_DIR:-"${JSONSH_SYSTEM_DIR}"} 19 | 20 | if [ -z "${JSONSH_DIR}" ]; then 21 | echo "JSONSH_DIR should be set" >&2 22 | exit 1 23 | else 24 | # to get absolte path 25 | JSONSH_DIR=$(cd "${JSONSH_DIR}" && pwd) 26 | if [ ! -f "${JSONSH_DIR}/JSON.sh" ]; then 27 | echo "${JSONSH_DIR}/JSON.sh not found" >&2 28 | exit 1 29 | fi 30 | fi 31 | 32 | readonly JSONSH_DIR 33 | 34 | # debug output if wanted 35 | _jsonshlib_echo_debug() 36 | { 37 | if [ "${JSONSHLIB_DEBUG}" == "1" ]; then 38 | echo "[debug:${FUNCNAME[1]}] $*" >&2 39 | fi 40 | } 41 | 42 | # 43 | # single entry point with JSON.sh 44 | # load json defined as argument, and set result to JSONSH_CACHE 45 | # 46 | # keep result in cache to avoid useless calls to JSON.sh 47 | # 48 | # usage : 49 | # to set source json : loadJSON "json content" 50 | # to get JSON.sh output, don't set argument 51 | # 52 | loadJSON() 53 | { 54 | local json_source="$1" 55 | local current_md5= 56 | 57 | if [ -z "${json_source}" ]; then 58 | if [ -z "${JSONSH_CACHE}" ]; then 59 | echo "JSON content is empty" >&2 60 | exit 1 61 | fi 62 | _jsonshlib_echo_debug "get JSON.sh result from cache" 63 | echo "${JSONSH_CACHE}" 64 | else 65 | # only follow to JSON.sh if JSon content differs 66 | current_md5=$(echo "${json_source}" | md5sum | cut -d ' ' -f1) 67 | if [ "${JSONSH_SOURCE_MD5}" != "${current_md5}" ]; then 68 | _jsonshlib_echo_debug "new JSON source, build JSON.sh cache" 69 | JSONSH_SOURCE_MD5=${current_md5} 70 | JSONSH_CACHE=$("${JSONSH_DIR}/JSON.sh" -l <<< "${json_source}") 71 | fi 72 | fi 73 | 74 | return 0 75 | 76 | } 77 | 78 | # 79 | # convert JSON.sh key output format (JSON array) and trim value, through pipe 80 | # 81 | # sample : 82 | # json.sh output : ["foo","bar",0,"baz"] " json value " 83 | # new output : foo.bar[0].baz json value 84 | # 85 | # for each value, outside double quotes and spaces are removed 86 | # 87 | # _JSonSH_rewrite_output getKeys : print only keys 88 | # _JSonSH_rewrite_output getValue : print only value for the field 89 | # _JSonSH_rewrite_output getFull : print pair of key/value 90 | # 91 | # separator between key and value can be overrided if JSONSH_SEPARATOR is set (default = ":") 92 | # 93 | _JSonSH_rewrite_output() 94 | { 95 | local action=$1 96 | local wanted_key=$2 97 | 98 | if [[ "${action}" == "getValue" ]] && [[ -z "${wanted_key}" ]]; then 99 | echo "key is required" >&2 100 | exit 1 101 | fi 102 | 103 | JSONSH_SEPARATOR=${JSONSH_SEPARATOR:-":"} 104 | 105 | awk -F '\t' \ 106 | -v action="${action}" \ 107 | -v wanted_key="${wanted_key}" \ 108 | -v separator="${JSONSH_SEPARATOR}" \ 109 | '{ 110 | json_key = $1 111 | # drop the key from the line 112 | $1 = "" 113 | json_value=$0 114 | 115 | ## Actions on json key : 116 | # 1) remove some chars : brackets and double quotes 117 | gsub(/\[|\]|\"/,"",json_key) 118 | # 2) detect array index between comma, put digits between brackets 119 | json_key = gensub(/(,([[:digit:]]+)(,|))/,"[\\2]\\3","g",json_key) 120 | # 3) replace each comma with dot 121 | gsub(/,/,".",json_key) 122 | 123 | ## Actions on json value : 124 | # remove first/last double quotes if present 125 | json_value = gensub(/"(.*)"$/,"\\1","g",json_value) 126 | # trim first/last spaces of value 127 | gsub(/^\s+|\s+$/,"",json_value) 128 | 129 | switch (action) { 130 | case "getKeys": 131 | print json_key 132 | break 133 | case "getValue": 134 | # remove first/last double quotes if present 135 | wanted_key = gensub(/"(.*)"$/,"\\1","g",wanted_key) 136 | # the value for a key is wanted 137 | if (json_key == wanted_key) 138 | { 139 | # display value if found and stop 140 | print json_value 141 | exit 0 142 | } 143 | break 144 | case "getFull": 145 | if (json_key ~ /^[0-9]+$/ ) 146 | { 147 | # the key is a number, only value is needed 148 | print json_value 149 | } else { 150 | # the key is a string, display key and value 151 | print json_key separator json_value 152 | } 153 | break 154 | default: 155 | print "Bad action !" >"/dev/stderr" 156 | exit 1 157 | break 158 | } 159 | }' &2 "[WARNING] $*" 48 | } 49 | 50 | # join alements of an array with a separator (single char) 51 | # usage: 52 | # _arrayJoin "|" "${my_array[@]}" 53 | # 54 | _arrayJoin() 55 | { 56 | local IFS="$1" 57 | shift 58 | echo "$*" 59 | } 60 | 61 | _StringToLower() 62 | { 63 | echo "$1" | tr '[:upper:]' '[:lower:]' 64 | } 65 | 66 | _StringToUpper() 67 | { 68 | echo "$1" | tr '[:lower:]' '[:upper:]' 69 | } 70 | 71 | # verify if an array contains an item 72 | # _in_array "wanted" "${array[@]}" 73 | # _in_array "wanted_key" "${!array[@]}" 74 | _in_array() 75 | { 76 | local item wanted 77 | wanted="$1" 78 | shift 79 | for item; do 80 | [[ "${item}" == "${wanted}" ]] && return 0 81 | done 82 | return 1 83 | } 84 | 85 | isTargetValid() 86 | { 87 | if ! _in_array "${TARGET}" "${TARGETS[@]}"; then 88 | help "'${TARGET}' is not a valid target, accepted values are: ${TARGETS[*]}" 89 | exit 1 90 | fi 91 | } 92 | 93 | createApp() 94 | { 95 | local answer 96 | 97 | echo "For which OVH API do you want to create a new API Application? ($( _arrayJoin "|" "${TARGETS[@]}"))" 98 | while [[ -z "${answer}" ]] 99 | do 100 | read -r answer 101 | done 102 | TARGET=$( _StringToUpper "${answer}" ) 103 | isTargetValid 104 | 105 | echo 106 | echo -e "In order to create an API Application, please visit the link below:\\n${API_CREATE_APP_URLS[${TARGET}]}" 107 | echo 108 | echo "Once your application is created, we will configure this script for this application" 109 | echo -n "Enter the Application Key: " 110 | read -r OVH_APP_KEY 111 | echo -n "Enter the Application Secret: " 112 | read -r OVH_APP_SECRET 113 | echo "OK!" 114 | echo "These informations will be stored in the following file: ${CURRENT_PATH}/${OVH_APPLICATION_FILE}_${TARGET}" 115 | echo -e "${OVH_APP_KEY}\\n${OVH_APP_SECRET}" > "${CURRENT_PATH}/${OVH_APPLICATION_FILE}_${TARGET}" 116 | 117 | echo 118 | echo "Do you also need to create a consumer key? (y/n)" 119 | read -r answer 120 | if [[ -n "${answer}" ]] && [[ "$( _StringToLower "${answer}")" == "y" ]]; then 121 | createConsumerKey 122 | else 123 | echo -e "OK, no consumer key created for now.\\nYou will be able to initalize the consumer key later calling:\\n${HELP_CMD} --init" 124 | fi 125 | } 126 | 127 | createConsumerKey() 128 | { 129 | local answer 130 | 131 | # ensure an OVH App key is set 132 | initApplication 133 | hasOvhAppKey || exit 1 134 | 135 | # condition keeped for retro-compatibility, to always allow post accessRules from --data 136 | if [[ -z "${POST_DATA}" ]]; then 137 | buildAccessRules 138 | fi 139 | 140 | answer=$(requestNoAuth "POST" "/auth/credential") 141 | 142 | getJSONFieldString "${answer}" 'consumerKey' > "${CURRENT_PATH}/${CONSUMER_KEY_FILE}_${TARGET}" 143 | echo "In order to validate the generated consumerKey, visit the validation url at:" 144 | getJSONFieldString "${answer}" 'validationUrl' 145 | } 146 | 147 | initConsumerKey() 148 | { 149 | if cat "${CURRENT_PATH}/${CONSUMER_KEY_FILE}_${TARGET}" &> /dev/null; then 150 | OVH_CONSUMER_KEY="$(cat "${CURRENT_PATH}/${CONSUMER_KEY_FILE}_${TARGET}")" 151 | fi 152 | } 153 | 154 | initApplication() 155 | { 156 | if cat "${CURRENT_PATH}/${OVH_APPLICATION_FILE}_${TARGET}" &> /dev/null; then 157 | OVH_APP_KEY=$(sed -n 1p "${CURRENT_PATH}/${OVH_APPLICATION_FILE}_${TARGET}") 158 | OVH_APP_SECRET=$(sed -n 2p "${CURRENT_PATH}/${OVH_APPLICATION_FILE}_${TARGET}") 159 | fi 160 | } 161 | 162 | updateTime() 163 | { 164 | # use OVH API's timestamp instead of user's one to bypass misconfigured host. 165 | curl -s "${API_URL}/auth/time" 166 | } 167 | 168 | # usage: 169 | # updateSignData "method" "url" "post_data" "timestamp" 170 | # return: print signature 171 | updateSignData() 172 | { 173 | local sig_data 174 | local method=$1 175 | local url=$2 176 | local post_data=$3 177 | local timestamp=$4 178 | 179 | sig_data="${OVH_APP_SECRET}+${OVH_CONSUMER_KEY}+${method}+${API_URL}${url}+${post_data}+${timestamp}" 180 | echo "\$1\$$(echo -n "${sig_data}" | sha1sum - | cut -d' ' -f1)" 181 | } 182 | 183 | help() 184 | { 185 | # print error message if set 186 | [[ -n "$1" ]] && echo -e "Error: $1\\n" 187 | 188 | cat < : the API URL to call, for example /domains (default is /me) 191 | --method : the HTTP method to use, for example POST (default is GET) 192 | --data : the data body to send with the request 193 | --target : the target API [$( _arrayJoin "|" "${TARGETS[@]}")] (default is EU) 194 | --init : to initialize the consumer key, and manage custom access rules file 195 | --initApp : to initialize the API application 196 | --list-profile : list available profiles in ~/.ovh-api-bash-client/profile directory 197 | --profile 198 | * default : from ~/.ovh-api-bash-client/profile directory 199 | * : from ~/.ovh-api-bash-client/profile/ directory 200 | 201 | EOF 202 | } 203 | 204 | buildAccessRules() 205 | { 206 | local access_rules_file="${CURRENT_PATH}/access.rules" 207 | local method path 208 | local json_rules 209 | local answer 210 | 211 | if [[ ! -f "${access_rules_file}" ]]; then 212 | echo "${access_rules_file} missing, created full access rules" 213 | echo -e "GET /*\\nPUT /*\\nPOST /*\\nDELETE /*" > "${CURRENT_PATH}/access.rules" 214 | fi 215 | 216 | echo -e "Current rules for that profile\\n" 217 | cat "${access_rules_file}" 218 | echo -e "\\nDo you need to customize this rules ?" 219 | read -n1 -r -p "(y/n)> " answer 220 | echo -e "\\n" 221 | 222 | case ${answer} in 223 | [Yy]) echo "Operation canceled, please edit ${access_rules_file}"; exit;; 224 | [Nn]) echo "Now generating POST JSON Data for accessRules";; 225 | *) echo "bad choice"; exit 1;; 226 | esac 227 | 228 | while read -r method path; 229 | do 230 | if [[ -n "${method}" ]] && [[ -n "${path}" ]]; then 231 | json_rules+='{ "method": "'${method}'", "path": "'${path}'"},' 232 | fi 233 | done < "${access_rules_file}" 234 | json_rules=${json_rules::-1} 235 | if [[ -z "${json_rules}" ]]; then 236 | echoWarning "no rule defined, please verify your file '${access_rules_file}'" 237 | exit 1 238 | fi 239 | 240 | POST_DATA='{ "accessRules": [ '${json_rules}' ] }' 241 | 242 | } 243 | parseArguments() 244 | { 245 | # an action launched out of this function 246 | INIT_KEY_ACTION= 247 | 248 | while [[ $# -gt 0 ]] 249 | do 250 | case $1 in 251 | --data) 252 | shift 253 | POST_DATA=$1 254 | ;; 255 | --init) 256 | INIT_KEY_ACTION="ConsumerKey" 257 | ;; 258 | --initApp) 259 | INIT_KEY_ACTION="AppKey" 260 | ;; 261 | --method) 262 | shift 263 | METHOD=$1 264 | ;; 265 | --url) 266 | shift 267 | URL=$1 268 | ;; 269 | --target) 270 | shift 271 | TARGET=$1 272 | isTargetValid 273 | ;; 274 | --profile) 275 | shift 276 | PROFILE=$1 277 | ;; 278 | --list-profile) 279 | listProfile 280 | exit 0 281 | ;; 282 | --help|-h) 283 | help 284 | exit 0 285 | ;; 286 | *) 287 | help "Unknow parameter $1" 288 | exit 0 289 | ;; 290 | esac 291 | shift 292 | done 293 | 294 | } 295 | 296 | # usage: 297 | # requestNoAuth "method" "url" 298 | requestNoAuth() 299 | { 300 | local method=$1 301 | local url=$2 302 | 303 | local timestamp 304 | timestamp=$(updateTime) 305 | 306 | curl -s -X "${method}" \ 307 | --header 'Content-Type:application/json;charset=utf-8' \ 308 | --header "X-Ovh-Application:${OVH_APP_KEY}" \ 309 | --header "X-Ovh-Timestamp:${timestamp}" \ 310 | --data "${POST_DATA}" \ 311 | "${API_URL}${url}" 312 | } 313 | 314 | request() 315 | { 316 | local response response_status response_content sig timestamp 317 | 318 | timestamp=$(updateTime) 319 | sig=$(updateSignData "${METHOD}" "${URL}" "${POST_DATA}" "${timestamp}") 320 | 321 | response=$(curl -s -w '\n%{http_code}\n' -X "${METHOD}" \ 322 | --header 'Content-Type:application/json;charset=utf-8' \ 323 | --header "X-Ovh-Application:${OVH_APP_KEY}" \ 324 | --header "X-Ovh-Timestamp:${timestamp}" \ 325 | --header "X-Ovh-Signature:${sig}" \ 326 | --header "X-Ovh-Consumer:${OVH_CONSUMER_KEY}" \ 327 | --data "${POST_DATA}" \ 328 | "${API_URL}${URL}") 329 | 330 | response_status=$(echo "${response}" | sed -n '$p') 331 | response_content=$(echo "${response}" | sed '$d') 332 | echo "${response_status} ${response_content}" 333 | } 334 | 335 | getJSONFieldString() 336 | { 337 | local json field result 338 | 339 | json="$1" 340 | field="$2" 341 | # shellcheck disable=SC1117 342 | result=$(echo "${json}" | "${BASE_PATH}/${LIBS}/JSON.sh" | grep "\[\"${field}\"\]" | sed -r "s/\[\"${field}\"\]\s+(.*)/\1/") 343 | echo "${result:1:${#result}-2}" 344 | } 345 | 346 | # set CURRENT_PATH with profile name 347 | # usage: initProfile |set|get] profile_name 348 | # set: create the profile if missing 349 | # get: raise an error if no profile with that name 350 | initProfile() 351 | { 352 | local create_profile=$1 353 | local profile=$2 354 | 355 | if [[ ! -d "${PROFILES_PATH}" ]]; then 356 | mkdir -pv "${PROFILES_PATH}" || exit 1 357 | fi 358 | 359 | # checking if some profiles remains in legacy profile path 360 | local legacy_profiles= 361 | local legacy_default_profile= 362 | if [[ -d "${LEGACY_PROFILES_PATH}" ]]; then 363 | # is there any profile in legacy path ? 364 | legacy_profiles=$(ls -A "${LEGACY_PROFILES_PATH}" 2>/dev/null) 365 | legacy_default_profile=$(cd "${BASE_PATH}" && ls .ovh* access.rules 2>/dev/null) 366 | 367 | if [[ -n "${legacy_profiles}" ]] || [[ -n "${legacy_default_profile}" ]]; then 368 | # notify about migration to new location: 369 | _echoWarning "Your profiles were in the legacy path, migrating to ${PROFILES_PATH}:" 370 | 371 | if [[ -n "${legacy_default_profile}" ]]; then 372 | _echoWarning "> migrating default profile:" 373 | echo "${legacy_default_profile}" 374 | mv "${BASE_PATH}"/{.ovh*,access.rules} "${PROFILES_PATH}" 375 | fi 376 | 377 | if [[ -n "${legacy_profiles}" ]]; then 378 | _echoWarning "> migrating custom profiles:" 379 | echo "${legacy_profiles}" 380 | mv "${LEGACY_PROFILES_PATH}"/* "${PROFILES_PATH}" 381 | fi 382 | 383 | fi 384 | fi 385 | 386 | # if profile is not set, or with value 'default' 387 | if [[ -z "${profile}" ]] || [[ "${profile}" == "default" ]]; then 388 | # configuration stored in the profile main path 389 | CURRENT_PATH="${PROFILES_PATH}" 390 | else 391 | # ensure profile directory exists 392 | if [[ ! -d "${PROFILES_PATH}/${profile}" ]]; then 393 | case ${create_profile} in 394 | get) 395 | echo "${PROFILES_PATH}/${profile} should exists" 396 | listProfile 397 | exit 1 398 | ;; 399 | set) 400 | mkdir "${PROFILES_PATH}/${profile}" || exit 1 401 | ;; 402 | esac 403 | fi 404 | # override default configuration location 405 | CURRENT_PATH="$( cd "${PROFILES_PATH}/${profile}" && pwd )" 406 | fi 407 | 408 | if [[ -n "${profile}" ]]; then 409 | HELP_CMD="${HELP_CMD} --profile ${profile}" 410 | fi 411 | 412 | } 413 | 414 | listProfile() 415 | { 416 | local dir= 417 | echo "Available profiles: " 418 | echo "- default" 419 | 420 | if [[ -d "${PROFILES_PATH}" ]]; then 421 | # only list directory 422 | for dir in $(cd "${PROFILES_PATH}" && ls -d -- */ 2>/dev/null) 423 | do 424 | # display directory name without slash 425 | echo "- ${dir%%/}" 426 | done 427 | fi 428 | } 429 | 430 | # ensure OVH App Key an App Secret are defined 431 | hasOvhAppKey() 432 | { 433 | if [[ -z "${OVH_APP_KEY}" ]] && [[ -z "${OVH_APP_SECRET}" ]]; then 434 | echo -e "No application is defined for target ${TARGET}, please call to initialize it:\\n${HELP_CMD} --initApp" 435 | return 1 436 | fi 437 | return 0 438 | } 439 | 440 | main() 441 | { 442 | parseArguments "$@" 443 | 444 | # set to default value if empty 445 | TARGET=${TARGET:-"EU"} 446 | METHOD=${METHOD:-"GET"} 447 | URL=${URL:-"/me"} 448 | PROFILE=${PROFILE:-"default"} 449 | POST_DATA=${POST_DATA:-} 450 | 451 | readonly API_URL="${API_URLS[${TARGET}]}" 452 | 453 | local profileAction="get" 454 | 455 | if [[ -n "${INIT_KEY_ACTION}" ]]; then 456 | profileAction="set" 457 | fi 458 | 459 | initProfile "${profileAction}" "${PROFILE}" 460 | 461 | # user want to add An API Key 462 | case ${INIT_KEY_ACTION} in 463 | AppKey) createApp;; 464 | ConsumerKey) createConsumerKey;; 465 | esac 466 | ## exit after initializing any API Keys 467 | [[ -n "${INIT_KEY_ACTION}" ]] && exit 0 468 | 469 | initApplication 470 | initConsumerKey 471 | 472 | if hasOvhAppKey; then 473 | if [[ -z "${OVH_CONSUMER_KEY}" ]]; then 474 | echo "No consumer key for target ${TARGET}, please call to initialize it:" 475 | echo "${HELP_CMD} --init" 476 | else 477 | request "${METHOD}" "${URL}" 478 | fi 479 | fi 480 | } 481 | 482 | main "$@" 483 | --------------------------------------------------------------------------------