def SetUpJsonCredentialsAndCache(api, logger, credentials=None): """Helper to ensure each GCS API client shares the same credentials.""" api.credentials = (credentials or _CheckAndGetCredentials(logger) or NoOpCredentials()) # Set credential cache so that we don't have to get a new access token for # every call we make. All GCS APIs use the same credentials as the JSON API, # so we use its version in the key for caching access tokens. credential_store_key = (GetCredentialStoreKey(api.credentials, GetGcsJsonApiVersion())) api.credentials.set_store( multiprocess_file_storage.MultiprocessFileStorage( GetCredentialStoreFilename(), credential_store_key)) # The cached entry for this credential often contains more context than what # we can construct from boto config attributes (e.g. for a user credential, # the cached version might also contain a RAPT token and expiry info). # Prefer the cached credential if present. cached_cred = None if not isinstance(api.credentials, NoOpCredentials): # A NoOpCredentials object doesn't actually have a store attribute. cached_cred = api.credentials.store.get() # As of gsutil 4.31, we never use the OAuth2Credentials class for # credentials directly; rather, we use subclasses (user credentials were # the only ones left using it, but they now use # Oauth2WithReauthCredentials). If we detect that a cached credential is # an instance of OAuth2Credentials and not a subclass of it (as might # happen when transitioning to version v4.31+), we don't fetch it from the # cache. This results in our new-style credential being refreshed and # overwriting the old credential cache entry in our credstore. if (cached_cred and type(cached_cred) != oauth2client.client.OAuth2Credentials): api.credentials = cached_cred
def __init__(self, logger=None, credentials=None, debug=0): """Performs necessary setup for interacting with Google Cloud Pub/Sub. Args: logger: logging.logger for outputting log messages. credentials: Credentials to be used for interacting with Google Cloud Pub/Sub debug: Debug level for the API implementation (0..3). """ super(PubsubApi, self).__init__() self.logger = logger no_op_credentials = False if not credentials: loaded_credentials = CheckAndGetCredentials(logger) if not loaded_credentials: loaded_credentials = NoOpCredentials() no_op_credentials = True else: if isinstance(credentials, NoOpCredentials): no_op_credentials = True self.credentials = credentials or loaded_credentials self.certs_file = GetCertsFile() self.http = GetNewHttp() self.http_base = 'https://' self.host_base = config.get('Credentials', 'gs_pubsub_host', 'pubsub.googleapis.com') gs_pubsub_port = config.get('Credentials', 'gs_pubsub_port', None) if not gs_pubsub_port: self.host_port = '' else: self.host_port = ':' + gs_pubsub_port self.url_base = (self.http_base + self.host_base + self.host_port) self.num_retries = GetNumRetries() self.max_retry_wait = GetMaxRetryDelay() log_request = (debug >= 3) log_response = (debug >= 3) self.api_client = apitools_client.PubsubV1( url=self.url_base, http=self.http, log_request=log_request, log_response=log_response, credentials=self.credentials) self.api_client.max_retry_wait = self.max_retry_wait self.api_client.num_retries = self.num_retries if no_op_credentials: # This API key is not secret and is used to identify gsutil during # anonymous requests. self.api_client.AddGlobalParam( 'key', u'AIzaSyDnacJHrKma0048b13sh8cgxNUwulubmJM')
def MaybeCheckForAndOfferSoftwareUpdate(self, command_name, debug): """Checks the last time we checked for an update and offers one if needed. Offer is made if the time since the last update check is longer than the configured threshold offers the user to update gsutil. Args: command_name: The name of the command being run. debug: Debug level to pass in to boto connection (range 0..3). Returns: True if the user decides to update. """ # Don't try to interact with user if: # - gsutil is not connected to a tty (e.g., if being run from cron); # - user is running gsutil -q # - user is running the config command (which could otherwise attempt to # check for an update for a user running behind a proxy, who has not yet # configured gsutil to go through the proxy; for such users we need the # first connection attempt to be made by the gsutil config command). # - user is running the version command (which gets run when using # gsutil -D, which would prevent users with proxy config problems from # sending us gsutil -D output). # - user is running the update command (which could otherwise cause an # additional note that an update is available when user is already trying # to perform an update); # - user specified gs_host (which could be a non-production different # service instance, in which case credentials won't work for checking # gsutil tarball). # - user is using a Cloud SDK install (which should only be updated via # gcloud components update) logger = logging.getLogger() gs_host = boto.config.get('Credentials', 'gs_host', None) gs_host_is_not_default = (gs_host != boto.gs.connection.GSConnection.DefaultHost) if (not system_util.IsRunningInteractively() or command_name in ('config', 'update', 'ver', 'version') or not logger.isEnabledFor(logging.INFO) or gs_host_is_not_default or system_util.InvokedViaCloudSdk()): return False software_update_check_period = boto.config.getint( 'GSUtil', 'software_update_check_period', 30) # Setting software_update_check_period to 0 means periodic software # update checking is disabled. if software_update_check_period == 0: return False last_checked_for_gsutil_update_timestamp_file = ( boto_util.GetLastCheckedForGsutilUpdateTimestampFile()) cur_ts = int(time.time()) if not os.path.isfile(last_checked_for_gsutil_update_timestamp_file): # Set last_checked_ts from date of VERSION file, so if the user installed # an old copy of gsutil it will get noticed (and an update offered) the # first time they try to run it. last_checked_ts = gslib.GetGsutilVersionModifiedTime() with open(last_checked_for_gsutil_update_timestamp_file, 'w') as f: f.write(str(last_checked_ts)) else: try: with open(last_checked_for_gsutil_update_timestamp_file, 'r') as f: last_checked_ts = int(f.readline()) except (TypeError, ValueError): return False if (cur_ts - last_checked_ts > software_update_check_period * SECONDS_PER_DAY): # Create a credential-less gsutil API to check for the public # update tarball. gsutil_api = GcsJsonApi(self.bucket_storage_uri_class, logger, DiscardMessagesQueue(), credentials=NoOpCredentials(), debug=debug) cur_ver = LookUpGsutilVersion(gsutil_api, GSUTIL_PUB_TARBALL) with open(last_checked_for_gsutil_update_timestamp_file, 'w') as f: f.write(str(cur_ts)) (g, m) = CompareVersions(cur_ver, gslib.VERSION) if m: print '\n'.join( textwrap.wrap( 'A newer version of gsutil (%s) is available than the version you ' 'are running (%s). NOTE: This is a major new version, so it is ' 'strongly recommended that you review the release note details at ' '%s before updating to this version, especially if you use gsutil ' 'in scripts.' % (cur_ver, gslib.VERSION, RELEASE_NOTES_URL))) if gslib.IS_PACKAGE_INSTALL: return False print answer = raw_input('Would you like to update [y/N]? ') return answer and answer.lower()[0] == 'y' elif g: print '\n'.join( textwrap.wrap( 'A newer version of gsutil (%s) is available than the version you ' 'are running (%s). A detailed log of gsutil release changes is ' 'available at %s if you would like to read them before updating.' % (cur_ver, gslib.VERSION, RELEASE_NOTES_URL))) if gslib.IS_PACKAGE_INSTALL: return False print answer = raw_input('Would you like to update [Y/n]? ') return not answer or answer.lower()[0] != 'n' return False