Compare commits

...

No commits in common. "c7ca50fcdf0e194925631ab975a2001ba4e2adf0" and "a8b9e6bfe293b4a117c54bc6c538fe253c7aba20" have entirely different histories.

6 changed files with 221 additions and 184 deletions

6
.gitignore vendored
View File

@ -1 +1,5 @@
env/*
*.pyc
.py2
.py3
.venv
*.egg-info

View File

@ -19,6 +19,9 @@ show_help() {
echo "* virtualenv - from pip"
echo "* SSH key - from ssh-keygen"
echo "* GitHub public key - with SSH key"
echo "* GitLab public key - with SSH key"
echo "* BitBucket Cloud public key - with SSH key"
echo "* Gogs Cloud public key - with SSH key"
echo "* conduit - configuration manager"
echo
echo "If any already exist they will not be reinstalled."
@ -83,69 +86,20 @@ if [ ! -f ~/.ssh/id_rsa ] && agree "Generate SSH key"; then
ssh-keygen -t rsa -b 4096 -C "$email" -N "" -f ~/.ssh/id_rsa
fi
if agree "GitHub public key"; then
if ! missing virtualenv && agree "Set SSH keys on remote Git servers"; then
env=$(mktemp -d)
virtualenv $env > /dev/null
source $env/bin/activate
pip install githubpy > /dev/null
python <(cat << EOF
from __future__ import print_function
from os import environ
from os.path import join
from getpass import getpass
from github import GitHub
def getinput(prompt):
try:
return raw_input(prompt)
except NameError:
return input(prompt)
def main():
username = getinput('GitHub username: ')
password = getpass('GitHub password: ')
github = GitHub(username=username, password=password)
keys = github.user.keys().get()
id_rsa_pub_path = join(environ['HOME'], '.ssh', 'id_rsa.pub')
with open(id_rsa_pub_path, 'r') as id_rsa_pub_file:
local_key = id_rsa_pub_file.read()
for key in keys:
if local_key.startswith(key['key']):
print('Satisfied: GitHub public key')
exit(0)
title = getinput('GitHub key name: ')
github.user.keys().post(title=title, key=local_key)
print('Installed: GitHub public key')
exit(0)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
exit(130)
EOF
)
pip install git+https://code.infektor.net/config/bootstrap.git > /dev/null
python -c 'import bootstrap; bootstrap.set_ssh_keys()'
deactivate
rm -r $env
fi
# TODO: Gogs SSH key
if [ -f ~/.ssh/id_rsa.pub ]; then
echo "----------------------------------------------------------------------"
cat ~/.ssh/id_rsa.pub
echo "----------------------------------------------------------------------"
read -rp "Set other SSH key recipients, press ENTER to continue: "
fi
missing conduit && agree "Install conduit" && \
pip_install git+ssh://git@github.com/kbenzie/conduit.git
echo "To use install pip packages update your PATH:"
echo "To use installed pip packages update your PATH:"
echo 'export PATH=~/.local/bin:$PATH'
[ -f $0 ] && agree "Remove $0" "N" && rm $0 || exit 0

View File

@ -1,5 +1,4 @@
@echo off
rem = """
if [%1]==[/?] goto :help
echo %* | find "/?" > nul
@ -17,6 +16,9 @@ echo * Python - from Chocolatey
echo * virtualenv - from pip
echo * SSH key - from ssh-keygen
echo * GitHub public key - with SSH key
echo * GitLab public key - with SSH key
echo * BitBucket Cloud public key - with SSH key
echo * Gogs Cloud public key - with SSH key
echo * conduit - configuration manager
echo
echo optional arguments:
@ -63,84 +65,16 @@ mkdir %USERPROFILE%\.ssh
set /P email="SSH email: "
"C:\tools\cmder\vendor\git-for-windows\usr\bin\ssh-keygen.exe" -t rsa -b 4096 -C "%email%" -N "" -f %USERPROFILE%\.ssh\id_rsa
if errorlevel 1 exit /B 1
goto github
:cleanup
if errorlevel 1 exit /B 1
:: These commands are exectued after the embedded python code below, this is
:: required because commands following the embedded python code result in
:: python syntax errors.
rmdir /Q /S "%~dp0\bootstrap_env
echo "Completed: %0 will now be removed"
start /b "" cmd /c del "%~f0"&exit /b
goto end
:: GitHub public key
:github
:: Set SSH keys on remote Git servers
"C:\Python27\Scripts\virtualenv.exe" %~dp0\bootstrap_env
if errorlevel 1 exit /B 1
"%~dp0\bootstrap_env\Scripts\pip.exe" install githubpy
"%~dp0\bootstrap_env\Scripts\pip.exe" install git+https://code.infektor.net/config/bootstrap.git
if errorlevel 1 exit /B 1
"%~dp0\bootstrap_env\Scripts\python.exe" -x "%~f0"
goto cleanup """
"%~dp0\bootstrap_env\Scripts\python.exe" -c "import bootstrap; bootstrap.set_ssh_keys()"
if errorlevel 1 exit /B 1
rmdir /Q /S "%~dp0\bootstrap_env"
echo "Completed: %0 will now be removed"
start /b "" cmd /c del "%~f0"&exit /b
from os import environ
from os.path import join
from getpass import getpass
from sys import stdout
from subprocess import call
from github import GitHub
SEP = '----------------------------------------------------------------------'
def getinput(prompt):
try:
return raw_input(prompt)
except NameError:
return input(prompt)
def set_github_key():
username = getinput('GitHub username: ')
password = getpass('GitHub password: ')
github = GitHub(username=username, password=password)
keys = github.user.keys().get()
id_rsa_pub_path = join(environ['USERPROFILE'], '.ssh', 'id_rsa.pub')
with open(id_rsa_pub_path, 'r') as id_rsa_pub_file:
local_key = id_rsa_pub_file.read()
for key in keys:
if local_key.startswith(key['key']):
stdout.write('Satisfied: GitHub public key\n')
return
title = getinput('GitHub key name: ')
github.user.keys().post(title=title, key=local_key)
stdout.write('Installed: GitHub public key\n')
def show_public_key():
stdout.write('%s\n' % SEP)
with open(join(environ['USERPROFILE'], '.ssh', 'id_rsa.pub')) as key:
stdout.write('%s\n' % key.read())
stdout.write('%s\n' % SEP)
getinput('Set other SSH key recipients, press ENTER to continue: ')
def install_conduit():
path = environ['PATH'].split(';')
path.append(r'C:\tools\cmder\vendor\git-for-windows\bin')
environ['PATH'] = ';'.join(path)
call([r'C:\Python27\Scripts\pip.exe', 'install',
'git+ssh://git@github.com/kbenzie/conduit.git'])
if __name__ == '__main__':
try:
set_github_key()
show_public_key()
install_conduit()
except KeyboardInterrupt:
exit(1)
rem = """
:end """
:end

View File

@ -17,6 +17,9 @@ show_help() {
echo "* virtualenv - from pip"
echo "* SSH key - from ssh-keygen"
echo "* GitHub public key - with SSH key"
echo "* GitLab public key - with SSH key"
echo "* BitBucket Cloud public key - with SSH key"
echo "* Gogs Cloud public key - with SSH key"
echo "* conduit - configuration manager"
echo
echo "If any already exist they will not be reinstalled."
@ -88,66 +91,16 @@ if [ ! -f ~/.ssh/id_rsa ] && agree "Generate SSH key"; then
ssh-keygen -t rsa -b 4096 -C "$email" -N "" -f ~/.ssh/id_rsa
fi
if ! missing virtualenv && agree "GitHub public key"; then
if ! missing virtualenv && agree "Set SSH keys on remote Git servers"; then
env=$(mktemp -d)
virtualenv $env &> /dev/null
source $env/bin/activate
pip install githubpy &> /dev/null
python <(cat << EOF
from __future__ import print_function
from os import environ
from os.path import join
from getpass import getpass
from github import GitHub
def getinput(prompt):
try:
return raw_input(prompt)
except NameError:
return input(prompt)
def main():
username = getinput('GitHub username: ')
password = getpass('GitHub password: ')
github = GitHub(username=username, password=password)
keys = github.user.keys().get()
id_rsa_pub_path = join(environ['HOME'], '.ssh', 'id_rsa.pub')
with open(id_rsa_pub_path, 'r') as id_rsa_pub_file:
local_key = id_rsa_pub_file.read()
for key in keys:
if local_key.startswith(key['key']):
print('Satisfied: GitHub public key')
exit(0)
title = getinput('GitHub key name: ')
github.user.keys().post(title=title, key=local_key)
print('Installed: GitHub public key')
exit(0)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
exit(130)
EOF
)
pip install git+https://code.infektor.net/config/bootstrap.git > /dev/null
python -c 'import bootstrap; bootstrap.set_ssh_keys()'
deactivate
rm -r $env
fi
# TODO: Gogs SSH key
# Prompt user to setup other SSH key recipients
if [ -f ~/.ssh/id_rsa.pub ]; then
echo '----------------------------------------------------------------------'
cat ~/.ssh/id_rsa.pub
echo '----------------------------------------------------------------------'
read -rp "Set other SSH key recipients, press ENTER to continue: "
fi
! missing pip && missing conduit && agree "Install conduit" && \
pip_install git+ssh://git@github.com/kbenzie/conduit.git

181
bootstrap/__init__.py Normal file
View File

@ -0,0 +1,181 @@
"""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
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."""
with open(join(environ['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."""
api_url = 'https://api.bitbucket.org/1.0'
username, password = get_username_password('BitBucket Cloud')
auth = HTTPBasicAuth(username, password)
keys_url = '%s/users/%s/ssh-keys' % (api_url, username)
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)

11
setup.py Normal file
View File

@ -0,0 +1,11 @@
"""Setup bootstrap package."""
from setuptools import find_packages, setup
setup(
name='bootstrap',
version='0.1.0',
packages=find_packages(),
install_requires=[
'requests',
])