230 lines
7.7 KiB
Python
230 lines
7.7 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2019 Google LLC. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""Service Consumer Management API helper functions."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
from apitools.base.py import exceptions as apitools_exceptions
|
|
from apitools.base.py import list_pager
|
|
from googlecloudsdk.api_lib.services import exceptions
|
|
from googlecloudsdk.api_lib.util import apis
|
|
|
|
_SERVICE_CONSUMER_RESOURCE = 'services/%s/%s'
|
|
_LIMIT_OVERRIDE_RESOURCE = '%s/producerOverrides/%s'
|
|
_VALID_CONSUMER_PREFIX = {'projects/', 'folders/', 'organizations/'}
|
|
|
|
|
|
def ListQuotaMetrics(service, consumer, page_size=None, limit=None):
|
|
"""List service quota metrics for a consumer.
|
|
|
|
Args:
|
|
service: The service to list metrics for.
|
|
consumer: The consumer to list metrics for, e.g. "projects/123".
|
|
page_size: The page size to list.
|
|
limit: The max number of metrics to return.
|
|
|
|
Raises:
|
|
exceptions.PermissionDeniedException: when listing metrics fails.
|
|
apitools_exceptions.HttpError: Another miscellaneous error with the service.
|
|
|
|
Returns:
|
|
The list of quota metrics
|
|
"""
|
|
_ValidateConsumer(consumer)
|
|
client = _GetClientInstance()
|
|
messages = client.MESSAGES_MODULE
|
|
|
|
request = messages.ServiceconsumermanagementServicesConsumerQuotaMetricsListRequest(
|
|
parent=_SERVICE_CONSUMER_RESOURCE % (service, consumer))
|
|
return list_pager.YieldFromList(
|
|
client.services_consumerQuotaMetrics,
|
|
request,
|
|
limit=limit,
|
|
batch_size_attribute='pageSize',
|
|
batch_size=page_size,
|
|
field='metrics')
|
|
|
|
|
|
def UpdateQuotaOverrideCall(service,
|
|
consumer,
|
|
metric,
|
|
unit,
|
|
dimensions,
|
|
value,
|
|
force=False):
|
|
"""Update a quota override.
|
|
|
|
Args:
|
|
service: The service to update a quota override for.
|
|
consumer: The consumer to update a quota override for, e.g. "projects/123".
|
|
metric: The quota metric name.
|
|
unit: The unit of quota metric.
|
|
dimensions: The dimensions of the override in dictionary format. It can be
|
|
None.
|
|
value: The override integer value.
|
|
force: Force override update even if the change results in a substantial
|
|
decrease in available quota.
|
|
|
|
Raises:
|
|
exceptions.UpdateQuotaOverridePermissionDeniedException: when updating an
|
|
override fails.
|
|
apitools_exceptions.HttpError: Another miscellaneous error with the service.
|
|
|
|
Returns:
|
|
The quota override operation.
|
|
"""
|
|
_ValidateConsumer(consumer)
|
|
client = _GetClientInstance()
|
|
messages = client.MESSAGES_MODULE
|
|
|
|
dimensions_message = _GetDimensions(messages, dimensions)
|
|
request = messages.ServiceconsumermanagementServicesConsumerQuotaMetricsImportProducerOverridesRequest(
|
|
parent=_SERVICE_CONSUMER_RESOURCE % (service, consumer),
|
|
v1Beta1ImportProducerOverridesRequest=messages
|
|
.V1Beta1ImportProducerOverridesRequest(
|
|
inlineSource=messages.V1Beta1OverrideInlineSource(
|
|
overrides=[
|
|
messages.V1Beta1QuotaOverride(
|
|
metric=metric,
|
|
unit=unit,
|
|
overrideValue=value,
|
|
dimensions=dimensions_message)
|
|
],),
|
|
force=force),
|
|
)
|
|
try:
|
|
return client.services_consumerQuotaMetrics.ImportProducerOverrides(request)
|
|
except (apitools_exceptions.HttpForbiddenError,
|
|
apitools_exceptions.HttpNotFoundError) as e:
|
|
exceptions.ReraiseError(
|
|
e, exceptions.UpdateQuotaOverridePermissionDeniedException)
|
|
|
|
|
|
def DeleteQuotaOverrideCall(service,
|
|
consumer,
|
|
metric,
|
|
unit,
|
|
override_id,
|
|
force=False):
|
|
"""Delete a quota override.
|
|
|
|
Args:
|
|
service: The service to delete a quota aoverride for.
|
|
consumer: The consumer to delete a quota override for, e.g. "projects/123".
|
|
metric: The quota metric name.
|
|
unit: The unit of quota metric.
|
|
override_id: The override ID.
|
|
force: Force override deletion even if the change results in a substantial
|
|
decrease in available quota.
|
|
|
|
Raises:
|
|
exceptions.DeleteQuotaOverridePermissionDeniedException: when deleting an
|
|
override fails.
|
|
apitools_exceptions.HttpError: Another miscellaneous error with the service.
|
|
|
|
Returns:
|
|
The quota override operation.
|
|
"""
|
|
_ValidateConsumer(consumer)
|
|
client = _GetClientInstance()
|
|
messages = client.MESSAGES_MODULE
|
|
|
|
parent = _GetMetricResourceName(service, consumer, metric, unit)
|
|
name = _LIMIT_OVERRIDE_RESOURCE % (parent, override_id)
|
|
request = messages.ServiceconsumermanagementServicesConsumerQuotaMetricsLimitsProducerOverridesDeleteRequest(
|
|
name=name,
|
|
force=force,
|
|
)
|
|
try:
|
|
return client.services_consumerQuotaMetrics_limits_producerOverrides.Delete(
|
|
request)
|
|
except (apitools_exceptions.HttpForbiddenError,
|
|
apitools_exceptions.HttpNotFoundError) as e:
|
|
exceptions.ReraiseError(
|
|
e, exceptions.DeleteQuotaOverridePermissionDeniedException)
|
|
|
|
|
|
def _GetDimensions(messages, dimensions):
|
|
if dimensions is None:
|
|
return None
|
|
dt = messages.V1Beta1QuotaOverride.DimensionsValue
|
|
# sorted by key strings to maintain the unit test behavior consistency.
|
|
return dt(
|
|
additionalProperties=[
|
|
dt.AdditionalProperty(key=k, value=dimensions[k])
|
|
for k in sorted(dimensions.keys())
|
|
],)
|
|
|
|
|
|
def _GetMetricResourceName(service, consumer, metric, unit):
|
|
"""Get the metric resource name from metric name and unit.
|
|
|
|
Args:
|
|
service: The service to manage an override for.
|
|
consumer: The consumer to manage an override for, e.g. "projects/123".
|
|
metric: The quota metric name.
|
|
unit: The unit of quota metric.
|
|
|
|
Raises:
|
|
exceptions.Error: when the limit with given metric and unit is not found.
|
|
|
|
Returns:
|
|
The quota override operation.
|
|
"""
|
|
metrics = ListQuotaMetrics(service, consumer)
|
|
for m in metrics:
|
|
if m.metric == metric:
|
|
for q in m.consumerQuotaLimits:
|
|
if q.unit == unit:
|
|
return q.name
|
|
raise exceptions.Error('limit not found with name "%s" and unit "%s".' %
|
|
(metric, unit))
|
|
|
|
|
|
def GetOperation(name):
|
|
"""Make API call to get an operation.
|
|
|
|
Args:
|
|
name: The name of the operation.
|
|
|
|
Raises:
|
|
exceptions.OperationErrorException: when the getting operation API fails.
|
|
apitools_exceptions.HttpError: Another miscellaneous error with the service.
|
|
|
|
Returns:
|
|
The result of the operation
|
|
"""
|
|
client = _GetClientInstance()
|
|
messages = client.MESSAGES_MODULE
|
|
request = messages.ServiceconsumermanagementOperationsGetRequest(name=name)
|
|
try:
|
|
return client.operations.Get(request)
|
|
except (apitools_exceptions.HttpForbiddenError,
|
|
apitools_exceptions.HttpNotFoundError) as e:
|
|
exceptions.ReraiseError(e, exceptions.OperationErrorException)
|
|
|
|
|
|
def _ValidateConsumer(consumer):
|
|
for prefix in _VALID_CONSUMER_PREFIX:
|
|
if consumer.startswith(prefix):
|
|
return
|
|
raise exceptions.Error('invalid consumer format "%s".' % consumer)
|
|
|
|
|
|
def _GetClientInstance():
|
|
return apis.GetClientInstance('serviceconsumermanagement', 'v1beta1')
|