File: //snap/google-cloud-cli/current/lib/googlecloudsdk/api_lib/services/scm.py
# -*- 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')