HEX
Server: Apache/2.4.65 (Ubuntu)
System: Linux ielts-store-v2 6.8.0-1036-gcp #38~22.04.1-Ubuntu SMP Thu Aug 14 01:19:18 UTC 2025 x86_64
User: root (0)
PHP: 7.2.34-54+ubuntu20.04.1+deb.sury.org+1
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,
Upload Files
File: //snap/google-cloud-cli/current/lib/googlecloudsdk/command_lib/app/create_util.py
# -*- coding: utf-8 -*- #
# Copyright 2016 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 app creation."""

from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.core import exceptions
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io


APP_CREATE_WARNING = """\
Creating an App Engine application for a project is irreversible and the region
cannot be changed. More information about regions is at
<https://cloud.google.com/appengine/docs/locations>.
"""
DEFAULT_MAX_INSTANCES_FORWARD_CHANGE_WARNING = """\
Starting from March, 2025, App Engine sets the automatic scaling maximum instances
default for standard environment deployments to 20. This change doesn't impact
existing apps. To override the default, specify the new max_instances value in your
app.yaml file, and deploy a new version or redeploy over an existing version.
For more details on max_instances, see
<https://cloud.google.com/appengine/docs/standard/reference/app-yaml.md#scaling_elements>.
"""

TRY_CLOUD_RUN_NUDGE_MSG = """\
Cloud Run offers the most modern fully managed application hosting experience
with lower minimum billable times and support for GPUs on demand for your AI/ML workloads.
Deploy code written in any programming language supported by App Engine on Cloud Run.
Learn more at https://cloud.google.com/run/docs/quickstarts#build-and-deploy-a-web-service
"""


class UnspecifiedRegionError(exceptions.Error):
  """Region is not provided on the command line and running interactively."""


class AppAlreadyExistsError(exceptions.Error):
  """The app which is getting created already exists."""


def AddAppCreateFlags(parser):
  """Add the common flags to a app create command."""
  parser.add_argument(
      '--region',
      help=(
          'The region to create the app within.  '
          'Use `gcloud app regions list` to list available regions.  '
          'If not provided, select region interactively.'
      ),
  )
  parser.add_argument(
      '--service-account',
      help=("""\
          The app-level default service account to create the app with.
          Note that you can specify a distinct service account for each
          App Engine version with `gcloud app deploy --service-account`.
          However if you do not specify a version-level service account,
          this default will be used. If this parameter is not provided for app
          creation, the app-level default will be set to be the out-of-box
          App Engine Default Service Account,
          https://cloud.google.com/appengine/docs/standard/python3/service-account
          outlines the limitation of that service account."""),
  )
  parser.add_argument(
      '--ssl-policy',
      choices=['TLS_VERSION_1_0', 'TLS_VERSION_1_2'],
      help='The app-level SSL policy to create the app with.',
  )


def CheckAppNotExists(api_client, project):
  """Raises an error if the app already exists.

  Args:
    api_client: The App Engine Admin API client
    project: The GCP project

  Raises:
    AppAlreadyExistsError if app already exists
  """
  try:
    app = api_client.GetApplication()  # Should raise NotFoundError
  except apitools_exceptions.HttpNotFoundError:
    pass
  else:
    region = ' in region [{}]'.format(app.locationId) if app.locationId else ''
    raise AppAlreadyExistsError(
        'The project [{project}] already contains an App Engine '
        'application{region}.  You can deploy your application using '
        '`gcloud app deploy`.'.format(project=project, region=region))


def CreateApp(
    api_client,
    project,
    region,
    suppress_warning=False,
    service_account=None,
    ssl_policy=None,
):
  """Create an App Engine app in the given region.

  Prints info about the app being created and displays a progress tracker.

  Args:
    api_client: The App Engine Admin API client
    project: The GCP project
    region: The region to create the app
    suppress_warning: True if user doesn't need to be warned this is
      irreversible.
    service_account: The app level service account for the App Engine app.
    ssl_policy: str, the app-level SSL policy to update for this App Engine app.
      Can be default or modern.

  Raises:
    AppAlreadyExistsError if app already exists
  """

  ssl_policy_enum = {
      'TLS_VERSION_1_0': (
          api_client.messages.Application.SslPolicyValueValuesEnum.DEFAULT
      ),
      'TLS_VERSION_1_2': (
          api_client.messages.Application.SslPolicyValueValuesEnum.MODERN
      ),
  }.get(ssl_policy)

  if not suppress_warning:
    log.status.Print(
        'You are creating an app for project [{project}].'.format(
            project=project
        )
    )
    if service_account:
      log.status.Print(
          'Designating app-level default service account to be '
          '[{service_account}].'.format(service_account=service_account)
      )
    if ssl_policy_enum:
      log.status.Print(
          'Designating app-level SSL policy to be [{ssl_policy}].'.format(
              ssl_policy=ssl_policy
          )
      )
    log.warning(APP_CREATE_WARNING)
    # TODO: b/388712720 - Cleanup warning once backend experiments are cleaned
    log.warning(DEFAULT_MAX_INSTANCES_FORWARD_CHANGE_WARNING)

    log.status.Print('NOTE: ' + TRY_CLOUD_RUN_NUDGE_MSG)
  try:
    api_client.CreateApp(
        region, service_account=service_account, ssl_policy=ssl_policy_enum
    )
  except apitools_exceptions.HttpConflictError:
    raise AppAlreadyExistsError(
        'The project [{project}] already contains an App Engine application. '
        'You can deploy your application using `gcloud app deploy`.'.format(
            project=project))


def CreateAppInteractively(
    api_client,
    project,
    regions=None,
    extra_warning='',
    service_account=None,
    ssl_policy=None,
):
  """Interactively choose a region and create an App Engine app.

  The caller is responsible for calling this method only when the user can be
  prompted interactively.

  Example interaction:

      Please choose the region where you want your App Engine application
      located:

        [1] us-east1      (supports standard and flexible)
        [2] europe-west   (supports standard)
        [3] us-central    (supports standard and flexible)
        [4] cancel
      Please enter your numeric choice:  1

  Args:
    api_client: The App Engine Admin API client
    project: The GCP project
    regions: The list of regions to choose from; if None, all possible regions
      are listed
    extra_warning: An additional warning to print before listing regions.
    service_account: The app level service account for the App Engine app.
    ssl_policy: str, the app-level SSL policy to update for this App Engine app.
      Can be default or modern.

  Raises:
    AppAlreadyExistsError if app already exists
  """
  log.status.Print('You are creating an app for project [{}].'.format(project))
  log.warning(APP_CREATE_WARNING)
  # TODO: b/388712720 - Cleanup warning once backend experiments are cleaned
  log.warning(DEFAULT_MAX_INSTANCES_FORWARD_CHANGE_WARNING)

  log.status.Print('NOTE: ' + TRY_CLOUD_RUN_NUDGE_MSG)
  regions = regions or sorted(set(api_client.ListRegions()), key=str)
  if extra_warning:
    log.warning(extra_warning)
  idx = console_io.PromptChoice(
      regions,
      message=(
          'Please choose the region where you want your App Engine '
          'application located:\n\n'
      ),
      cancel_option=True,
  )
  region = regions[idx]
  CreateApp(
      api_client,
      project,
      region.region,
      suppress_warning=True,
      service_account=service_account,
      ssl_policy=ssl_policy,
  )