WIP
This commit is contained in:
parent
c3e9f66df1
commit
5c75771355
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
.env/**
|
.env/**
|
||||||
|
.env
|
||||||
|
__pycache__
|
||||||
__pycache__/**
|
__pycache__/**
|
5
config.yml
Normal file
5
config.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
server_port: 5000
|
||||||
|
server_url: "http://localhost"
|
||||||
|
server_password: "sekret_password"
|
||||||
|
server_access_username: "user"
|
||||||
|
client_loglevel: "DEBUG"
|
4
images/valhalla/cool-image-name/v0.0.2alpha/image.qcow2
Normal file
4
images/valhalla/cool-image-name/v0.0.2alpha/image.qcow2
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
duiuwqhdiuhwqiudhewiufhwieuhiuwhfiuiueyr837r87438r3iuh87duihew8732roh87yro3r
|
||||||
|
ry398yr983yr937yr743tfhuieh9843ty347nv743nyv34[9yt34
|
||||||
|
4yv9[843qyt9843yt98439843ry3948feiuh9843fy934t
|
||||||
|
ru09438ur9843ur9843ut9834tup43349]]
|
@ -1,37 +1,201 @@
|
|||||||
import requests as req
|
import requests as req
|
||||||
import logging
|
import logging
|
||||||
import json
|
import os
|
||||||
|
import time
|
||||||
|
import urllib3
|
||||||
|
import shutil
|
||||||
|
|
||||||
class ValhallaServer():
|
from utils.MachineData import MachineData
|
||||||
|
|
||||||
def __init__(self, server_address: str, server_port: str, server_user: str, server_access_password: str, logging_level: str):
|
|
||||||
|
class ValhallaServer:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
server_address: str,
|
||||||
|
server_port: str,
|
||||||
|
server_user: str,
|
||||||
|
server_access_password: str,
|
||||||
|
logging_level: str,
|
||||||
|
):
|
||||||
self.server_address = server_address
|
self.server_address = server_address
|
||||||
self.server_port = server_port
|
self.server_port = server_port
|
||||||
self.server_user = server_user
|
self.server_user = server_user
|
||||||
|
self.server_name = "not connected"
|
||||||
|
self.server_version = "not_connected"
|
||||||
self.server_access_password = server_access_password
|
self.server_access_password = server_access_password
|
||||||
self.logging_level = logging_level
|
self.logging_level = logging_level
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
self.bearer_token = ""
|
self.bearer_token = ""
|
||||||
|
self.auth_headers = {}
|
||||||
|
self.user_id = 0
|
||||||
|
self.vm_ids_list_from_server = []
|
||||||
|
self.vms_metadata = {}
|
||||||
log_level_mapping_dict = {
|
log_level_mapping_dict = {
|
||||||
"NOTSET": 0,
|
"NOTSET": 0,
|
||||||
"DEBUG": 10,
|
"DEBUG": 10,
|
||||||
"INFO": 20,
|
"INFO": 20,
|
||||||
"WARNING": 30,
|
"WARNING": 30,
|
||||||
"ERROR": 40,
|
"ERROR": 40,
|
||||||
"CRITICAL": 50,
|
"CRITICAL": 50,
|
||||||
}
|
}
|
||||||
self.logger.setLevel(log_level_mapping_dict[logging_level])
|
self.logger.setLevel(log_level_mapping_dict[logging_level])
|
||||||
|
|
||||||
def authenticate(self):
|
def authenticate(self):
|
||||||
try:
|
try:
|
||||||
login_data = {
|
login_data = {
|
||||||
"username": self.server_user,
|
"username": self.server_user,
|
||||||
"password": self.server_access_password
|
"password": self.server_access_password,
|
||||||
}
|
}
|
||||||
headers = {"Content-Type": "application/json"}
|
headers = {"Content-Type": "application/json"}
|
||||||
print(json.dumps(login_data))
|
response = req.post(
|
||||||
response = req.post(url=f"{self.server_address}:{self.server_port}/login", json=login_data, headers=headers)
|
url=f"{self.server_address}:{self.server_port}/login",
|
||||||
self.logger.info(str(response.json()))
|
json=login_data,
|
||||||
print(str(response.json()))
|
headers=headers,
|
||||||
|
)
|
||||||
|
# self.logger.info(str(response.json()))
|
||||||
|
if response.status_code == 202:
|
||||||
|
user_data = response.json()
|
||||||
|
self.bearer_token = user_data["token"]
|
||||||
|
self.user_id = user_data["user_id"]
|
||||||
|
self.auth_headers = {"Authorization": f"Bearer {self.bearer_token}"}
|
||||||
|
else:
|
||||||
|
raise Exception("Bad input or server not responding")
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.logger.error(f"{str(ex)}")
|
self.logger.error(f"{str(ex)}")
|
||||||
|
|
||||||
|
def get_server_data(self):
|
||||||
|
try:
|
||||||
|
response = req.get(
|
||||||
|
url=f"{self.server_address}:{self.server_port}/",
|
||||||
|
headers=self.auth_headers,
|
||||||
|
)
|
||||||
|
print(str(response.json()))
|
||||||
|
if response.status_code == 200:
|
||||||
|
server_data = response.json()
|
||||||
|
self.server_version = server_data["server_version"]
|
||||||
|
self.server_name = server_data["server_name"]
|
||||||
|
except Exception as ex:
|
||||||
|
self.logger.error(f"{str(ex)}")
|
||||||
|
|
||||||
|
def update_machine_data_on_server(self, machine_data: MachineData):
|
||||||
|
try:
|
||||||
|
response = req.get(
|
||||||
|
url=f"{self.server_address}:{self.server_port}/clients/{machine_data.mac_address}",
|
||||||
|
headers=self.auth_headers,
|
||||||
|
)
|
||||||
|
if response.status_code == 401:
|
||||||
|
self.authenticate()
|
||||||
|
print(self.bearer_token)
|
||||||
|
response = req.get(
|
||||||
|
url=f"{self.server_address}:{self.server_port}/clients/{machine_data.mac_address}",
|
||||||
|
headers=self.auth_headers,
|
||||||
|
)
|
||||||
|
print(f"{str(response.json())}")
|
||||||
|
client_data = {
|
||||||
|
"mac_address": machine_data.mac_address,
|
||||||
|
"ip_address": machine_data.ip_address,
|
||||||
|
"hostname": machine_data.hostname,
|
||||||
|
"client_version": machine_data.client_version,
|
||||||
|
"vm_list_on_machine": [],
|
||||||
|
}
|
||||||
|
if response.status_code == 404:
|
||||||
|
print("Client not registered, registering now...")
|
||||||
|
for i in range(1, 5):
|
||||||
|
register_response = req.post(
|
||||||
|
url=f"{self.server_address}:{self.server_port}/clients",
|
||||||
|
headers=self.auth_headers,
|
||||||
|
json=client_data,
|
||||||
|
)
|
||||||
|
if register_response == 201:
|
||||||
|
print("Registered successfully")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("Failed to register, waiting 5s before trying again...")
|
||||||
|
time.sleep(5)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
client_data_from_server = response.json()
|
||||||
|
try:
|
||||||
|
client_data.pop("vm_list_on_machine")
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
if client_data_from_server != client_data:
|
||||||
|
print("Client data needs updating, updating now...")
|
||||||
|
for i in range(1, 5):
|
||||||
|
register_response = req.put(
|
||||||
|
url=f"{self.server_address}:{self.server_port}/clients",
|
||||||
|
headers=self.auth_headers,
|
||||||
|
json=client_data,
|
||||||
|
)
|
||||||
|
if register_response.status_code == 202:
|
||||||
|
print("Updated successfully")
|
||||||
|
break
|
||||||
|
elif response.status_code == 401:
|
||||||
|
print("Reauthentication needed...")
|
||||||
|
self.authenticate()
|
||||||
|
else:
|
||||||
|
print("Failed to update, waiting 5s before trying again...")
|
||||||
|
time.sleep(5)
|
||||||
|
continue
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
self.logger.error(f"{str(ex)}")
|
||||||
|
|
||||||
|
def get_vm_list_from_server(self, machine_data: MachineData):
|
||||||
|
try:
|
||||||
|
response = req.get(
|
||||||
|
url=f"{self.server_address}:{self.server_port}/clients/{machine_data.mac_address}/vms",
|
||||||
|
headers=self.auth_headers,
|
||||||
|
)
|
||||||
|
if response.status_code == 401:
|
||||||
|
self.authenticate()
|
||||||
|
response = req.get(
|
||||||
|
url=f"{self.server_address}:{self.server_port}/clients/{machine_data.mac_address}/vms",
|
||||||
|
headers=self.auth_headers,
|
||||||
|
)
|
||||||
|
if response.status_code == 200:
|
||||||
|
vm_list = response.json()
|
||||||
|
self.vm_ids_list_from_server = vm_list
|
||||||
|
return vm_list
|
||||||
|
else:
|
||||||
|
print(f"Error getting data from remote server: {response.json()}")
|
||||||
|
except Exception as ex:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_vms_data_from_server(self):
|
||||||
|
try:
|
||||||
|
vms_data = {}
|
||||||
|
for image_id in self.vm_ids_list_from_server:
|
||||||
|
response = req.get(
|
||||||
|
url=f"{self.server_address}:{self.server_port}/images/{image_id}",
|
||||||
|
headers=self.auth_headers,
|
||||||
|
)
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
vms_data[f"{image_id}"] = data
|
||||||
|
self.vms_metadata = vms_data
|
||||||
|
except Exception as ex:
|
||||||
|
print(str(ex))
|
||||||
|
|
||||||
|
def update_vms_images_from_server(self):
|
||||||
|
try:
|
||||||
|
for image_id in self.vm_ids_list_from_server:
|
||||||
|
image_data = self.vms_metadata[f"{image_id}"]
|
||||||
|
print(f"{image_data['image_name']} download")
|
||||||
|
http = urllib3.PoolManager()
|
||||||
|
self.authenticate()
|
||||||
|
filename = f"images/{self.server_name}/{image_data['image_name']}/{image_data['image_version']}/image.qcow2"
|
||||||
|
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
||||||
|
with http.request(
|
||||||
|
method="GET",
|
||||||
|
url=f"{self.server_address}:{self.server_port}/images/{image_id}/download",
|
||||||
|
preload_content=False,
|
||||||
|
headers=self.auth_headers,
|
||||||
|
) as r, open(
|
||||||
|
filename,
|
||||||
|
"wb",
|
||||||
|
) as out_file:
|
||||||
|
shutil.copyfileobj(r, out_file)
|
||||||
|
except Exception as ex:
|
||||||
|
print(str(ex))
|
||||||
|
Binary file not shown.
72
utils/MachineData.py
Normal file
72
utils/MachineData.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
from getmac import get_mac_address as gma
|
||||||
|
import socket
|
||||||
|
import yaml
|
||||||
|
import os
|
||||||
|
import psutil
|
||||||
|
|
||||||
|
class MachineData():
|
||||||
|
|
||||||
|
def get_ip_address(self):
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
s.connect(("8.8.8.8", 80))
|
||||||
|
return s.getsockname()[0]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.mac_address = gma()
|
||||||
|
self.ip_address = str(self.get_ip_address())
|
||||||
|
self.hostname = socket.gethostname()
|
||||||
|
self.client_version = "v0.0.1alpha"
|
||||||
|
self.cpu_count = os.cpu_count()
|
||||||
|
self.ram_size = (psutil.virtual_memory().total / 1024) / 1024
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open("config.yml", "r") as stream:
|
||||||
|
try:
|
||||||
|
config_file = yaml.safe_load(stream)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
print(str(e))
|
||||||
|
exit(-1)
|
||||||
|
config = config_file
|
||||||
|
|
||||||
|
try:
|
||||||
|
server_url_override = os.environ.get("VALHALLA_SERVER_URL")
|
||||||
|
server_port_override = os.environ.get("VALHALLA_SERVER_PORT")
|
||||||
|
server_password_override = os.environ.get("VALHALLA_SERVER_PASSWORD")
|
||||||
|
server_access_username_override = os.environ.get(
|
||||||
|
"VALHALLA_SERVER_ACCESS_USERNAME")
|
||||||
|
client_logging_override = os.environ.get("VALHALLA_CLIENT_LOGLEVEL")
|
||||||
|
|
||||||
|
if server_port_override:
|
||||||
|
config["server_port"] = server_port_override
|
||||||
|
|
||||||
|
if server_url_override:
|
||||||
|
config["server_url"] = server_url_override
|
||||||
|
|
||||||
|
if server_password_override:
|
||||||
|
config["server_password"] = server_password_override
|
||||||
|
|
||||||
|
if server_access_username_override:
|
||||||
|
config["server_access_username"] = server_access_username_override
|
||||||
|
|
||||||
|
if client_logging_override:
|
||||||
|
config["client_loglevel"] = client_logging_override
|
||||||
|
|
||||||
|
self.server_url = config["server_url"]
|
||||||
|
self.server_port = config["server_port"]
|
||||||
|
self.server_password = config["server_password"]
|
||||||
|
self.server_access_username = config["server_access_username"]
|
||||||
|
self.client_loglevel = config["client_loglevel"]
|
||||||
|
except KeyError as ke:
|
||||||
|
print(str(ke))
|
||||||
|
pass
|
||||||
|
except TypeError as te:
|
||||||
|
print(str(te))
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
print(str(e))
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
class VirtualmachineConfig():
|
||||||
|
def __init__(cpu_count: int, memory_size: int, ):
|
1
utils/__init__.py
Normal file
1
utils/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from . import MachineData
|
@ -1,7 +1,28 @@
|
|||||||
from network.ValhallaServer import ValhallaServer
|
from network.ValhallaServer import ValhallaServer
|
||||||
|
from utils.MachineData import MachineData
|
||||||
|
|
||||||
server = ValhallaServer(server_address="http://localhost", server_port=str(5000), server_user="user", server_access_password="sekret_password", logging_level="DEBUG")
|
machine_data = MachineData()
|
||||||
|
|
||||||
|
server = ValhallaServer(
|
||||||
|
server_address=machine_data.server_url,
|
||||||
|
server_port=machine_data.server_port,
|
||||||
|
server_user=machine_data.server_access_username,
|
||||||
|
server_access_password=machine_data.server_password,
|
||||||
|
logging_level=machine_data.client_loglevel,
|
||||||
|
)
|
||||||
|
|
||||||
server.authenticate()
|
server.authenticate()
|
||||||
|
|
||||||
|
server.get_server_data()
|
||||||
|
|
||||||
|
server.update_machine_data_on_server(machine_data=machine_data)
|
||||||
|
|
||||||
|
vm_list = server.get_vm_list_from_server(machine_data=machine_data)
|
||||||
|
|
||||||
|
print(vm_list)
|
||||||
|
|
||||||
|
server.get_vms_data_from_server()
|
||||||
|
|
||||||
|
server.update_vms_images_from_server()
|
||||||
|
|
||||||
# vim:ft=py
|
# vim:ft=py
|
Loading…
Reference in New Issue
Block a user