From 0a372b2e00a6cfcce4716178e2ebffbacf196638 Mon Sep 17 00:00:00 2001 From: Mathieu Broillet Date: Sun, 11 Jun 2023 19:15:07 +0200 Subject: [PATCH] ssh/local for commands and lxc creation --- resources/config.json | 8 ++++ resources/lxc/0000/config.json | 14 +++---- src/main.py | 6 +-- src/utils/lxc_utils.py | 71 ++++++++++++++++++++++++++++++---- src/utils/proxmox_utils.py | 29 ++++++++++++-- 5 files changed, 106 insertions(+), 22 deletions(-) create mode 100644 resources/config.json diff --git a/resources/config.json b/resources/config.json new file mode 100644 index 0000000..036a127 --- /dev/null +++ b/resources/config.json @@ -0,0 +1,8 @@ +{ + "pve":{ + "host": "192.168.10.99", + "user": "root", + "port": 22, + "local": false + } +} \ No newline at end of file diff --git a/resources/lxc/0000/config.json b/resources/lxc/0000/config.json index d739000..826e1bc 100644 --- a/resources/lxc/0000/config.json +++ b/resources/lxc/0000/config.json @@ -1,5 +1,4 @@ { - "lxc_id": "0000", "lxc_hostname": "test", "os": { "name": "alpine", @@ -8,15 +7,17 @@ "resources": { "cpu": "1", "memory": "512", + "swap": "512", "disk": "10", - "storage": "local-lvm" + "storage": "local-zfs" }, "network": { "bridge": "vmbr0", "ipv4": "dhcp", - "ipv6": "", + "ipv6": "auto", "mac": "00:00:00:00:00:00", - "gateway": "", + "gateway4": "", + "gateway6": "", "vlan": "" }, "options": { @@ -25,9 +26,6 @@ "password": "qwertz1234", "ssh": false }, - "creation": { - "type": "tteck", - "script": "https://git.broillet.ch/Mathieu/ProxmoxHelperScripts/src/branch/main/install/alpine-vaultwarden-install.sh" - }, + "creation": {}, "deploy": [] } \ No newline at end of file diff --git a/src/main.py b/src/main.py index f9125d1..69a5da6 100644 --- a/src/main.py +++ b/src/main.py @@ -19,14 +19,14 @@ def run(): lxc_folders = os.listdir(project_path / "resources" / "lxc") for lxc_folder in lxc_folders: lxc_file = os.path.join(project_path / "resources" / "lxc", lxc_folder, "config.json") - logging.info(f"Reading LXC ID {lxc_file}") + logging.info(f"Reading LXC ID {lxc_folder}") # Open the file with open(lxc_file, "r") as file: # Load the LXC - load_lxc(file.read()) + load_lxc(file.read(), lxc_id=lxc_folder) print(get_all_lxcs()) # print(get_all_lxcs()[0].get_tteck_env_variables()) - # get_all_lxcs()[0].create() \ No newline at end of file + print(get_all_lxcs()[0].get_pct_command()) \ No newline at end of file diff --git a/src/utils/lxc_utils.py b/src/utils/lxc_utils.py index b0bf1d1..c63cf03 100644 --- a/src/utils/lxc_utils.py +++ b/src/utils/lxc_utils.py @@ -27,18 +27,19 @@ def get_lxc(lxc_id): return None -def load_lxc(file): +def load_lxc(file, lxc_id): """ Load LXC from JSON file :param file: json config file + :param lxc_id: id of the lxc :return: """ # Load JSON data data = json.loads(file) # Extract values from JSON - lxc_id = data["lxc_id"] + lxc_id = lxc_id lxc_hostname = data["lxc_hostname"] os = data["os"] resources = data["resources"] @@ -68,6 +69,7 @@ class LXC: self.resources = resources self.cpu = resources["cpu"] self.memory = resources["memory"] + self.swap = resources["swap"] self.disk = resources["disk"] self.storage = resources["storage"] @@ -76,7 +78,8 @@ class LXC: self.ipv4 = network["ipv4"] self.ipv6 = network["ipv6"] self.mac = network["mac"] - self.gateway = network["gateway"] + self.gateway4 = network["gateway4"] + self.gateway6 = network["gateway6"] self.vlan = network["vlan"] self.options = options @@ -135,6 +138,22 @@ class LXC: """ return self.os_release + def get_os_template(self): + """ + Get OS template + :return: os template + """ + + wanted_template = proxmox_utils.run_command_on_pve( + f"pveam available --section system | grep {self.os_name}-{self.os_release} | awk '{{print \\$2}}'") + + if wanted_template == "": + logging.warning(f"Template {self.os_name}-{self.os_release} not found, downloading it...") + proxmox_utils.run_command_on_pve(f"pveam download local {wanted_template}") + return None + + return f"local:vztmpl/{wanted_template}" + def get_resources(self): """ Get resources @@ -156,6 +175,13 @@ class LXC: """ return self.memory + def get_swap(self): + """ + Get swap + :return: swap + """ + return self.swap + def get_disk(self): """ Get disk @@ -205,12 +231,19 @@ class LXC: """ return self.mac - def get_gateway(self): + def get_gateway4(self): """ - Get gateway + Get gateway IPV4 :return: gateway """ - return self.gateway + return self.gateway4 + + def get_gateway6(self): + """ + Get gateway IPV6 + :return: gateway + """ + return self.gateway6 def get_vlan(self): """ @@ -278,6 +311,30 @@ class LXC: def deploy(self): pass + def get_pct_command(self): + """ + Get pct command to create LXC + :return: pct command + """ + + pct_command = f"pct create {self.lxc_id} {self.get_os_template()} " \ + f"--hostname {self.lxc_hostname} " \ + f"--cores {self.cpu} " \ + f"--memory {self.memory} " \ + f"--swap {self.memory} " \ + f"--net0 name=eth0,bridge={self.bridge},ip={self.ipv4},hwaddr={self.mac} " \ + f"--onboot {int(self.start_on_boot == 0)} " \ + f"--ostype {self.os_name} " \ + f"--password {self.password} " \ + f"--storage {self.storage} " \ + f"--rootfs volume={self.storage}:{self.disk},size={self.disk} " \ + f"--unprivileged {not self.privileged} " + + # TODO: add gateway4 + # f"ip6={self.ipv6},gw6={self.gateway6},trunks={self.vlan} " \ # TODO + # f"-ssh-public-keys {self.ssh}" # TODO + return pct_command + def get_tteck_env_variables(self): """ Get TTECK environment variables to run scripts silently @@ -294,7 +351,7 @@ class LXC: "RAM_SIZE": self.memory, "BRG": self.bridge, "NET": self.ipv4, - "GATE": self.gateway, + "GATE": self.gateway4, "DISABLEIP6": "no", "MTU": "", "SD": "", diff --git a/src/utils/proxmox_utils.py b/src/utils/proxmox_utils.py index f5d91cc..a5e57d4 100644 --- a/src/utils/proxmox_utils.py +++ b/src/utils/proxmox_utils.py @@ -1,6 +1,10 @@ +import json import logging +import os import subprocess +from src.get_path_file import project_path + def get_pve_version(): """ @@ -62,7 +66,24 @@ def run_command_on_pve(command): :return: command """ - # Run command and return output (not as bytes) - logging.debug(f"Running command on PVE: \n{command}") - return subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - encoding="utf-8").stdout.decode() + config_file = os.path.join(project_path / "resources" / "config.json") + with open(config_file, "r") as file: + + data = json.loads(file.read()) + + # Check if PVE is local or remote + if data['pve']['local']: + # Run command and return output (not as bytes) + logging.debug(f"Running command on PVE (ssh): \n{command}") + return subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + encoding="utf-8").stdout.decode().rstrip() + + else: + host = data['pve']['host'] + username = data['pve']['user'] + port = data['pve']['port'] + + # Run command on PVE via SSH and return output + logging.debug(f"Running command on PVE (locally): \n{command}") + return subprocess.run(f"ssh {username}@{host} -p {port} \"{command}\"", shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, encoding="utf-8").stdout.rstrip()