2022-12-01 13:00:16 +01:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
import platform
|
|
|
|
import socket
|
|
|
|
from ipaddress import ip_address
|
|
|
|
from os import environ as env
|
|
|
|
from os import system
|
|
|
|
from os.path import exists, expanduser
|
2022-12-01 13:41:57 +01:00
|
|
|
from time import sleep
|
2022-12-01 13:00:16 +01:00
|
|
|
from typing import List
|
|
|
|
|
2022-11-30 22:45:44 +01:00
|
|
|
import novaclient.client
|
2022-12-01 13:00:16 +01:00
|
|
|
import novaclient.v2.client
|
|
|
|
from keystoneauth1.identity import v3
|
|
|
|
from keystoneauth1.session import Session
|
2022-11-30 22:45:44 +01:00
|
|
|
from novaclient.v2.keypairs import Keypair
|
|
|
|
from novaclient.v2.servers import Server
|
|
|
|
from pick import pick
|
|
|
|
|
2022-12-01 13:00:16 +01:00
|
|
|
SERVER_NAME='gbv'
|
|
|
|
|
|
|
|
def try_connect(ip: str) -> bool:
|
2022-11-30 22:45:44 +01:00
|
|
|
sock = None
|
|
|
|
try:
|
|
|
|
sock = socket.create_connection((ip, 22), 1)
|
2022-12-01 22:13:31 +01:00
|
|
|
except (socket.timeout, ConnectionRefusedError):
|
2022-11-30 22:45:44 +01:00
|
|
|
return False
|
|
|
|
sock.close()
|
|
|
|
return True
|
|
|
|
|
2022-12-01 13:00:16 +01:00
|
|
|
|
|
|
|
def open_conn(ip: str, port: int = 23406):
|
|
|
|
print('Opening tunnel...')
|
2022-11-30 22:45:44 +01:00
|
|
|
system(f'ssh -D {port} -i ~/.ssh/id_ovh -o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -N debian@{ip}')
|
|
|
|
|
|
|
|
|
2022-12-01 13:00:16 +01:00
|
|
|
sess = Session(v3.Password(
|
|
|
|
auth_url=env['OS_AUTH_URL'],
|
|
|
|
username=env['OS_USERNAME'],
|
|
|
|
password=env['OS_PASSWORD'],
|
|
|
|
project_id=env['OS_TENANT_ID'],
|
|
|
|
user_domain_name=env['OS_USER_DOMAIN_NAME']))
|
2022-11-30 22:45:44 +01:00
|
|
|
|
2022-12-01 13:41:57 +01:00
|
|
|
print('Logging in...')
|
2022-12-01 13:00:16 +01:00
|
|
|
nova: novaclient.v2.client.Client = novaclient.client.Client(
|
|
|
|
"2.1", session=sess, region_name=env['OS_REGION_NAME'])
|
2022-11-30 22:45:44 +01:00
|
|
|
|
|
|
|
if not exists(expanduser('~/.ssh/id_ovh')):
|
|
|
|
system("ssh-keygen -f ~/.ssh/id_ovh")
|
|
|
|
|
2022-12-01 13:41:57 +01:00
|
|
|
print('Making sure keypair is present...')
|
2022-11-30 22:45:44 +01:00
|
|
|
keypairs: List[Keypair] = nova.keypairs.list()
|
|
|
|
keyname = 'ovh_' + platform.uname()[1].split('.', 1)[0]
|
|
|
|
if keyname not in (k.name for k in keypairs):
|
|
|
|
with open(expanduser('~/.ssh/id_ovh')) as f:
|
2022-12-01 13:41:57 +01:00
|
|
|
print('Uploading keypair...')
|
2022-11-30 22:45:44 +01:00
|
|
|
nova.keypairs.create(keyname, f.read())
|
|
|
|
|
|
|
|
flavor = nova.flavors.find(name='s1-2')
|
|
|
|
image = nova.glance.find_image('Debian 10')
|
|
|
|
net = nova.neutron.find_network('Ext-Net')
|
2022-12-01 13:00:16 +01:00
|
|
|
|
2022-12-01 13:41:57 +01:00
|
|
|
print('Creating server...')
|
2022-12-01 13:00:16 +01:00
|
|
|
nova.servers.create(SERVER_NAME, image, flavor,
|
|
|
|
nics=[{'net-id': net.id}], key_name=keyname)
|
|
|
|
sv: Server = nova.servers.find(name=SERVER_NAME)
|
2022-12-01 13:41:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
while sv.status != 'ACTIVE':
|
|
|
|
print('Waiting for server to POST...')
|
|
|
|
sleep(5)
|
|
|
|
sv = nova.servers.find(name=SERVER_NAME)
|
|
|
|
pass
|
|
|
|
|
2022-11-30 22:45:44 +01:00
|
|
|
ips = []
|
|
|
|
|
2022-12-01 13:41:57 +01:00
|
|
|
interface = None
|
|
|
|
while not interface:
|
|
|
|
interfaces = sv.interface_list()
|
|
|
|
ext_interface = [k for k in interfaces if k.net_id == net.id]
|
|
|
|
if ext_interface and ext_interface[0].port_state == 'ACTIVE':
|
|
|
|
interface = ext_interface[0]
|
|
|
|
else:
|
|
|
|
sleep(2)
|
|
|
|
|
|
|
|
for i in interface.fixed_ips:
|
|
|
|
ips.append(i['ip_address'])
|
2022-11-30 22:45:44 +01:00
|
|
|
ip = list(filter(lambda x: ip_address(x).version == 4, ips))[0]
|
|
|
|
|
2022-12-01 13:41:57 +01:00
|
|
|
while not try_connect(ip):
|
|
|
|
print('Waiting for SSH service to become available...')
|
2022-12-01 22:13:31 +01:00
|
|
|
sleep(4)
|
2022-11-30 22:45:44 +01:00
|
|
|
pass
|
|
|
|
|
|
|
|
open_conn(ip)
|
|
|
|
|
|
|
|
exit = False
|
|
|
|
while not exit:
|
2022-12-01 13:00:16 +01:00
|
|
|
choice = pick(['Reconnect', 'Destroy server and exit', 'Keep server online and exit'],
|
2022-12-01 13:41:57 +01:00
|
|
|
'The connection has ended. How do you want to proceed?')[0]
|
2022-11-30 22:45:44 +01:00
|
|
|
if choice == 'Reconnect':
|
|
|
|
open_conn(ip)
|
|
|
|
elif choice == 'Destroy server and exit':
|
|
|
|
sv.delete()
|
|
|
|
exit = True
|
|
|
|
else:
|
|
|
|
exit = True
|