# # Copyright 2008 Google Inc. All Rights Reserved. """ The acl module contains the objects and methods used to manage ACLs in Autotest. The valid actions are: add: adds acl(s), or users or hosts to an ACL remove: deletes acl(s), or users or hosts from an ACL list: lists acl(s) The common options are: --alist / -A: file containing a list of ACLs See topic_common.py for a High Level Design and Algorithm. """ from autotest_lib.cli import topic_common, action_common class acl(topic_common.atest): """ACL class atest acl [create|delete|list|add|remove] <options>""" usage_action = '[create|delete|list|add|remove]' topic = 'acl_group' msg_topic = 'ACL' msg_items = '<acls>' def __init__(self): """Add to the parser the options common to all the ACL actions""" super(acl, self).__init__() self.parser.add_option('-A', '--alist', help='File listing the ACLs', type='string', default=None, metavar='ACL_FLIST') self.topic_parse_info = topic_common.item_parse_info( attribute_name='acls', filename_option='alist', use_leftover=True) def get_items(self): """Get the items in the ACL list.""" return self.acls class acl_help(acl): """Just here to get the atest logic working. Usage is set by its parent""" pass class acl_list(action_common.atest_list, acl): """atest acl list [--verbose] [--user <users>|--mach <machine>|--alist <file>] [<acls>]""" def __init__(self): super(acl_list, self).__init__() self.parser.add_option('-u', '--user', help='List ACLs containing USER', type='string', metavar='USER') self.parser.add_option('-m', '--machine', help='List ACLs containing MACHINE', type='string', metavar='MACHINE') def parse(self): user_info = topic_common.item_parse_info(attribute_name='users', inline_option='user') host_info = topic_common.item_parse_info(attribute_name='hosts', inline_option='machine') (options, leftover) = super(acl_list, self).parse([user_info, host_info]) users = getattr(self, 'users') hosts = getattr(self, 'hosts') acls = getattr(self, 'acls') if ((users and (hosts or acls)) or (hosts and acls)): self.invalid_syntax('Only specify one of --user,' '--machine or ACL') if len(users) > 1: self.invalid_syntax('Only specify one <user>') if len(hosts) > 1: self.invalid_syntax('Only specify one <machine>') try: self.users = users[0] except IndexError: pass try: self.hosts = hosts[0] except IndexError: pass return (options, leftover) def execute(self): filters = {} check_results = {} if self.acls: filters['name__in'] = self.acls check_results['name__in'] = 'name' if self.users: filters['users__login'] = self.users check_results['users__login'] = None if self.hosts: filters['hosts__hostname'] = self.hosts check_results['hosts__hostname'] = None return super(acl_list, self).execute(op='get_acl_groups', filters=filters, check_results=check_results) def output(self, results): # If an ACL was specified, always print its details if self.acls or self.verbose: sublist_keys=('hosts', 'users') else: sublist_keys=() super(acl_list, self).output(results, keys=('name', 'description'), sublist_keys=sublist_keys) class acl_create(action_common.atest_create, acl): """atest acl create <acl> --desc <description>""" def __init__(self): super(acl_create, self).__init__() self.parser.add_option('-d', '--desc', help='Creates the ACL with the DESCRIPTION', type='string') self.parser.remove_option('--alist') def parse(self): (options, leftover) = super(acl_create, self).parse(req_items='acls') if not options.desc: self.invalid_syntax('Must specify a description to create an ACL.') self.data_item_key = 'name' self.data['description'] = options.desc if len(self.acls) > 1: self.invalid_syntax('Can only create one ACL at a time') return (options, leftover) class acl_delete(action_common.atest_delete, acl): """atest acl delete [<acls> | --alist <file>""" pass class acl_add_or_remove(acl): """Shared implementation for acl add and acl remove.""" def __init__(self): super(acl_add_or_remove, self).__init__() # Get the appropriate help for adding or removing. words = self.usage_words lower_words = tuple(word.lower() for word in words) self.parser.add_option('-u', '--user', help='%s USER(s) %s the ACL' % words, type='string', metavar='USER') self.parser.add_option('-U', '--ulist', help='File containing users to %s %s ' 'the ACL' % lower_words, type='string', metavar='USER_FLIST') self.parser.add_option('-m', '--machine', help='%s MACHINE(s) %s the ACL' % words, type='string', metavar='MACHINE') self.parser.add_option('-M', '--mlist', help='File containing machines to %s %s ' 'the ACL' % lower_words, type='string', metavar='MACHINE_FLIST') def parse(self): user_info = topic_common.item_parse_info(attribute_name='users', inline_option='user', filename_option='ulist') host_info = topic_common.item_parse_info(attribute_name='hosts', inline_option='machine', filename_option='mlist') (options, leftover) = super(acl_add_or_remove, self).parse([user_info, host_info], req_items='acls') if (not getattr(self, 'users', None) and not getattr(self, 'hosts', None)): self.invalid_syntax('Specify at least one USER or MACHINE') return (options, leftover) class acl_add(action_common.atest_add, acl_add_or_remove): """atest acl add <acl> --user <user>| --machine <machine>|--mlist <FILE>]""" pass class acl_remove(action_common.atest_remove, acl_add_or_remove): """atest acl remove [<acls> | --alist <file> --user <user> | --machine <machine> | --mlist <FILE>]""" pass