1# Licensed under the Apache License, Version 2.0 (the "License"); you may 2# not use this file except in compliance with the License. You may obtain 3# a copy of the License at 4# 5# http://www.apache.org/licenses/LICENSE-2.0 6# 7# Unless required by applicable law or agreed to in writing, software 8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10# License for the specific language governing permissions and limitations 11# under the License. 12# 13 14"""Registered limits action implementations.""" 15 16import logging 17 18from osc_lib.command import command 19from osc_lib import exceptions 20from osc_lib import utils 21 22from openstackclient.i18n import _ 23from openstackclient.identity import common as common_utils 24 25LOG = logging.getLogger(__name__) 26 27 28class CreateRegisteredLimit(command.ShowOne): 29 _description = _("Create a registered limit") 30 31 def get_parser(self, prog_name): 32 parser = super(CreateRegisteredLimit, self).get_parser(prog_name) 33 parser.add_argument( 34 '--description', 35 metavar='<description>', 36 help=_('Description of the registered limit'), 37 ) 38 parser.add_argument( 39 '--region', 40 metavar='<region>', 41 help=_('Region for the registered limit to affect'), 42 ) 43 parser.add_argument( 44 '--service', 45 metavar='<service>', 46 required=True, 47 help=_('Service responsible for the resource to limit (required)'), 48 ) 49 parser.add_argument( 50 '--default-limit', 51 type=int, 52 metavar='<default-limit>', 53 required=True, 54 help=_('The default limit for the resources to assume (required)'), 55 ) 56 parser.add_argument( 57 'resource_name', 58 metavar='<resource-name>', 59 help=_('The name of the resource to limit'), 60 ) 61 return parser 62 63 def take_action(self, parsed_args): 64 identity_client = self.app.client_manager.identity 65 66 service = utils.find_resource( 67 identity_client.services, parsed_args.service 68 ) 69 region = None 70 if parsed_args.region: 71 val = getattr(parsed_args, 'region', None) 72 if 'None' not in val: 73 # NOTE (vishakha): Due to bug #1799153 and for any another 74 # related case where GET resource API does not support the 75 # filter by name, osc_lib.utils.find_resource() method cannot 76 # be used because that method try to fall back to list all the 77 # resource if requested resource cannot be get via name. Which 78 # ends up with NoUniqueMatch error. 79 # So osc_lib.utils.find_resource() function cannot be used for 80 # 'regions', using common_utils.get_resource() instead. 81 region = common_utils.get_resource( 82 identity_client.regions, parsed_args.region 83 ) 84 85 registered_limit = identity_client.registered_limits.create( 86 service, 87 parsed_args.resource_name, 88 parsed_args.default_limit, 89 description=parsed_args.description, 90 region=region 91 ) 92 93 registered_limit._info.pop('links', None) 94 return zip(*sorted(registered_limit._info.items())) 95 96 97class DeleteRegisteredLimit(command.Command): 98 _description = _("Delete a registered limit") 99 100 def get_parser(self, prog_name): 101 parser = super(DeleteRegisteredLimit, self).get_parser(prog_name) 102 parser.add_argument( 103 'registered_limit_id', 104 metavar='<registered-limit-id>', 105 nargs="+", 106 help=_('Registered limit to delete (ID)'), 107 ) 108 return parser 109 110 def take_action(self, parsed_args): 111 identity_client = self.app.client_manager.identity 112 113 errors = 0 114 for registered_limit_id in parsed_args.registered_limit_id: 115 try: 116 identity_client.registered_limits.delete(registered_limit_id) 117 except Exception as e: 118 errors += 1 119 from pprint import pprint 120 pprint(type(e)) 121 LOG.error(_("Failed to delete registered limit with ID " 122 "'%(id)s': %(e)s"), 123 {'id': registered_limit_id, 'e': e}) 124 125 if errors > 0: 126 total = len(parsed_args.registered_limit_id) 127 msg = (_("%(errors)s of %(total)s registered limits failed to " 128 "delete.") % {'errors': errors, 'total': total}) 129 raise exceptions.CommandError(msg) 130 131 132class ListRegisteredLimit(command.Lister): 133 _description = _("List registered limits") 134 135 def get_parser(self, prog_name): 136 parser = super(ListRegisteredLimit, self).get_parser(prog_name) 137 parser.add_argument( 138 '--service', 139 metavar='<service>', 140 help=_('Service responsible for the resource to limit'), 141 ) 142 parser.add_argument( 143 '--resource-name', 144 metavar='<resource-name>', 145 dest='resource_name', 146 help=_('The name of the resource to limit'), 147 ) 148 parser.add_argument( 149 '--region', 150 metavar='<region>', 151 help=_('Region for the limit to affect.'), 152 ) 153 return parser 154 155 def take_action(self, parsed_args): 156 identity_client = self.app.client_manager.identity 157 158 service = None 159 if parsed_args.service: 160 service = common_utils.find_service( 161 identity_client, parsed_args.service 162 ) 163 region = None 164 if parsed_args.region: 165 val = getattr(parsed_args, 'region', None) 166 if 'None' not in val: 167 # NOTE (vishakha): Due to bug #1799153 and for any another 168 # related case where GET resource API does not support the 169 # filter by name, osc_lib.utils.find_resource() method cannot 170 # be used because that method try to fall back to list all the 171 # resource if requested resource cannot be get via name. Which 172 # ends up with NoUniqueMatch error. 173 # So osc_lib.utils.find_resource() function cannot be used for 174 # 'regions', using common_utils.get_resource() instead. 175 region = common_utils.get_resource( 176 identity_client.regions, parsed_args.region 177 ) 178 179 registered_limits = identity_client.registered_limits.list( 180 service=service, 181 resource_name=parsed_args.resource_name, 182 region=region 183 ) 184 185 columns = ( 186 'ID', 'Service ID', 'Resource Name', 'Default Limit', 187 'Description', 'Region ID' 188 ) 189 return ( 190 columns, 191 (utils.get_item_properties(s, columns) for s in registered_limits), 192 ) 193 194 195class SetRegisteredLimit(command.ShowOne): 196 _description = _("Update information about a registered limit") 197 198 def get_parser(self, prog_name): 199 parser = super(SetRegisteredLimit, self).get_parser(prog_name) 200 parser.add_argument( 201 'registered_limit_id', 202 metavar='<registered-limit-id>', 203 help=_('Registered limit to update (ID)'), 204 ) 205 parser.add_argument( 206 '--service', 207 metavar='<service>', 208 help=_('Service to be updated responsible for the resource to ' 209 'limit. Either --service, --resource-name or --region must ' 210 'be different than existing value otherwise it will be ' 211 'duplicate entry') 212 ) 213 parser.add_argument( 214 '--resource-name', 215 metavar='<resource-name>', 216 help=_('Resource to be updated responsible for the resource to ' 217 'limit. Either --service, --resource-name or --region must ' 218 'be different than existing value otherwise it will be ' 219 'duplicate entry'), 220 ) 221 parser.add_argument( 222 '--default-limit', 223 metavar='<default-limit>', 224 type=int, 225 help=_('The default limit for the resources to assume'), 226 ) 227 parser.add_argument( 228 '--description', 229 metavar='<description>', 230 help=_('Description to update of the registered limit'), 231 ) 232 parser.add_argument( 233 '--region', 234 metavar='<region>', 235 help=_('Region for the registered limit to affect. Either ' 236 '--service, --resource-name or --region must be ' 237 'different than existing value otherwise it will be ' 238 'duplicate entry'), 239 ) 240 return parser 241 242 def take_action(self, parsed_args): 243 identity_client = self.app.client_manager.identity 244 245 service = None 246 if parsed_args.service: 247 service = common_utils.find_service( 248 identity_client, parsed_args.service 249 ) 250 251 region = None 252 if parsed_args.region: 253 val = getattr(parsed_args, 'region', None) 254 if 'None' not in val: 255 # NOTE (vishakha): Due to bug #1799153 and for any another 256 # related case where GET resource API does not support the 257 # filter by name, osc_lib.utils.find_resource() method cannot 258 # be used because that method try to fall back to list all the 259 # resource if requested resource cannot be get via name. Which 260 # ends up with NoUniqueMatch error. 261 # So osc_lib.utils.find_resource() function cannot be used for 262 # 'regions', using common_utils.get_resource() instead. 263 region = common_utils.get_resource( 264 identity_client.regions, parsed_args.region 265 ) 266 267 registered_limit = identity_client.registered_limits.update( 268 parsed_args.registered_limit_id, 269 service=service, 270 resource_name=parsed_args.resource_name, 271 default_limit=parsed_args.default_limit, 272 description=parsed_args.description, 273 region=region 274 ) 275 276 registered_limit._info.pop('links', None) 277 return zip(*sorted(registered_limit._info.items())) 278 279 280class ShowRegisteredLimit(command.ShowOne): 281 _description = _("Display registered limit details") 282 283 def get_parser(self, prog_name): 284 parser = super(ShowRegisteredLimit, self).get_parser(prog_name) 285 parser.add_argument( 286 'registered_limit_id', 287 metavar='<registered-limit-id>', 288 help=_('Registered limit to display (ID)'), 289 ) 290 return parser 291 292 def take_action(self, parsed_args): 293 identity_client = self.app.client_manager.identity 294 registered_limit = identity_client.registered_limits.get( 295 parsed_args.registered_limit_id 296 ) 297 registered_limit._info.pop('links', None) 298 return zip(*sorted(registered_limit._info.items())) 299