diff --git a/vnc_console_connection/config.py b/vnc_console_connection/config.py new file mode 100755 index 0000000..2a36c96 --- /dev/null +++ b/vnc_console_connection/config.py @@ -0,0 +1,5 @@ +import configparser + +config = configparser.ConfigParser(allow_no_value=True) +config.read('config-and-secrets.conf') + diff --git a/vnc_console_connection/db_export.py b/vnc_console_connection/db_export.py new file mode 100755 index 0000000..d283eb4 --- /dev/null +++ b/vnc_console_connection/db_export.py @@ -0,0 +1,55 @@ +import psycopg2 as pg2 +from config import config + +db_name = config['db']['db_name'] +db_user = config['db']['db_user'] +db_password = config['db']['db_password'] +db_port = config['db']['db_port'] + + +def setconn(u_id, vm_num, vm_port,vm_host): + conn = pg2.connect("host = localhost dbname={} user={} password={} port={}".format(db_name,db_user,db_password,db_port)) + conn.autocommit = True + cur = conn.cursor() + cur.execute("SELECT entity_id FROM guacamole_entity WHERE name = '{}'".format(u_id)) + row = cur.fetchone() + if row == None: + cur.execute("INSERT INTO guacamole_entity (name, type) VALUES ('{}','USER')".format(u_id)) + cur.execute("SELECT entity_id FROM guacamole_entity WHERE name = '{}'".format(u_id)) + row = cur.fetchone() + en_id = row[0] + cur.execute("INSERT INTO guacamole_user(entity_id, password_hash, password_date) VALUES ('{}', '\x74657374', now())".format(en_id)) + print("create user : " , u_id) + else: + en_id = row[0] + cur.execute("SELECT password_hash FROM guacamole_user WHERE entity_id = '{}'".format(en_id)) + row = cur.fetchone() + if row == None: + cur.execute("INSERT INTO guacamole_user(entity_id, password_hash, password_date) VALUES ('{}', '\x74657374', now())".format(en_id)) + print("user exsit") + cn = "{}{}".format(u_id,vm_num) + cur.execute("SELECT connection_id FROM guacamole_connection WHERE connection_name = '{}'".format(cn)) + row = cur.fetchone() + if row == None: + #create connection + cur.execute("INSERT INTO guacamole_connection (connection_name, protocol) VALUES ('{}', 'vnc')".format(cn)) + cur.execute("SELECT MAX(connection_id) FROM guacamole_connection WHERE connection_name = '{}' AND parent_id IS NULL".format(cn)) + temp_cn_id = cur.fetchone() + cn_id = temp_cn_id[0] + cur.execute("INSERT INTO guacamole_connection_parameter VALUES ('{}','hostname','{}')".format(cn_id, vm_host)) + cur.execute("INSERT INTO guacamole_connection_parameter VALUES ('{}','port','{}')".format(cn_id,vm_port)) + #connection permission + cur.execute("INSERT INTO guacamole_connection_permission(entity_id, connection_id, permission) VALUES ('{}', '{}', 'READ')".format(en_id,cn_id)) + #clipboard-encoding + cur.execute("INSERT INTO guacamole_connection_parameter VALUES ('{}','clipboard-encoding','UTF-8')".format(cn_id)) + print("create connection") + else: + cur.execute("SELECT MAX(connection_id) FROM guacamole_connection WHERE connection_name = '{}' AND parent_id IS NULL".format(cn)) + temp_cn_id = cur.fetchone() + cn_id = temp_cn_id[0] + cur.execute("UPDATE guacamole_connection_parameter SET parameter_value='{}' where connection_id='{}' and parameter_name='hostname'".format(vm_host,cn_id)) + cur.execute("UPDATE guacamole_connection_parameter SET parameter_value='{}' where connection_id='{}' and parameter_name='port'".format(vm_port,cn_id)) + #cur.execute("UPDATE guacamole_connection_parameter SET parameter_value='UTF-8' where connection_id='{}' and parameter_name='clipboard-encoding'".format(cn_id)) + print("no connection") + conn.close() + return None \ No newline at end of file diff --git a/vnc_console_connection/get_info.py b/vnc_console_connection/get_info.py new file mode 100755 index 0000000..ac09633 --- /dev/null +++ b/vnc_console_connection/get_info.py @@ -0,0 +1,88 @@ +import json + +from enum import IntEnum +from xmlrpc.client import ServerProxy as RPCClient +from xmltodict import parse +from config import config +from ldap_list import vm_list +from db_export import setconn + +# Constants +ALL_VM_STATES = -1 +START_ID = -1 # First id whatever it is +END_ID = -1 # Last id whatever it is +session_string = config['oca']['client_secrets'] +opnserver = config['oca']['opn_server'] + +class VMState(IntEnum): + INIT = 0 + PENDING = 1 + HOLD = 2 + ACTIVE = 3 + STOPPED = 4 + SUSPENDED = 5 + DONE = 6 + FAILED = 7 + POWEROFF = 8 + UNDEPLOYED = 9 + CLONING = 10 + CLONING_FAILURE = 11 + + +class VmFilterFlag(IntEnum): + UIDUserResources = 0 # UID User’s Resources + UserAndItsGroupsResources = -1 # Resources belonging to the user and any of his groups + AllResources = -2 # All resources + UserResources = -3 # Resources belonging to the user + UserPrimaryGroupResources = -4 # Resources belonging to the user’s primary group + + +class VM: + def __init__(self, vm: dict): + self.id = vm.get('ID', None) + self.owner = { + 'id': vm.get('UID', None), + 'name': vm.get('UNAME', None), + 'gname': vm.get('GNAME', None) + } + self.name = vm.get('NAME', None) + self.status = vm.get('STATE', None) + if self.status: + self.status = VMState(int(self.status)).name.lower() + + template = vm['TEMPLATE'] + + self.graphics = template.get('GRAPHICS', {}) + self.memory = template.get('MEMORY', None) + self.vcpu = template.get('VCPU', None) + self.host = { + 'name': ((vm.get('HISTORY_RECORDS', {}) or {}).get('HISTORY', {}) or {}).get('HOSTNAME', None), + 'id': ((vm.get('HISTORY_RECORDS', {}) or {}).get('HISTORY', {}) or {}).get('HID', None), + } + + +def main(): + with RPCClient(opnserver) as rpc_client: + success, response, *_ = rpc_client.one.vmpool.infoextended( + session_string , VmFilterFlag.AllResources.value, START_ID, END_ID, VMState.ACTIVE.value + ) + if success: + vms = json.loads(json.dumps(parse(response)))['VM_POOL']['VM'] + for entry in vm_list.entries: + temp_uname = entry.mail + for i, vm in enumerate(vms): + vm_user = vm['UNAME'] + vm_id = vm['ID'] + vm_port = vm['TEMPLATE']['GRAPHICS'].get('PORT') + vm_host = vm['HISTORY_RECORDS']['HISTORY']['HOSTNAME'] + if vm['UNAME'] == temp_uname: + #print(entry.uid, vm_id, vm_port, vm_host) + setconn(entry.uid, vm_id, vm_port, vm_host) + + else: + print(response) + + +if __name__ == "__main__": + main() + diff --git a/vnc_console_connection/ldap_list.py b/vnc_console_connection/ldap_list.py new file mode 100755 index 0000000..a9e322f --- /dev/null +++ b/vnc_console_connection/ldap_list.py @@ -0,0 +1,30 @@ +import ldap3 +import sys +from config import config +from ldap3 import Server, Connection, ObjectDef, Reader, ALL, SUBTREE, ALL_ATTRIBUTES +from ldap3.core import exceptions + + +LDAP_SERVER = config['ldap']['server'] +LDAP_PASSWORD = config['ldap']['admin_password'] +LDAP_USER = config['ldap']['admin_dn'] +LDAP_PORT = int(config['ldap']['ldap_port']) + +# Create the Server object with the given address. +server = Server(LDAP_SERVER, LDAP_PORT, get_info=ALL) +#Create a connection object, and bind with the given DN and password. +try: + conn = Connection(server, LDAP_USER, LDAP_PASSWORD, auto_bind=True) + print('LDAP Bind Successful.') + # Perform a search for a pre-defined criteria. + # Mention the search filter / filter type and attributes. + conn.search('ou=customer,dc=ungleich,dc=ch', '(&(!({}={})))'.format('mail','*@ungleich.ch') , attributes=['uid','mail']) + #conn.search('ou=customer,dc=ungleich,dc=ch', '(objectClass=*)' , attributes=['uid','mail']) + # Print the resulting entriesn. + #for entry in conn.entries: + #print(entry.uid, entry.mail) + vm_list = conn +except exceptions.LDAPException as err: + sys.exit(f'LDAP Error: {err}') + +