import novaclient.client from novaclient.v2.client import Client from novaclient.v2.keypairs import Keypair from novaclient.v2.servers import Server from keystoneauth1 import session from keystoneauth1.identity import v3 from os import environ as env from os.path import exists, expanduser from os import system from time import sleep import platform from pick import pick from typing import List from ipaddress import ip_address import socket def try_connect(ip): sock = None try: sock = socket.create_connection((ip, 22), 1) except socket.timeout: return False sock.close() return True def open_conn(ip, port=23406): system(f'ssh -D {port} -i ~/.ssh/id_ovh -o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -N debian@{ip}') auth = 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']) sess = session.Session(auth) nova: 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") # List keypairs 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: nova.keypairs.create(keyname, f.read()) # Select flavor flavor = nova.flavors.find(name='s1-2') # Select image image = nova.glance.find_image('Debian 10') net = nova.neutron.find_network('Ext-Net') nova.servers.create('gbv', image, flavor, nics=[{'net-id':net.id}], key_name=keyname) sv: Server = nova.servers.find(name='gbv') ips = [] for x in sv.interface_list(): for i in x.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 server to come online...') 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?') if choice == 'Reconnect': open_conn(ip) elif choice == 'Destroy server and exit': sv.delete() exit = True else: exit = True