import argparse import orm.base_config as base_config import os import requests from . import cli_common from . import config class ResponseError(Exception): pass class ConnectionError(Exception): pass def add_to_parser(service_sub): parser = service_sub.add_parser('rms', help='Resource Management Service', formatter_class=lambda prog: argparse. HelpFormatter(prog, max_help_position=30, width=120)) parser.add_argument('--version', action='version', version='%(prog)s 1.0') parser.add_argument('--auth-region', type=str, help='Region used for authentication', default=get_environment_variable('auth-region')) parser.add_argument('--keystone-auth-url', type=str, help='keystone-auth-url used for authentication', default=get_environment_variable('keystone-auth-url')) parser.add_argument('--tenant-name', type=str, help='Keystone user tenant name', default=get_environment_variable('tenant-name')) parser.add_argument('--username', type=str, help='Keystone user name', default=get_environment_variable('username')) parser.add_argument('--user-domain', type=str, help='Keystone user domain', default=get_environment_variable('user-domain')) parser.add_argument('--password', type=str, help='Keystone user password', default=get_environment_variable('password')) parser.add_argument('--project-domain', type=str, help='Keystone project domain', default=get_environment_variable('project-domain')) parser.add_argument('--rms-base-url', type=str, help='RMS base URL', default=get_environment_variable('rms-base-url')) parser.add_argument('--tracking_id', type=str, help='tracking id') parser.add_argument('--port', type=int, help='port number of RMS server') parser.add_argument('--timeout', type=int, help='request timeout in seconds (default: 10)') parser.add_argument('-v', '--verbose', help='show details', action="store_true") parser.add_argument('-f', '--faceless', help=argparse.SUPPRESS, default=False, action="store_true") subparsers = parser.add_subparsers(dest='subcmd', metavar=' [-h] ') clnt_hdr = '[<"X-RANGER-Client" header>] ' # get group h1 = '' parser_get_group = subparsers.add_parser('get_group', help=h1) parser_get_group.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_get_group.add_argument('group_id', type=str, help=h1) # get all groups parser_list_groups = subparsers.add_parser('list_groups', help="") parser_list_groups.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) # create group h1 = '' parser_create_group = subparsers.add_parser('create_group', help='%s %s' % (clnt_hdr, h1)) parser_create_group.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_create_group.add_argument('datafile', type=argparse.FileType('r'), help='') # update group h1, h2 = '', '' parser_update_group = subparsers.add_parser('update_group', help="%s %s %s" % (clnt_hdr, h1, h2)) parser_update_group.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_update_group.add_argument('group_id', help=h2) parser_update_group.add_argument('datafile', type=argparse.FileType('r'), help='') # delete group h1 = '' parser_delete_group = subparsers.add_parser('delete_group', help='%s %s' % (clnt_hdr, h1)) parser_delete_group.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_delete_group.add_argument('group_id', type=str, help=h1) # get region h1, h2 = '', '[--use_version ]' parser_get_region = subparsers.add_parser('get_region', help='%s %s' % (h1, h2)) parser_get_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_get_region.add_argument('--use_version', type=int, help='') parser_get_region.add_argument('region_name_or_id', type=str, help=h1) # update region h1, h2 = '', '' parser_update_region = subparsers.add_parser('update_region', help='%s %s %s' % (clnt_hdr, h1, h2)) parser_update_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_update_region.add_argument('region_id', type=str, help=h1) parser_update_region.add_argument('datafile', type=argparse.FileType('r'), help='') # create region h1 = '' parser_create_region = subparsers.add_parser('create_region', help='%s %s' % (clnt_hdr, h1)) parser_create_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_create_region.add_argument('datafile', type=argparse.FileType('r'), help='') # delete region h1 = '' parser_delete_region = subparsers.add_parser('delete_region', help='%s %s' % (clnt_hdr, h1)) parser_delete_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_delete_region.add_argument('region_id', type=str, help=h1) # list regions parser_list_region = subparsers.add_parser('list_regions', help='\ [--use_version ] [--type ][--status ]\ [--metadata ] [--ranger_agent_version ]\ [--clli ]\ [--regionname ] [--osversion ]\ [--location_type ]\ [--state ] [--country ] [--city ] [--street ]\ [--zip ] [--clcp_name ]') parser_list_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_list_region.add_argument('--use_version', type=int, help='') parser_list_region.add_argument('--type', type=str, help='') parser_list_region.add_argument('--status', type=str, help='') parser_list_region.add_argument('--metadata', action='append', nargs="+", type=str, help='') parser_list_region.add_argument('--ranger_agent_version', type=str, help='') parser_list_region.add_argument('--clli', type=str, help='') parser_list_region.add_argument('--regionname', type=str, help='') parser_list_region.add_argument('--osversion', type=str, help='') parser_list_region.add_argument('--location_type', type=str, help='') parser_list_region.add_argument('--state', type=str, help='') parser_list_region.add_argument('--country', type=str, help='') parser_list_region.add_argument('--city', type=str, help='') parser_list_region.add_argument('--street', type=str, help='') parser_list_region.add_argument('--zip', type=str, help='') parser_list_region.add_argument('--clcp_name', type=str, help='') # add metadata to region h1, h2 = '', '' parser_add_metadata = subparsers.add_parser('add_metadata', help='%s %s %s' % (clnt_hdr, h1, h2)) parser_add_metadata.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_add_metadata.add_argument('region_id', type=str, help=h1) parser_add_metadata.add_argument('datafile', type=argparse.FileType('r'), help=h2) # update region's metadata h1, h2 = '', '' parser_update_metadata = subparsers.add_parser('update_metadata', help='%s %s %s' % (clnt_hdr, h1, h2)) parser_update_metadata.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_update_metadata.add_argument('region_id', type=str, help=h1) parser_update_metadata.add_argument('datafile', type=argparse.FileType('r'), help=h2) # delete metadata key from region h1, h2 = '', '' parser_delete_metadata = subparsers.add_parser('delete_metadata', help='%s %s %s' % (clnt_hdr, h1, h2)) parser_delete_metadata.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_delete_metadata.add_argument('region_id', type=str, help=h1) parser_delete_metadata.add_argument('metadata_key', type=str, help=h2) # get region's metadata h1 = '' parser_get_metadata = subparsers.add_parser('get_metadata', help='%s' % (h1)) parser_get_metadata.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_get_metadata.add_argument('region_id', type=str, help=h1) # update region's status h1, h2 = '', '' parser_update_status = subparsers.add_parser('update_status', help='%s %s %s' % (clnt_hdr, h1, h2)) parser_update_status.add_argument('client', **cli_common.ORM_CLIENT_KWARGS) parser_update_status.add_argument('region_id', type=str, help=h1) parser_update_status.add_argument('status', type=str, help=h2) def validate_args(args): for argument in ('tenant_name', 'username', 'password', 'auth_region', 'keystone_auth_url'): argument_value = getattr(args, argument, None) if argument_value is not None: globals()[argument] = argument_value else: configuration_value = getattr(config, argument) if configuration_value: globals()[argument] = configuration_value else: message = ('ERROR: {} for token generation was not supplied. ' 'Please use its command-line argument or ' 'environment variable.'.format(argument)) print(message) raise cli_common.MissingArgumentError(message) def preparm(p): return ('' if len(p) else '?') + ('&' if len(p) else '') def cmd_details(args): if args.subcmd == 'get_region': return requests.get, '/%s' % args.region_name_or_id elif args.subcmd == 'create_region': return requests.post, '' elif args.subcmd == 'update_region': return requests.put, '/%s' % args.region_id elif args.subcmd == 'delete_region': return requests.delete, '/%s' % args.region_id elif args.subcmd == 'list_regions': param = '' if args.type: param += '%stype=%s' % (preparm(param), args.type) if args.status: param += '%sstatus=%s' % (preparm(param), args.status) if args.metadata: for meta in args.metadata: param += '%smetadata=%s' % (preparm(param), meta[0]) if args.ranger_agent_version: param += '%sranger_agent_version=%s' % (preparm(param), args.ranger_agent_version) if args.clli: param += '%sclli=%s' % (preparm(param), args.clli) if args.regionname: param += '%sregionname=%s' % (preparm(param), args.regionname) if args.osversion: param += '%sosversion=%s' % (preparm(param), args.osversion) if args.location_type: param += '%slocation_type=%s' % (preparm(param), args.location_type) if args.state: param += '%sstate=%s' % (preparm(param), args.state) if args.country: param += '%scountry=%s' % (preparm(param), args.country) if args.city: param += '%scity=%s' % (preparm(param), args.city) if args.street: param += '%sstreet=%s' % (preparm(param), args.street) if args.zip: param += '%szip=%s' % (preparm(param), args.zip) if args.clcp_name: param += '%svlcp_name=%s' % (preparm(param), args.clcp_name) return requests.get, '/%s' % param elif args.subcmd == 'add_metadata': return requests.post, '/%s/metadata' % args.region_id elif args.subcmd == 'update_metadata': return requests.put, '/%s/metadata' % args.region_id elif args.subcmd == 'delete_metadata': return requests.delete, '/%s/metadata/%s' % (args.region_id, args.metadata_key) elif args.subcmd == 'get_metadata': return requests.get, '/%s/metadata' % args.region_id elif args.subcmd == 'update_status': return requests.put, '/%s/status' % args.region_id elif args.subcmd == 'get_group': return requests.get, '/%s' % args.group_id elif args.subcmd == 'list_groups': return requests.get, '/' elif args.subcmd == 'create_group': return requests.post, '/' elif args.subcmd == 'update_group': return requests.put, '/%s' % args.group_id elif args.subcmd == 'delete_group': return requests.delete, '/%s' % args.group_id def get_path(args): path = 'v2/orm/regions' if 'group' in args.subcmd: path = 'v2/orm/groups' return path def get_environment_variable(argument): # The rules are: all caps, underscores instead of dashes and prefixed environment_variable = 'RANGER_{}'.format( argument.replace('-', '_').upper()) return os.environ.get(environment_variable) def run(args): url_path = get_path(args) rms_base_url = args.rms_base_url if args.rms_base_url \ else base_config.rms['base_url'] data = args.datafile.read() if 'datafile' in args else '{}' timeout = args.timeout if args.timeout else 10 rest_cmd, cmd_url = cmd_details(args) url = '%s/%s' % (rms_base_url, url_path) + cmd_url if args.faceless: auth_key = auth_region = requester = client = '' else: try: validate_args(args) auth_key = cli_common.get_token(timeout, args) except Exception: exit(1) auth_region = globals()['auth_region'] requester = globals()['username'] client = requester if (args.subcmd == 'get_region' or args.subcmd == 'list_regions') \ and "use_version" in args: if args.use_version == 1: url = '%s:%d/lcp' % (host, port) + cmd_url elif args.use_version is not None and args.use_version != 2: print('API error: use_version argument - invalid value, ' 'allowed values: 1 or 2') exit(1) if args.subcmd == "update_status": data = '{"status": "%s"}' % args.status tracking_id = args.tracking_id if args.tracking_id else None headers = { 'content-type': 'application/json', 'X-Auth-Token': auth_key, 'X-Auth-Region': auth_region, 'X-RANGER-Requester': requester, 'X-RANGER-Client': client, 'X-RANGER-Tracking-Id': tracking_id } if args.verbose: print(("Sending API:\ntimeout: %d\ndata: %s\n" "headers: %s\ncmd: %s\nurl: %s\n" % (timeout, data, headers, rest_cmd.__name__, url))) try: resp = rest_cmd(url, data=data, timeout=timeout, headers=headers, verify=config.verify) except Exception as e: print(str(e)) exit(1) if not 200 <= resp.status_code < 300: content = resp.content print('API error: %s %s (Reason: %d)\n%s' % ( rest_cmd.__name__.upper(), url, resp.status_code, content)) exit(1) if resp.status_code == 204: # no content exit(0) rj = resp.json() if rj == 'Not found': print('No output was found') else: cli_common.pretty_print_json(rj)