From 1a0e3f220f147ff9293dcdbc1986e22effe0c378 Mon Sep 17 00:00:00 2001 From: Didier BONNEFOI Date: Tue, 13 Jun 2017 18:06:41 +0200 Subject: [PATCH 1/4] Allow multiple API keys management with profiles - add --profile to override default configuration location - add --list-profile to display available profiles - rework messages to display command with the current profile if set Bugfix - ensure OVH App Key an App Secret are defined when creating consumer key Enhancements - when using --init, allow override default "all permissions grants" if --data is set - add -h/--help --- .gitignore | 2 +- README.md | 14 ++++++ ovh-api-bash-client.sh | 98 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 99 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 5b5f8e2..387cdb2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .ovhApplication* .ovhConsumerKey* libs/ - +profile/ diff --git a/README.md b/README.md index e203459..ce39407 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,11 @@ In order to create a new consumer key, run: Options ------- +### Show help +``` + ./ovh-api-bash-client.sh --help +``` + Possible arguments are: ``` --url : the API URL to call, for example /domains (default is /me) @@ -38,6 +43,8 @@ Possible arguments are: --target : the target API (default is EU) --init : to initialize the consumer key --initApp : to initialize the API application + --profile : load a configuration from profile/ directory, (override default location) + --list-profile : list available profiles in profile/ directory ``` Usage @@ -60,3 +67,10 @@ To activate the monitoring on your dedicated server, run: ./ovh-api-bash-client.sh --method PUT --url "/dedicated/server/ns00000.ovh.net" --data '{"monitoring": true}' ``` +create a Consumer key for different account or usage +``` + mkdir profile/demo1 + mkdir profile/demo2 + ./ovh-api-bash-client.sh --profile demo1 --init + ./ovh-api-bash-client.sh --profile demo2 --init +``` diff --git a/ovh-api-bash-client.sh b/ovh-api-bash-client.sh index f493d53..5139f32 100755 --- a/ovh-api-bash-client.sh +++ b/ovh-api-bash-client.sh @@ -18,8 +18,13 @@ API_URLS[EU]="https://api.ovh.com/1.0" declare -A API_CREATE_APP_URLS API_CREATE_APP_URLS[CA]="https://ca.api.ovh.com/createApp/" API_CREATE_APP_URLS[EU]="https://api.ovh.com/createApp/" -CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BASE_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +CURRENT_PATH="${BASE_PATH}" +#PROFILES_PATH +PROFILES_PATH="${BASE_PATH}/profile" + +HELP_CMD="$0" # THESE VARS WILL BE USED LATER METHOD="GET" @@ -53,6 +58,7 @@ isTargetValid() createApp() { + echo "For which OVH API do you want to create a new API Application? ($( echo ${TARGETS[@]} | sed 's/\s/|/g' ))" while [ -z "$NEXT" ] do @@ -81,7 +87,7 @@ createApp() initApplication createConsumerKey else - echo -e "OK, no consumer key created for now.\nYou will be able to initiaze the consumer key later calling :\n$0 --init" + echo -e "OK, no consumer key created for now.\nYou will be able to initalize the consumer key later calling :\n${HELP_CMD} --init" fi } @@ -89,9 +95,16 @@ createConsumerKey() { METHOD="POST" URL="/auth/credential" - POST_DATA='{ "accessRules": [ { "method": "GET", "path": "/*"}, { "method": "PUT", "path": "/*"}, { "method": "POST", "path": "/*"}, { "method": "DELETE", "path": "/*"} ] }' + # ensure an OVH App key is set + hasOvhAppKey || exit 1 + + # all grants if no post data defined + if [ -z "${POST_DATA}" ]; then + POST_DATA='{ "accessRules": [ { "method": "GET", "path": "/*"}, { "method": "PUT", "path": "/*"}, { "method": "POST", "path": "/*"}, { "method": "DELETE", "path": "/*"} ] }' + fi ANSWER=$(requestNoAuth) + getJSONFieldString "$ANSWER" 'consumerKey' > $CURRENT_PATH/${CONSUMER_KEY_FILE}_${TARGET} echo -e "In order to validate the generated consumerKey, visit the validation url at:\n$(getJSONFieldString "$ANSWER" 'validationUrl')" } @@ -128,7 +141,7 @@ updateSignData() help() { - echo + echo echo "Help: possible arguments are:" echo " --url : the API URL to call, for example /domains (default is /me)" echo " --method : the HTTP method to use, for example POST (default is GET)" @@ -136,6 +149,8 @@ help() echo " --target <$( echo ${TARGETS[@]} | sed 's/\s/|/g' )> : the target API (default is EU)" echo " --init : to initialize the consumer key" echo " --initApp : to initialize the API application" + echo " --profile : load a configuration from profile/ directory, (override default location)" + echo " --list-profile : list available profiles in profile/ directory" echo } @@ -170,6 +185,19 @@ parseArguments() TARGET=$1 isTargetValid ;; + --profile) + shift + initProfile "$1" + ;; + --list-profile) + shift + listProfile + exit 0 + ;; + --help|-h) + help + exit 0 + ;; *) echo "Unknow parameter $1" help @@ -201,28 +229,70 @@ getJSONFieldString() { JSON="$1" FIELD="$2" - RESULT=$(echo $JSON | $CURRENT_PATH/$LIBS/JSON.sh | grep "\[\"$FIELD\"\]" | sed -r "s/\[\"$FIELD\"\]\s+(.*)/\1/") + RESULT=$(echo $JSON | $BASE_PATH/$LIBS/JSON.sh | grep "\[\"$FIELD\"\]" | sed -r "s/\[\"$FIELD\"\]\s+(.*)/\1/") echo ${RESULT:1:${#RESULT}-2} } +# override CURRENT_PATH with profile name +# usage : initProfile profile_name +initProfile() +{ + local profile=$1 + if [ -n "${profile}" ]; then + + if [ ! -d "${PROFILES_PATH}/${profile}" ] + then + echo "${PROFILES_PATH}/${profile} should exists" + exit 1 + fi + # override default configuration location + CURRENT_PATH="$( cd "${PROFILES_PATH}/${profile}" && pwd )" + HELP_CMD="${HELP_CMD} --profile ${profile}" + else + echo "profile not set, choose in : " + listProfile + exit 1 + fi +} + +listProfile() +{ + cd ${PROFILES_PATH} && ls -1 +} + +# ensure OVH App Key an App Secret are defined +hasOvhAppKey() +{ + if [ -z "$OVH_APP_KEY" ] && [ -z "$OVH_APP_SECRET" ] + then + echo -e "No application is defined for target $TARGET, please call to initialize it:\n${HELP_CMD} --initApp" + return 1 + fi + return 0 +} + main() { + + if [ ! -d "${PROFILES_PATH}" ] + then + mkdir "${PROFILES_PATH}" + fi + parseArguments "$@" - + initApplication initConsumerKey - - if [ -z $OVH_APP_KEY ] && [ -z $OVH_APP_SECRET ] + + if hasOvhAppKey then - echo -e "No application is defined for target $TARGET, please call to initialize it:\n$0 --initApp" - elif [ -z $OVH_CONSUMER_KEY ] - then - echo -e "No consumer key for target $TARGET, please call to initialize it:\n$0 --init" - else + if [ -z "$OVH_CONSUMER_KEY" ]; then + echo -e "No consumer key for target $TARGET, please call to initialize it:\n${HELP_CMD} --init" + else request $METHOD $URL + fi fi } main "$@" - From 485cbd833ef5643f97f8217f712f347436023580 Mon Sep 17 00:00:00 2001 From: Didier BONNEFOI Date: Mon, 19 Jun 2017 18:36:33 +0200 Subject: [PATCH 2/4] if --profile is set to 'default', load configuration from script directory --- README.md | 18 ++++++++------- ovh-api-bash-client.sh | 52 +++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index ce39407..bb9afd0 100644 --- a/README.md +++ b/README.md @@ -37,14 +37,16 @@ Options Possible arguments are: ``` - --url : the API URL to call, for example /domains (default is /me) - --method : the HTTP method to use, for example POST (default is GET) - --data : the data body to send with the request - --target : the target API (default is EU) - --init : to initialize the consumer key - --initApp : to initialize the API application - --profile : load a configuration from profile/ directory, (override default location) - --list-profile : list available profiles in profile/ directory + --url : the API URL to call, for example /domains (default is /me) + --method : the HTTP method to use, for example POST (default is GET) + --data : the data body to send with the request + --target : the target API (default is EU) + --init : to initialize the consumer key + --initApp : to initialize the API application + --list-profile : list available profiles in profile/ directory + --profile + * default : from script directory + * : from profile/ directory ``` Usage diff --git a/ovh-api-bash-client.sh b/ovh-api-bash-client.sh index 5139f32..c1f351d 100755 --- a/ovh-api-bash-client.sh +++ b/ovh-api-bash-client.sh @@ -20,8 +20,6 @@ API_CREATE_APP_URLS[CA]="https://ca.api.ovh.com/createApp/" API_CREATE_APP_URLS[EU]="https://api.ovh.com/createApp/" BASE_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -CURRENT_PATH="${BASE_PATH}" -#PROFILES_PATH PROFILES_PATH="${BASE_PATH}/profile" HELP_CMD="$0" @@ -143,14 +141,16 @@ help() { echo echo "Help: possible arguments are:" - echo " --url : the API URL to call, for example /domains (default is /me)" - echo " --method : the HTTP method to use, for example POST (default is GET)" - echo " --data : the data body to send with the request" - echo " --target <$( echo ${TARGETS[@]} | sed 's/\s/|/g' )> : the target API (default is EU)" - echo " --init : to initialize the consumer key" - echo " --initApp : to initialize the API application" - echo " --profile : load a configuration from profile/ directory, (override default location)" - echo " --list-profile : list available profiles in profile/ directory" + echo " --url : the API URL to call, for example /domains (default is /me)" + echo " --method : the HTTP method to use, for example POST (default is GET)" + echo " --data : the data body to send with the request" + echo " --target <$( echo ${TARGETS[@]} | sed 's/\s/|/g' )> : the target API (default is EU)" + echo " --init : to initialize the consumer key" + echo " --initApp : to initialize the API application" + echo " --list-profile : list available profiles in profile/ directory" + echo " --profile " + echo " * default : from script directory" + echo " * : from profile/ directory" echo } @@ -187,10 +187,9 @@ parseArguments() ;; --profile) shift - initProfile "$1" + PROFILE=$1 ;; --list-profile) - shift listProfile exit 0 ;; @@ -233,30 +232,40 @@ getJSONFieldString() echo ${RESULT:1:${#RESULT}-2} } -# override CURRENT_PATH with profile name +# set CURRENT_PATH with profile name # usage : initProfile profile_name initProfile() { local profile=$1 - if [ -n "${profile}" ]; then + if [ ! -d "${PROFILES_PATH}" ] + then + mkdir "${PROFILES_PATH}" || exit 1 + fi + + # if profile is not set, or with value 'default' + if [[ -z "${profile}" ]] || [[ "${profile}" == "default" ]] + then + # configuration stored in the script path + CURRENT_PATH="${BASE_PATH}" + else + # ensure profile directory exists if [ ! -d "${PROFILES_PATH}/${profile}" ] then echo "${PROFILES_PATH}/${profile} should exists" + listProfile exit 1 fi # override default configuration location CURRENT_PATH="$( cd "${PROFILES_PATH}/${profile}" && pwd )" HELP_CMD="${HELP_CMD} --profile ${profile}" - else - echo "profile not set, choose in : " - listProfile - exit 1 fi + } listProfile() { + echo "Available profiles : " cd ${PROFILES_PATH} && ls -1 } @@ -274,13 +283,10 @@ hasOvhAppKey() main() { - if [ ! -d "${PROFILES_PATH}" ] - then - mkdir "${PROFILES_PATH}" - fi - parseArguments "$@" + initProfile ${PROFILE} + initApplication initConsumerKey From 143ad5114bfebdff219bcdaf1440a5835cf6bb81 Mon Sep 17 00:00:00 2001 From: Didier BONNEFOI Date: Wed, 21 Jun 2017 00:21:47 +0200 Subject: [PATCH 3/4] Allow to set --profile option at any position : - functions to create keys now launched out of parseArguments() bugfix : - fix empty CURRENT_PATH when launching --init/--initApp enhancements : - better output for --list-profile output + add 'default' profile refactoring : - move initApplication() into createConsumerKey() instead of calling it each time --- ovh-api-bash-client.sh | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/ovh-api-bash-client.sh b/ovh-api-bash-client.sh index c1f351d..20990b3 100755 --- a/ovh-api-bash-client.sh +++ b/ovh-api-bash-client.sh @@ -31,7 +31,7 @@ TARGET="EU" TIME="" SIGDATA="" POST_DATA="" - +PROFILE="" isTargetValid() { @@ -82,7 +82,6 @@ createApp() read NEXT if [ -n "$NEXT" ] && [ $( echo $NEXT | tr [:upper:] [:lower:] ) = y ] then - initApplication createConsumerKey else echo -e "OK, no consumer key created for now.\nYou will be able to initalize the consumer key later calling :\n${HELP_CMD} --init" @@ -91,10 +90,12 @@ createApp() createConsumerKey() { + METHOD="POST" URL="/auth/credential" # ensure an OVH App key is set + initApplication hasOvhAppKey || exit 1 # all grants if no post data defined @@ -156,6 +157,9 @@ help() parseArguments() { + # an action launched out of this function + INIT_KEY_ACTION= + while [ $# -gt 0 ] do case $1 in @@ -164,13 +168,10 @@ parseArguments() POST_DATA=$1 ;; --init) - initApplication - createConsumerKey - exit 0 + INIT_KEY_ACTION="ConsumerKey" ;; --initApp) - createApp - exit 0 + INIT_KEY_ACTION="AppKey" ;; --method) shift @@ -265,8 +266,18 @@ initProfile() listProfile() { + local dir= echo "Available profiles : " - cd ${PROFILES_PATH} && ls -1 + echo "- default" + if [ -d "${PROFILES_PATH}" ] + then + # only list directory + for dir in $(cd ${PROFILES_PATH}; echo */); + do + # display directory name without slash + echo "- ${dir%%/}" + done + fi } # ensure OVH App Key an App Secret are defined @@ -285,8 +296,17 @@ main() parseArguments "$@" + # set profile location initProfile ${PROFILE} + # user want to add An API Key + case ${INIT_KEY_ACTION} in + AppKey) createApp;; + ConsumerKey) createConsumerKey;; + esac + ## exit after initializing any API Keys + [ -n "${INIT_KEY_ACTION}" ] && exit 0 + initApplication initConsumerKey From 71c1d5fe6f031bf93091489074800d4d83fc2ee6 Mon Sep 17 00:00:00 2001 From: Didier BONNEFOI Date: Wed, 21 Jun 2017 14:31:13 +0200 Subject: [PATCH 4/4] profiles management enhancements - when launching --init/--initApp, create the defined profile if missing - fix profiles listing (bad directory) - help command : always add --profile argument if profile name is defined --- README.md | 6 ++---- ovh-api-bash-client.sh | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index bb9afd0..5c87b24 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -ovh API Bash client + orovh API Bash client ================ A bash client for OVH API (https://api.ovh.com/) @@ -69,10 +69,8 @@ To activate the monitoring on your dedicated server, run: ./ovh-api-bash-client.sh --method PUT --url "/dedicated/server/ns00000.ovh.net" --data '{"monitoring": true}' ``` -create a Consumer key for different account or usage +To create a Consumer key for different account or usage (profile is created if missing) ``` - mkdir profile/demo1 - mkdir profile/demo2 ./ovh-api-bash-client.sh --profile demo1 --init ./ovh-api-bash-client.sh --profile demo2 --init ``` diff --git a/ovh-api-bash-client.sh b/ovh-api-bash-client.sh index 20990b3..85c0a3d 100755 --- a/ovh-api-bash-client.sh +++ b/ovh-api-bash-client.sh @@ -234,10 +234,13 @@ getJSONFieldString() } # set CURRENT_PATH with profile name -# usage : initProfile profile_name +# usage : initProfile |set|get] profile_name +# set : create the profile if missing +# get : raise an error if no profile with that name initProfile() { - local profile=$1 + local createProfile=$1 + local profile=$2 if [ ! -d "${PROFILES_PATH}" ] then @@ -253,12 +256,23 @@ initProfile() # ensure profile directory exists if [ ! -d "${PROFILES_PATH}/${profile}" ] then - echo "${PROFILES_PATH}/${profile} should exists" - listProfile - exit 1 + case ${createProfile} in + get) + echo "${PROFILES_PATH}/${profile} should exists" + listProfile + exit 1 + ;; + set) + mkdir "${PROFILES_PATH}/${profile}" || exit 1 + ;; + esac fi # override default configuration location CURRENT_PATH="$( cd "${PROFILES_PATH}/${profile}" && pwd )" + fi + + if [ -n "${profile}" ] + then HELP_CMD="${HELP_CMD} --profile ${profile}" fi @@ -269,10 +283,11 @@ listProfile() local dir= echo "Available profiles : " echo "- default" + if [ -d "${PROFILES_PATH}" ] then - # only list directory - for dir in $(cd ${PROFILES_PATH}; echo */); + # only list directory + for dir in $(cd ${PROFILES_PATH} && ls -d */ 2>/dev/null) do # display directory name without slash echo "- ${dir%%/}" @@ -296,8 +311,13 @@ main() parseArguments "$@" - # set profile location - initProfile ${PROFILE} + local profileAction="get" + + if [ -n "${INIT_KEY_ACTION}" ]; then + profileAction="set" + fi + + initProfile ${profileAction} ${PROFILE} # user want to add An API Key case ${INIT_KEY_ACTION} in