Пример #1
0
 def QuotaProject(self, enable_resource_quota, force_resource_quota,
                  allow_account_impersonation, use_google_auth):
     if not (enable_resource_quota or force_resource_quota):
         return None
     creds = store.LoadIfEnabled(allow_account_impersonation,
                                 use_google_auth)
     return core_creds.GetQuotaProject(creds, force_resource_quota)
Пример #2
0
 def _RunReceiveLocalData(self, conn, socket_address):
     """Receive data from provided local connection and send over WebSocket."""
     websocket_conn = None
     try:
         websocket_conn = self._InitiateWebSocketConnection(
             conn,
             functools.partial(_GetAccessTokenCallback,
                               store.LoadIfEnabled()))
         while not self._shutdown:
             data = conn.recv(utils.SUBPROTOCOL_MAX_DATA_FRAME_SIZE)
             if not data:
                 break
             websocket_conn.Send(data)
     finally:
         if self._shutdown:
             log.info('Terminating connection to [%r].', socket_address)
         else:
             log.info('Client closed connection from [%r].', socket_address)
         try:
             conn.close()
         except EnvironmentError:
             pass
         try:
             if websocket_conn:
                 websocket_conn.Close()
         except (EnvironmentError, exceptions.Error):
             pass
Пример #3
0
def Http(timeout='unset'):
    """Get an httplib2.Http client for working with the Google API.

  Args:
    timeout: double, The timeout in seconds to pass to httplib2.  This is the
        socket level timeout.  If timeout is None, timeout is infinite.  If
        default argument 'unset' is given, a sensible default is selected.

  Returns:
    An authorized httplib2.Http client object, or a regular httplib2.Http object
    if no credentials are available.

  Raises:
    c_store.Error: If an error loading the credentials occurs.
  """
    http_client = http.Http(timeout=timeout)

    authority_selector = properties.VALUES.auth.authority_selector.Get()
    authorization_token_file = (
        properties.VALUES.auth.authorization_token_file.Get())
    if authority_selector or authorization_token_file:
        http_client = _WrapRequestForIAMAuth(http_client, authority_selector,
                                             authorization_token_file)

    creds = store.LoadIfEnabled()
    if creds:
        http_client = creds.authorize(http_client)
        # Wrap the request method to put in our own error handling.
        http_client = http.Modifiers.WrapRequest(
            http_client, [], _HandleAuthError, client.AccessTokenRefreshError)

    return http_client
Пример #4
0
 def _TestConnection(self):
   log.status.Print('Testing if tunnel connection works.')
   websocket_conn = self._InitiateWebSocketConnection(
       None,
       functools.partial(_GetAccessTokenCallback,
                         store.LoadIfEnabled(use_google_auth=True)))
   websocket_conn.Close()
Пример #5
0
def _getCreds():
    if not GOOGLE_CLOUD_SDK_ROOT:
        raise Exception("Unable to find the Google Cloud SDK - make sure it's installed, "
                        "gcloud utility is in the PATH and configured properly")

    global GOOGLE_CLOUD_SDK_CREDS
    if not GOOGLE_CLOUD_SDK_CREDS:
        from googlecloudsdk.core.credentials import store
        store.DevShellCredentialProvider().Register()
        store.GceCredentialProvider().Register()
        GOOGLE_CLOUD_SDK_CREDS = store.LoadIfEnabled()
    elif GOOGLE_CLOUD_SDK_CREDS.access_token_expired:
        print('DEBUG: Updating credentials token')
        from googlecloudsdk.core.credentials import store
        GOOGLE_CLOUD_SDK_CREDS = store.LoadIfEnabled()

    return GOOGLE_CLOUD_SDK_CREDS
Пример #6
0
def Http(timeout='unset', enable_resource_quota=True,
         force_resource_quota=False, response_encoding=None, ca_certs=None,
         allow_account_impersonation=True):
  """Get an httplib2.Http client for working with the Google API.

  Args:
    timeout: double, The timeout in seconds to pass to httplib2.  This is the
        socket level timeout.  If timeout is None, timeout is infinite.  If
        default argument 'unset' is given, a sensible default is selected.
    enable_resource_quota: bool, By default, we are going to tell APIs to use
        the quota of the project being operated on. For some APIs we want to use
        gcloud's quota, so you can explicitly disable that behavior by passing
        False here.
    force_resource_quota: bool, If true resource project quota will be used by
      this client regardless of the settings in gcloud. This should be used for
      newer APIs that cannot work with legacy project quota.
    response_encoding: str, the encoding to use to decode the response.
    ca_certs: str, absolute filename of a ca_certs file that overrides the
        default
    allow_account_impersonation: bool, True to allow use of impersonated service
      account credentials for calls made with this client. If False, the active
      user credentials will always be used.

  Returns:
    An authorized httplib2.Http client object, or a regular httplib2.Http object
    if no credentials are available.

  Raises:
    c_store.Error: If an error loading the credentials occurs.
  """
  http_client = http.Http(timeout=timeout, response_encoding=response_encoding,
                          ca_certs=ca_certs)

  # Wrappers for IAM header injection.
  authority_selector = properties.VALUES.auth.authority_selector.Get()
  authorization_token_file = (
      properties.VALUES.auth.authorization_token_file.Get())
  handlers = _GetIAMAuthHandlers(authority_selector, authorization_token_file)

  creds = store.LoadIfEnabled(
      allow_account_impersonation=allow_account_impersonation)
  if creds:
    # Inject the resource project header for quota unless explicitly disabled.
    if enable_resource_quota or force_resource_quota:
      quota_project = _GetQuotaProject(creds, force_resource_quota)
      if quota_project:
        handlers.append(http.Modifiers.Handler(
            http.Modifiers.SetHeader('X-Goog-User-Project', quota_project)))

    http_client = creds.authorize(http_client)
    # Wrap the request method to put in our own error handling.
    http_client = http.Modifiers.WrapRequest(
        http_client, handlers, _HandleAuthError, client.AccessTokenRefreshError)

  return http_client
Пример #7
0
def PossiblyEnableFlex(project):
    """Attempts to enable the Flexible Environment API on the project.

  Possible scenarios:
  -If Flexible Environment is already enabled, success.
  -If Flexible Environment API is not yet enabled, attempts to enable it. If
   that succeeds, success.
  -If the account doesn't have permissions to confirm that the Flexible
   Environment API is or isn't enabled on this project, succeeds with a warning.
     -If the account is a service account, adds an additional warning that
      the Service Management API may need to be enabled.
  -If the Flexible Environment API is not enabled on the project and the attempt
   to enable it fails, raises PrepareFailureError.

  Args:
    project: str, the project ID.

  Raises:
    PrepareFailureError: if enabling the API fails with a 403 or 404 error code.
    googlecloudsdk.api_lib.util.exceptions.HttpException: miscellaneous errors
        returned by server.
  """
    try:
        log.warn(
            'Checking the status of the Appengine Flexible Environment API '
            'during Appengine Flexible deployments is currently in beta.')
        enable_api.EnableServiceIfDisabled(project,
                                           'appengineflex.googleapis.com')
    except sm_exceptions.ListServicesPermissionDeniedException:
        # If we can't find out whether the Flexible API is enabled, proceed with
        # a warning.
        warning = FLEXIBLE_SERVICE_VERIFY_WARNING.format(project)
        # If user is using a service account, add more info about what might
        # have gone wrong.
        credential = c_store.LoadIfEnabled()
        if credential:
            account_type = creds.CredentialType.FromCredentials(credential)
            if account_type in (creds.CredentialType.SERVICE_ACCOUNT,
                                creds.CredentialType.P12_SERVICE_ACCOUNT):
                warning += '\n\n{}'.format(
                    FLEXIBLE_SERVICE_VERIFY_WITH_SERVICE_ACCOUNT)
        log.warn(warning)
    except sm_exceptions.EnableServicePermissionDeniedException:
        # If enabling the Flexible API fails due to a permissions error, the
        # deployment fails.
        raise PrepareFailureError(PREPARE_FAILURE_MSG.format(project))
    except api_lib_exceptions.HttpException as err:
        # The deployment should also fail if there are unforeseen errors in
        # enabling the Flexible API. If so, display detailed information.
        err.error_format = ('Error [{status_code}] {status_message}'
                            '{error.details?'
                            '\nDetailed error information:\n{?}}')
        raise err
Пример #8
0
def AuthorizeEnvironment():
    client = apis.GetClientInstance('cloudshell', 'v1alpha1')
    messages = apis.GetMessagesModule('cloudshell', 'v1alpha1')

    creds = store.LoadIfEnabled()
    access_token = None
    if creds is not None:
        access_token = creds.get_access_token().access_token
        client.users_environments.Authorize(
            messages.CloudshellUsersEnvironmentsAuthorizeRequest(
                name=DEFAULT_ENVIRONMENT_NAME,
                authorizeEnvironmentRequest=messages.
                AuthorizeEnvironmentRequest(accessToken=access_token)))
Пример #9
0
def Http(timeout='unset', enable_resource_quota=True):
    """Get an httplib2.Http client for working with the Google API.

  Args:
    timeout: double, The timeout in seconds to pass to httplib2.  This is the
        socket level timeout.  If timeout is None, timeout is infinite.  If
        default argument 'unset' is given, a sensible default is selected.
    enable_resource_quota: bool, By default, we are going to tell APIs to use
        the quota of the project being operated on. For some APIs we want to use
        gcloud's quota, so you can explicitly disable that behavior by passing
        False here.

  Returns:
    An authorized httplib2.Http client object, or a regular httplib2.Http object
    if no credentials are available.

  Raises:
    c_store.Error: If an error loading the credentials occurs.
  """
    http_client = http.Http(timeout=timeout)

    # Wrappers for IAM header injection.
    authority_selector = properties.VALUES.auth.authority_selector.Get()
    authorization_token_file = (
        properties.VALUES.auth.authorization_token_file.Get())
    handlers = _GetIAMAuthHandlers(authority_selector,
                                   authorization_token_file)

    # Inject the resource project header for quota unless explicitly disabled.
    if enable_resource_quota:
        quota_project = properties.VALUES.billing.quota_project.Get()
        if quota_project == properties.VALUES.billing.LEGACY:
            quota_project = None
        elif quota_project == properties.VALUES.billing.CURRENT_PROJECT:
            quota_project = properties.VALUES.core.project.Get()

        if quota_project:
            handlers.append(
                http.Modifiers.Handler(
                    http.Modifiers.SetHeader('X-Goog-User-Project',
                                             quota_project)))

    creds = store.LoadIfEnabled()
    if creds:
        http_client = creds.authorize(http_client)
        # Wrap the request method to put in our own error handling.
        http_client = http.Modifiers.WrapRequest(
            http_client, handlers, _HandleAuthError,
            client.AccessTokenRefreshError)

    return http_client
Пример #10
0
def GetGapicCredentials(enable_resource_quota=True,
                        allow_account_impersonation=True):
    """Returns a credential object for use by gapic client libraries.

  Currently, we set _quota_project on the credentials, unlike for http requests,
  which add quota project through request wrapping to implement
  go/gcloud-quota-model-v2.

  Additionally, we wrap the refresh method and plug in our own
  google.auth.transport.Request object that uses our transport.

  Args:
    enable_resource_quota: bool, By default, we are going to tell APIs to use
        the quota of the project being operated on. For some APIs we want to use
        gcloud's quota, so you can explicitly disable that behavior by passing
        False here.
    allow_account_impersonation: bool, True to allow use of impersonated service
        account credentials for calls made with this client. If False, the
        active user credentials will always be used.

  Returns:
    A google auth credentials.Credentials object.

  Raises:
    MissingStoredCredentialsError: If a google-auth credential cannot be loaded.
  """

    credentials = store.LoadIfEnabled(
        allow_account_impersonation=allow_account_impersonation,
        use_google_auth=True)
    if not creds.IsGoogleAuthCredentials(credentials):
        raise MissingStoredCredentialsError('Unable to load credentials')

    if enable_resource_quota:
        # pylint: disable=protected-access
        credentials._quota_project_id = creds.GetQuotaProject(credentials)

    # In order to ensure that credentials.Credentials:refresh is called with a
    # google.auth.transport.Request that uses our transport, we ignore the request
    # argument that is passed in and plug in our own.
    original_refresh = credentials.refresh

    def WrappedRefresh(request):
        del request  # unused
        return original_refresh(requests.GoogleAuthRequest())

    credentials.refresh = WrappedRefresh

    return credentials
Пример #11
0
    def WrapCredentials(self,
                        http_client,
                        allow_account_impersonation=True,
                        use_google_auth=None):
        """Get an http client for working with Google APIs.

    Args:
      http_client: The http client to be wrapped.
      allow_account_impersonation: bool, True to allow use of impersonated
        service account credentials for calls made with this client. If False,
        the active user credentials will always be used.
      use_google_auth: bool, True if the calling command indicates to use
        google-auth library for authentication. If False, authentication will
        fallback to using the oauth2client library. If None, set the value based
        the configuration.

    Returns:
      An authorized http client with exception handling.

    Raises:
      c_store.Error: If an error loading the credentials occurs.
    """

        # Wrappers for IAM header injection.
        authority_selector = properties.VALUES.auth.authority_selector.Get()
        authorization_token_file = (
            properties.VALUES.auth.authorization_token_file.Get())
        handlers = _GetIAMAuthHandlers(authority_selector,
                                       authorization_token_file)

        if use_google_auth is None:
            use_google_auth = base.UseGoogleAuth()
        creds = store.LoadIfEnabled(allow_account_impersonation,
                                    use_google_auth)
        if creds:
            http_client = self.AuthorizeClient(http_client, creds)
            # Set this attribute so we can access it later, even after the http_client
            # request method has been wrapped
            setattr(http_client, '_googlecloudsdk_credentials', creds)

        self.WrapRequest(http_client, handlers, _HandleAuthError,
                         (client.AccessTokenRefreshError,
                          google_auth_exceptions.RefreshError))

        return http_client
Пример #12
0
 def __init__(self,
              enable_resource_quota=True,
              force_resource_quota=False,
              allow_account_impersonation=True):
     super(StoredCredentials, self).__init__()
     self.stored_credentials = store.LoadIfEnabled(
         allow_account_impersonation=allow_account_impersonation,
         use_google_auth=True)
     if self.stored_credentials is None:
         raise MissingStoredCredentialsError()
     if creds.IsOauth2ClientCredentials(self.stored_credentials):
         self.token = self.stored_credentials.access_token
     else:
         self.token = self.stored_credentials.token
     if enable_resource_quota or force_resource_quota:
         self.quota_project_id = creds.GetQuotaProject(
             self.stored_credentials, force_resource_quota)
     else:
         self.quota_project_id = None
Пример #13
0
  def StartProxyServer(self):
    """Start accepting connections."""
    self._cred = store.LoadIfEnabled()
    self._TestConnection()
    self._server_shutdown = False
    self._server_socket = self._OpenLocalTcpSocket()

    self._connections = []
    try:
      with execution_utils.RaisesKeyboardInterrupt():
        while True:
          self._connections.append(self._AcceptNewConnection())
    except KeyboardInterrupt:
      log.info('Keyboard interrupt received.')
    finally:
      self._CloseServerSocket()

    self._server_shutdown = True
    self._CloseClientConnections()
    log.Print('Server shutdown complete.')
Пример #14
0
def AuthorizeEnvironment():
    """Pushes gcloud credentials to the user's environment."""

    client = apis.GetClientInstance('cloudshell', 'v1alpha1')
    messages = apis.GetMessagesModule('cloudshell', 'v1alpha1')

    # Load creds and refresh them if they're about to expire
    creds = store.LoadIfEnabled()
    if creds is not None and creds.token_expiry - creds.token_expiry.utcnow(
    ) < MIN_CREDS_EXPIRY:
        store.Refresh(creds)

    access_token = None
    if creds is not None:
        access_token = creds.get_access_token().access_token
        client.users_environments.Authorize(
            messages.CloudshellUsersEnvironmentsAuthorizeRequest(
                name=DEFAULT_ENVIRONMENT_NAME,
                authorizeEnvironmentRequest=messages.
                AuthorizeEnvironmentRequest(accessToken=access_token)))
Пример #15
0
    def _RunReceiveLocalData(self, conn, socket_address, user_agent):
        """Receive data from provided local connection and send over WebSocket.

    Args:
      conn: A socket or _StdinSocket representing the local connection.
      socket_address: A verbose loggable string describing where conn is
        connected to.
      user_agent: The user_agent of this connection
    """
        websocket_conn = None
        try:
            websocket_conn = self._InitiateWebSocketConnection(
                conn,
                functools.partial(_GetAccessTokenCallback,
                                  store.LoadIfEnabled(use_google_auth=True)),
                user_agent)
            while not self._shutdown:
                data = conn.recv(utils.SUBPROTOCOL_MAX_DATA_FRAME_SIZE)
                if not data:
                    # When we recv an EOF, we notify the websocket_conn of it, then we
                    # wait for all data to send before returning.
                    websocket_conn.LocalEOF()
                    if not websocket_conn.WaitForAllSent():
                        log.warning('Failed to send all data from [%s].',
                                    socket_address)
                    break
                websocket_conn.Send(data)
        finally:
            if self._shutdown:
                log.info('Terminating connection to [%s].', socket_address)
            else:
                log.info('Client closed connection from [%s].', socket_address)
            try:
                conn.close()
            except EnvironmentError:
                pass
            try:
                if websocket_conn:
                    websocket_conn.Close()
            except (EnvironmentError, exceptions.Error):
                pass
    def __init__(self, server=None, ignore_bad_certs=False):
        self.server = server or 'appengine.google.com'
        self.project = properties.VALUES.core.project.Get(required=True)
        self.ignore_bad_certs = ignore_bad_certs
        # Auth related options
        self.oauth2_access_token = None
        self.oauth2_refresh_token = None
        self.oauth_scopes = APPCFG_SCOPES
        self.authenticate_service_account = False
        self.client_id = None
        self.client_secret = None

        credentials = c_store.LoadIfEnabled()
        if credentials:
            if isinstance(credentials,
                          service_account.ServiceAccountCredentials):
                self.oauth2_access_token = credentials.access_token
                self.client_id = credentials.client_id
                self.client_secret = credentials.client_secret
            elif isinstance(credentials, c_devshell.DevshellCredentials):
                # TODO(b/36057357): This passes the access token to use for API calls to
                # appcfg which means that commands that are longer than the lifetime
                # of the access token may fail - e.g. some long deployments.  The proper
                # solution is to integrate appcfg closer with the Cloud SDK libraries,
                # this code will go away then and the standard credentials flow will be
                # used.
                self.oauth2_access_token = credentials.access_token
                self.client_id = None
                self.client_secret = None
            elif isinstance(credentials,
                            oauth2client_gce.AppAssertionCredentials):
                # If we are on GCE, use the service account
                self.authenticate_service_account = True
                self.client_id = None
                self.client_secret = None
            else:
                # Otherwise use a stored refresh token
                self.oauth2_refresh_token = credentials.refresh_token
                self.client_id = credentials.client_id
                self.client_secret = credentials.client_secret
Пример #17
0
def PrepareV1Environment(args):
    """Ensures that the user's environment is ready to accept SSH connections."""

    # Load Cloud Shell API.
    client = apis.GetClientInstance('cloudshell', 'v1')
    messages = apis.GetMessagesModule('cloudshell', 'v1')
    operations_client = apis.GetClientInstance('cloudshell', 'v1')

    # Ensure we have a key pair on the local machine.
    ssh_env = ssh.Environment.Current()
    ssh_env.RequireSSH()
    keys = ssh.Keys.FromFilename(filename=args.ssh_key_file)
    keys.EnsureKeysExist(overwrite=args.force_key_file_overwrite)

    # Look up the Cloud Shell environment.
    environment = client.users_environments.Get(
        messages.CloudshellUsersEnvironmentsGetRequest(
            name=DEFAULT_ENVIRONMENT_NAME))

    # If the environment doesn't have the public key, push it.
    key = keys.GetPublicKey().ToEntry()
    has_key = False
    for candidate in environment.publicKeys:
        if key == candidate:
            has_key = True
            break
    if not has_key:
        add_public_key_operation = client.users_environments.AddPublicKey(
            messages.CloudshellUsersEnvironmentsAddPublicKeyRequest(
                environment=DEFAULT_ENVIRONMENT_NAME,
                addPublicKeyRequest=messages.AddPublicKeyRequest(key=key),
            ))

        environment = waiter.WaitFor(EnvironmentPoller(
            client.users_environments, operations_client.operations),
                                     add_public_key_operation,
                                     'Pushing your public key to Cloud Shell',
                                     sleep_ms=500,
                                     max_wait_ms=None)

    # If the environment isn't running, start it.
    if environment.state != messages.Environment.StateValueValuesEnum.RUNNING:
        log.Print('Starting your Cloud Shell machine...')

        access_token = None
        if args.authorize_session:
            creds = store.LoadIfEnabled()
            if creds is not None and creds.token_expiry - creds.token_expiry.utcnow(
            ) < MIN_CREDS_EXPIRY:
                store.Refresh(creds)

            if creds is not None:
                access_token = creds.get_access_token().access_token

        start_operation = client.users_environments.Start(
            messages.CloudshellUsersEnvironmentsStartRequest(
                name=DEFAULT_ENVIRONMENT_NAME,
                startEnvironmentRequest=messages.StartEnvironmentRequest(
                    accessToken=access_token)))

        environment = waiter.WaitFor(
            EnvironmentPoller(client.users_environments,
                              operations_client.operations),
            start_operation,
            'Waiting for your Cloud Shell machine to start',
            sleep_ms=500,
            max_wait_ms=None)

    return ConnectionInfo(
        ssh_env=ssh_env,
        user=environment.sshUsername,
        host=environment.sshHost,
        port=environment.sshPort,
        key=keys.key_file,
    )
Пример #18
0
 def _TestConnection(self):
     log.Print('Testing if can connect.')
     websocket_conn = self._InitiateWebSocketConnection(
         None,
         functools.partial(_GetAccessTokenCallback, store.LoadIfEnabled()))
     websocket_conn.Close()
Пример #19
0
def PrepareEnvironment(args):
    """Ensures that the user's environment is ready to accept SSH connections."""

    # Load Cloud Shell API
    client = apis.GetClientInstance('cloudshell', 'v1alpha1')
    messages = apis.GetMessagesModule('cloudshell', 'v1alpha1')
    operations_client = apis.GetClientInstance('cloudshell', 'v1')

    # Ensure we have a key pair on the local machine
    ssh_env = ssh.Environment.Current()
    ssh_env.RequireSSH()
    keys = ssh.Keys.FromFilename(filename=args.ssh_key_file)
    keys.EnsureKeysExist(overwrite=args.force_key_file_overwrite)

    # Look up the Cloud Shell environment
    environment = client.users_environments.Get(
        messages.CloudshellUsersEnvironmentsGetRequest(
            name=DEFAULT_ENVIRONMENT_NAME))

    if args.boosted and environment.size != messages.Environment.SizeValueValuesEnum.BOOSTED:
        boosted_environment = messages.Environment(
            size=messages.Environment.SizeValueValuesEnum.BOOSTED)
        client.users_environments.Patch(
            messages.CloudshellUsersEnvironmentsPatchRequest(
                name=DEFAULT_ENVIRONMENT_NAME,
                updateMask='size',
                environment=boosted_environment))

    # If the environment doesn't have the public key, push it
    key_parts = keys.GetPublicKey().ToEntry().split(' ')
    key_format = ValidateKeyType(key_parts[0].replace('-', '_').upper(),
                                 messages)
    key = messages.PublicKey(
        format=key_format,
        key=base64.b64decode(key_parts[1]),
    )
    has_key = False
    for candidate in environment.publicKeys:
        if key.format == candidate.format and key.key == candidate.key:
            has_key = True
            break
    if not has_key:
        log.Print('Pushing your public key to Cloud Shell...')
        client.users_environments_publicKeys.Create(
            messages.CloudshellUsersEnvironmentsPublicKeysCreateRequest(
                parent=DEFAULT_ENVIRONMENT_NAME,
                createPublicKeyRequest=messages.CreatePublicKeyRequest(
                    key=key),
            ))

    # If the environment isn't running, start it
    if environment.state != messages.Environment.StateValueValuesEnum.RUNNING:
        log.Print('Starting your Cloud Shell machine...')

        creds = store.LoadIfEnabled()
        if creds is not None and creds.token_expiry - creds.token_expiry.utcnow(
        ) < MIN_CREDS_EXPIRY:
            store.Refresh(creds)

        access_token = None
        if creds is not None:
            access_token = creds.get_access_token().access_token

        start_operation = client.users_environments.Start(
            messages.CloudshellUsersEnvironmentsStartRequest(
                name=DEFAULT_ENVIRONMENT_NAME,
                startEnvironmentRequest=messages.StartEnvironmentRequest(
                    accessToken=access_token)))

        environment = waiter.WaitFor(
            StartEnvironmentPoller(client.users_environments,
                                   operations_client.operations),
            start_operation,
            'Waiting for your Cloud Shell machine to start',
            sleep_ms=500,
            max_wait_ms=None)

    return ConnectionInfo(
        ssh_env=ssh_env,
        user=environment.sshUsername,
        host=environment.sshHost,
        port=environment.sshPort,
        key=keys.key_file,
    )
Пример #20
0
 def password(self):
     cred = c_store.LoadIfEnabled()
     return cred.access_token if cred else None