py-pve-cloud 0.0.2__tar.gz → 0.0.4__tar.gz

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.

Files changed (25) hide show
  1. {py_pve_cloud-0.0.2/src/py_pve_cloud.egg-info → py_pve_cloud-0.0.4}/PKG-INFO +2 -1
  2. py_pve_cloud-0.0.4/README.md +21 -0
  3. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/pyproject.toml +4 -2
  4. py_pve_cloud-0.0.4/src/pve_cloud/cli/pvcli.py +97 -0
  5. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/cli/pvclu.py +4 -4
  6. py_pve_cloud-0.0.4/src/pve_cloud/lib/inventory.py +3 -0
  7. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4/src/py_pve_cloud.egg-info}/PKG-INFO +2 -1
  8. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/py_pve_cloud.egg-info/SOURCES.txt +2 -0
  9. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/py_pve_cloud.egg-info/entry_points.txt +1 -0
  10. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/py_pve_cloud.egg-info/requires.txt +1 -0
  11. py_pve_cloud-0.0.2/README.md +0 -4
  12. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/LICENSE +0 -0
  13. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/setup.cfg +0 -0
  14. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/orm/alchemy.py +0 -0
  15. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/orm/alembic.ini +0 -0
  16. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/orm/migrations/env.py +0 -0
  17. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/orm/migrations/versions/24a548bfce3e_len_rules_enforcements.py +0 -0
  18. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/orm/migrations/versions/27724e407e2b_proxy_fqdn.py +0 -0
  19. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/orm/migrations/versions/3c95509a5de9_fix.py +0 -0
  20. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/orm/migrations/versions/7868bcd05006_migrate_old.py +0 -0
  21. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/orm/migrations/versions/7dea8c4ee39f_init.py +0 -0
  22. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/orm/migrations/versions/944a8fd5d5bc_ext_ctrl_plns.py +0 -0
  23. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/pve_cloud/orm/migrations/versions/d9b711555be8_ext_control_plane.py +0 -0
  24. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/py_pve_cloud.egg-info/dependency_links.txt +0 -0
  25. {py_pve_cloud-0.0.2 → py_pve_cloud-0.0.4}/src/py_pve_cloud.egg-info/top_level.txt +0 -0
@@ -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
@@ -0,0 +1,21 @@
1
+ # py-pve-cloud
2
+
3
+ this is the core python library package that serves as a foundation for pve cloud.
4
+
5
+ ## alembic orm
6
+
7
+ this project uses sqlalchemy + alembic integrated into the collection for management of the patroni database schema.
8
+
9
+ edit `src/orm/alchemy.py` database classes and run `alembic revision --auto-enerate -m "revision description"` from the orm folder, to commit your changes into the general migrations. before you need to do a `pip install .` to get the needed orm pypi packages.
10
+
11
+ you also need to `export PG_CONN_STR=postgresql+psycopg2://postgres:{{ patroni_postgres_pw }}@{{ proxy or master ip }}:{{ 5000 / 5432 }}/pve_cloud?sslmode=disable` env variable first with a testing database for alembic to work against. to create a new migration the database needs to be on the latest version, run `alembic upgrade head` to upgrade it.
12
+
13
+
14
+ ## Releasing to pypi
15
+
16
+ ```bash
17
+ pip install build twine
18
+ rm -rf dist
19
+ python3 -m build
20
+ python3 -m twine upload dist/*
21
+ ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "py-pve-cloud"
7
- version = "0.0.2"
7
+ version = "0.0.4"
8
8
  authors = [{ name = "Tobias Huebner", email = "tobias.huebner@vmzberlin.com" }]
9
9
  license = "GPL-3.0-or-later"
10
10
  license-files = ["LICENSE"]
@@ -12,7 +12,8 @@ dependencies = [
12
12
  "PyYAML==6.0.2",
13
13
  "psycopg2-binary==2.9.10",
14
14
  "SQLAlchemy==2.0.43",
15
- "alembic==1.16.5"
15
+ "alembic==1.16.5",
16
+ "proxmoxer==2.2.0"
16
17
  ]
17
18
 
18
19
  [tool.setuptools.package-data]
@@ -20,4 +21,5 @@ dependencies = [
20
21
 
21
22
  [project.scripts]
22
23
  pvclu = "pve_cloud.cli.pvclu:main"
24
+ pvcli = "pve_cloud.cli.pvcli:main"
23
25
 
@@ -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()
@@ -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,7 +1,9 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
+ src/pve_cloud/cli/pvcli.py
4
5
  src/pve_cloud/cli/pvclu.py
6
+ src/pve_cloud/lib/inventory.py
5
7
  src/pve_cloud/orm/alchemy.py
6
8
  src/pve_cloud/orm/alembic.ini
7
9
  src/pve_cloud/orm/migrations/env.py
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ pvcli = pve_cloud.cli.pvcli:main
2
3
  pvclu = pve_cloud.cli.pvclu:main
@@ -2,3 +2,4 @@ PyYAML==6.0.2
2
2
  psycopg2-binary==2.9.10
3
3
  SQLAlchemy==2.0.43
4
4
  alembic==1.16.5
5
+ proxmoxer==2.2.0
@@ -1,4 +0,0 @@
1
- ## Releasing to pypi
2
-
3
-
4
- `python3 -m build && python3 -m twine upload dist/*`
File without changes
File without changes