def BrowseApp(project, service, version, launch_browser): """Let you browse the given service at the given version. Args: project: str, project ID. service: str, specific service, 'default' if None version: str, specific version, latest if None launch_browser: boolean, if False only print url Returns: None if the browser should open the URL The relevant output as a dict for calliope format to print if not Raises: MissingApplicationError: If an app does not exist. """ try: url = deploy_command_util.GetAppHostname(app_id=project, service=service, version=version, use_ssl=appinfo.SECURE_HTTPS, deploy=False) except api_lib_exceptions.NotFoundError: log.debug('No app found:', exc_info=True) raise exceptions.MissingApplicationError(project) if check_browser.ShouldLaunchBrowser(launch_browser): OpenURL(url) return None else: return { 'url': url, 'service': service or 'default', 'version': version, }
def _PossiblyCreateApp(api_client, project): """Returns an app resource, and creates it if the stars are aligned. App creation happens only if the current project is app-less, we are running in interactive mode and the user explicitly wants to. Args: api_client: Admin API client. project: The GCP project/app id. Returns: An app object (never returns None). Raises: MissingApplicationError: If an app does not exist and cannot be created. """ try: return api_client.GetApplication() except api_lib_exceptions.NotFoundError: # Invariant: GCP Project does exist but (singleton) GAE app is not yet # created. # # Check for interactive mode, since this action is irreversible and somewhat # surprising. CreateAppInteractively will provide a cancel option for # interactive users, and MissingApplicationException includes instructions # for non-interactive users to fix this. log.debug('No app found:', exc_info=True) if console_io.CanPrompt(): # Equivalent to running `gcloud app create` create_util.CreateAppInteractively(api_client, project) # App resource must be fetched again return api_client.GetApplication() raise exceptions.MissingApplicationError(project)
def _PossiblyCreateApp(api_client, project, app_create): """Returns an app resource, and creates it if the stars are aligned. App creation happens only if the current project is app-less, app_create is True, we are running in interactive mode and the user explicitly wants to. Args: api_client: Admin API client. project: The GCP project/app id. app_create: True if interactive app creation should be allowed. Returns: An app object (never returns None). Raises: MissingApplicationError: If an app does not exist and cannot be created. """ try: return api_client.GetApplication() except api_lib_exceptions.NotFoundError: # Invariant: GCP Project does exist but (singleton) GAE app is not yet # created. Offer to create one if the following conditions are true: # 1. `app_create` is True (currently `beta` only) # 2. We are currently running in interactive mode msg = output_helpers.CREATE_APP_PROMPT.format(project=project) if (app_create and console_io.CanPrompt() and console_io.PromptContinue(message=msg)): # Equivalent to running `gcloud beta app create` create_util.CreateAppInteractively(api_client, project) # App resource must be fetched again return api_client.GetApplication() raise exceptions.MissingApplicationError(project)
def Describe(api_client): try: return api_client.GetApplication() except apitools_exceptions.HttpNotFoundError: log.debug('No app found:', exc_info=True) project = api_client.project raise exceptions.MissingApplicationError(project)
def Run(self, args): api_client = appengine_api_client.GetApiClient() try: return api_client.GetApplication() except api_lib_exceptions.NotFoundError: log.debug('No app found:', exc_info=True) project = api_client.project raise exceptions.MissingApplicationError(project)
def _PossiblyCreateApp(api_client, project): """Returns an app resource, and creates it if the stars are aligned. App creation happens only if the current project is app-less, we are running in interactive mode and the user explicitly wants to. Args: api_client: Admin API client. project: The GCP project/app id. Returns: An app object (never returns None). Raises: MissingApplicationError: If an app does not exist and cannot be created. """ try: return api_client.GetApplication() except apitools_exceptions.HttpNotFoundError: # Invariant: GCP Project does exist but (singleton) GAE app is not yet # created. # # Check for interactive mode, since this action is irreversible and somewhat # surprising. CreateAppInteractively will provide a cancel option for # interactive users, and MissingApplicationException includes instructions # for non-interactive users to fix this. log.debug('No app found:', exc_info=True) if console_io.CanPrompt(): # Equivalent to running `gcloud app create` create_util.CreateAppInteractively(api_client, project) # App resource must be fetched again return api_client.GetApplication() raise exceptions.MissingApplicationError(project) except apitools_exceptions.HttpForbiddenError: active_account = properties.VALUES.core.account.Get() # pylint: disable=protected-access raise core_api_exceptions.HttpException( ('Permissions error fetching application [{}]. Please ' 'make sure that you have permission to view applications on the ' 'project and that {} has the App Engine Deployer ' '(roles/appengine.deployer) role.'.format(api_client._FormatApp(), active_account)))
def BrowseApp(project, service=None, version=None): """Open the app in a browser, optionally with given service and version. Args: project: str, project ID. service: str, (optional) specific service, defaults to 'default' version: str, (optional) specific version, defaults to latest Raises: MissingApplicationError: If an app does not exist. """ try: url = deploy_command_util.GetAppHostname(app_id=project, service=service, version=version, use_ssl=appinfo.SECURE_HTTPS, deploy=False) except api_lib_exceptions.NotFoundError: log.debug('No app found:', exc_info=True) raise exceptions.MissingApplicationError(project) OpenURL(url)
def RunDeploy(unused_self, args, enable_endpoints=False): """Perform a deployment based on the given args.""" version_id = args.version or util.GenerateVersionId() flags.ValidateVersion(version_id) project = properties.VALUES.core.project.Get(required=True) deploy_options = DeployOptions.FromProperties(enable_endpoints) # Parse existing app.yamls or try to generate a new one if the directory is # empty. if not args.deployables: yaml_path = deploy_command_util.DEFAULT_DEPLOYABLE if not os.path.exists(deploy_command_util.DEFAULT_DEPLOYABLE): log.warning('Automatic app detection is currently in Beta') yaml_path = deploy_command_util.CreateAppYamlForAppDirectory( os.getcwd()) app_config = yaml_parsing.AppConfigSet([yaml_path]) else: app_config = yaml_parsing.AppConfigSet(args.deployables) services = app_config.Services() flags.ValidateImageUrl(args.image_url, services) # The new API client. api_client = appengine_api_client.GetApiClient() # pylint: disable=protected-access log.debug('API endpoint: [{endpoint}], API version: [{version}]'.format( endpoint=api_client.client.url, version=api_client.client._VERSION)) # The legacy admin console API client. # The Admin Console API existed long before the App Engine Admin API, and # isn't being improved. We're in the process of migrating all of the calls # over to the Admin API, but a few things (notably config deployments) haven't # been ported over yet. ac_client = appengine_client.AppengineClient(args.server, args.ignore_bad_certs) # Tell the user what is going to happen, and ask them to confirm. deployed_urls = output_helpers.DisplayProposedDeployment( project, app_config, version_id, deploy_options.promote) console_io.PromptContinue(cancel_on_no=True) # Do generic app setup if deploying any services. if services: try: # TODO(b/31064052): Do this before displaying the proposed deployment and # reuse the default hostname from the app app = api_client.GetApplication() except api_lib_exceptions.AppNotFoundError: raise exceptions.MissingApplicationError(project) # All deployment paths for a service involve uploading source to GCS. code_bucket_ref = args.bucket or flags.GetCodeBucket(app, project) metrics.CustomTimedEvent(metric_names.GET_CODE_BUCKET) log.debug( 'Using bucket [{b}].'.format(b=code_bucket_ref.ToBucketUrl())) # Prepare Flex if any service is going to deploy an image. if any([m.RequiresImage() for m in services.values()]): deploy_command_util.DoPrepareManagedVms(ac_client) all_services = dict([(s.id, s) for s in api_client.ListServices()]) else: code_bucket_ref = None all_services = {} new_versions = [] deployer = ServiceDeployer(api_client, deploy_options) for (name, service) in services.iteritems(): new_version = version_util.Version(project, name, version_id) deployer.Deploy(service, new_version, code_bucket_ref, args.image_url, all_services) new_versions.append(new_version) log.status.Print('Deployed service [{0}] to [{1}]'.format( name, deployed_urls[name])) # Deploy config files. for (name, config) in app_config.Configs().iteritems(): message = 'Updating config [{config}]'.format(config=name) with console_io.ProgressTracker(message): ac_client.UpdateConfig(name, config.parsed) PrintPostDeployHints(new_versions) # Return all the things that were deployed. return {'versions': new_versions, 'configs': app_config.Configs().keys()}