mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 1 | # |
| 2 | # Copyright 2008 Google Inc. All Rights Reserved. |
| 3 | |
| 4 | """ |
| 5 | The acl module contains the objects and methods used to |
| 6 | manage ACLs in Autotest. |
| 7 | |
| 8 | The valid actions are: |
| 9 | add: adds acl(s), or users or hosts to an ACL |
| 10 | remove: deletes acl(s), or users or hosts from an ACL |
| 11 | list: lists acl(s) |
| 12 | |
| 13 | The common options are: |
| 14 | --alist / -A: file containing a list of ACLs |
| 15 | |
| 16 | See topic_common.py for a High Level Design and Algorithm. |
| 17 | |
| 18 | """ |
| 19 | |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 20 | from autotest_lib.cli import topic_common, action_common |
| 21 | |
| 22 | |
| 23 | class 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 | |
mbligh | 9deeefa | 2009-05-01 23:11:08 +0000 | [diff] [blame] | 40 | self.topic_parse_info = topic_common.item_parse_info( |
| 41 | attribute_name='acls', |
| 42 | filename_option='alist', |
| 43 | use_leftover=True) |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 44 | |
| 45 | |
| 46 | def get_items(self): |
David James | c0276db | 2013-02-22 17:55:34 -0800 | [diff] [blame] | 47 | """Get the items in the ACL list.""" |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 48 | return self.acls |
| 49 | |
| 50 | |
| 51 | class acl_help(acl): |
| 52 | """Just here to get the atest logic working. |
| 53 | Usage is set by its parent""" |
| 54 | pass |
| 55 | |
| 56 | |
| 57 | class 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): |
mbligh | 9deeefa | 2009-05-01 23:11:08 +0000 | [diff] [blame] | 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]) |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 81 | |
Dale Curtis | 8adf789 | 2011-09-08 16:13:36 -0700 | [diff] [blame] | 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)): |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 87 | self.invalid_syntax('Only specify one of --user,' |
| 88 | '--machine or ACL') |
| 89 | |
Dale Curtis | 8adf789 | 2011-09-08 16:13:36 -0700 | [diff] [blame] | 90 | if len(users) > 1: |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 91 | self.invalid_syntax('Only specify one <user>') |
Dale Curtis | 8adf789 | 2011-09-08 16:13:36 -0700 | [diff] [blame] | 92 | if len(hosts) > 1: |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 93 | self.invalid_syntax('Only specify one <machine>') |
| 94 | |
| 95 | try: |
Dale Curtis | 8adf789 | 2011-09-08 16:13:36 -0700 | [diff] [blame] | 96 | self.users = users[0] |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 97 | except IndexError: |
| 98 | pass |
| 99 | |
| 100 | try: |
Dale Curtis | 8adf789 | 2011-09-08 16:13:36 -0700 | [diff] [blame] | 101 | self.hosts = hosts[0] |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 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): |
mbligh | 838c747 | 2009-05-13 20:56:50 +0000 | [diff] [blame] | 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 | |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 135 | super(acl_list, self).output(results, |
mbligh | 838c747 | 2009-05-13 20:56:50 +0000 | [diff] [blame] | 136 | keys=('name', 'description'), |
| 137 | sublist_keys=sublist_keys) |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 138 | |
| 139 | |
| 140 | class 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): |
mbligh | 9deeefa | 2009-05-01 23:11:08 +0000 | [diff] [blame] | 151 | (options, leftover) = super(acl_create, self).parse(req_items='acls') |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 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 | |
| 165 | class acl_delete(action_common.atest_delete, acl): |
| 166 | """atest acl delete [<acls> | --alist <file>""" |
| 167 | pass |
| 168 | |
| 169 | |
| 170 | class acl_add_or_remove(acl): |
David James | c0276db | 2013-02-22 17:55:34 -0800 | [diff] [blame] | 171 | """Shared implementation for acl add and acl remove.""" |
| 172 | |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 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): |
mbligh | 9deeefa | 2009-05-01 23:11:08 +0000 | [diff] [blame] | 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') |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 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 | |
| 217 | class 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 | |
| 223 | class 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 |