#!/bin/bash

#
# Copyright 2015-present Open Networking Foundation
#
# 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.
#

# -----------------------------------------------------------------------------
# Tool to collect cluster-wide diagnostics into a single tar stream.
# -----------------------------------------------------------------------------
function usage() {
    echo "usage: $(basename $0) [-x] [-n name] [-P port] [-u user] [-p password] [ip1 ip2...]"
    echo ""
    echo "Environment Variables:"
    echo "    ONOS_INSTANCES    IPs or hostnames of ONOS cluster machines"
    echo "    ONOS_WEB_USER     username for REST API"
    echo "    ONOS_WEB_PASS     password for REST API"
    echo ""
    echo "Example Usages:"
    echo "    # Collect compressed diagnostics for the cluster."
    echo "    # REST API user and password are drawn from environment variables."
    echo "    # Collection archive will be named /tmp/onos-diags.tar.gz"
    echo "    # The cluster node IPs will be drawn from ONOS_INSTANCES variable."
    echo "    > $(basename $0) "
    echo ""
    echo "    # Collect diagnostics for the cluster and leave them extracted. "
    echo "    # Collection directory will be named /tmp/prague-diags/"
    echo "    # Collection archive will be named /tmp/prague-diags.tar.gz."
    echo "    # REST API user name is 'onos' and password is 'rules'."
    echo "    # The cluster node IPs will be drawn from ONOS_INSTANCES variable."
    echo "    > $(basename $0) -x -n prague -u onos -p rules"
    echo ""
    echo "    # Collect compressed diagnostics for a cluster."
    echo "    # REST API user name is 'onos' and password is 'rules'."
    echo "    # Collection archive will be named /tmp/onos-diags.tar.gz"
    echo "    # The cluster node IPs are listed explicitly."
    echo "    > $(basename $0) -u onos -p rules 172.17.0.11 172.17.0.12 172.17.0.13"

    exit 1
}

ONOS_WEB_USER=${ONOS_WEB_USER:-onos}  # ONOS WEB User defaults to 'onos'
ONOS_WEB_PASS=${ONOS_WEB_PASS:-rocks} # ONOS WEB Password defaults to 'rocks'
ONOS_WEB_PORT=${ONOS_WEB_PORT:-8181}  # REST API port defaults to '8181'

. $(dirname $0)/_find-node

# TODO We should make SR commands optional
CLI_COMMANDS=(
    "feature:repo-list"
    "feature:list"
    "bundle:list"
    "scr-list"

    "summary"
    "nodes"
    "apps -s"
    "netcfg"
    "cfg get"

    "devices"
    "links"
    "hosts"
    "interfaces"

    "ports -e"
    "portstats -nz"

    "packet-processors"
    "packet-requests"

    "intents"
    "flows -s"
    "groups"

    "roles"
    "masters"

    "maps"

    "fpm-connections"
    "routes"
    "obj-next-ids"
    "obj-pending-nexts"
    "obj-queues"

    "sr-device-subnets"
    "sr-ecmp-spg"
    "sr-should-program"
    "sr-link-state"
    "sr-mcast-tree"
    "sr-mcast-leader"
    "sr-mcast-role"
    "sr-pw-list"
    "sr-next-mcast"
    "sr-next-dst"
    "sr-next-port"
    "sr-next-vlan"
    "sr-next-pw"
    "sr-next-xconnect"
    "sr-next-mac-vlan"
    "dhcp-relay"

    "mcast-host-routes"
    "mcast-host-show"
)

port=${ONOS_WEB_PORT}
user=${ONOS_WEB_USER}
password=${ONOS_WEB_PASS}

# Scan arguments for user/password or other options...
while getopts n:P:u:p:x?h o; do
    case "$o" in
        n) name=$OPTARG;;
        P) port=$OPTARG;;
        u) user=$OPTARG;;
        p) password=$OPTARG;;
        x) extract=true;;
        *) usage;;
    esac
done

let OPC=$OPTIND-1
shift $OPC

[ $# -lt 1 -a -z "$ONOS_INSTANCES" ] && usage;

diags=/tmp/${name:-onos}-diags
rm -fr $diags $diags.tar.gz; mkdir -p $diags

[ -z $1 ] && nodes=$ONOS_INSTANCES || nodes=$*

# Collect diagnostics from each cluster node
for node in $nodes; do
    printf "Collecting diagnostics on $node..."

    # Prepare a clean place for collecting the node diagnostic data
    cd $diags; rm -fr $node; mkdir -p $node; cd $node;

    # Acquire locally obtained diagnostics via REST API and extract them
    printf "logs "
    curl -sS --fail --user $user:$password  \
        http://$node:$port/onos/v1/diagnostics > ../$node.tar.gz
    tar zxf ../$node.tar.gz && rm ../$node.tar.gz

    # Acquire remotely obtained diagnostics via ssh CLI
    for cmd in "${CLI_COMMANDS[@]}"; do
        cmdLog="$(echo $cmd | cut -d\  -f1 | sed 's/:/-/g').txt"
        printf "$cmdLog "
        onos $node $cmd 2>/dev/null >$cmdLog
    done

    printf " Done.\n"
done

# Tar-up diagnostics from all the nodes
cd $diags
tar zcf $diags.tar.gz *
[ -z $extract ] && rm -fr $diags
