Add python package to setup SSH keys
Supports setting SSH keys for the following services: * GitHub * GitLab * BitBucket Cloud * Gogs
This commit is contained in:
		
							parent
							
								
									930e540f01
								
							
						
					
					
						commit
						ed415a5c9c
					
				
							
								
								
									
										185
									
								
								bootstrap/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								bootstrap/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,185 @@ | |||||||
|  | """Interactively set SSH keys on remote Git servers.""" | ||||||
|  | 
 | ||||||
|  | from __future__ import print_function | ||||||
|  | from getpass import getpass | ||||||
|  | from os import environ | ||||||
|  | from os.path import join | ||||||
|  | from platform import node, system | ||||||
|  | 
 | ||||||
|  | from requests import ConnectionError, get, post | ||||||
|  | from requests.auth import HTTPBasicAuth | ||||||
|  | from requests.compat import urlparse | ||||||
|  | 
 | ||||||
|  | try: | ||||||
|  |     input = raw_input | ||||||
|  | except NameError: | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class BootstrapError(Exception): | ||||||
|  |     """Bootstrap Exception.""" | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def bootstrap_error(response): | ||||||
|  |     """Create a BootstrapError from a Response.""" | ||||||
|  |     return BootstrapError('%s %s' % (response.status_code, response.reason)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def agree(question, default='Y'): | ||||||
|  |     """Prompt user to answer a yes/no question.""" | ||||||
|  |     valid = { | ||||||
|  |         'y': True, | ||||||
|  |         'Y': True, | ||||||
|  |         'yes': True, | ||||||
|  |         'n': False, | ||||||
|  |         'N': False, | ||||||
|  |         'no': False, | ||||||
|  |         '': {'Y': True, | ||||||
|  |              'N': False}[default] | ||||||
|  |     } | ||||||
|  |     answer = input('%s [%s]? ' % (question, {'Y': 'Y/n', 'N': 'y/N'}[default])) | ||||||
|  |     try: | ||||||
|  |         return valid[answer] | ||||||
|  |     except KeyError: | ||||||
|  |         print('invalid input: %s' % answer) | ||||||
|  |         return agree(question) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_url(service, default): | ||||||
|  |     """Get URL.""" | ||||||
|  |     url = input('%s URL%s: ' % (service, ' (%s)' % default if default else '')) | ||||||
|  |     if url == '': | ||||||
|  |         if default: | ||||||
|  |             return default | ||||||
|  |         else: | ||||||
|  |             print('invalid input: %s' % url) | ||||||
|  |             return get_url(service, default) | ||||||
|  |     return url | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_username_password(service): | ||||||
|  |     """Get username/password.""" | ||||||
|  |     username = input('%s username: ' % service) | ||||||
|  |     password = getpass('%s password: ' % service) | ||||||
|  |     return (username, password) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_local_key(): | ||||||
|  |     """Get local SSH key.""" | ||||||
|  |     if system() == 'Windows': | ||||||
|  |         home = environ['userprofile'] | ||||||
|  |     else: | ||||||
|  |         home = environ['HOME'] | ||||||
|  |     with open(join(home, '.ssh', 'id_rsa.pub'), 'r') as key_file: | ||||||
|  |         return key_file.read().rstrip() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def key_exists(keys, local_key): | ||||||
|  |     """Check if local SSH key is already set.""" | ||||||
|  |     for key in keys: | ||||||
|  |         if local_key.startswith(key['key']): | ||||||
|  |             return True | ||||||
|  |     return False | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def set_github_ssh_key(): | ||||||
|  |     """Set GitHub SSH key.""" | ||||||
|  |     url = urlparse(get_url('GitHub', 'https://github.com')) | ||||||
|  |     keys_url = '%s://api.%s/user/keys' % (url.scheme, url.netloc) | ||||||
|  |     username, password = get_username_password('GitHub') | ||||||
|  |     auth = HTTPBasicAuth(username, password) | ||||||
|  |     response = get(keys_url, auth=auth) | ||||||
|  |     if response.status_code != 200: | ||||||
|  |         raise bootstrap_error(response) | ||||||
|  |     keys = response.json() | ||||||
|  |     local_key = get_local_key() | ||||||
|  |     if not key_exists(keys, local_key): | ||||||
|  |         response = post( | ||||||
|  |             keys_url, auth=auth, json={'title': node(), | ||||||
|  |                                        'key': local_key}) | ||||||
|  |         if response.status_code != 201: | ||||||
|  |             raise bootstrap_error(response) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def set_gitlab_ssh_key(): | ||||||
|  |     """Set GitLab SSH key.""" | ||||||
|  |     api_url = '%s/api/v4' % get_url('GitLab', 'https://gitlab.com') | ||||||
|  |     session_url = '%s/session' % api_url | ||||||
|  |     keys_url = '%s/user/keys' % api_url | ||||||
|  |     username, password = get_username_password('GitLab') | ||||||
|  |     response = post(session_url, {'login': username, 'password': password}) | ||||||
|  |     if response.status_code != 201: | ||||||
|  |         raise bootstrap_error(response) | ||||||
|  |     auth = {'Private-Token': response.json()['private_token']} | ||||||
|  |     response = get(keys_url, headers=auth) | ||||||
|  |     if response.status_code != 200: | ||||||
|  |         raise bootstrap_error(response) | ||||||
|  |     keys = response.json() | ||||||
|  |     local_key = get_local_key() | ||||||
|  |     if not key_exists(keys, local_key): | ||||||
|  |         response = post( | ||||||
|  |             keys_url, headers=auth, json={'title': node(), | ||||||
|  |                                           'key': local_key}) | ||||||
|  |         if response.status_code != 201: | ||||||
|  |             raise bootstrap_error(response) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def set_bitbucket_cloud_ssh_key(): | ||||||
|  |     """Set BitBucket Cloud SSH key.""" | ||||||
|  |     username, password = get_username_password('BitBucket Cloud') | ||||||
|  |     keys_url = 'https://api.bitbucket.org/1.0/users/%s/ssh-keys' % username | ||||||
|  |     auth = HTTPBasicAuth(username, password) | ||||||
|  |     response = get(keys_url, auth=auth) | ||||||
|  |     if response.status_code != 200: | ||||||
|  |         raise bootstrap_error(response) | ||||||
|  |     keys = response.json() | ||||||
|  |     local_key = get_local_key() | ||||||
|  |     if not key_exists(keys, local_key): | ||||||
|  |         response = post( | ||||||
|  |             keys_url, auth=auth, data={'label': node(), | ||||||
|  |                                        'key': local_key}) | ||||||
|  |         if response.status_code != 200: | ||||||
|  |             raise bootstrap_error(response) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def set_gogs_ssh_key(): | ||||||
|  |     """Set Gogs SSH key.""" | ||||||
|  |     keys_url = '%s/api/v1/user/keys' % get_url('Gogs', None) | ||||||
|  |     username, password = get_username_password('Gogs') | ||||||
|  |     auth = HTTPBasicAuth(username, password) | ||||||
|  |     response = get(keys_url, auth=auth) | ||||||
|  |     if response.status_code != 200: | ||||||
|  |         raise bootstrap_error(response) | ||||||
|  |     keys = response.json() | ||||||
|  |     local_key = get_local_key() | ||||||
|  |     if not key_exists(keys, local_key): | ||||||
|  |         response = post( | ||||||
|  |             keys_url, auth=auth, json={'title': node(), | ||||||
|  |                                        'key': local_key}) | ||||||
|  |         if response.status_code != 201: | ||||||
|  |             raise bootstrap_error(response) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def set_ssh_keys(): | ||||||
|  |     """Interactively set SSH keys on remote Git servers.""" | ||||||
|  |     try: | ||||||
|  |         for service in ['GitHub', 'GitLab', 'BitBucket Cloud', 'Gogs']: | ||||||
|  |             question = 'Set %s SSH key' % service | ||||||
|  |             default = 'Y' | ||||||
|  |             while agree(question, default): | ||||||
|  |                 try: | ||||||
|  |                     { | ||||||
|  |                         'GitHub': set_github_ssh_key, | ||||||
|  |                         'GitLab': set_gitlab_ssh_key, | ||||||
|  |                         'BitBucket Cloud': set_bitbucket_cloud_ssh_key, | ||||||
|  |                         'Gogs': set_gogs_ssh_key, | ||||||
|  |                     }[service]() | ||||||
|  |                     if service == 'BitBucket Cloud': | ||||||
|  |                         break | ||||||
|  |                     question = 'Set another %s SSH key' % service | ||||||
|  |                     default = 'N' | ||||||
|  |                 except (BootstrapError, ConnectionError) as error: | ||||||
|  |                     print('error: %s' % error.message) | ||||||
|  |     except KeyboardInterrupt: | ||||||
|  |         exit(130) | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user