Add HTTP config download option

This commit is contained in:
jpattWPC 2023-10-15 11:39:54 -05:00
parent 2476778fe6
commit 07ea02d246
3 changed files with 81 additions and 48 deletions

View File

@ -8,6 +8,28 @@ This project's focus is to create a simple VDI client intended for mass deployme
![VDI View](screenshots/vdiview.png) ![VDI View](screenshots/vdiview.png)
## Command Line Usage
No command line options are required for default behavior. The following command line options are available:
usage: vdiclient.py [-h] [--list_themes] [--config_type {file,http}] [--config_location CONFIG_LOCATION]
[--config_username CONFIG_USERNAME] [--config_password CONFIG_PASSWORD] [--ignore_ssl]
Proxmox VDI Client
options:
-h, --help show this help message and exit
--list_themes List all available themes
--config_type {file,http}
Select config type (default: file)
--config_location CONFIG_LOCATION
Specify the config location (default: search for config file)
--config_username CONFIG_USERNAME
HTTP basic authentication username (default: None)
--config_password CONFIG_PASSWORD
HTTP basic authentication password (default: None)
--ignore_ssl HTTPS ignore SSL certificate errors (default: False)
## Windows Installation ## Windows Installation
You **MUST** install virt-viewer prior to using PVE VDI client, you may download it from the [official Virtual Machine Manager](https://virt-manager.org/download.html) site. You **MUST** install virt-viewer prior to using PVE VDI client, you may download it from the [official Virtual Machine Manager](https://virt-manager.org/download.html) site.

2
dist/vdiclient.json vendored
View File

@ -1,6 +1,6 @@
{ {
"upgrade_guid" : "46cbad92-353e-4b28-9bee-83950991dad8", "upgrade_guid" : "46cbad92-353e-4b28-9bee-83950991dad8",
"version" : "1.2.06", "version" : "1.3.01",
"product_name" : "VDI Client", "product_name" : "VDI Client",
"manufacturer" : "Josh Patten", "manufacturer" : "Josh Patten",
"name" : "VDI Client", "name" : "VDI Client",

View File

@ -5,9 +5,9 @@ gui = 'TK'
import requests import requests
from datetime import datetime from datetime import datetime
from configparser import ConfigParser from configparser import ConfigParser
import argparse
import random import random
import sys import sys
import copy
import os import os
import subprocess import subprocess
from time import sleep from time import sleep
@ -19,6 +19,7 @@ class G:
hostpool = [] hostpool = []
spiceproxy_conv = {} spiceproxy_conv = {}
proxmox = None proxmox = None
icon = None
vvcmd = None vvcmd = None
scaling = 1 scaling = 1
######### #########
@ -33,54 +34,62 @@ class G:
viewer_kiosk = True viewer_kiosk = True
fullscreen = True fullscreen = True
verify_ssl = True verify_ssl = True
icon = None
inidebug = False inidebug = False
show_reset = False show_reset = False
show_hibernate = False show_hibernate = False
addl_params = None addl_params = None
pwresetcmd = None
auto_vmid = None
theme = 'LightBlue' theme = 'LightBlue'
guest_type = 'both' guest_type = 'both'
width = None width = None
height = None height = None
pwresetcmd = None
auto_vmid = None
def loadconfig(config_location = None):
if config_location: def loadconfig(config_location = None, config_type='file', config_username = None, config_password = None, ssl_verify = True):
config = ConfigParser(delimiters='=') config = ConfigParser(delimiters='=')
try: if config_type == 'file':
config.read(config_location) if config_location:
except Exception as e: if not os.path.isfile(config_location):
win_popup_button(f'Unable to read supplied configuration:\n{e!r}', 'OK') win_popup_button(f'Unable to read supplied configuration:\n{config_location} does not exist!', 'OK')
config_location = None
if not config_location:
if os.name == 'nt': # Windows
config_location = f'{os.getenv("APPDATA")}\\VDIClient\\vdiclient.ini'
if not os.path.exists(config_location):
config_location = f'{os.getenv("PROGRAMFILES")}\\VDIClient\\vdiclient.ini'
if not os.path.exists(config_location):
config_location = f'{os.getenv("PROGRAMFILES(x86)")}\\VDIClient\\vdiclient.ini'
if not os.path.exists(config_location):
# Last ditch effort
config_location = 'C:\\Program Files\\VDIClient\\vdiclient.ini'
if not os.path.exists(config_location):
win_popup_button(f'Unable to read supplied configuration from any location!', 'OK')
return False return False
elif os.name == 'posix': #Linux else:
config_location = os.path.expanduser('~/.config/VDIClient/vdiclient.ini') if os.name == 'nt': # Windows
if not os.path.exists(config_location): config_list = [
config_location = '/etc/vdiclient/vdiclient.ini' f'{os.getenv("APPDATA")}\\VDIClient\\vdiclient.ini',
if not os.path.exists(config_location): f'{os.getenv("PROGRAMFILES")}\\VDIClient\\vdiclient.ini',
config_location = '/usr/local/etc/vdiclient/vdiclient.ini' f'{os.getenv("PROGRAMFILES(x86)")}\\VDIClient\\vdiclient.ini',
if not os.path.exists(config_location): 'C:\\Program Files\\VDIClient\\vdiclient.ini'
win_popup_button(f'Unable to read supplied configuration from any location!', 'OK') ]
return False
config = ConfigParser(delimiters='=') elif os.name == 'posix': #Linux
config_list = [
os.path.expanduser('~/.config/VDIClient/vdiclient.ini'),
'/etc/vdiclient/vdiclient.ini',
'/usr/local/etc/vdiclient/vdiclient.ini'
]
for location in config_list:
if os.path.exists(location):
config_location = location
break
if not config_location:
win_popup_button(f'Unable to read supplied configuration from any location!', 'OK')
return False
try: try:
config.read(config_location) config.read(config_location)
except Exception as e: except Exception as e:
win_popup_button(f'Unable to read configuration file:\n{e!r}', 'OK') win_popup_button(f'Unable to read configuration file:\n{e!r}', 'OK')
config_location = None return False
elif config_type == 'http':
try:
if config_username and config_password:
r = requests.get(url=config_location, auth=(config_username, config_password), verify = ssl_verify)
else:
r = requests.get(url=config_location, verify = ssl_verify)
config.read_string(r.text)
except Exception as e:
win_popup_button(f"Unable to read configuration from URL!\n{e}", "OK")
return False
if not 'General' in config: if not 'General' in config:
win_popup_button(f'Unable to read supplied configuration:\nNo `General` section defined!', 'OK') win_popup_button(f'Unable to read supplied configuration:\nNo `General` section defined!', 'OK')
return False return False
@ -131,6 +140,8 @@ def loadconfig(config_location = None):
G.pwresetcmd = config['Authentication']['pwresetcmd'] G.pwresetcmd = config['Authentication']['pwresetcmd']
if 'auto_vmid' in config['Authentication']: if 'auto_vmid' in config['Authentication']:
G.auto_vmid = config['Authentication'].getint('auto_vmid') G.auto_vmid = config['Authentication'].getint('auto_vmid')
if 'knock_ip' in config['Authentication']:
G.knock
if not 'Hosts' in config: if not 'Hosts' in config:
win_popup_button(f'Unable to read supplied configuration:\nNo `Hosts` section defined!', 'OK') win_popup_button(f'Unable to read supplied configuration:\nNo `Hosts` section defined!', 'OK')
return False return False
@ -599,19 +610,19 @@ def showvms():
def main(): def main():
G.scaling = 1 # TKinter requires integers G.scaling = 1 # TKinter requires integers
config_location = None parser = argparse.ArgumentParser(description='Proxmox VDI Client')
if len(sys.argv) > 1: parser.add_argument('--list_themes', help='List all available themes', action='store_true')
if sys.argv[1] == '--list_themes': parser.add_argument('--config_type', help='Select config type (default: file)', choices=['file', 'http'], default='file')
sg.preview_all_look_and_feel_themes() parser.add_argument('--config_location', help='Specify the config location (default: search for config file)', default=None)
return parser.add_argument('--config_username', help="HTTP basic authentication username (default: None)", default=None)
if sys.argv[1] == '--config': parser.add_argument('--config_password', help="HTTP basic authentication password (default: None)", default=None)
if len(sys.argv) < 3: parser.add_argument('--ignore_ssl', help="HTTPS ignore SSL certificate errors (default: False)", action='store_false', default=True)
win_popup_button('No config file provided with `--config` parameter.\nPlease provide location of config file!', 'OK') args = parser.parse_args()
return if args.list_themes:
else: sg.preview_all_look_and_feel_themes()
config_location = sys.argv[2] return
setcmd() setcmd()
if not loadconfig(config_location): if not loadconfig(config_location=args.config_location, config_type=args.config_type, config_username=args.config_username, config_password=args.config_password, ssl_verify=args.ignore_ssl):
return False return False
sg.theme(G.theme) sg.theme(G.theme)
loggedin = False loggedin = False