def do_show(self, args, obj): """Print a whole object, or a specific property following a dotted path. When a dotted path is specified (eg: attrs.opencenter_agent_actions.upgrade_agent.timeout), lookup is done in three ways: 1) Object Attribute: getattr 2) Dictionary key: [] 3) List Key: convert to int, then [] """ id = args.id act = getattr(self.endpoint, obj) if args.property is None: #No property specified, print whole item. print act[id] else: item = act[id] for path_section in args.property.split('.'): # Lookup by object attribute if hasattr(item, path_section): item = getattr(item, path_section) continue else: try: # Lookup by dictionary key item = item[path_section] continue except: try: # Lookup by list index item = item[int(path_section)] continue except: pass # None of the lookup methods succeeded, so property path must # be invalid. raise ValueError( 'Cannot resolve "%s" from property string "%s" for' ' %s %s' % ( path_section, args.property, singularize(obj), act[id].name ) ) # Assume the property is JSON and try to pretty-print. If that # fails, print the item normally try: print json.dumps(item, sort_keys=True, indent=2, separators=(',', ':')) except: print item
def do_show(self, args, obj): """Print a whole object, or a specific property following a dotted path. When a dotted path is specified (eg: attrs.opencenter_agent_actions.upgrade_agent.timeout), lookup is done in three ways: 1) Object Attribute: getattr 2) Dictionary key: [] 3) List Key: convert to int, then [] """ id = args.id act = getattr(self.endpoint, obj) if args.property is None: #No property specified, print whole item. print act[id] else: item = act[id] for path_section in args.property.split('.'): # Lookup by object attribute if hasattr(item, path_section): item = getattr(item, path_section) continue else: try: # Lookup by dictionary key item = item[path_section] continue except: try: # Lookup by list index item = item[int(path_section)] continue except: pass # None of the lookup methods succeeded, so property path must # be invalid. raise ValueError( 'Cannot resolve "%s" from property string "%s" for' ' %s %s' % (path_section, args.property, singularize(obj), act[id].name)) # Assume the property is JSON and try to pretty-print. If that # fails, print the item normally try: print json.dumps(item, sort_keys=True, indent=2, separators=(',', ':')) except: print item
def get_field_schema(self, command): obj = getattr(self.endpoint, command) schema = self.endpoint.get_schema(singularize(command)) fields = schema.field_schema return fields
def _construct_parse_tree(self, type_parsers): """ obj_type = object type eg Task, Adventure action = command eg create, delete argument = required, or optional argument. """ obj_types = self.endpoint._object_lists.keys() #information about each action actions = { 'list': {'description': 'list all %ss', 'args': [], }, 'show': {'description': 'show the properties of a %s', 'args': ['--id'] }, 'delete': {'description': 'remove a %s', 'args': ['id'] }, 'create': {'description': 'create a %s', 'args': ['schema'] }, 'update': {'description': 'modify a %s', 'args': ['schema'] }, 'execute': {'description': 'execute a %s', 'args': ['node_id', 'adventure_id'], 'applies_to': ['adventure'] }, 'filter': {'description': ('list %ss that match filter-string. ' 'Example filter string: ' 'name=workspace'), 'args': ['filter_string'] }, 'adventures': {'description': ('List currently available ' 'adventures for a %s'), 'args': ['id'], 'applies_to': ['node'] }, 'logs': {'description': 'Get output logged by a %s', 'args': ['id', '--offset'], 'applies_to': ['task'] } } # Hash for adding descriptions to specific arguments. # Useful for args that have come from the schema. descriptions = { 'adventures': { 'create': { 'dsl': ('Domain Specific Languague for defining ' ' adventures. For example: ' '[ { "ns": {}, "primitive": "download_cookbooks" ' '} ]') } } } def _get_help(obj, action, arg): """Function for retrieving help values from the descriptions hash if they exist.""" arg_help = None if obj in descriptions\ and action in descriptions[obj]\ and arg in descriptions[obj][action]: arg_help = descriptions[obj][action][arg] return arg_help for obj_type in obj_types: schema = self.endpoint.get_schema(singularize(obj_type)) arguments = schema.field_schema callback = getattr(self.endpoint, obj_type) desc = callback.__doc__ or '' type_parser = type_parsers.add_parser(singularize(obj_type), help='%s actions' % singularize(obj_type), description=desc, ) #"action" clashses with the action attribute of some object types #for example task.action, so the action arg is stored as cli_action action_parsers = type_parser.add_subparsers(dest='cli_action') for action in actions: #skip this action if it doesn't apply to this obj_type. if 'applies_to' in actions[action]: if singularize(obj_type) not in \ actions[action]['applies_to']: continue action_parser = action_parsers.add_parser( action, help=actions[action]['description'] % singularize(obj_type) ) #check the descriptions hash for argument help arg_help = None if obj_type in descriptions and action in \ descriptions[obj_type] and arg_name in \ descriptions[obj_type][action]: arg_help = descriptions[obj_type][action][arg_name] action_args = actions[action]['args'] if action_args == ['schema']: for arg_name, arg in arguments.items(): arg_help = _get_help(obj_type, action, arg_name) #id should be allocated rather than specified if action == "create" and arg_name == 'id': continue opt_string = '--' if arg['required']: opt_string = '' action_parser.add_argument('%s%s' % (opt_string, arg_name), help=arg_help) else: for arg in action_args: arg_help = _get_help(obj_type, action, arg) action_parser.add_argument(arg, help=arg_help) self.subcommands[obj_type] = type_parser type_parser.set_defaults(func=callback)
def _construct_parse_tree(self, type_parsers): """ obj_type = object type eg Task, Adventure action = command eg create, delete argument = required, or optional argument. """ obj_types = self.endpoint._object_lists.keys() #information about each action actions = { 'list': {'description': 'list all %ss', 'args': [], }, 'show': {'description': 'show the properties of a %s', 'args': ['id'] }, 'delete': {'description': 'remove a %s', 'args': ['id'] }, 'create': {'description': 'create a %s', 'args': ['schema'] }, # 'filter', 'update': {'description': 'modify a %s', 'args': ['schema'] }, 'execute': {'description': 'execute a %s', 'args': ['node_id', 'adventure_id'], 'applies_to': ['adventure'] } } for obj_type in obj_types: schema = self.endpoint.get_schema(singularize(obj_type)) arguments = schema.field_schema callback = getattr(self.endpoint, obj_type) desc = callback.__doc__ or '' type_parser = type_parsers.add_parser(singularize(obj_type), help='%s actions' % singularize(obj_type), description=desc, ) #"action" clashses with the action attribute of some object types #for example task.action, so the action arg is stored as cli_action action_parsers = type_parser.add_subparsers(dest='cli_action') for action in actions: #skip this action if it doesn't apply to this obj_type. if 'applies_to' in actions[action]: if singularize(obj_type) not in \ actions[action]['applies_to']: continue action_parser = action_parsers.add_parser( action, help=actions[action]['description'] % singularize(obj_type) ) action_args = actions[action]['args'] if action_args == ['schema']: for arg_name, arg in arguments.items(): #id should be allocated rather than specified if action == "create" and arg_name == 'id': continue opt_string = '--' if arg['required']: opt_string = '' action_parser.add_argument('%s%s' % (opt_string, arg_name)) else: for arg in action_args: action_parser.add_argument(arg) self.subcommands[obj_type] = type_parser type_parser.set_defaults(func=callback)