Merge pull request #5 from bonidier/ovhapi_lib

Ovhapi lib
pull/7/head
Antoine Leveugle 2017-09-19 08:35:40 +02:00 committed by GitHub
commit e4f968c78a
9 changed files with 603 additions and 1 deletions

2
.gitignore vendored
View File

@ -2,4 +2,4 @@
.ovhConsumerKey*
libs/
profile/
contrib/test/*.json

View File

@ -74,3 +74,8 @@ To create a Consumer key for different account or usage (profile is created if m
./ovh-api-bash-client.sh --profile demo1 --init
./ovh-api-bash-client.sh --profile demo2 --init
```
Embedded lib for external scripts
---------------------------------
See **contrib/** directory

104
contrib/README.md Normal file
View File

@ -0,0 +1,104 @@
## Embedded libs for external scripts
### jsonsh-lib.sh
#### Introduction
Wrapper for JSON.sh, enhancing output :
- action on keys : transform original key (JSON array) to a friendly format
- action on values : trim double quotes and spaces
**original JSON content**
```
{
"person": {
"name": "Foobar1",
"foo1": { "bar": "baz1" },
"child": [ {"name":"bob1_1"}, {"name":"bob1_2"} ]
},
"person": {
"name": "Foobar2",
"foo1": { "bar": "baz2" },
"child": [ {"name":"bob2_2"}, {"name":"bob2_2"} ]
}
}
```
**JSON.sh output**
```
["person","name"] "Foobar1"
["person","foo1","bar"] "baz1"
["person","child",0,"name"] "bob1_1"
["person","child",1,"name"] "bob1_2"
["person","name"] "Foobar2"
["person","foo1","bar"] "baz2"
["person","child",0,"name"] "bob2_2"
["person","child",1,"name"] "bob2_2"
```
**wrapper output**
```
person.name Foobar1
person.foo1.bar baz1
person.child[0].name bob1_1
person.child[1].name bob1_2
person.name Foobar2
person.foo1.bar baz2
person.child[0].name bob2_2
person.child[1].name bob2_2
```
#### Functions
- loadJSON() : forward JSON content to JSON.sh script if JSON is set, otherwise print JSON.sh output)
- getJSONKeys() : print JSON keys
- getJSONValue() : print JSON key's value
- getJSONValues() : print full result (json key and value)
JSON.sh is called only one time
From your script or commandline, you can set :
- JSONSH_DIR if JSON.sh is not installed on your system path (should be set before including the lib)
- JSONSH_SEPARATOR if you want a custom separator between JSON key and value (default is ":")
- JSONSHLIB_DEBUG to 1 to enable lib debugging
#### Samples
See **test/** directory :
```
JSONSHLIB_DEBUG=1 ./test/jsonshlib_test.sh
```
### ovh-api-lib.sh
- OvhRequestApi() is wrapper for ovh-api-bash-client.sh
- use jsonsh-lib.sh ( just using loadJSON() )
**usage**
```
OvhRequestApi url [method] [post_data]
```
From your script or commandline, you can set :
- OVHAPI_BASHCLIENT_PROFILE
- OVHAPI_TARGET
- OVHAPILIB_DEBUG to 1 to enable lib debugging
This function set variables OVHAPI_HTTP_STATUS and OVHAPI_HTTP_RESPONSE
OVHAPI_HTTP_RESPONSE is forwarded to loadJSON() to avoid user to put this line each time.
#### Samples
Once you've a valid OVH API authentication, you can use the library
You can find some samples scripts in the **samples/** directory
**sample usage**
```
OVHAPI_BASHCLIENT_PROFILE=demo samples/list-domains.sh
```
See **samples/** directory for more details

209
contrib/jsonsh-lib.sh Normal file
View File

@ -0,0 +1,209 @@
#!/usr/bin/env bash
#
# Lib for parsing https://github.com/dominictarr/JSON.sh output
#
JSONSH_CACHE=
JSONSH_SOURCE_MD5=
JSONSH_SEPARATOR=
JSONSHLIB_DEBUG=${JSONSHLIB_DEBUG:-0}
### detect JSON.sh location
# JSON.sh searched in system path
readonly JSONSH_SYSTEM_DIR=$(dirname "$(which JSON.sh 2>/dev/null)" )
# can be overrided
JSONSH_DIR=${JSONSH_DIR:-"${JSONSH_SYSTEM_DIR}"}
if [ -z "${JSONSH_DIR}" ]; then
echo "JSONSH_DIR should be set" >&2
exit 1
else
# to get absolte path
JSONSH_DIR=$(cd "${JSONSH_DIR}" && pwd)
if [ ! -f "${JSONSH_DIR}/JSON.sh" ]; then
echo "${JSONSH_DIR}/JSON.sh not found" >&2
exit 1
fi
fi
readonly JSONSH_DIR
# debug output if wanted
_jsonshlib_echo_debug()
{
if [ "${JSONSHLIB_DEBUG}" == "1" ]; then
echo "[debug:${FUNCNAME[1]}] $*" >&2
fi
}
#
# single entry point with JSON.sh
# load json defined as argument, and set result to JSONSH_CACHE
#
# keep result in cache to avoid useless calls to JSON.sh
#
# usage :
# to set source json : loadJSON "json content"
# to get JSON.sh output, don't set argument
#
loadJSON()
{
local json_source="$1"
local current_md5=
if [ -z "${json_source}" ]; then
if [ -z "${JSONSH_CACHE}" ]; then
echo "JSON content is empty" >&2
exit 1
fi
_jsonshlib_echo_debug "get JSON.sh result from cache"
echo "${JSONSH_CACHE}"
else
# only follow to JSON.sh if JSon content differs
current_md5=$(echo "${json_source}" | md5sum | cut -d ' ' -f1)
if [ "${JSONSH_SOURCE_MD5}" != "${current_md5}" ]; then
_jsonshlib_echo_debug "new JSON source, build JSON.sh cache"
JSONSH_SOURCE_MD5=${current_md5}
JSONSH_CACHE=$("${JSONSH_DIR}/JSON.sh" -l <<< "${json_source}")
fi
fi
return 0
}
#
# convert JSON.sh key output format (JSON array) and trim value, through pipe
#
# sample :
# json.sh output : ["foo","bar",0,"baz"] " json value "
# new output : foo.bar[0].baz json value
#
# for each value, outside double quotes and spaces are removed
#
# _JSonSH_rewrite_output getKeys : print only keys
# _JSonSH_rewrite_output getValue <field> : print only value for the field
# _JSonSH_rewrite_output getFull : print pair of key/value
#
# separator between key and value can be overrided if JSONSH_SEPARATOR is set (default = ":")
#
_JSonSH_rewrite_output()
{
local action=$1
local wanted_key=$2
if [[ "${action}" == "getValue" ]] && [[ -z "${wanted_key}" ]]; then
echo "key is required" >&2
exit 1
fi
JSONSH_SEPARATOR=${JSONSH_SEPARATOR:-":"}
awk -F '\t' \
-v action="${action}" \
-v wanted_key="${wanted_key}" \
-v separator="${JSONSH_SEPARATOR}" \
'{
json_key = $1
# drop the key from the line
$1 = ""
json_value=$0
## Actions on json key :
# 1) remove some chars : brackets and double quotes
gsub(/\[|\]|\"/,"",json_key)
# 2) detect array index between comma, put digits between brackets
json_key = gensub(/(,([[:digit:]]+)(,|))/,"[\\2]\\3","g",json_key)
# 3) replace each comma with dot
gsub(/,/,".",json_key)
## Actions on json value :
# remove first/last double quotes if present
json_value = gensub(/"(.*)"$/,"\\1","g",json_value)
# trim first/last spaces of value
gsub(/^\s+|\s+$/,"",json_value)
switch (action) {
case "getKeys":
print json_key
break
case "getValue":
# remove first/last double quotes if present
wanted_key = gensub(/"(.*)"$/,"\\1","g",wanted_key)
# the value for a key is wanted
if (json_key == wanted_key)
{
# display value if found and stop
print json_value
exit 0
}
break
case "getFull":
if (json_key ~ /^[0-9]+$/ )
{
# the key is a number, only value is needed
print json_value
} else {
# the key is a string, display key and value
print json_key separator json_value
}
break
default:
print "Bad action !" >"/dev/stderr"
exit 1
break
}
}' </dev/stdin
}
#
# print JSON keys
#
# usage : getJSONKeys
#
getJSONKeys()
{
local json=
json=$(loadJSON) || exit 1
echo "${json}" | _JSonSH_rewrite_output getKeys
return $?
}
#
# print the value for a defined field
#
# usage : getJSONValue field
#
getJSONValue()
{
local field="$1"
local json=
_jsonshlib_echo_debug "key : ${field}"
json=$(loadJSON) || exit 1
echo "${json}" | _JSonSH_rewrite_output getValue "${field}"
return $?
}
#
# usage : getJSONValues
#
# print full result (json key and value)
#
getJSONValues()
{
local json=
json=$(loadJSON) || exit 1
echo "${json}" | _JSonSH_rewrite_output getFull
return $?
}
_jsonshlib_echo_debug "JSONSH_DIR=$JSONSH_DIR"

96
contrib/ovh-api-lib.sh Normal file
View File

@ -0,0 +1,96 @@
#!/usr/bin/env bash
readonly OVHAPI_BASHCLIENT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}")/.." && pwd)
readonly OVHAPI_BASHCLIENT_BIN="${OVHAPI_BASHCLIENT_DIR}/ovh-api-bash-client.sh"
readonly OVHAPI_BASHCLIENT_CONTRIB_DIR="${OVHAPI_BASHCLIENT_DIR}/contrib"
JSONSH_DIR="${OVHAPI_BASHCLIENT_DIR}/libs/"
. "${OVHAPI_BASHCLIENT_CONTRIB_DIR}/jsonsh-lib.sh" || exit 1
OVHAPI_HTTP_STATUS=
OVHAPI_HTTP_RESPONSE=
# debug output: should be setted to 1 from external script
OVHAPILIB_DEBUG=${OVHAPILIB_DEBUG:-0}
# use ovh-api-bash-client default target if not set
OVHAPI_TARGET=${OVHAPI_TARGET:-}
# ensure the client is available
if [ ! -f "${OVHAPI_BASHCLIENT_BIN}" ]; then
echo "${OVHAPI_BASHCLIENT_BIN} not found"
exit 1
fi
# debug output if wanted
_ovhapilib_echo_debug()
{
if [ "${OVHAPILIB_DEBUG}" == "1" ]; then
echo "[debug:${FUNCNAME[1]}] $*" >&2
fi
}
# to override profile, define value in the variable OVHAPI_BASHCLIENT_PROFILE
# to override target, define value in the variable OVHAPI_TARGET
# OvhRequestApi url [method] [post_data]
#
# default method: get
# return response code in OVHAPI_HTTP_STATUS and content in OVHAPI_HTTP_RESPONSE
OvhRequestApi()
{
local url=$1
local method=$2
local data=$3
local client_response=
local cmd_profile=
local cmd=(${OVHAPI_BASHCLIENT_BIN})
## construct arguments array
if [ -n "${OVHAPI_BASHCLIENT_PROFILE}" ]; then
cmd+=(--profile ${OVHAPI_BASHCLIENT_PROFILE})
fi
cmd_profile=${cmd[*]}
if [ -n "${url}" ]; then
cmd+=(--url ${url})
fi
if [ -n "${method}" ]; then
cmd+=(--method ${method})
fi
if [ -n "${OVHAPI_TARGET}" ]; then
cmd+=(--target ${OVHAPI_TARGET})
fi
if [ "${method}" == "POST" ]; then
# double-quote data content for bash input
data=$(printf "%q" "${data}")
cmd+=(--data ${data})
fi
_ovhapilib_echo_debug "command: ${cmd[*]}"
# best way found to correctly pass quoted arguments to a command called from a function
client_response=$(echo "${cmd[*]}" | bash)
OVHAPI_HTTP_STATUS=$(echo "${client_response}" | cut -d ' ' -f1)
OVHAPI_HTTP_RESPONSE="$(echo "${client_response}" | cut -d ' ' -f2-)"
# catch profile error
if [[ ! ${OVHAPI_HTTP_STATUS} =~ ^[0-9]+$ ]] && [[ ${OVHAPI_HTTP_RESPONSE} == *$'\n'* ]]; then
OVHAPI_HTTP_STATUS=500
OVHAPI_HTTP_RESPONSE=$(cat <<EOF
["more than one line returned, check your profile : ${cmd_profile}"]
EOF
)
fi
_ovhapilib_echo_debug "http_status=${OVHAPI_HTTP_STATUS}"
# forward result to JSON.sh to be usable with JSONSH functions
# (avoid user to put this line each time)
loadJSON "${OVHAPI_HTTP_RESPONSE}"
}

34
contrib/samples/list-domains.sh Executable file
View File

@ -0,0 +1,34 @@
#!/usr/bin/env bash
HERE=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
source ${HERE}/../ovh-api-lib.sh || exit 1
OvhRequestApi /me
if [ ${OVHAPI_HTTP_STATUS} -ne 200 ]; then
echo "profile error:"
getJSONValues
exit
fi
OvhRequestApi "/domain"
if [ "${OVHAPI_HTTP_STATUS}" -eq 200 ]; then
domains=($(getJSONValues))
echo "number of domains=${#domains[@]}"
# for example, only list for first domain
#for domain in "${domains[@]}"
for domain in "${domains[0]}"
do
echo -e "\n== informations about ${domain} =="
OvhRequestApi "/domain/${domain}"
echo "-- single value --"
# key can be passed with/without double quote
getJSONValue lastUpdate
getJSONValue '"transferLockStatus"'
echo "-- get all values --"
getJSONValues
done
else
getJSONValues
fi

View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
HERE=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
source ${HERE}/../ovh-api-lib.sh || exit 1
OvhRequestApi /me
if [ ${OVHAPI_HTTP_STATUS} -ne 200 ]; then
echo "profile error:"
getJSONValues
exit
fi
echo "-- all fields --"
getJSONValues
echo "-- only some fields --"
getJSONValue "email"
getJSONValue "currency.code"
getJSONValue "currency.symbol"

View File

@ -0,0 +1,42 @@
#!/usr/bin/env bash
HERE=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
source ${HERE}/../ovh-api-lib.sh || exit 1
OvhRequestApi /me
if [ ${OVHAPI_HTTP_STATUS} -ne 200 ]; then
echo "profile error:"
getJSONValues
exit
fi
if [ -z "${OVH_DOMAIN}" ]; then
echo -e "please set one of your domains with :\nOVH_DOMAIN=your_domain.tld"
echo -e "choose in :\n"
OvhRequestApi "/domain"
getJSONValues
exit 1
fi
txt_field="ovhapilib"
txt_value="test1: text with space and quo't'es"
# avoid backslashes :-) :
CUSTOMDATA=$(cat <<EOF
{"fieldType":"TXT","subDomain":"${txt_field}","target":"${txt_value}","ttl":0}
EOF
)
OvhRequestApi "/domain/zone/${OVH_DOMAIN}/record/" POST "${CUSTOMDATA}"
echo ${OVHAPI_HTTP_STATUS}
getJSONValues
txt_value="test2: text with space and quo't'es"
CUSTOMDATA="{\"fieldType\":\"TXT\",\"subDomain\":\"${txt_field}\",\"target\":\"${txt_value}\",\"ttl\":0}"
OvhRequestApi "/domain/zone/${OVH_DOMAIN}/record/" POST "${CUSTOMDATA}"
echo ${OVHAPI_HTTP_STATUS}
getJSONValues

94
contrib/test/jsonshlib_test.sh Executable file
View File

@ -0,0 +1,94 @@
#!/usr/bin/env bash
HERE=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
JSONSH_DIR=${HERE}/../../libs/
source ${HERE}/../../contrib/jsonsh-lib.sh || exit 1
# optional output separator
JSONSH_SEPARATOR="\t:\t"
_pause()
{
echo -e "\n== $1 ==\n"
read -p "-- Press ENTER --"
}
_pause "demo file"
JSON=$(cat <<EOF
{
"person": {
"name": "Foobar1",
"foo1": { "bar": "baz1" },
"child": [ {"name":"bob1_1"}, {"name":"bob1_2"} ]
},
"person": {
"name": "Foobar2",
"foo1": { "bar": "baz2" },
"child": [ {"name":"bob2_2"}, {"name":"bob2_2"} ]
}
}
EOF
)
loadJSON "$JSON"
echo "-- JSON.sh output --"
loadJSON
echo "-- wrapper output --"
getJSONValues
##### testing JSON.sh package.json #####
_pause "simple test with official JSON.sh package.json file"
if [ ! -f "${HERE}/package.json" ]; then
curl -L -o "${HERE}/package.json" https://github.com/dominictarr/JSON.sh/raw/master/package.json
fi
JSON=$(<${HERE}/package.json)
loadJSON "${JSON}"
_pause "Get only keys"
getJSONKeys
_pause "Get a value"
getJSONValue repository.url
getJSONValue "author"
_pause "Get all items"
getJSONValues
_pause "== simple test with a JSON array"
JSON='["foo","bar"]'
loadJSON "${JSON}"
_pause "Get only keys"
getJSONKeys
_pause "Get value for an id (array index)"
getJSONValue 1
_pause "Get all items"
getJSONValues
##### performance test with bigger JSON file :-) #####
echo "== test with a bigger JSON =="
if [ ! -f "${HERE}/earthporn.json" ]; then
# if you have the "Too Many Requests" message, download from your browser
curl -o "${HERE}/earthporn.json" https://www.reddit.com/r/earthporn.json
fi
JSON=$(<${HERE}/earthporn.json)
time loadJSON "${JSON}"
_pause "Get only keys"
time getJSONKeys
_pause "Get some values"
time getJSONValue "data.children[10].data.ups"
time getJSONValue "data.after"
time getJSONValue "data.children[19].data.preview.images[0].resolutions[3].url"
_pause "Get all values"
time getJSONValues