# -*- coding: utf-8 -*- # # Copyright 2023 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. """Utilities for Cloud Quotas API QuotaPreference.""" from apitools.base.py import list_pager from googlecloudsdk.api_lib.quotas import message_util from googlecloudsdk.api_lib.util import apis from googlecloudsdk.api_lib.util import common_args from googlecloudsdk.calliope import base PAGE_SIZE = 100 _CONSUMER_LOCATION_RESOURCE = '%s/locations/global' _RECONCILING_ONLY_FILTER = 'reconciling:true' VERSION_MAP = { base.ReleaseTrack.ALPHA: 'v1alpha', base.ReleaseTrack.BETA: 'v1beta', base.ReleaseTrack.GA: 'v1', } def _GetClientInstance(release_track: base.ReleaseTrack, no_http=False): api_version = VERSION_MAP.get(release_track) return apis.GetClientInstance('cloudquotas', api_version, no_http=no_http) def _GetPreferenceName(request_parent, preference_id): if preference_id is None: return None return request_parent + '/quotaPreferences/' + preference_id def _GetDimensions(messages, dimensions): if dimensions is None: return None dimensions_value = messages.QuotaPreference.DimensionsValue # sorted by key strings to maintain the unit test behavior consistency. return dimensions_value( additionalProperties=[ dimensions_value.AdditionalProperty( key=location, value=dimensions[location] ) for location in sorted(dimensions.keys()) ], ) def _GetJustification(email, justification): if email is not None and justification is not None: return 'email: %s. %s' % (email, justification) if email is None: return justification if justification is None: return 'email: %s.' % email return None def _GetIgnoreSafetyChecks(args, request): ignore_safety_checks = [] if args.allow_quota_decrease_below_usage: ignore_safety_checks.append( request.IgnoreSafetyChecksValueValuesEnum.QUOTA_DECREASE_BELOW_USAGE ) if args.allow_high_percentage_quota_decrease: ignore_safety_checks.append( request.IgnoreSafetyChecksValueValuesEnum.QUOTA_DECREASE_PERCENTAGE_TOO_HIGH ) return ignore_safety_checks def _GetFilter(custom_filter, reconciling_only): if custom_filter is not None and reconciling_only: return custom_filter + ' AND ' + _RECONCILING_ONLY_FILTER if reconciling_only: return _RECONCILING_ONLY_FILTER if custom_filter is not None: return custom_filter return None def CreateQuotaPreference( args, release_track: base.ReleaseTrack = base.ReleaseTrack.ALPHA ): """Creates a new QuotaPreference that declares the desired value for a quota. Args: args: argparse.Namespace, The arguments that this command was invoked with. release_track: base.ReleaseTrack, The release track to use. Returns: The created QuotaPreference """ consumer = message_util.CreateConsumer( args.project, args.folder, args.organization ) client = _GetClientInstance(release_track) messages = client.MESSAGES_MODULE parent = _CONSUMER_LOCATION_RESOURCE % (consumer) quota_preference = messages.QuotaPreference( name=_GetPreferenceName(parent, args.preference_id), dimensions=_GetDimensions(messages, args.dimensions), quotaConfig=messages.QuotaConfig( preferredValue=int(args.preferred_value) ), service=args.service, quotaId=args.quota_id, justification=_GetJustification(args.email, args.justification), contactEmail=args.email, ) if args.project: request = messages.CloudquotasProjectsLocationsQuotaPreferencesCreateRequest( parent=parent, quotaPreferenceId=args.preference_id, quotaPreference=quota_preference, ignoreSafetyChecks=_GetIgnoreSafetyChecks( args, messages.CloudquotasProjectsLocationsQuotaPreferencesCreateRequest, ), ) return client.projects_locations_quotaPreferences.Create(request) if args.folder: request = messages.CloudquotasFoldersLocationsQuotaPreferencesCreateRequest( parent=parent, quotaPreferenceId=args.preference_id, quotaPreference=quota_preference, ignoreSafetyChecks=_GetIgnoreSafetyChecks( args, messages.CloudquotasFoldersLocationsQuotaPreferencesCreateRequest, ), ) return client.folders_locations_quotaPreferences.Create(request) if args.organization: request = messages.CloudquotasOrganizationsLocationsQuotaPreferencesCreateRequest( parent=parent, quotaPreferenceId=args.preference_id, quotaPreference=quota_preference, ignoreSafetyChecks=_GetIgnoreSafetyChecks( args, messages.CloudquotasOrganizationsLocationsQuotaPreferencesCreateRequest, ), ) return client.organizations_locations_quotaPreferences.Create(request) def UpdateQuotaPreference( args, release_track: base.ReleaseTrack = base.ReleaseTrack.ALPHA ): """Updates the parameters of a single QuotaPreference. Args: args: argparse.Namespace, The arguments that this command was invoked with. release_track: base.ReleaseTrack, The release track to use. Returns: The updated QuotaPreference. """ consumer = message_util.CreateConsumer( args.project, args.folder, args.organization ) client = _GetClientInstance(release_track) messages = client.MESSAGES_MODULE preference_name = _GetPreferenceName( _CONSUMER_LOCATION_RESOURCE % (consumer), args.PREFERENCE_ID ) quota_preference = messages.QuotaPreference( name=preference_name, dimensions=_GetDimensions(messages, args.dimensions), quotaConfig=messages.QuotaConfig( preferredValue=int(args.preferred_value) ), service=args.service, quotaId=args.quota_id, justification=_GetJustification(args.email, args.justification), contactEmail=args.email, ) if args.project: request = messages.CloudquotasProjectsLocationsQuotaPreferencesPatchRequest( name=preference_name, quotaPreference=quota_preference, allowMissing=args.allow_missing, validateOnly=args.validate_only, ignoreSafetyChecks=_GetIgnoreSafetyChecks( args, messages.CloudquotasProjectsLocationsQuotaPreferencesPatchRequest, ), ) return client.projects_locations_quotaPreferences.Patch(request) if args.folder: request = messages.CloudquotasFoldersLocationsQuotaPreferencesPatchRequest( name=preference_name, quotaPreference=quota_preference, allowMissing=args.allow_missing, validateOnly=args.validate_only, ignoreSafetyChecks=_GetIgnoreSafetyChecks( args, messages.CloudquotasFoldersLocationsQuotaPreferencesPatchRequest, ), ) return client.folders_locations_quotaPreferences.Patch(request) if args.organization: request = messages.CloudquotasOrganizationsLocationsQuotaPreferencesPatchRequest( name=preference_name, quotaPreference=quota_preference, allowMissing=args.allow_missing, validateOnly=args.validate_only, ignoreSafetyChecks=_GetIgnoreSafetyChecks( args, messages.CloudquotasOrganizationsLocationsQuotaPreferencesPatchRequest, ), ) return client.organizations_locations_quotaPreferences.Patch(request) def GetQuotaPreference( args, release_track: base.ReleaseTrack = base.ReleaseTrack.ALPHA ): """Retrieve the QuotaPreference for a project, folder or organization. Args: args: argparse.Namespace, The arguments that this command was invoked with. release_track: base.ReleaseTrack, The release track to use. Returns: The request QuotaPreference. """ consumer = message_util.CreateConsumer( args.project, args.folder, args.organization ) client = _GetClientInstance(release_track) messages = client.MESSAGES_MODULE name = ( _CONSUMER_LOCATION_RESOURCE % (consumer) + '/quotaPreferences/%s' % args.PREFERENCE_ID ) if args.project: request = messages.CloudquotasProjectsLocationsQuotaPreferencesGetRequest( name=name ) return client.projects_locations_quotaPreferences.Get(request) if args.folder: request = messages.CloudquotasFoldersLocationsQuotaPreferencesGetRequest( name=name ) return client.folders_locations_quotaPreferences.Get(request) if args.organization: request = ( messages.CloudquotasOrganizationsLocationsQuotaPreferencesGetRequest( name=name ) ) return client.organizations_locations_quotaPreferences.Get(request) def ListQuotaPreferences( args, release_track: base.ReleaseTrack = base.ReleaseTrack.ALPHA ): """Lists QuotaPreferences in a given project, folder or organization. Args: args: argparse.Namespace, The arguments that this command was invoked with. release_track: base.ReleaseTrack, The release track to use. Returns: List of QuotaPreferences. """ consumer = message_util.CreateConsumer( args.project, args.folder, args.organization ) client = _GetClientInstance(release_track) messages = client.MESSAGES_MODULE parent = _CONSUMER_LOCATION_RESOURCE % consumer print(args.page_size) if args.project: request = messages.CloudquotasProjectsLocationsQuotaPreferencesListRequest( parent=parent, pageSize=args.page_size, filter=_GetFilter(args.filter, args.reconciling_only), orderBy=common_args.ParseSortByArg(args.sort_by), ) return list_pager.YieldFromList( client.projects_locations_quotaPreferences, request, batch_size_attribute='pageSize', batch_size=args.page_size if args.page_size is not None else PAGE_SIZE, field='quotaPreferences', limit=args.limit, ) if args.folder: request = messages.CloudquotasFoldersLocationsQuotaPreferencesListRequest( parent=parent, pageSize=args.page_size, filter=_GetFilter(args.filter, args.reconciling_only), orderBy=common_args.ParseSortByArg(args.sort_by), ) return list_pager.YieldFromList( client.folders_locations_quotaPreferences, request, batch_size_attribute='pageSize', batch_size=args.page_size if args.page_size is not None else PAGE_SIZE, field='quotaPreferences', limit=args.limit, ) if args.organization: request = ( messages.CloudquotasOrganizationsLocationsQuotaPreferencesListRequest( parent=parent, pageSize=args.page_size, filter=_GetFilter(args.filter, args.reconciling_only), orderBy=common_args.ParseSortByArg(args.sort_by), ) ) return list_pager.YieldFromList( client.organizations_locations_quotaPreferences, request, batch_size_attribute='pageSize', batch_size=args.page_size if args.page_size is not None else PAGE_SIZE, field='quotaPreferences', limit=args.limit, )