diff --git a/.changelogs/1.0.3/64_improve_error_handling_and_validations.yml b/.changelogs/1.0.3/64_improve_error_handling_and_validations.yml new file mode 100644 index 0000000..89efa41 --- /dev/null +++ b/.changelogs/1.0.3/64_improve_error_handling_and_validations.yml @@ -0,0 +1,2 @@ +fixed: + - Improved the overall validation and error handling. [#64] diff --git a/README.md b/README.md index f21e513..b95e33c 100644 --- a/README.md +++ b/README.md @@ -351,6 +351,9 @@ Bugs can be reported via the GitHub issue tracker [here](https://github.com/gypt ### Contributing Feel free to add further documentation, to adjust already existing one or to contribute with code. Please take care about the style guide and naming conventions. You can find more in our [CONTRIBUTING.md](https://github.com/gyptazy/ProxLB/blob/main/CONTRIBUTING.md) file. +### Documentation +You can also find additional and more detailed documentation within the [docs/](https://github.com/gyptazy/ProxLB/tree/main/docs) directory. + ### Support If you need assistance or have any questions, we offer support through our dedicated [chat room](https://matrix.to/#/#proxlb:gyptazy.ch) in Matrix and on Reddit. Join our community for real-time help, advice, and discussions. Connect with us in our dedicated chat room for immediate support and live interaction with other users and developers. You can also visit our [GitHub Community](https://github.com/gyptazy/ProxLB/discussions/) to post your queries, share your experiences, and get support from fellow community members and moderators. You may also just open directly an issue [here](https://github.com/gyptazy/ProxLB/issues) on GitHub. We are here to help and ensure you have the best experience possible. diff --git a/docs/02_Configuration.md b/docs/02_Configuration.md index 3e2c1fb..9b1de9d 100644 --- a/docs/02_Configuration.md +++ b/docs/02_Configuration.md @@ -23,4 +23,15 @@ Afterwards, restart the service (if running in daemon mode) to activate this reb Access the Proxmox Web UI by opening your web browser and navigating to your Proxmox VE web interface, then log in with your credentials. Navigate to the VM you want to tag by selecting it from the left-hand navigation panel. Click on the "Options" tab to view the VM's options, then select "Edit" or "Add" (depending on whether you are editing an existing tag or adding a new one). In the tag field, enter plb_exclude_ followed by your unique identifier, for example, plb_exclude_critical. Save the changes to apply the tag to the VM. Repeat these steps for each VM that should be excluded from being on the same node. ### Ignore VMs (tag style) - In Proxmox, you can ensure that certain VMs are ignored during the rebalancing process by setting a specific tag within the Proxmox Web UI, rather than solely relying on configurations in the ProxLB config file. This can be achieved by adding the tag 'plb_ignore_vm' to the VM. Once this tag is applied, the VM will be excluded from any further rebalancing operations, simplifying the management process. \ No newline at end of file + In Proxmox, you can ensure that certain VMs are ignored during the rebalancing process by setting a specific tag within the Proxmox Web UI, rather than solely relying on configurations in the ProxLB config file. This can be achieved by adding the tag 'plb_ignore_vm' to the VM. Once this tag is applied, the VM will be excluded from any further rebalancing operations, simplifying the management process. + +## Authentication / User Account / User / Permissions +### Authentication +ProxLB also supports different accounts in ProxLB. Therefore, you can simply create a new user and group and add the required roles permissions. + +### Required Roles +When using ProxLB with a dedicated account, you might also keep the assigned roles low. Therefore, you need to ensure that the newly created user is at least assigned to the following roles: +* Datastore.Audit (Required for storage evaluation) +* Sys.Audit (Required to get resource metrics of the nodes) +* VM.Audit (Requited to get resource metrics of VMs/CTs) +* VM.Migrate (Required for migration of VMs/CTs) \ No newline at end of file diff --git a/proxlb b/proxlb index 560c69b..57a80f3 100755 --- a/proxlb +++ b/proxlb @@ -89,13 +89,19 @@ def initialize_logger(log_level, update_log_verbosity=False): logging.info(f'{info_prefix} Logger verbosity got updated to: {log_level}.') -def pre_validations(config_path): +def pre_validations(config_path, proxlb_config=False): """ Run pre-validations as sanity checks. """ info_prefix = 'Info: [pre-validations]:' - __validate_imports() - __validate_config_file(config_path) - logging.info(f'{info_prefix} All pre-validations done.') + if proxlb_config: + logging.info(f'{info_prefix} Validating ProxLB config file content.') + __validate_config_content(proxlb_config) + logging.info(f'{info_prefix} ProxLB config file content validation done.') + else: + logging.info(f'{info_prefix} Validating basic configuration.') + __validate_imports() + __validate_config_file(config_path) + logging.info(f'{info_prefix} All pre-validations done.') def post_validations(): @@ -145,6 +151,56 @@ def __validate_config_file(config_path): logging.info(f'{info_prefix} Configuration file loaded from: {config_path}.') +def __validate_config_content(proxlb_config): + """ Validate the user's config options. """ + error_prefix = 'Error: [config]:' + info_prefix = 'Info: [config]:' + + validate_bool_options = [ + 'proxmox_api_ssl_v', + 'vm_balancing_enable', + 'vm_parallel_migrations', + 'storage_balancing_enable', + 'storage_parallel_migrations', + 'update_service', + 'api', + 'master_only', + 'daemon' + ] + + for bool_val in validate_bool_options: + if type(proxlb_config.get(bool_val, None)) == bool: + logging.info(f'{info_prefix} Config option {bool_val} is in a correct format.') + else: + logging.critical(f'{error_prefix} Config option {bool_val} is incorrect: {proxlb_config.get(bool_val, None)}') + sys.exit(2) + + validate_string_options = [ + 'vm_balancing_method', + 'vm_balancing_mode', + 'vm_balancing_mode_option', + 'vm_balancing_type', + 'storage_balancing_method', + 'log_verbosity' + ] + + whitelist_string_options = { + 'vm_balancing_method': ['memory', 'disk', 'cpu'], + 'vm_balancing_mode': ['used', 'assigned'], + 'vm_balancing_mode_option': ['bytes', 'percent'], + 'vm_balancing_type': ['vm', 'ct', 'all'], + 'storage_balancing_method': ['disk_space'], + 'log_verbosity': ['INFO', 'CRITICAL'] + } + + for string_val in validate_string_options: + if proxlb_config[string_val] in whitelist_string_options[string_val]: + logging.info(f'{info_prefix} Config option {string_val} is in a correct format.') + else: + logging.critical(f'{error_prefix} Config option {string_val} is incorrect: {proxlb_config.get(string_val, None)}') + sys.exit(2) + + def initialize_args(): """ Initialize given arguments for ProxLB. """ argparser = argparse.ArgumentParser(description='ProxLB') @@ -271,6 +327,9 @@ def api_connect(proxmox_api_host, proxmox_api_user, proxmox_api_pass, proxmox_ap try: api_object = proxmoxer.ProxmoxAPI(proxmox_api_host, user=proxmox_api_user, password=proxmox_api_pass, verify_ssl=proxmox_api_ssl_v) + except proxmoxer.backends.https.AuthenticationError as proxmox_api_error: + logging.critical(f'{error_prefix} Provided credentials do not work: {proxmox_api_error}') + sys.exit(2) except urllib3.exceptions.NameResolutionError: logging.critical(f'{error_prefix} Could not resolve the given host: {proxmox_api_host}.') sys.exit(2) @@ -1343,6 +1402,7 @@ def main(): # Parse global config. proxlb_config = initialize_config_options(config_path) + pre_validations(config_path, proxlb_config) # Overwrite logging handler with user defined log verbosity. initialize_logger(proxlb_config['log_verbosity'], update_log_verbosity=True)