py-pve-cloud 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of py-pve-cloud might be problematic. Click here for more details.

pve_cloud/cli/pvcli.py ADDED
@@ -0,0 +1,97 @@
1
+ import argparse
2
+ import yaml
3
+ from proxmoxer import ProxmoxAPI
4
+ import os
5
+ import paramiko
6
+
7
+
8
+ def connect_cluster(args):
9
+ # try load current dynamic inventory
10
+ inv_path = os.path.expanduser("~/.pve-cloud-dyn-inv.yaml")
11
+ if os.path.exists(inv_path):
12
+ with open(inv_path, "r") as file:
13
+ dynamic_inventory = yaml.safe_load(file)
14
+ else:
15
+ # initialize empty
16
+ dynamic_inventory = {}
17
+
18
+ # init cloud domain if not there
19
+ if args.pve_cloud_domain not in dynamic_inventory:
20
+ dynamic_inventory[args.pve_cloud_domain] = {}
21
+
22
+ # connect to the passed host
23
+ proxmox = ProxmoxAPI(
24
+ args.pve_host, user="root", backend='ssh_paramiko'
25
+ )
26
+
27
+ # try get the cluster name
28
+ cluster_name = None
29
+ status_resp = proxmox.cluster.status.get()
30
+ for entry in status_resp:
31
+ if entry['id'] == "cluster":
32
+ cluster_name = entry['name']
33
+ break
34
+
35
+ if cluster_name is None:
36
+ raise Exception("Could not get cluster name")
37
+
38
+ if cluster_name in dynamic_inventory[args.pve_cloud_domain] and not args.force:
39
+ print(f"cluster {cluster_name} already in dynamic inventory")
40
+ return
41
+
42
+ # overwrite on force / create fresh
43
+ dynamic_inventory[args.pve_cloud_domain][cluster_name] = {}
44
+
45
+ # not present => add and safe the dynamic inventory
46
+ cluster_hosts = proxmox.nodes.get()
47
+
48
+ for node in cluster_hosts:
49
+ node_name = node["node"]
50
+
51
+ if node["status"] == "offline":
52
+ print(f"skipping offline node {node_name}")
53
+ continue
54
+
55
+ # get the main ip
56
+ ifaces = proxmox.nodes(node_name).network.get()
57
+ node_ip_address = None
58
+ for iface in ifaces:
59
+ if 'gateway' in iface:
60
+ if node_ip_address is not None:
61
+ raise Exception(f"found multiple ifaces with gateways for node {node_name}")
62
+ node_ip_address = iface.get("address")
63
+
64
+ if node_ip_address is None:
65
+ raise Exception(f"Could not find ip for node {node_name}")
66
+
67
+ dynamic_inventory[args.pve_cloud_domain][cluster_name][node_name] = {
68
+ "ansible_user": "root",
69
+ "ansible_host": node_ip_address
70
+ }
71
+
72
+ with open(inv_path, "w") as file:
73
+ yaml.dump(dynamic_inventory, file)
74
+
75
+
76
+
77
+ def main():
78
+ parser = argparse.ArgumentParser(description="PVE general purpose cli for setting up.")
79
+
80
+ base_parser = argparse.ArgumentParser(add_help=False)
81
+
82
+ subparsers = parser.add_subparsers(dest="command", required=True)
83
+
84
+ connect_cluster_parser = subparsers.add_parser("connect-cluster", help="Add an entire pve cluster to this machine for use.", parents=[base_parser])
85
+ connect_cluster_parser.add_argument("--pve-host", type=str, help="PVE Host to connect to and add the entire cluster for the local machine.", required=True)
86
+ # todo: try and get the pve cloud domain from the cluster in case it is already initialized.
87
+ connect_cluster_parser.add_argument("--pve-cloud-domain", type=str, help="PVE Cloud domain the hosts are part of / should be initialized under.", required=True)
88
+ connect_cluster_parser.add_argument("--force", action="store_true", help="Will readd the cluster if set.")
89
+ connect_cluster_parser.set_defaults(func=connect_cluster)
90
+
91
+
92
+ args = parser.parse_args()
93
+ args.func(args)
94
+
95
+
96
+ if __name__ == "__main__":
97
+ main()
pve_cloud/cli/pvclu.py CHANGED
@@ -5,12 +5,12 @@ import socket
5
5
 
6
6
 
7
7
  def get_cloud_domain(target_pve):
8
- with open(os.path.expanduser("~/.pve-inventory.yaml"), "r") as f:
8
+ with open(os.path.expanduser("~/.pve-cloud-dyn-inv.yaml"), "r") as f:
9
9
  pve_inventory = yaml.safe_load(f)
10
10
 
11
11
  for pve_cloud in pve_inventory:
12
12
  for pve_cluster in pve_inventory[pve_cloud]:
13
- if pve_cluster == target_pve:
13
+ if pve_cluster + "." + pve_cloud == target_pve:
14
14
  return pve_cloud
15
15
 
16
16
  raise Exception(f"Could not identify cloud domain for {target_pve}")
@@ -21,12 +21,12 @@ def get_cld_domain_prsr(args):
21
21
 
22
22
 
23
23
  def get_online_pve_host(target_pve):
24
- with open(os.path.expanduser("~/.pve-inventory.yaml"), "r") as f:
24
+ with open(os.path.expanduser("~/.pve-cloud-dyn-inv.yaml"), "r") as f:
25
25
  pve_inventory = yaml.safe_load(f)
26
26
 
27
27
  for pve_cloud in pve_inventory:
28
28
  for pve_cluster in pve_inventory[pve_cloud]:
29
- if pve_cluster == target_pve:
29
+ if pve_cluster + "." + pve_cloud == target_pve:
30
30
  for pve_host in pve_inventory[pve_cloud][pve_cluster]:
31
31
  # check if host is available
32
32
  pve_host_ip = pve_inventory[pve_cloud][pve_cluster][pve_host]["ansible_host"]
@@ -0,0 +1,3 @@
1
+
2
+
3
+ def get_pve_cloud_inventory()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: py-pve-cloud
3
- Version: 0.0.2
3
+ Version: 0.0.4
4
4
  Author-email: Tobias Huebner <tobias.huebner@vmzberlin.com>
5
5
  License-Expression: GPL-3.0-or-later
6
6
  License-File: LICENSE
@@ -8,4 +8,5 @@ Requires-Dist: PyYAML==6.0.2
8
8
  Requires-Dist: psycopg2-binary==2.9.10
9
9
  Requires-Dist: SQLAlchemy==2.0.43
10
10
  Requires-Dist: alembic==1.16.5
11
+ Requires-Dist: proxmoxer==2.2.0
11
12
  Dynamic: license-file
@@ -1,4 +1,6 @@
1
- pve_cloud/cli/pvclu.py,sha256=xv833SHRvcUycwIsZ6gDKQkvvz-5igzwwdqGaN2NpF8,2454
1
+ pve_cloud/cli/pvcli.py,sha256=inR4KMI63nWufPYoM9udxgh3CN10xyQlJw_kGzVw7DQ,3166
2
+ pve_cloud/cli/pvclu.py,sha256=D5R5Gzo_iSImPTtEHVJWZoFr66uijeFbb-k6ODz_71o,2498
3
+ pve_cloud/lib/inventory.py,sha256=0W31j34jtxUa-3Cxe0HmHJqc_8CpvvxyDqd0sAZ5oCI,31
2
4
  pve_cloud/orm/alchemy.py,sha256=1PABOo2d-ceIwlSZPYx19aXZFszDXMh8YIXgkLT-554,5000
3
5
  pve_cloud/orm/alembic.ini,sha256=7140n-YUj06aAIHOHACm8U0xhUFUoBZ4Jw23KlYB9EA,4865
4
6
  pve_cloud/orm/migrations/env.py,sha256=xtOgjF1KLmRUkG1-yb4eV4F2JzarDKFU1tdWJovNHDc,2200
@@ -9,9 +11,9 @@ pve_cloud/orm/migrations/versions/7868bcd05006_migrate_old.py,sha256=rU8Bw2tYDyn
9
11
  pve_cloud/orm/migrations/versions/7dea8c4ee39f_init.py,sha256=iMDyHhtyvpSywMnLhiSEL3W12YSm6sPa18XRgzQcwDg,954
10
12
  pve_cloud/orm/migrations/versions/944a8fd5d5bc_ext_ctrl_plns.py,sha256=LnVAShLaU1asz1L7TYs7oI9SnLxPp2IOA6K83kHNkN0,1674
11
13
  pve_cloud/orm/migrations/versions/d9b711555be8_ext_control_plane.py,sha256=uBqv1r5pLX-RjqciKYx0zvWyygJMa5u58DTnVfIEAF0,1073
12
- py_pve_cloud-0.0.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
13
- py_pve_cloud-0.0.2.dist-info/METADATA,sha256=BiWtfqaXFEJLAbYO8j_F-7oZRc2CkKs8u84dBXB5yx4,330
14
- py_pve_cloud-0.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
- py_pve_cloud-0.0.2.dist-info/entry_points.txt,sha256=xkrTpjvvswH0Vo_AQ8_BNkTbaUbrCBWYaavWQjjnykU,51
16
- py_pve_cloud-0.0.2.dist-info/top_level.txt,sha256=mpT7ttGRyZJVt_obhPLBHyIBcjKhUdJ-qVsMEVX5WJg,10
17
- py_pve_cloud-0.0.2.dist-info/RECORD,,
14
+ py_pve_cloud-0.0.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
15
+ py_pve_cloud-0.0.4.dist-info/METADATA,sha256=EENqU0S2uq7SBI05ChHVDybFOBFEhcA55zEb4RWPJFo,362
16
+ py_pve_cloud-0.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
+ py_pve_cloud-0.0.4.dist-info/entry_points.txt,sha256=VvncsKmTJ46irz-9wQZ4Zo1FgNBjRltGDBKR9ht18mE,84
18
+ py_pve_cloud-0.0.4.dist-info/top_level.txt,sha256=mpT7ttGRyZJVt_obhPLBHyIBcjKhUdJ-qVsMEVX5WJg,10
19
+ py_pve_cloud-0.0.4.dist-info/RECORD,,
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ pvcli = pve_cloud.cli.pvcli:main
2
3
  pvclu = pve_cloud.cli.pvclu:main