1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-03-11 00:58:39 +03:00

Addind support for older proxmox versions (6.x), where some returns from API calls where different

This commit is contained in:
Adolfo Gómez García 2024-10-02 01:37:12 +02:00
parent e2ec608ead
commit ccefa7867c
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
3 changed files with 81 additions and 38 deletions

View File

@ -62,7 +62,7 @@ class TestProxmoxClient(UDSTransactionTestCase):
hagroup: str = ''
def setUp(self) -> None:
v = vars.get_vars('proxmox_cluster')
v = vars.get_vars('proxmox_cluster_old')
if not v:
self.skipTest('No proxmox vars')

View File

@ -266,6 +266,10 @@ class ProxmoxClient:
return False
return True
@cached('version', consts.CACHE_DURATION_LONG, key_helper=caching_key_helper)
def get_version(self) -> str:
return self.do_get('version')['data']['version']
@cached('cluster', consts.CACHE_DURATION, key_helper=caching_key_helper)
def get_cluster_info(self, **kwargs: typing.Any) -> types.ClusterInfo:
return types.ClusterInfo.from_dict(self.do_get('cluster/status'))
@ -593,9 +597,17 @@ class ProxmoxClient:
)
def get_task_info(self, node: str, upid: str) -> types.TaskStatus:
return types.TaskStatus.from_dict(
self.do_get(f'nodes/{node}/tasks/{urllib.parse.quote(upid)}/status', node=node)
)
# On older Versions, the result of some operations are simply missing
# To avoid this, we will return a "done" task if upid is empty
if upid == '':
return types.TaskStatus.done_task()
try:
return types.TaskStatus.from_dict(
self.do_get(f'nodes/{node}/tasks/{urllib.parse.quote(upid)}/status', node=node)
)
except Exception:
raise exceptions.ProxmoxNotFound(f'Task {upid} not found')
@cached('vms', consts.CACHE_DURATION, key_helper=caching_key_helper)
def list_vms(
@ -797,13 +809,13 @@ class ProxmoxClient:
@cached('pools', consts.CACHE_DURATION // 6, key_helper=caching_key_helper)
def list_pools(self, **kwargs: typing.Any) -> list[types.PoolInfo]:
return [types.PoolInfo.from_dict(poolInfo) for poolInfo in self.do_get('pools')['data']]
return [types.PoolInfo.from_dict(pool_info) for pool_info in self.do_get('pools')['data']]
@cached('pool', consts.CACHE_DURATION, key_helper=caching_key_helper)
def get_pool_info(
self, pool_id: str, retrieve_vm_names: bool = False, **kwargs: typing.Any
self, poolid: str, retrieve_vm_names: bool = False, **kwargs: typing.Any
) -> types.PoolInfo:
pool_info = types.PoolInfo.from_dict(self.do_get(f'pools/{pool_id}')['data'])
pool_info = types.PoolInfo.from_dict(self.do_get(f'pools/{poolid}')['data'], poolid=poolid)
if retrieve_vm_names:
for i in range(len(pool_info.members)):
try:

View File

@ -160,8 +160,10 @@ class ExecResult:
upid: str
@staticmethod
def from_dict(dictionary: collections.abc.MutableMapping[str, typing.Any]) -> 'ExecResult':
upid = dictionary['data']
def from_dict(data: collections.abc.MutableMapping[str, typing.Any]) -> 'ExecResult':
upid = data['data']
if upid is None:
return ExecResult.null() # No data, return null, that in turn, has a finished task
d = upid.split(':')
return ExecResult(
node=d[1],
@ -174,6 +176,19 @@ class ExecResult:
upid=upid,
)
@staticmethod
def null() -> 'ExecResult':
return ExecResult(
node='',
pid=0,
pstart=0,
starttime=datetime.datetime.now(),
type='',
vmid=0,
user='',
upid='',
)
@dataclasses.dataclass
class TaskStatus:
@ -204,6 +219,21 @@ class TaskStatus:
id=data['id'],
)
@staticmethod
def done_task() -> 'TaskStatus':
return TaskStatus(
node='',
pid=0,
pstart=0,
starttime=datetime.datetime.now(),
type='',
status='stopped',
exitstatus='OK',
user='',
upid='',
id='',
)
def is_running(self) -> bool:
return self.status == 'running'
@ -224,7 +254,7 @@ class NetworkConfiguration:
macaddr: str
netdata: str # Original data
def is_null(self) -> bool:
return self.net == ''
@ -246,6 +276,7 @@ class NetworkConfiguration:
def null() -> 'NetworkConfiguration':
return NetworkConfiguration(net='', type='', macaddr='', netdata='')
@dataclasses.dataclass
class HAInfo:
state: str
@ -304,10 +335,10 @@ class VMInfo:
return self.id == -1
@staticmethod
def from_dict(dictionary: collections.abc.MutableMapping[str, typing.Any]) -> 'VMInfo':
def from_dict(data: collections.abc.MutableMapping[str, typing.Any]) -> 'VMInfo':
vgpu_type = None
# Look for vgpu type if present
for k, v in dictionary.items():
for k, v in data.items():
if k.startswith('hostpci'):
for i in v.split(','):
if i.startswith('mdev='):
@ -318,27 +349,27 @@ class VMInfo:
break # Already found it, stop looking
return VMInfo(
status=VMStatus.from_str(dictionary['status']),
id=int(dictionary.get('vmid', 0)),
node=dictionary.get('node', ''),
template=dictionary.get('template', False),
ha=HAInfo.from_dict(dictionary.get('ha', {})),
agent=dictionary.get('agent', None),
cpus=dictionary.get('cpus', None),
lock=dictionary.get('lock', None),
disk=dictionary.get('disk', None),
maxdisk=dictionary.get('maxdisk', None),
mem=dictionary.get('mem', None),
maxmem=dictionary.get('maxmem', None),
name=dictionary.get('name', None),
pid=dictionary.get('pid', None),
qmpstatus=dictionary.get('qmpstatus', None),
tags=dictionary.get('tags', None),
uptime=dictionary.get('uptime', None),
netin=dictionary.get('netin', None),
netout=dictionary.get('netout', None),
diskread=dictionary.get('diskread', None),
diskwrite=dictionary.get('diskwrite', None),
status=VMStatus.from_str(data['status']),
id=int(data.get('vmid', 0)),
node=data.get('node', ''),
template=bool(data.get('template', False)),
ha=HAInfo.from_dict(data.get('ha', {})),
agent=data.get('agent', None),
cpus=data.get('cpus', None),
lock=data.get('lock', None),
disk=data.get('disk', None),
maxdisk=data.get('maxdisk', None),
mem=data.get('mem', None),
maxmem=data.get('maxmem', None),
name=data.get('name', None),
pid=data.get('pid', None),
qmpstatus=data.get('qmpstatus', None),
tags=data.get('tags', None),
uptime=data.get('uptime', None),
netin=data.get('netin', None),
netout=data.get('netout', None),
diskread=data.get('diskread', None),
diskwrite=data.get('diskwrite', None),
vgpu_type=vgpu_type,
)
@ -496,15 +527,15 @@ class PoolInfo:
members: list[PoolMemberInfo]
@staticmethod
def from_dict(dictionary: collections.abc.MutableMapping[str, typing.Any]) -> 'PoolInfo':
if 'members' in dictionary:
members: list[PoolMemberInfo] = [PoolMemberInfo.from_dict(i) for i in dictionary['members']]
def from_dict(data: collections.abc.MutableMapping[str, typing.Any], *, poolid: typing.Optional[str] = None) -> 'PoolInfo':
if 'members' in data:
members: list[PoolMemberInfo] = [PoolMemberInfo.from_dict(i) for i in data['members']]
else:
members = []
return PoolInfo(
id=dictionary.get('poolid', ''),
comments=dictionary.get('comments', ''),
id=data.get('poolid', poolid) or '',
comments=data.get('comments', ''),
members=members,
)