| #!/bin/sh |
| # |
| # Copyright (c) 2019 AT&T Intellectual Property. |
| # Copyright (c) 2019 Nokia. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| ############################# |
| # Simple cli for xapp manager |
| # |
| # In addition to standard shell tools, requires packages "curl" and |
| # "yajl-tools" (the second provides json_reformat on Ubuntu; on Red Hat-style |
| # distributions install "yajl" instead). |
| # |
| myname=appmgrcli |
| |
| usage() { |
| cat <<EOF1 |
| usage: $myname [-h host] [-p port] [-v] command params... |
| - command is one of deploy, undeploy, status, subscriptions, health, help |
| - (abbreviations dep, undep, stat, subs, heal allowed) |
| - Parameters of the commands that may have parameters: |
| -- deploy: name of the xapp to deploy |
| -- undeploy: name of the xapp to undeploy |
| -- status: |
| ---- No parameters: Lists information about all deployed xapps |
| ---- xapp name as parameter: Prints information about the given xapp |
| ---- xapp name and instance: Lists information about the given instance only |
| -- subscriptions is followed by sub-command list, add, delete, or modify |
| ---(abbreviations del and mod for delete and modify are allowed): |
| ---- list without parameters lists all subscriptions |
| ---- list with subscription id prints that subscription |
| ---- add URL eventType maxRetry retryTimer |
| ------- URL is the URL to notify |
| ------- eventType one of created,deleted,all |
| ------- maxRetry and retryTimer are positive decimal numbers |
| ---- modify id URL eventType maxRetry retryTimer |
| ------- id is the subscription id (find out with the list command) |
| --------the rest of the parameters are like in add |
| ---- delete id |
| ------- id is the subscription id to delete (find out with the list command) |
| - Default values for host and port can be set in environment |
| - variables APPMGR_HOST and APPMGR_PORT |
| - Option -v sets verbose mode. |
| EOF1 |
| } |
| |
| # Defaults |
| |
| host=localhost |
| port=8080 |
| verbose=0 |
| |
| # Check for environment override |
| if [ "x$APPMGR_HOST" != "x" ]; then |
| host="$APPMGR_HOST" |
| fi |
| if [ "x$APPMGR_PORT" != "x" ]; then |
| port="$APPMGR_PORT" |
| fi |
| |
| # Proper shell option parsing: |
| while getopts "h:p:v" flag |
| do |
| # Curiously, getopts does not guard against an argument-requiring option |
| # eating the next option. It also does not handle the -- convention. |
| # Here is how to fix that. |
| if [ "X$OPTARG" = 'X--' ]; then |
| break # Explicit end of options |
| fi |
| if expr -- "$OPTARG" : '-.*' > /dev/null ; then |
| echo $myname: Option -$flag has no required value, or value begins with -, |
| echo - which is disallowed. |
| usage |
| exit 1 |
| fi |
| case $flag in |
| (h) host="$OPTARG" |
| ;; |
| (p) port="$OPTARG" |
| ;; |
| (v) verbose=1 |
| ;; |
| (*) |
| echo $myname: Bad option letter or required option argument missing. |
| usage |
| exit 1 |
| ;; |
| esac |
| done |
| # Get rid of the option part |
| shift $((OPTIND-1)) |
| |
| if [ $verbose = 1 ]; then |
| echo "host = $host" |
| echo "port = $port" |
| fi |
| |
| # Verify command |
| |
| case $1 in |
| (deploy|dep) |
| cmd=deploy |
| ;; |
| (undeploy|undep) |
| cmd=undeploy |
| ;; |
| (status|stat) |
| cmd=status |
| ;; |
| (subscriptions|subs) |
| cmd=subscriptions |
| ;; |
| (health|heal) |
| cmd=health |
| ;; |
| (help) |
| usage |
| exit 0 |
| ;; |
| (*) |
| if [ "x$1" = "x" ]; then |
| echo "$myname: Missing command" |
| else |
| echo "$myname: Unrecognized command $1" |
| fi |
| usage |
| exit 1 |
| ;; |
| esac |
| |
| if [ $verbose = 1 ]; then |
| echo "Command $cmd params=$2" |
| fi |
| |
| errfile=`mktemp /tmp/appmgr_e.XXXXXXXXXX` |
| resultfile=`mktemp /tmp/appmgr_r.XXXXXXXXXX` |
| # Variable status used for the return value of the whole script. |
| status=0 |
| |
| # Helper for command execution: |
| # Do a rest call with "curl": $1 = method, $2 = path (without host and port |
| # which come from variables), $3 data to POST if needed |
| # returns 0 if OK, and any returned data is in $resultfile |
| # else 1, and error message from curl is in $errfile, which is printed |
| # before returning the 1. |
| # Also sets $status to the return value. |
| # |
| # On curl options: --silent --show-error disables progress bar, but allows |
| # error messages. --connect-timeout 20 limits waiting for connection to |
| # 20 seconds. In practice connection will succeed almost immediately, |
| # or in the case of wrong address not at all. |
| # |
| rest() { |
| local data |
| if [ "x$3" != "x" ]; then |
| data="--data $3" |
| fi |
| if curl --silent --show-error --connect-timeout 20 --header "Content-Type: application/json" -X $1 -o $resultfile "http://${host}:${port}$2" $data 2> $errfile ;then |
| status=0 |
| else |
| cat $errfile |
| status=1 |
| fi |
| return $status |
| } |
| |
| remove_temps () { |
| rm -f $errfile $resultfile |
| } |
| |
| # Execute command ($cmd guaranteed to be valid) |
| # Assumes the API currently implemented. |
| # Functions for each command below (except health which is so simple). |
| |
| base=/ric/v1 |
| base_xapps=$base/xapps |
| base_health=$base/health |
| base_subs=$base/subscriptions |
| |
| do_deploy() { |
| if [ "x$1" != "x" ]; then |
| if rest POST $base_xapps \{\"name\":\"$1\"\} ; then |
| json_reformat < $resultfile |
| fi |
| else |
| echo Error: expected the name of xapp to deploy |
| status=1 |
| fi |
| } |
| |
| do_undeploy() { |
| local urlpath |
| |
| urlpath=$base_xapps |
| if [ "x$1" != "x" ]; then |
| urlpath="$urlpath/$1" |
| if rest DELETE $urlpath; then |
| # Currently xapp_manager returns an empty result if |
| # undeploy is succesfull. Don't reformat file if empty. |
| if [ -s $resultfile ]; then |
| json_reformat < $resultfile |
| else |
| echo "$1 undeployed" |
| fi |
| fi |
| else |
| echo Error: expected the name of xapp to undeploy |
| status=1 |
| fi |
| } |
| |
| do_status() { |
| local urlpath |
| |
| urlpath=$base_xapps |
| if [ "x$1" != "x" ]; then |
| urlpath="$urlpath/$1" |
| fi |
| if [ "x$2" != "x" ]; then |
| urlpath="$urlpath/instances/$2" |
| fi |
| if rest GET $urlpath; then |
| json_reformat < $resultfile |
| fi |
| } |
| |
| # This is a bit more complex. $1 is sub-command: list, add, delete, modify |
| |
| # Validate the subscription data that follows a subscription add or modify |
| # subcommand. $1=URL, $2=eventType, $3=maxRetries, $4=retryTimer |
| # URL must look like URL, event type must be one of created deleted all, |
| # maxRetries and retryTimer must be non-negative numbers. |
| # If errors, sets variable status=1 and prints errors, else leaves |
| # status unchanged. |
| # |
| validate_subscription() { |
| if ! expr "$1" : "^http://.*" \| "$1" : "^https://.*" >/dev/null; then |
| echo "$myname: bad URL $1" |
| status=1 |
| fi |
| if ! [ "$2" = created -o "$2" = deleted -o "$2" = all ]; then |
| echo "$myname: unrecognized event $2" |
| status=1 |
| fi |
| if ! expr "$3" : "^[0-9][0-9]*$" >/dev/null; then |
| echo "$myname: invalid maximum retries count $3" |
| status=1 |
| fi |
| if ! expr "$4" : "^[0-9][0-9]*$" >/dev/null; then |
| echo "$myname: invalid retry time $4" |
| status=1 |
| fi |
| } |
| |
| do_subscriptions() { |
| local urlpath |
| urlpath=$base_subs |
| case $1 in |
| (list) |
| if [ "x$2" != "x" ]; then |
| urlpath="$urlpath/$2" |
| fi |
| if rest GET $urlpath; then |
| json_reformat < $resultfile |
| else |
| status=1 |
| fi |
| ;; |
| (add) |
| validate_subscription "$2" "$3" "$4" "$5" |
| if [ $status = 0 ]; then |
| if rest POST $urlpath \{\"targetUrl\":\"$2\",\"eventType\":\"$3\",\"maxRetries\":$4,\"retryTimer\":$5\} ; then |
| json_reformat < $resultfile |
| else |
| status=1 |
| fi |
| fi |
| ;; |
| (delete|del) |
| if [ "x$2" != "x" ]; then |
| urlpath="$urlpath/$2" |
| else |
| echo "$myname: Subscription id required" |
| status=1 |
| fi |
| if [ $status = 0 ]; then |
| if rest DELETE $urlpath; then |
| # Currently xapp_manager returns an empty result if |
| # delete is succesfull. Don't reformat file if empty. |
| if [ -s $resultfile ]; then |
| json_reformat < $resultfile |
| else |
| echo "Subscription $2 deleted" |
| fi |
| else |
| status=1 |
| fi |
| fi |
| ;; |
| (modify|mod) |
| if [ "x$2" != "x" ]; then |
| urlpath="$urlpath/$2" |
| else |
| echo "$myname: Subscription id required" |
| status=1 |
| fi |
| if [ $status = 0 ]; then |
| validate_subscription "$3" "$4" "$5" "$6" |
| if [ $status = 0 ]; then |
| if rest PUT $urlpath \{\"targetUrl\":\"$3\",\"eventType\":\"$4\",\"maxRetries\":$5,\"retryTimer\":$6\} ; then |
| json_reformat < $resultfile |
| else |
| status=1 |
| fi |
| fi |
| fi |
| ;; |
| (*) |
| echo "$myname: unrecognized subscriptions subcommand $1" |
| status=1 |
| esac |
| } |
| |
| case $cmd in |
| (deploy) |
| do_deploy "$2" |
| ;; |
| (undeploy) |
| do_undeploy "$2" |
| ;; |
| (status) |
| do_status "$2" "$3" |
| ;; |
| (subscriptions) |
| do_subscriptions "$2" "$3" "$4" "$5" "$6" "$7" |
| ;; |
| (health) |
| if rest GET $base_health ; then |
| echo OK |
| else |
| echo NOT OK |
| fi |
| ;; |
| esac |
| remove_temps |
| exit $status |
| |
| # An Emacs hack to set the indentation style of this file |
| # Local Variables: |
| # sh-indentation:2 |
| # End: |