1# 2# Copyright 2008 Google Inc. All Rights Reserved. 3 4""" 5The acl module contains the objects and methods used to 6manage ACLs in Autotest. 7 8The valid actions are: 9add: adds acl(s), or users or hosts to an ACL 10remove: deletes acl(s), or users or hosts from an ACL 11list: lists acl(s) 12 13The common options are: 14--alist / -A: file containing a list of ACLs 15 16See topic_common.py for a High Level Design and Algorithm. 17 18""" 19 20from autotest_lib.cli import topic_common, action_common 21 22 23class acl(topic_common.atest): 24 """ACL class 25 atest acl [create|delete|list|add|remove] <options>""" 26 usage_action = '[create|delete|list|add|remove]' 27 topic = 'acl_group' 28 msg_topic = 'ACL' 29 msg_items = '<acls>' 30 31 def __init__(self): 32 """Add to the parser the options common to all the ACL actions""" 33 super(acl, self).__init__() 34 self.parser.add_option('-A', '--alist', 35 help='File listing the ACLs', 36 type='string', 37 default=None, 38 metavar='ACL_FLIST') 39 40 self.topic_parse_info = topic_common.item_parse_info( 41 attribute_name='acls', 42 filename_option='alist', 43 use_leftover=True) 44 45 46 def get_items(self): 47 """Get the items in the ACL list.""" 48 return self.acls 49 50 51class acl_help(acl): 52 """Just here to get the atest logic working. 53 Usage is set by its parent""" 54 pass 55 56 57class acl_list(action_common.atest_list, acl): 58 """atest acl list [--verbose] 59 [--user <users>|--mach <machine>|--alist <file>] [<acls>]""" 60 def __init__(self): 61 super(acl_list, self).__init__() 62 63 self.parser.add_option('-u', '--user', 64 help='List ACLs containing USER', 65 type='string', 66 metavar='USER') 67 self.parser.add_option('-m', '--machine', 68 help='List ACLs containing MACHINE', 69 type='string', 70 metavar='MACHINE') 71 72 73 def parse(self): 74 user_info = topic_common.item_parse_info(attribute_name='users', 75 inline_option='user') 76 host_info = topic_common.item_parse_info(attribute_name='hosts', 77 inline_option='machine') 78 79 (options, leftover) = super(acl_list, self).parse([user_info, 80 host_info]) 81 82 users = getattr(self, 'users') 83 hosts = getattr(self, 'hosts') 84 acls = getattr(self, 'acls') 85 if ((users and (hosts or acls)) or 86 (hosts and acls)): 87 self.invalid_syntax('Only specify one of --user,' 88 '--machine or ACL') 89 90 if len(users) > 1: 91 self.invalid_syntax('Only specify one <user>') 92 if len(hosts) > 1: 93 self.invalid_syntax('Only specify one <machine>') 94 95 try: 96 self.users = users[0] 97 except IndexError: 98 pass 99 100 try: 101 self.hosts = hosts[0] 102 except IndexError: 103 pass 104 return (options, leftover) 105 106 107 def execute(self): 108 filters = {} 109 check_results = {} 110 if self.acls: 111 filters['name__in'] = self.acls 112 check_results['name__in'] = 'name' 113 114 if self.users: 115 filters['users__login'] = self.users 116 check_results['users__login'] = None 117 118 if self.hosts: 119 filters['hosts__hostname'] = self.hosts 120 check_results['hosts__hostname'] = None 121 122 return super(acl_list, 123 self).execute(op='get_acl_groups', 124 filters=filters, 125 check_results=check_results) 126 127 128 def output(self, results): 129 # If an ACL was specified, always print its details 130 if self.acls or self.verbose: 131 sublist_keys=('hosts', 'users') 132 else: 133 sublist_keys=() 134 135 super(acl_list, self).output(results, 136 keys=('name', 'description'), 137 sublist_keys=sublist_keys) 138 139 140class acl_create(action_common.atest_create, acl): 141 """atest acl create <acl> --desc <description>""" 142 def __init__(self): 143 super(acl_create, self).__init__() 144 self.parser.add_option('-d', '--desc', 145 help='Creates the ACL with the DESCRIPTION', 146 type='string') 147 self.parser.remove_option('--alist') 148 149 150 def parse(self): 151 (options, leftover) = super(acl_create, self).parse(req_items='acls') 152 153 if not options.desc: 154 self.invalid_syntax('Must specify a description to create an ACL.') 155 156 self.data_item_key = 'name' 157 self.data['description'] = options.desc 158 159 if len(self.acls) > 1: 160 self.invalid_syntax('Can only create one ACL at a time') 161 162 return (options, leftover) 163 164 165class acl_delete(action_common.atest_delete, acl): 166 """atest acl delete [<acls> | --alist <file>""" 167 pass 168 169 170class acl_add_or_remove(acl): 171 """Shared implementation for acl add and acl remove.""" 172 173 def __init__(self): 174 super(acl_add_or_remove, self).__init__() 175 # Get the appropriate help for adding or removing. 176 words = self.usage_words 177 lower_words = tuple(word.lower() for word in words) 178 179 self.parser.add_option('-u', '--user', 180 help='%s USER(s) %s the ACL' % words, 181 type='string', 182 metavar='USER') 183 self.parser.add_option('-U', '--ulist', 184 help='File containing users to %s %s ' 185 'the ACL' % lower_words, 186 type='string', 187 metavar='USER_FLIST') 188 self.parser.add_option('-m', '--machine', 189 help='%s MACHINE(s) %s the ACL' % words, 190 type='string', 191 metavar='MACHINE') 192 self.parser.add_option('-M', '--mlist', 193 help='File containing machines to %s %s ' 194 'the ACL' % lower_words, 195 type='string', 196 metavar='MACHINE_FLIST') 197 198 199 def parse(self): 200 user_info = topic_common.item_parse_info(attribute_name='users', 201 inline_option='user', 202 filename_option='ulist') 203 host_info = topic_common.item_parse_info(attribute_name='hosts', 204 inline_option='machine', 205 filename_option='mlist') 206 (options, leftover) = super(acl_add_or_remove, 207 self).parse([user_info, host_info], 208 req_items='acls') 209 210 if (not getattr(self, 'users', None) and 211 not getattr(self, 'hosts', None)): 212 self.invalid_syntax('Specify at least one USER or MACHINE') 213 214 return (options, leftover) 215 216 217class acl_add(action_common.atest_add, acl_add_or_remove): 218 """atest acl add <acl> --user <user>| 219 --machine <machine>|--mlist <FILE>]""" 220 pass 221 222 223class acl_remove(action_common.atest_remove, acl_add_or_remove): 224 """atest acl remove [<acls> | --alist <file> 225 --user <user> | --machine <machine> | --mlist <FILE>]""" 226 pass 227