# -*- coding: utf-8 -*- # # Copyright 2017 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. """services disable command.""" from googlecloudsdk.api_lib.services import services_util from googlecloudsdk.api_lib.services import serviceusage from googlecloudsdk.calliope import base from googlecloudsdk.command_lib.services import arg_parsers from googlecloudsdk.command_lib.services import common_flags from googlecloudsdk.core import log from googlecloudsdk.core import properties from googlecloudsdk.core.console import console_io OP_BASE_CMD = 'gcloud beta services operations ' OP_WAIT_CMD = OP_BASE_CMD + 'wait {0}' # TODO(b/321801975) make command public after preview. @base.UniverseCompatible @base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA) class DisableAlpha(base.SilentCommand): """Disable a service for consumption for a project, folder or organization. This command disables one or more previously-enabled services for consumption. To see a list of the enabled services for a project, run: $ {parent_command} list More information on listing services can be found at: https://cloud.google.com/service-usage/docs/list-services and on disabling a service at: https://cloud.google.com/service-usage/docs/enable-disable ## EXAMPLES To disable a service called `my-consumed-service` for the current project, run: $ {command} my-consumed-service To disable a service called `my-consumed-service` for the project `my-project`, run: $ {command} my-consumed-service --project=my-project To disable a service called `my-consumed-service` for the folder `my-folder`, run: $ {command} my-consumed-service --folder=my-folder To disable a service called `my-consumed-service` for the organization `my-organization`, run: $ {command} my-consumed-service --organization=my-organization To run the same command asynchronously (non-blocking), run: $ {command} my-consumed-service --async """ @staticmethod def Args(parser): """Args is called by calliope to gather arguments for this command. Args: parser: An argparse parser that you can use to add arguments that go on the command line after this command. Positional arguments are allowed. """ common_flags.consumer_service_flag(suffix='to disable').AddToParser(parser) common_flags.add_resource_args(parser) base.ASYNC_FLAG.AddToParser(parser) common_flags.validate_only_args(parser, suffix='disable') common_flags.bypass_api_usage_check_flag(parser) common_flags.add_dependency_check_args(parser) parser.add_argument( '--force', action='store_true', help=( 'If specified, the disable call will proceed even if there are' ' enabled services which depend on the service to be disabled, or' ' the service to be disabled was used in the last 30 days, or the' ' service to be disabled was enabled in the last 3 days. Forcing' ' the call means that the services which depend on the service to' ' be disabled will also be disabled. (Note): If ' ' --bypass-api-usage-check, --bypass-dependency-service-check, or' ' --disable-dependency-services flags are used, they will take' ' precedence over --force.' ), ) def Run(self, args): """Run 'services disable'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: Nothing. """ project = ( args.project if args.IsSpecified('project') else properties.VALUES.core.project.Get(required=True) ) folder = args.folder if args.IsSpecified('folder') else None organization = ( args.organization if args.IsSpecified('organization') else None ) bypass_api_usage_check = args.force # Default behaviour without any flags. # The operation will be blocked if there are # any enabled dependent services. skip_dependency_check = False disable_dependency_services = False # All dependent services will be disabled. if args.IsSpecified('force') or args.IsSpecified( 'disable_dependency_services' ): disable_dependency_services = True # API usage check of the service to be disabled will be bypassed. if args.IsSpecified('bypass_api_usage_check'): bypass_api_usage_check = True # All dependent services will remain enabled. if args.IsSpecified('bypass_dependency_service_check'): skip_dependency_check = True service_names = [] for service_name in args.service: service_name = arg_parsers.GetServiceNameFromArg(service_name) protected_msg = serviceusage.GetProtectedServiceWarning(service_name) if protected_msg: if args.IsSpecified('quiet'): raise console_io.RequiredPromptError() do_disable = console_io.PromptContinue( protected_msg, default=False, throw_if_unattended=True ) if not do_disable: continue service_names.append(service_name) if not service_names: return None op = serviceusage.RemoveEnableRule( project, service_names, force=bypass_api_usage_check, folder=folder, organization=organization, validate_only=args.validate_only, skip_dependency_check=skip_dependency_check, disable_dependency_services=disable_dependency_services, ) if op is None: return None if args.async_: cmd = OP_WAIT_CMD.format(op.name) log.status.Print( 'Asynchronous operation is in progress... Use the following' f' command to wait for its completion:\n {cmd}' ) op = services_util.WaitOperation(op.name, serviceusage.GetOperationV2Beta) if args.validate_only: services_util.PrintOperation(op) else: services_util.PrintOperationWithResponseForUpdateConsumerPolicy(op) @base.ReleaseTracks(base.ReleaseTrack.GA) class Disable(base.SilentCommand): """Disable a service for consumption for a project. This command disables one or more previously-enabled services for consumption. To see a list of the enabled services for a project, run: $ {parent_command} list More information on listing services can be found at: https://cloud.google.com/service-usage/docs/list-services and on disabling a service at: https://cloud.google.com/service-usage/docs/enable-disable ## EXAMPLES To disable a service called `my-consumed-service` for the active project, run: $ {command} my-consumed-service To run the same command asynchronously (non-blocking), run: $ {command} my-consumed-service --async """ @staticmethod def Args(parser): """Args is called by calliope to gather arguments for this command. Args: parser: An argparse parser that you can use to add arguments that go on the command line after this command. Positional arguments are allowed. """ common_flags.consumer_service_flag(suffix='to disable').AddToParser(parser) base.ASYNC_FLAG.AddToParser(parser) parser.add_argument( '--force', action='store_true', help=( 'If specified, the disable call will proceed even if there are' ' enabled services which depend on the service to be disabled or' ' disable the service used in last 30 days or was enabled in' ' recent 3 days. Forcing the call means that the services which' ' depend on the service to be disabled will also be disabled.' ), ) def Run(self, args): """Run 'services disable'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: Nothing. """ project = properties.VALUES.core.project.Get(required=True) for service_name in args.service: service_name = arg_parsers.GetServiceNameFromArg(service_name) protected_msg = serviceusage.GetProtectedServiceWarning(service_name) if protected_msg: if args.IsSpecified('quiet'): raise console_io.RequiredPromptError() do_disable = console_io.PromptContinue( protected_msg, default=False, throw_if_unattended=True ) if not do_disable: continue op = serviceusage.DisableApiCall(project, service_name, args.force) if op.done: continue if args.async_: cmd = OP_WAIT_CMD.format(op.name) log.status.Print( 'Asynchronous operation is in progress... ' 'Use the following command to wait for its ' f'completion:\n {cmd}' ) continue op = services_util.WaitOperation(op.name, serviceusage.GetOperation) services_util.PrintOperation(op)