def _WriteBotoConfigFile(self, config_file, use_oauth2=True, launch_browser=True, oauth2_scopes=[SCOPE_FULL_CONTROL]): """Creates a boto config file interactively. Needed credentials are obtained interactively, either by asking the user for access key and secret, or by walking the user through the OAuth2 approval flow. Args: config_file: File object to which the resulting config file will be written. use_oauth2: If True, walk user through OAuth2 approval flow and produce a config with an oauth2_refresh_token credential. If false, ask the user for access key and secret. launch_browser: In the OAuth2 approval flow, attempt to open a browser window and navigate to the approval URL. oauth2_scopes: A list of OAuth2 scopes to request authorization for, when using OAuth2. """ # Collect credentials provider_map = {'aws': 'aws', 'google': 'gs'} uri_map = {'aws': 's3', 'google': 'gs'} key_ids = {} sec_keys = {} if use_oauth2: oauth2_refresh_token = oauth2_helper.OAuth2ApprovalFlow( oauth2_helper.OAuth2ClientFromBotoConfig(boto.config), oauth2_scopes, launch_browser) else: got_creds = False for provider in provider_map: if provider == 'google': key_ids[provider] = raw_input( 'What is your %s access key ID? ' % provider) sec_keys[provider] = raw_input( 'What is your %s secret access key? ' % provider) got_creds = True if not key_ids[provider] or not sec_keys[provider]: raise CommandException( 'Incomplete credentials provided. Please try again.' ) if not got_creds: raise CommandException( 'No credentials provided. Please try again.') # Write the config file prelude. config_file.write(CONFIG_PRELUDE_CONTENT.lstrip()) config_file.write( '# This file was created by gsutil version %s at %s.\n' % (self.gsutil_ver, datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) config_file.write( '#\n# You can create additional configuration files by ' 'running\n# gsutil config [options] [-o <config-file>]\n\n\n') # Write the config file Credentials section. config_file.write('[Credentials]\n\n') if use_oauth2: config_file.write( '# Google OAuth2 credentials (for "gs://" URIs):\n') config_file.write('# The following OAuth2 token is authorized for ' 'scope(s):\n') for scope in oauth2_scopes: config_file.write('# %s\n' % scope) config_file.write('gs_oauth2_refresh_token = %s\n\n' % oauth2_refresh_token.refresh_token) else: config_file.write( '# To add Google OAuth2 credentials ("gs://" URIs), ' 'edit and uncomment the\n# following line:\n' '#gs_oauth2_refresh_token = <your OAuth2 refresh token>\n\n') for provider in provider_map: key_prefix = provider_map[provider] uri_scheme = uri_map[provider] if provider in key_ids and provider in sec_keys: config_file.write('# %s credentials ("%s://" URIs):\n' % (provider, uri_scheme)) config_file.write('%s_access_key_id = %s\n' % (key_prefix, key_ids[provider])) config_file.write('%s_secret_access_key = %s\n' % (key_prefix, sec_keys[provider])) else: config_file.write( '# To add %s credentials ("%s://" URIs), edit and ' 'uncomment the\n# following two lines:\n' '#%s_access_key_id = <your %s access key ID>\n' '#%s_secret_access_key = <your %s secret access key>\n' % (provider, uri_scheme, key_prefix, provider, key_prefix, provider)) host_key = Provider.HostKeyMap[provider] config_file.write( '# The ability to specify an alternate storage host ' 'is primarily for cloud\n# storage service developers.\n' '#%s_host = <alternate storage host address>\n\n' % host_key) # Write the config file Boto section. config_file.write('%s\n' % CONFIG_BOTO_SECTION_CONTENT) # Write the config file GSUtil section that doesn't depend on user input. config_file.write(CONFIG_INPUTLESS_GSUTIL_SECTION_CONTENT) # Write the default API version. config_file.write(""" # 'default_api_version' specifies the default Google Cloud Storage API # version to use. If not set below gsutil defaults to API version 1. """) api_version = 2 if not use_oauth2: api_version = 1 config_file.write('default_api_version = %d\n' % api_version) default_project_id = '0' project_id_section_prelude = """ # 'default_project_id' specifies the default Google Cloud Storage project ID to # use with the 'mb' and 'ls' commands. If defined it overrides the default value # you set in the API Console. Either of these defaults can be overridden # by specifying the -p option to the 'mb' and 'ls' commands. """ if default_project_id: config_file.write('%sdefault_project_id = %s\n\n\n' % (project_id_section_prelude, default_project_id)) else: sys.stderr.write( 'No default project ID entered. You will need to edit ' 'the default_project_id value\nin your boto config file ' 'before using "gsutil ls gs://" or "mb" commands' 'with the\ndefault API version (2).\n') config_file.write('%s#default_project_id = <value>\n\n\n' % project_id_section_prelude) # Write the config file OAuth2 section. config_file.write(CONFIG_OAUTH2_CONFIG_CONTENT)
def _WriteBotoConfigFile(self, config_file, use_oauth2=True, launch_browser=True, oauth2_scopes=[SCOPE_FULL_CONTROL]): """Creates a boto config file interactively. Needed credentials are obtained interactively, either by asking the user for access key and secret, or by walking the user through the OAuth2 approval flow. Args: config_file: file object to which the resulting config file will be written. use_oauth2: if True, walk user through OAuth2 approval flow and produce a config with an oauth2_refresh_token credential. If false, ask the user for access key and secret. launch_browser: in the OAuth2 approval flow, attempt to open a browser window and navigate to the approval URL. oauth2_scopes: a list of OAuth2 scopes to request authorization for, when using OAuth2. """ # Collect credentials provider_map = {'aws': 'aws', 'google': 'gs'} uri_map = {'aws': 's3', 'google': 'gs'} key_ids = {} sec_keys = {} if use_oauth2: oauth2_refresh_token = oauth2_helper.OAuth2ApprovalFlow( oauth2_helper.OAuth2ClientFromBotoConfig(boto.config), oauth2_scopes, launch_browser) else: got_creds = False for provider in provider_map: if provider == 'google': key_ids[provider] = raw_input('What is your %s access key ID? ' % provider) sec_keys[provider] = raw_input('What is your %s secret access key? ' % provider) got_creds = True if not key_ids[provider] or not sec_keys[provider]: raise CommandException( 'Incomplete credentials provided. Please try again.') if not got_creds: raise CommandException('No credentials provided. Please try again.') # Write the config file prelude. config_file.write(CONFIG_PRELUDE_CONTENT) config_file.write( '# This file was created by gsutil version "%s"\n# at %s.\n' % (self.LoadVersionString(), datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) config_file.write('#\n# You can create additional configuration files by ' 'running\n# gsutil config [options] [-o <config-file>]\n\n\n') # Write the config file Credentials section. config_file.write('[Credentials]\n\n') if use_oauth2: config_file.write('# Google OAuth2 credentials (for "gs://" URIs):\n') config_file.write('# The following OAuth2 token is authorized for ' 'scope(s):\n') for scope in oauth2_scopes: config_file.write('# %s\n' % scope) config_file.write('gs_oauth2_refresh_token = %s\n\n' % oauth2_refresh_token.refresh_token) else: config_file.write('# To add Google OAuth2 credentials ("gs://" URIs), ' 'edit and uncomment the\n# following line:\n' '#gs_oauth2_refresh_token = <your OAuth2 refresh token>\n\n') for provider in provider_map: key_prefix = provider_map[provider] uri_scheme = uri_map[provider] if provider in key_ids and provider in sec_keys: config_file.write('# %s credentials ("%s://" URIs):\n' % (provider, uri_scheme)) config_file.write('%s_access_key_id = %s\n' % (key_prefix, key_ids[provider])) config_file.write('%s_secret_access_key = %s\n' % (key_prefix, sec_keys[provider])) else: config_file.write('# To add %s credentials ("%s://" URIs), edit and ' 'uncomment the\n# following two lines:\n' '#%s_access_key_id = <your %s access key ID>\n' '#%s_secret_access_key = <your %s secret access key>\n' % (provider, uri_scheme, key_prefix, provider, key_prefix, provider)) host_key = Provider.HostKeyMap[provider] config_file.write('# The ability to specify an alternate storage host ' 'is primarily for cloud\n# storage service developers.\n' '#%s_host = <alternate storage host address>\n\n' % host_key) # Write the config file Boto section. config_file.write('%s\n' % CONFIG_BOTO_SECTION_CONTENT) # Write the config file GSUtil section that doesn't depend on user input. config_file.write(CONFIG_INPUTLESS_GSUTIL_SECTION_CONTENT) # Write the default API version. config_file.write(""" # 'default_api_version' specifies the default Google Cloud Storage API # version to use. If not set below gsutil defaults to API version 1. """) api_version = 2 if not use_oauth2: api_version = 1 config_file.write('default_api_version = %d\n' % api_version) # Write the config file GSUtil section that includes the default # project ID input from the user. if launch_browser: sys.stdout.write( 'Attempting to launch a browser to open the Google API console at ' 'URL: %s\n\n' '[Note: due to a Python bug, you may see a spurious error message ' '"object is not\n callable [...] in [...] Popen.__del__" which can ' 'be ignored.]\n\n' % GOOG_API_CONSOLE_URI) sys.stdout.write( 'In your browser you should see the API Console. Click "Storage" and ' 'look for the value under "Identifying your project\n\n') if not webbrowser.open(GOOG_API_CONSOLE_URI, new=1, autoraise=True): sys.stdout.write( 'Launching browser appears to have failed; please navigate a ' 'browser to the following URL:\n%s\n' % GOOG_API_CONSOLE_URI) # Short delay; webbrowser.open on linux insists on printing out a message # which we don't want to run into the prompt for the auth code. time.sleep(2) else: sys.stdout.write( '\nPlease navigate your browser to %s,\nthen click "Services" on the ' 'left side panel and ensure you have Google Cloud\nStorage' 'activated, then click "Google Cloud Storage" on the left side ' 'panel and\nfind the "x-goog-project-id" on that page.\n' % GOOG_API_CONSOLE_URI) default_project_id = raw_input('What is your project-id? ') project_id_section_prelude = """ # 'default_project_id' specifies the default Google Cloud Storage project ID to # use with the 'mb' and 'ls' commands. If defined it overrides the default value # you set in the API Console. Either of these defaults can be overridden # by specifying the -p option to the 'mb' and 'ls' commands. """ if default_project_id: config_file.write('%sdefault_project_id = %s\n\n\n' % (project_id_section_prelude, default_project_id)) else: sys.stderr.write('No default project ID entered. You will need to edit ' 'the default_project_id value\nin your boto config file ' 'before using "gsutil ls gs://" or "mb" commands' 'with the default API version 2.\n') config_file.write('%s#default_project_id = <value>\n\n\n' % project_id_section_prelude) # Write the config file OAuth2 section. config_file.write(CONFIG_OAUTH2_CONFIG_CONTENT)