Getting Resource ID

The following is a script that derives the ID to identify the resource used in the RESTful API URI, request bodies, and response bodies from the volume name, host name, and so on.

get_id.py


import argparse
from getpass import getpass
import re
import sys

from eternus_rest import EtdxBaseApi

# Change the following values for your environment.
# If you execute this file without --url, --user and --password options,
# these are used as default values.
storage_url = "https://192.168.0.2:5665"
storage_user_name = None
storage_password = None


def get_args():
    """Parse the argument of command line."""
    parser = argparse.ArgumentParser(
            description="Get resource ID of restful API.",
            epilog="(e.g.) python3 get_id.py --url https://192.168.0.2:5665 "
                   "--user USER --password PASS --resource volume "
                   "--name .*vol.*")

    parser.add_argument("--url", type=str,
                        help="(optional) Base address of restful API. "
                             "(e.g. https://192.168.0.2:5665)")
    parser.add_argument("--user", type=str, metavar="USERNAME",
                        help="(optional) User name to login restful API.")
    parser.add_argument("--password", type=str,
                        help="(optional) Password to login restful API.")
    parser.add_argument("--resource", type=str, required=True,
                        choices=["volume", "raidgroup", "tpp", "ftrp", "host"],
                        help="Resource name to get ID.")
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--number", type=int, nargs='*',
                       help="(optional) Number of resource to get ID.")
    group.add_argument("--name", type=str, nargs='*',
                       help="(optional) Name of resource to get ID. "
                            "(Regular expression)")
    parser.add_argument("--host_type", type=str,
                        choices=["FC", "iSCSI"],
                        help="(optional) Host type to get host ID. "
                             "If \"host\" is specified for resource, "
                             "host_type must be specified. "
                             "For other resources, host_type is ignored.")

    args = parser.parse_args()
    return(args)


def set_args(args):
    """Set the argument to the global variables."""
    global storage_url
    global storage_user_name
    global storage_password

    if args.url is not None:
        storage_url = args.url
    if args.user is not None:
        storage_user_name = args.user
    if args.password is not None:
        storage_password = args.password


def is_valid_args(args):
    """Validate the argument.

    Args:
        args (object): Argument object parsed by argparse.

    Returns:
        bool: True if valid, False otherwise.
    """
    # If "host" is specified for resource, host_type must be specified.
    # For other resources, set host_type to None.
    if args.resource == "host" and args.host_type is None:
        print("host_type is required to get host ID.")
        return False
    elif args.resource != "host":
        args.host_type = None

    return True


def main():
    global storage_user_name
    global storage_password

    args = get_args()
    set_args(args)
    if not is_valid_args(args):
        return False

    if storage_user_name is None:
        storage_user_name = input('Enter user name: ')
    if storage_password is None:
        storage_password = getpass("Enter password: ")
    storage = EtdxBaseApi(storage_url)

    # Login
    if not storage.login(storage_user_name, storage_password):
        return False

    if args.resource == "host":
        r = storage.get("/api/v1/{0!s}?fields=number,name,type"
                        .format(args.resource))
    else:
        r = storage.get("/api/v1/{0!s}?fields=number,name"
                        .format(args.resource))
    if r.status_code != 200:
        print("Failed to get the resource ({0!s}) information."
              .format(args.resource))
        return False
    data = r.json()

    # Resources are in {resource_name}_list.
    if "{0!s}_list".format(args.resource) in data:
        list = data["{0!s}_list".format(args.resource)]
    else:
        print("Can not get this resource ID ({0!s})."
              .format(args.resource))
        return False

    # Find the resource with the same number or matched regexp name.
    find_list = []
    for i in list:
        # If the specified resource is host, check the type.
        if args.host_type is not None and i["type"] != args.host_type:
            continue

        if args.number is not None:
            for number in args.number:
                if i["number"] == number:
                    find_list.append(i)
                    break
        if args.name is not None:
            for name in args.name:
                if re.fullmatch(name, i["name"]):
                    find_list.append(i)
                    break
    if find_list == []:
        print("Could not find the specified resource.")
        return False

    # Print the find resources.
    for i in find_list:
        if args.resource == "host":
            print("{{ {0!s}_id: {1!s}, type: \"{2!s}\", number: {3!s}"
                  ", name: \"{4!s}\" }}"
                  .format(args.resource,
                          i["{0!s}_id".format(args.resource)],
                          i["type"],
                          i["number"],
                          i["name"]))
        else:
            print("{{ {0!s}_id: {1!s}, number: {2!s}, name: \"{3!s}\" }}"
                  .format(args.resource,
                          i["{0!s}_id".format(args.resource)],
                          i["number"],
                          i["name"]))

    # Logout
    storage.logout()

    return True


if __name__ == '__main__':
    if not main():
        sys.exit(1)