# -*- encoding: utf-8 -*- import PySimpleGUI as sg import ovh client = ovh.Client() service = client.get('/cloud/project')[0] service_url = f'/cloud/project/{service}' # regions = [f['region'] for f in flavors if f['name'] == 's1-2'] regions = ['GRA7', 'SBG5', 'DE1', 'UK1', 'BHS5'] def get_flavor_id(region, name='s1-2'): flavors = client.get(service_url + '/flavor') flavorId = [f['id'] for f in flavors if f['name'] == name and f['region'] == region][0] return flavorId def get_image_id(region, name='Ubuntu 20.04'): images = client.get(service_url + '/image') imageId = [i['id'] for i in images if i['name'] == name and i['region'] == region][0] return imageId def get_eleves(): ovh_ssh_keys = client.get(service_url + '/sshkey') liste_eleves = [(k['id'], k['name'].split('_')[1], k['publicKey']) for k in ovh_ssh_keys if k['name'].startswith('ssh_')] return liste_eleves def delete_eleve(eleve_id): client.delete(service_url + '/sshkey/' + eleve_id) def create_eleve(prenom, publicKey): client.post(service_url + '/sshkey', name='ssh_' + prenom, publicKey=publicKey ) def get_instances(): ovh_instances = client.get(service_url + '/instance') instances = [] for i in ovh_instances: id_inst = i['id'] name = i['name'] if not name.startswith('eica-'): continue if i['ipAddresses']: ip = i['ipAddresses'][0]['ip'] else: ip = 'Waiting...' region = i['region'] status = i['status'] instances.append((id_inst, name, ip, region, status,)) return instances def create_instance(eleve_id, name, region): image_id = get_image_id(region) flavor_id = get_flavor_id(region) client.post(service_url + '/instance', name='eica-' + name, sshKeyId=eleve_id, flavorId=flavor_id, imageId=image_id, region=region ) def delete_instance(instance_id): print(service_url + '/instance/' + instance_id) client.delete(service_url + '/instance/' + instance_id) def make_main_window(): liste_eleves = get_eleves() liste_instances = get_instances() col = [ [sg.Button('Ajouter', size=(12, 1))], [sg.Button('Modifier', size=(12, 1))], [sg.Button('Supprimer', size=(12, 1))], [sg.Combo(regions, size=(12, 1), default_value=regions[0], k='region')], [sg.Button('Instancier', size=(12, 1), button_color=('white', 'green'))], [sg.Button('Quitter', size=(12, 1))], ] col1 = [ [sg.Table(values=liste_instances, headings=['id', 'Nom', 'Adresse IP', 'Région', 'Statut'], max_col_width=25, col_widths=[0, 15, 12, 10, 10], hide_vertical_scroll=True, background_color='light blue', text_color='black', auto_size_columns=False, justification='right', num_rows=len(liste_instances), alternating_row_color='lightyellow', key='table_instances', tooltip='Liste des instances actives')], ] col2 = [ [sg.Button('Détruire', size=(12, 1), button_color=('white', 'red'))], [sg.Button('Actualiser', size=(12, 1))], ] layout = [ [sg.Text('Liste des élèves')], [sg.Table(values=liste_eleves, headings=['', 'Prénom', ''], max_col_width=25, col_widths=[0, 20, 0], hide_vertical_scroll=True, background_color='light blue', text_color='black', auto_size_columns=False, justification='right', num_rows=len(liste_eleves), alternating_row_color='lightyellow', key='table_eleves', tooltip='Liste des élèves'), sg.Column(col), sg.Column(col1), sg.Column(col2)], ] window = sg.Window('OVH - Gestion des instances', layout=layout, size=(900, 300), finalize=True) window.liste_eleves = liste_eleves window.liste_instances = liste_instances return window def make_add_window(caption, role='create', initial_values=None): if initial_values: eleve_id, prenom, pk = initial_values else: eleve_id = prenom = pk = '' layout = [ [sg.InputText(eleve_id, k='eleve_id', visible=False)], [sg.Text(text='Prénom', size=(10, 2)), sg.InputText( default_text=prenom, size=(20, 2), k='prenom')], [sg.Text(text='Clé publique', size=(10, 2)), sg.InputText( default_text=pk, size=(20, 2), k='pk')], [sg.Button('Valider', bind_return_key=True), sg.Button('Annuler', bind_return_key=True)] ] window = sg.Window(caption, layout=layout, finalize=True) window.role = role return window window1, window2 = make_main_window(), None while True: window, event, values = sg.read_all_windows() print(f'window : {window}, event : {event}, values : {values}') if window == window1: if event in (sg.WIN_CLOSED, 'Quitter'): break if event == 'Ajouter': window2 = make_add_window('Ajouter', role='create') window2.make_modal() if event == 'Supprimer': try: # dans le cas d'un tableau, la valeur est un tableau de(s) # index sélectionnés. On garde le premier quoi qu'il arrive selected_line = values['table_eleves'][0] # la colonne id est cachée au niveau de l'affichage id_eleve = window1.liste_eleves[selected_line][0] except IndexError: sg.popup_ok( 'Veuillez sélectionner un enregistrement à supprimer') continue confirmation = sg.popup("Confirmez-vous la suppression ?", button_type=sg.POPUP_BUTTONS_OK_CANCEL, custom_text=("Oui", "Non")) if confirmation == "Non": continue sg.PopupAnimated("sablier.png") delete_eleve(id_eleve) liste_eleves = get_eleves() sg.PopupAnimated(None) window1['table_eleves'].update(values=liste_eleves, num_rows=len(liste_eleves)) window1.liste_eleves = liste_eleves if event == 'Modifier': try: # voir 'Supprimer' pour une explication selected_line = values['table_eleves'][0] id_eleve, prenom, pk = window1.liste_eleves[selected_line] except IndexError: sg.popup_ok( 'Veuillez sélectionner un enregistrement à modifier') continue window2 = make_add_window('Modifier', initial_values=[id_eleve, prenom, pk], role='modify') window2.make_modal() if event == 'Instancier': selected_lines = values['table_eleves'] if len(selected_lines) == 0: sg.popup_ok( 'Veuillez sélectionner un élève') continue eleves = [] for row in selected_lines: id_eleve = window1.liste_eleves[row][0] prenom = window1.liste_eleves[row][1] eleves.append((id_eleve, prenom,)) nb_inst = len(eleves) confirmation = sg.popup(f"Confirmez-vous le lancement de {nb_inst} instances ?", button_type=sg.POPUP_BUTTONS_OK_CANCEL, custom_text=("Oui", "Non")) if confirmation == "Non": continue sg.PopupAnimated("sablier.png") for el in eleves: active_instances_names = [i[1].split( '-')[1] for i in window1.liste_instances] if not el[1] in active_instances_names: create_instance(el[0], el[1], values['region']) liste_instances = get_instances() sg.PopupAnimated(None) window1['table_instances'].update(values=liste_instances, num_rows=len(liste_instances)) window1.liste_instances = liste_instances if event == 'Détruire': selected_lines = values['table_instances'] if len(selected_lines) == 0: sg.popup_ok( 'Veuillez sélectionner une instance au moins') continue instances = [] for row in selected_lines: instances.append(window1.liste_instances[row][0]) nb_inst = len(instances) confirmation = sg.popup(f"Confirmez-vous la suppression de {nb_inst} instances ?", button_type=sg.POPUP_BUTTONS_OK_CANCEL, custom_text=("Oui", "Non")) if confirmation == "Non": continue sg.PopupAnimated("sablier.png") for id_inst in instances: delete_instance(id_inst) liste_instances = get_instances() sg.PopupAnimated(None) window1['table_instances'].update(values=liste_instances, num_rows=len(liste_instances)) window1.liste_instances = liste_instances if event == 'Actualiser': sg.PopupAnimated("sablier.png") liste_instances = get_instances() sg.PopupAnimated(None) window1['table_instances'].update(values=liste_instances, num_rows=len(liste_instances)) window1.liste_instances = liste_instances if window == window2: if event in (sg.WIN_CLOSED, 'Annuler'): window2.close() window2 = None if event == 'Valider' and window.role == 'create': prenom = values['prenom'].lower() # TODO : accents ? pk = values['pk'] create_eleve(prenom, pk) liste_eleves = get_eleves() window1['table_eleves'].update(values=liste_eleves, num_rows=len(liste_eleves)) window1.liste_eleves = liste_eleves window2.close() window2 = None if event == 'Valider' and window.role == 'modify': confirmation = sg.popup("Confirmez-vous la modification ?", button_type=sg.POPUP_BUTTONS_OK_CANCEL, custom_text=("Oui", "Non")) if confirmation == "Non": continue prenom = values['prenom'].lower() pk = values['pk'] eleve_id = values['eleve_id'] delete_eleve(eleve_id) create_eleve(prenom, pk) liste_eleves = get_eleves() window1['table_eleves'].update(values=liste_eleves, num_rows=len(liste_eleves)) window1.liste_eleves = liste_eleves window2.close() window2 = None window1.close() if window2 is not None: window2.close() print('Bye !')