set_node_location.pyΒΆ

#!/usr/bin/env python

# coding: utf-8

#         ______          __
#        / __/ /____ ___ / /
#    ____\ \/ __/ -_) -_) /      __  _
#   / _____/\__/\__/\__/_/_ ____/ /_(_)__  ___
#  / /__/ _ \/ _ \/ _ \/ -_) __/ __/ / _ \/ _ \
#  \___/\___/_//_/_//_/\__/\__/\__/_/\___/_//_/
#
# SteelConnection
# Simplify access to the Riverbed SteelConnect CX REST API.
#
# https://pypi.org/project/steelconnection
# https://github.com/grelleum/SteelConnection


"""Update SteelConnect CX nodes within a specified Org
by copying the site name to the location field
for those nodes where the location is unset.

Works with both Python2 and Python3.

USAGE:
    set_node_location.py REALM.riverbed.cc organization
    set_node_location.py REALM.riverbed.cc organization -u $USER -p $PASSWD
"""


from __future__ import print_function
import argparse
import sys
import steelconnection


def main(argv):
    """Update nodes."""
    args = arguments(argv)

    realm, organization = args.realm, args.organization
    if organization.endswith(".cc") and not realm.endswith(".cc"):
        realm, organization = organization, realm

    sc = steelconnection.SConnect(realm, username=args.username, password=args.password)

    # Find the target organization.
    org = sc.lookup.org(organization)
    print("\nOrg:", organization, "\tID:", org["id"])

    # Get list of all sites in target organization.
    sites = sc.get("org/{}/sites".format(org["id"]))
    print(status("site", sites, "in '{}'".format(organization)))

    # Create a map of site id to site name.
    site_names = {site["id"]: site["name"] for site in sites}

    # Get list of all nodes in target organization.
    nodes = sc.get("org/{}/nodes".format(org["id"]))
    print(status("node", nodes, "in '{}'".format(organization)))

    # Reduce list of nodes to those assigned to a site.
    nodes = [node for node in nodes if node["site"]]
    print(status("node", nodes, "assigned to a site"))

    # Reduce list of nodes to those not already assigned a loction.
    nodes = [node for node in nodes if not node["location"]]
    print(status("node", nodes, "with no specified location"))

    # Update location for the remaining nodes.
    return update_nodes(nodes, sc, organization, org["id"], site_names)


def update_nodes(nodes, sc, organization, org_id, site_names):
    """Loop through nodes and push location to SCM where applicable."""
    for node in nodes:
        print("=" * 75)
        print("Node:", node["id"], node["serial"], node["model"])
        print("org:", node["org"], organization)
        print("site:", node["site"])
        print("location:", node["location"])

        site_id = node["site"]
        site_name = site_names[site_id]
        print("\nSetting location to '{}'".format(site_name))
        node["location"] = site_name
        result = sc.put("node/" + node["id"], data=node)
        print("updated location:", result["location"])
        print("Response:", sc.response.status_code, sc.response.reason, "\n")
        print()


def status(category, values, suffix=""):
    """Return status in human-readable format."""
    size = len(values)
    pluralization = "" if size == 1 else "s"
    return "* Found {} {}{} {}.".format(size, category, pluralization, suffix)


def arguments(argv):
    """Get command line arguments."""
    description = (
        "Update SteelConnect CX nodes within a specified Org "
        "by copying the site name to the location field "
        "for those nodes where the location is unset."
    )
    parser = argparse.ArgumentParser(description=description)
    parser.add_argument(
        "realm", type=str, help="Domain name of SteelConnect CX Manager"
    )
    parser.add_argument("organization", type=str, help="Name of target organization")
    parser.add_argument(
        "-u", "--username", help="Username for SteelConnect CX Manager (optional)"
    )
    parser.add_argument(
        "-p", "--password", help="Password for SteelConnect CX Manager (optional)"
    )
    return parser.parse_args()


if __name__ == "__main__":
    result = main(sys.argv[1:])