Merge pull request #140 from gyptazy/fix/adjust-branch-license-info

enhancement: Adjust license information, adjust class/func descriptions
This commit is contained in:
Florian
2025-03-03 10:51:00 +01:00
committed by GitHub
19 changed files with 274 additions and 35 deletions

View File

@@ -252,10 +252,10 @@ The `maintenance_nodes` option allows operators to designate one or more Proxmox
Bugs can be reported via the GitHub issue tracker [here](https://github.com/gyptazy/ProxLB/issues). You may also report bugs via email or deliver PRs to fix them on your own. Therefore, you might also see the contributing chapter.
### 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/development/CONTRIBUTING.md) file.
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/development/docs) directory.
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.com) in Matrix or [Discord](https://discord.gg/JemGu7WbfQ). Join our community for real-time help, advice, and discussions. The Matrix and Discord room are bridged to ensure that the communication is not splitted - so simply feel free to join which fits most to you!

0
docs/01_requirements.md Normal file
View File

0
docs/02_installation.md Normal file
View File

0
docs/04_configuration.md Normal file
View File

0
docs/99-misc.md Normal file
View File

View File

@@ -7,6 +7,11 @@ perform balancing actions based on the configuration provided. It also includes
parser for handling command-line arguments and a custom logger for systemd integration.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
import logging
from utils.logger import SystemdLogger
from utils.cli_parser import CliParser

View File

@@ -1,10 +1,15 @@
"""
The balancing class is responsible for processing workloads on Proxmox clusters.
The previously generated data (hold in proxlb_data) will processed and guests and
other supported types will be moved across Proxmox clusters based on the defined
values by an operator.
The Balancing class is responsible for processing workloads on Proxmox clusters.
It processes the previously generated data (held in proxlb_data) and moves guests
and other supported types across Proxmox clusters based on the defined values by an operator.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
import proxmoxer
import time
from utils.logger import SystemdLogger
@@ -19,6 +24,23 @@ class Balancing:
The previously generated data (hold in proxlb_data) will processed and guests and
other supported types will be moved across Proxmox clusters based on the defined
values by an operator.
Methods:
__init__(self, proxmox_api: any, proxlb_data: Dict[str, Any]):
Initializes the Balancing class with the provided ProxLB data and initiates the rebalancing
process for guests.
exec_rebalancing_vm(self, proxmox_api: any, proxlb_data: Dict[str, Any], guest_name: str) -> None:
Executes the rebalancing of a virtual machine (VM) to a new node within the cluster. Logs the migration
process and handles exceptions.
exec_rebalancing_ct(self, proxmox_api: any, proxlb_data: Dict[str, Any], guest_name: str) -> None:
Executes the rebalancing of a container (CT) to a new node within the cluster. Logs the migration
process and handles exceptions.
get_rebalancing_job_status(self, proxmox_api: any, proxlb_data: Dict[str, Any], guest_name: str, guest_current_node: str, job_id: int, retry_counter: int = 1) -> bool:
Monitors the status of a rebalancing job on a Proxmox node until it completes or a timeout
is reached. Returns True if the job completed successfully, False otherwise.
"""
def __init__(self, proxmox_api: any, proxlb_data: Dict[str, Any]):

View File

@@ -1,9 +1,15 @@
"""
The calculation class is responsible for handling the balancing of virtual machines (VMs)
The Calculations class is responsible for handling the balancing of virtual machines (VMs)
and containers (CTs) across all available nodes in a Proxmox cluster. It provides methods
to calculate the optimal distribution of VMs and CTs based on the provided data.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
import sys
from typing import Dict, Any
from utils.logger import SystemdLogger
@@ -16,6 +22,37 @@ class Calculations:
The calculation class is responsible for handling the balancing of virtual machines (VMs)
and containers (CTs) across all available nodes in a Proxmox cluster. It provides methods
to calculate the optimal distribution of VMs and CTs based on the provided data.
Methods:
__init__(proxlb_data: Dict[str, Any]):
Initializes the Calculation class with the provided ProxLB data.
set_node_assignments(proxlb_data: Dict[str, Any]) -> Dict[str, Any]:
Sets the assigned resources of the nodes based on the current assigned
guest resources by their created groups as an initial base.
get_balanciness(proxlb_data: Dict[str, Any]) -> Dict[str, Any]:
Gets the balanciness for further actions where the highest and lowest
usage or assignments of Proxmox nodes are compared.
get_most_free_node(proxlb_data: Dict[str, Any], return_node: bool = False) -> Dict[str, Any]:
Gets the name of the Proxmox node in the cluster with the most free resources based on
the user-defined method (e.g., memory) and mode (e.g., used).
relocate_guests_on_maintenance_nodes(proxlb_data: Dict[str, Any]):
Relocates guests that are currently on nodes marked for maintenance to
nodes with the most available resources.
relocate_guests(proxlb_data: Dict[str, Any]):
Relocates guests within the provided data structure to ensure affinity groups are
placed on nodes with the most free resources.
val_anti_affinity(proxlb_data: Dict[str, Any], guest_name: str):
Validates and assigns nodes to guests based on anti-affinity rules.
update_node_resources(proxlb_data):
Updates the resource allocation and usage statistics for nodes when a guest
is moved from one node to another.
"""
def __init__(self, proxlb_data: Dict[str, Any]):

View File

@@ -1,9 +1,15 @@
"""
The groups class is responsible for handling the correlations between the guests
and their groups like affinity and anti-affinity groups. To ensure a proper balancing
guests will ge grouped and then evaluated for further balancing.
The Groups class is responsible for handling the correlations between the guests
and their groups, such as affinity and anti-affinity groups. It ensures proper balancing
by grouping guests and evaluating them for further balancing. The class provides methods
to initialize with ProxLB data and to generate groups based on guest and node data.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
from typing import Dict, Any
from utils.logger import SystemdLogger
from utils.helper import Helper
@@ -16,6 +22,14 @@ class Groups:
The groups class is responsible for handling the correlations between the guests
and their groups like affinity and anti-affinity groups. To ensure a proper balancing
guests will ge grouped and then evaluated for further balancing.
Methods:
__init__(proxlb_data: Dict[str, Any]):
Initializes the Groups class.
get_groups(guests: Dict[str, Any], nodes: Dict[str, Any]) -> Dict[str, Any]:
Generates and returns a dictionary of affinity and anti-affinity groups
based on the provided data.
"""
def __init__(self, proxlb_data: Dict[str, Any]):

View File

@@ -3,6 +3,11 @@ The Guests class retrieves all running guests on the Proxmox cluster across all
It handles both VM and CT guest types, collecting their resource metrics.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
from typing import Dict, Any
from utils.logger import SystemdLogger
from models.tags import Tags
@@ -14,6 +19,14 @@ class Guests:
"""
The Guests class retrieves all running guests on the Proxmox cluster across all available nodes.
It handles both VM and CT guest types, collecting their resource metrics.
Methods:
__init__:
Initializes the Guests class.
get_guests(proxmox_api: any, nodes: Dict[str, Any]) -> Dict[str, Any]:
Retrieves metrics for all running guests (both VMs and CTs) across all nodes in the Proxmox cluster.
It collects resource metrics such as CPU, memory, and disk usage, as well as tags and affinity/anti-affinity groups.
"""
def __init__(self):
"""

View File

@@ -1,8 +1,26 @@
"""
The Nodes class retrieves all running nodes in a Proxmox cluster
and collects their resource metrics.
Methods:
__init__:
Initializes the Nodes class.
get_nodes(proxmox_api: any, proxlb_config: Dict[str, Any]) -> Dict[str, Any]:
Gets metrics of all nodes in a Proxmox cluster.
set_node_maintenance(proxlb_config: Dict[str, Any], node_name: str) -> Dict[str, Any]:
Sets Proxmox nodes to a maintenance mode if required.
set_node_ignore(proxlb_config: Dict[str, Any], node_name: str) -> Dict[str, Any]:
Sets Proxmox nodes to be ignored if requested.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
from typing import Dict, Any
from utils.logger import SystemdLogger

View File

@@ -1,9 +1,15 @@
"""
The Tags class retrieves all tags from guests of the type VM or CT running
in a Proxmox cluster and validates for affinity, anti-affinity and ignore
tags set for the guest in the Proxmox API.
The Tags class retrieves and processes tags from guests of type VM or CT running
in a Proxmox cluster. It provides methods to fetch tags from the Proxmox API and
evaluate them for affinity, anti-affinity, and ignore tags, which are used during
balancing calculations.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
import time
from typing import List
from utils.logger import SystemdLogger
@@ -13,13 +19,30 @@ logger = SystemdLogger()
class Tags:
"""
The Tags class retrieves all tags from guests of the type VM or CT running
in a Proxmox cluster and validates for affinity, anti-affinity and ignore
tags set for the guest in the Proxmox API.
The Tags class retrieves and processes tags from guests of type VM or CT running
in a Proxmox cluster. It provides methods to fetch tags from the Proxmox API and
evaluate them for affinity, anti-affinity, and ignore tags, which are used during
balancing calculations.
Methods:
__init__:
Initializes the Tags class.
get_tags_from_guests(proxmox_api: any, node: str, guest_id: int, guest_type: str) -> List[str]:
Retrieves all tags for a given guest from the Proxmox API.
get_affinity_groups(tags: List[str]) -> List[str]:
Evaluates and returns all affinity tags from the provided list of tags.
get_anti_affinity_groups(tags: List[str]) -> List[str]:
Evaluates and returns all anti-affinity tags from the provided list of tags.
get_ignore(tags: List[str]) -> bool:
Evaluates and returns a boolean indicating whether the guest should be ignored based on the provided list of tags.
"""
def __init__(self):
"""
Initializes the Tags class.
Initializes the tags class.
"""
@staticmethod

View File

@@ -2,6 +2,11 @@
The CliParser class handles the parsing of command-line interface (CLI) arguments.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
import argparse
import utils.version
from utils.logger import SystemdLogger

View File

@@ -3,6 +3,11 @@ The ConfigParser class handles the parsing of configuration file
from a given YAML file from any location.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
import os
import sys
try:
@@ -24,8 +29,16 @@ logger = SystemdLogger()
class ConfigParser:
"""
The ConfigParser class handles the parsing of configuration file
from a given YAML file from any location.
The ConfigParser class handles the parsing of a configuration file.
Methods:
__init__(config_path: str)
test_config_path(config_path: str) -> None
Checks if the configuration file is present at the given config path.
get_config() -> Dict[str, Any]
Parses and returns the configuration data from the YAML file.
"""
def __init__(self, config_path: str):
"""

View File

@@ -3,6 +3,11 @@ The Helper class provides some basic helper functions to not mess up the code in
classes.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
import uuid
import sys
import time
@@ -17,6 +22,22 @@ class Helper:
"""
The Helper class provides some basic helper functions to not mess up the code in other
classes.
Methods:
__init__():
Initializes the general Helper class.
get_uuid_string() -> str:
Generates a random uuid and returns it as a string.
log_node_metrics(proxlb_data: Dict[str, Any], init: bool = True) -> None:
Logs the memory, CPU, and disk usage metrics of nodes in the provided proxlb_data dictionary.
get_version(print_version: bool = False) -> None:
Returns the current version of ProxLB and optionally prints it to stdout.
get_daemon_mode(proxlb_config: Dict[str, Any]) -> None:
Checks if the daemon mode is active and handles the scheduling accordingly.
"""
def __init__(self):
"""

View File

@@ -1,9 +1,13 @@
"""
The SystemdLogger class provides the root logger support. It dynamically
evaluates the further usage and imports of journald and adjusts
the logger to the systems functionality where it gets executed
The SystemdLogger class provides a singleton logger that integrates with systemd's journal if available.
It dynamically evaluates the environment and adjusts the logger accordingly.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
import logging
try:
from systemd.journal import JournalHandler
@@ -14,9 +18,36 @@ except ImportError:
class SystemdLogger:
"""
The SystemdLogger class provides the root logger support. It dynamically
evaluates the further usage and imports of journald and adjusts
the logger to the systems functionality where it gets executed.
The SystemdLogger class provides a singleton logger that integrates with systemd's journal if available.
It dynamically evaluates the environment and adjusts the logger accordingly.
Attributes:
instance (SystemdLogger): Singleton instance of the SystemdLogger class.
Methods:
__new__(cls, name: str = "ProxLB", level: str = logging.INFO) -> 'SystemdLogger':
Creates a new instance of the SystemdLogger class or returns the existing instance.
initialize_logger(self, name: str, level: str) -> None:
Initializes the logger with the given name and log level. Adds a JournalHandler if systemd is present.
set_log_level(self, level: str) -> None:
Sets the log level for the logger and all its handlers.
debug(self, msg: str) -> str:
Logs a message with level DEBUG.
info(self, msg: str) -> str:
Logs a message with level INFO.
warning(self, msg: str) -> str:
Logs a message with level WARNING.
error(self, msg: str) -> str:
Logs a message with level ERROR.
critical(self, msg: str) -> str:
Logs a message with level CRITICAL.
"""
# Create a singleton instance variable
instance = None

View File

@@ -1,7 +1,18 @@
"""
Module providing a function printing python version.
The proxmox_api class manages connections to the Proxmox API by parsing the required objects
for the authentication which can be based on username/password or API tokens.
This class provides methods to initialize the Proxmox API connection, test connectivity to
Proxmox hosts, and handle authentication using either username/password or API tokens.
It also includes functionality to distribute load across multiple Proxmox API endpoints
and manage SSL certificate validation.
"""
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
try:
import proxmoxer
PROXMOXER_PRESENT = True
@@ -42,20 +53,44 @@ logger = SystemdLogger()
class ProxmoxApi:
"""
Handles command-line argument parsing for ProxLB.
The proxmox_api class manages connections to the Proxmox API by parsing the required objects
for the authentication which can be based on username/password or API tokens.
This class provides methods to initialize the Proxmox API connection, test connectivity to
Proxmox hosts, and handle authentication using either username/password or API tokens.
It also includes functionality to distribute load across multiple Proxmox API endpoints
and manage SSL certificate validation.
Attributes:
logger (SystemdLogger): Logger instance for logging messages.
proxmox_api (proxmoxer.ProxmoxAPI): Authenticated ProxmoxAPI object.
Methods:
__init__(proxlb_config: Dict[str, Any]) -> None:
Initializes the ProxmoxApi instance with the provided configuration.
__getattr__(name):
Delegates attribute access to the proxmox_api object.
api_connect_get_hosts(proxmox_api_endpoints: list) -> str:
Determines a working Proxmox API host from a list of endpoints.
test_api_proxmox_host(host: str) -> str:
Tests connectivity to a Proxmox host by resolving its IP address.
test_api_proxmox_host_ipv4(host: str, port: int = 8006, timeout: int = 1) -> bool:
Tests reachability of a Proxmox host on its IPv4 address.
test_api_proxmox_host_ipv6(host: str, port: int = 8006, timeout: int = 1) -> bool:
Tests reachability of a Proxmox host on its IPv6 address.
api_connect(proxlb_config: Dict[str, Any]) -> proxmoxer.ProxmoxAPI:
Establishes a connection to the Proxmox API using the provided configuration.
"""
def __init__(self, proxlb_config: Dict[str, Any]) -> None:
"""
Initialize the ProxmoxApi instance.
Initializes the ProxmoxApi instance with the provided configuration.
This method sets up the ProxmoxApi instance by testing the required module dependencies
and establishing a connection to the Proxmox API using the provided configuration.
This constructor method sets up the Proxmox API connection by calling the
api_connect method with the given configuration dictionary. It logs the
initialization process for debugging purposes.
Args:
proxlb_config (Dict[str, Any]): Configuration dictionary containing Proxmox API connection details.
Returns:
None
proxlb_config (Dict[str, Any]): A dictionary containing the Proxmox API configuration.
"""
logger.debug("Starting: ProxmoxApi initialization.")
self.proxmox_api = self.api_connect(proxlb_config)
@@ -63,7 +98,7 @@ class ProxmoxApi:
def __getattr__(self, name):
"""
Delegate attribute access to proxmox_api.
Delegate attribute access to proxmox_api to the underlying proxmoxer module.
"""
return getattr(self.proxmox_api, name)

View File

@@ -1,5 +1,7 @@
__app_name__ = "ProxLB"
__app_desc__ = "A DRS alike loadbalancer for Proxmox clusters."
__author__ = "Florian Paul Azim Hoberg <gyptazy>"
__copyright__ = "Copyright (C) 2025 Florian Paul Azim Hoberg (@gyptazy)"
__license__ = "GPL-3.0"
__version__ = "1.1.0-alpha"
__url__ = "https://github.com/gyptazy/ProxLB"