1# -*- coding: utf-8 -*- # 2# Copyright 2019 Google LLC. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15"""Service Consumer Management API helper functions.""" 16 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import unicode_literals 20 21from apitools.base.py import exceptions as apitools_exceptions 22from apitools.base.py import list_pager 23from googlecloudsdk.api_lib.services import exceptions 24from googlecloudsdk.api_lib.util import apis 25 26_SERVICE_CONSUMER_RESOURCE = 'services/%s/%s' 27_LIMIT_OVERRIDE_RESOURCE = '%s/producerOverrides/%s' 28 29 30def ListQuotaMetrics(service, consumer, page_size=None, limit=None): 31 """List service quota metrics for a consumer. 32 33 Args: 34 service: The service to list metrics for. 35 consumer: The consumer to list metrics for, e.g. "projects/123". 36 page_size: The page size to list. 37 limit: The max number of metrics to return. 38 39 Raises: 40 exceptions.PermissionDeniedException: when listing metrics fails. 41 apitools_exceptions.HttpError: Another miscellaneous error with the service. 42 43 Returns: 44 The list of quota metrics 45 """ 46 client = _GetClientInstance() 47 messages = client.MESSAGES_MODULE 48 49 request = messages.ServiceconsumermanagementServicesConsumerQuotaMetricsListRequest( 50 parent=_SERVICE_CONSUMER_RESOURCE % (service, consumer)) 51 return list_pager.YieldFromList( 52 client.services_consumerQuotaMetrics, 53 request, 54 limit=limit, 55 batch_size_attribute='pageSize', 56 batch_size=page_size, 57 field='metrics') 58 59 60def UpdateQuotaOverrideCall(service, 61 consumer, 62 metric, 63 unit, 64 dimensions, 65 value, 66 force=False): 67 """Update a quota override. 68 69 Args: 70 service: The service to update a quota override for. 71 consumer: The consumer to update a quota override for, e.g. "projects/123". 72 metric: The quota metric name. 73 unit: The unit of quota metric. 74 dimensions: The dimensions of the override in dictionary format. It can be 75 None. 76 value: The override integer value. 77 force: Force override update even if the change results in a substantial 78 decrease in available quota. 79 80 Raises: 81 exceptions.UpdateQuotaOverridePermissionDeniedException: when updating an 82 override fails. 83 apitools_exceptions.HttpError: Another miscellaneous error with the service. 84 85 Returns: 86 The quota override operation. 87 """ 88 client = _GetClientInstance() 89 messages = client.MESSAGES_MODULE 90 91 dimensions_message = _GetDimensions(messages, dimensions) 92 request = messages.ServiceconsumermanagementServicesConsumerQuotaMetricsImportProducerOverridesRequest( 93 parent=_SERVICE_CONSUMER_RESOURCE % (service, consumer), 94 v1Beta1ImportProducerOverridesRequest=messages 95 .V1Beta1ImportProducerOverridesRequest( 96 inlineSource=messages.V1Beta1OverrideInlineSource( 97 overrides=[ 98 messages.V1Beta1QuotaOverride( 99 metric=metric, 100 unit=unit, 101 overrideValue=value, 102 dimensions=dimensions_message) 103 ],), 104 force=force), 105 ) 106 try: 107 return client.services_consumerQuotaMetrics.ImportProducerOverrides(request) 108 except (apitools_exceptions.HttpForbiddenError, 109 apitools_exceptions.HttpNotFoundError) as e: 110 exceptions.ReraiseError( 111 e, exceptions.UpdateQuotaOverridePermissionDeniedException) 112 113 114def DeleteQuotaOverrideCall(service, 115 consumer, 116 metric, 117 unit, 118 override_id, 119 force=False): 120 """Delete a quota override. 121 122 Args: 123 service: The service to delete a quota aoverride for. 124 consumer: The consumer to delete a quota override for, e.g. "projects/123". 125 metric: The quota metric name. 126 unit: The unit of quota metric. 127 override_id: The override ID. 128 force: Force override deletion even if the change results in a substantial 129 decrease in available quota. 130 131 Raises: 132 exceptions.DeleteQuotaOverridePermissionDeniedException: when deleting an 133 override fails. 134 apitools_exceptions.HttpError: Another miscellaneous error with the service. 135 136 Returns: 137 The quota override operation. 138 """ 139 client = _GetClientInstance() 140 messages = client.MESSAGES_MODULE 141 142 parent = _GetMetricResourceName(service, consumer, metric, unit) 143 name = _LIMIT_OVERRIDE_RESOURCE % (parent, override_id) 144 request = messages.ServiceconsumermanagementServicesConsumerQuotaMetricsLimitsProducerOverridesDeleteRequest( 145 name=name, 146 force=force, 147 ) 148 try: 149 return client.services_consumerQuotaMetrics_limits_producerOverrides.Delete( 150 request) 151 except (apitools_exceptions.HttpForbiddenError, 152 apitools_exceptions.HttpNotFoundError) as e: 153 exceptions.ReraiseError( 154 e, exceptions.DeleteQuotaOverridePermissionDeniedException) 155 156 157def _GetDimensions(messages, dimensions): 158 if dimensions is None: 159 return None 160 dt = messages.V1Beta1QuotaOverride.DimensionsValue 161 # sorted by key strings to maintain the unit test behavior consistency. 162 return dt( 163 additionalProperties=[ 164 dt.AdditionalProperty(key=k, value=dimensions[k]) 165 for k in sorted(dimensions.keys()) 166 ],) 167 168 169def _GetMetricResourceName(service, consumer, metric, unit): 170 """Get the metric resource name from metric name and unit. 171 172 Args: 173 service: The service to manage an override for. 174 consumer: The consumer to manage an override for, e.g. "projects/123". 175 metric: The quota metric name. 176 unit: The unit of quota metric. 177 178 Raises: 179 exceptions.Error: when the limit with given metric and unit is not found. 180 181 Returns: 182 The quota override operation. 183 """ 184 metrics = ListQuotaMetrics(service, consumer) 185 for m in metrics: 186 if m.metric == metric: 187 for q in m.consumerQuotaLimits: 188 if q.unit == unit: 189 return q.name 190 raise exceptions.Error('limit not found with name "%s" and unit "%s".' % 191 (metric, unit)) 192 193 194def GetOperation(name): 195 """Make API call to get an operation. 196 197 Args: 198 name: The name of the operation. 199 200 Raises: 201 exceptions.OperationErrorException: when the getting operation API fails. 202 apitools_exceptions.HttpError: Another miscellaneous error with the service. 203 204 Returns: 205 The result of the operation 206 """ 207 client = _GetClientInstance() 208 messages = client.MESSAGES_MODULE 209 request = messages.ServiceconsumermanagementOperationsGetRequest(name=name) 210 try: 211 return client.operations.Get(request) 212 except (apitools_exceptions.HttpForbiddenError, 213 apitools_exceptions.HttpNotFoundError) as e: 214 exceptions.ReraiseError(e, exceptions.OperationErrorException) 215 216 217def _GetClientInstance(): 218 return apis.GetClientInstance('serviceconsumermanagement', 'v1beta1') 219