#!/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 from time import sleep from typing import List import novaclient.client import novaclient.v2.client from keystoneauth1.identity import v3 from keystoneauth1.session import Session from novaclient.v2.keypairs import Keypair from novaclient.v2.servers import Server from pick import pick SERVER_NAME='gbv' def try_connect(ip: str) -> bool: sock = None try: sock = socket.create_connection((ip, 22), 1) except (socket.timeout, ConnectionRefusedError): return False sock.close() return True def open_conn(ip: str, port: int = 23406): print('Opening tunnel...') system(f'ssh -D {port} -i ~/.ssh/id_ovh -o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -N debian@{ip}') 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'])) print('Logging in...') nova: novaclient.v2.client.Client = novaclient.client.Client( "2.1", session=sess, region_name=env['OS_REGION_NAME']) if not exists(expanduser('~/.ssh/id_ovh')): system("ssh-keygen -f ~/.ssh/id_ovh") print('Making sure keypair is present...') 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: print('Uploading keypair...') 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') print('Creating server...') nova.servers.create(SERVER_NAME, image, flavor, nics=[{'net-id': net.id}], key_name=keyname) sv: Server = nova.servers.find(name=SERVER_NAME) while sv.status != 'ACTIVE': print('Waiting for server to POST...') sleep(5) sv = nova.servers.find(name=SERVER_NAME) pass ips = [] 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']) ip = list(filter(lambda x: ip_address(x).version == 4, ips))[0] while not try_connect(ip): print('Waiting for SSH service to become available...') sleep(4) pass open_conn(ip) exit = False while not exit: choice = pick(['Reconnect', 'Destroy server and exit', 'Keep server online and exit'], 'The connection has ended. How do you want to proceed?')[0] if choice == 'Reconnect': open_conn(ip) elif choice == 'Destroy server and exit': sv.delete() exit = True else: exit = True