Last active
April 7, 2025 19:42
-
-
Save gpetrousov/6fb2d5835e96c9133c0533190d780a79 to your computer and use it in GitHub Desktop.
experimetal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import json | |
# Disable SSL nags | |
requests.packages.urllib3.disable_warnings() | |
def get_proxmox_ticket(username, password, api_url): | |
"""Retrieves a Proxmox API ticket and cookie.""" | |
auth_data = { | |
'username': username, | |
'password': password | |
} | |
auth_response = requests.post(f'{api_url}/access/ticket', json=auth_data, verify=False) | |
auth_response.raise_for_status() | |
ticket = auth_response.json()['data']['ticket'] | |
csrf_token = auth_response.json()['data']['CSRFPreventionToken'] | |
# cookie = auth_response.cookies['PVEAuthCookie'] | |
return ticket, csrf_token | |
def create_proxmox_cluster(hostname, username, password, api_url): | |
"""Creates a Proxmox cluster.""" | |
ticket, csrf_token = get_proxmox_ticket(username, password, api_url) | |
headers = { | |
'CSRFPreventionToken': csrf_token, | |
'Content-Type': 'application/x-www-form-urlencoded', | |
} | |
cookies = {'PVEAuthCookie': ticket} | |
data = { | |
'clustername': "Experimental", | |
'link0': hostname, | |
} | |
create_response = requests.post(f'{api_url}/cluster/config/', headers=headers, cookies=cookies, data=data, verify=False) | |
# Check if cluster exists | |
if create_response.reason == "cluster config '/etc/pve/corosync.conf' already exists": | |
return "Cluster exists" | |
else: | |
return create_response.json() | |
node1_hostname = "<IP of node 1>" | |
node1_username = "root@pam" | |
node1_password = "<SSH password>" | |
node1_api_url = f"https://{node1_hostname}:8006/api2/json" | |
node2_hostname = "IP of node 2" | |
node2_username = "root@pam" | |
node2_password = "<SSH password>" | |
node2_api_url = f"https://{node2_hostname}:8006/api2/json" | |
# 1. Create the cluster on node1 | |
create_result = create_proxmox_cluster(node1_hostname, node1_username, node1_password, node1_api_url) | |
print(f"Cluster creation result: {json.dumps(create_result, indent=2)}") | |
# 2. Get join information from node1 | |
auth_data_node1 = { | |
"username": node1_username, | |
"password": node1_password | |
} | |
auth_response_node1 = requests.post(f"{node1_api_url}/access/ticket", json=auth_data_node1, verify=False) | |
auth_response_node1.raise_for_status() | |
ticket_node1 = auth_response_node1.json()["data"]["ticket"] | |
csrf_token_node1 = auth_response_node1.json()["data"]["CSRFPreventionToken"] | |
headers_node1 = { | |
'CSRFPreventionToken': csrf_token_node1, | |
'Content-Type': 'application/x-www-form-urlencoded', | |
} | |
cookies_nodes1 = {'PVEAuthCookie': ticket_node1} | |
print("Getting node1 cluster join info") | |
join_info_response = requests.get(f"{node1_api_url}/cluster/config/join", headers=headers_node1, cookies=cookies_nodes1, verify=False) | |
join_info_response.raise_for_status() | |
join_fingerprint = join_info_response.json()["data"]["nodelist"][0]["pve_fp"] | |
# 2.5 Craft request to join existing cluster | |
auth_data_node2 = { | |
"username": node2_username, | |
"password": node2_password | |
} | |
auth_response_node2 = requests.post(f"{node2_api_url}/access/ticket", json=auth_data_node2, verify=False) | |
auth_response_node2.raise_for_status() | |
ticket_node2 = auth_response_node2.json()["data"]["ticket"] | |
csrf_token_node2 = auth_response_node2.json()["data"]["CSRFPreventionToken"] | |
headers_node2 = { | |
'CSRFPreventionToken': csrf_token_node2, | |
'Content-Type': 'application/x-www-form-urlencoded', | |
} | |
data_node2 = { | |
"fingerprint": join_fingerprint, | |
"hostname": node1_hostname, | |
"password": node1_password, | |
"link0": node2_hostname | |
} | |
cookies_nodes2 = {'PVEAuthCookie': ticket_node2} | |
# 3. Add node2 to the cluster | |
print("Attempting to join") | |
join_response = requests.post(f"{node2_api_url}/cluster/config/join", headers=headers_node2, data=data_node2, cookies=cookies_nodes2, verify=False) | |
join_response.raise_for_status() | |
print(join_response.json()) | |
print("Join done!!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment