Compare commits

..

No commits in common. "main" and "test/pull-4" have entirely different histories.

2 changed files with 16 additions and 99 deletions

View File

@ -3,5 +3,5 @@
Agent for my-idlers Agent for my-idlers
``` ```
export AGENT_API=<API_KEY> HOST=https://idlers.test2.sysdeploy.org;python3 agent.py export API_KEY=<API_KEY> HOST=https://idlers.test2.sysdeploy.org/api/servers;python3 main.py
``` ```

111
agent.py
View File

@ -1,8 +1,8 @@
import os import os
import urllib.error
import urllib.request import urllib.request
import logging import logging
import json import json
import http.client
import subprocess import subprocess
import re import re
import shutil import shutil
@ -124,12 +124,7 @@ class ServerData:
# Parse the output # Parse the output
details = {} details = {}
model_number_match = re.search(r'Model Number:\s*(.*)', output) details['model_number'] = re.search(r'Model Number:\s*(.*)', output).group(1)
if model_number_match is None:
logging.warning("Skipping device {} as it does not have a model number".format(device))
continue
details['model_number'] = model_number_match.group(1)
details['serial_number'] = re.search(r'Serial Number:\s*(.*)', output).group(1) details['serial_number'] = re.search(r'Serial Number:\s*(.*)', output).group(1)
details['firmware_revision'] = re.search(r'Firmware Revision:\s*(.*)', output).group(1) details['firmware_revision'] = re.search(r'Firmware Revision:\s*(.*)', output).group(1)
details['transport'] = re.search(r'Transport:\s*(.*)', output).group(1) details['transport'] = re.search(r'Transport:\s*(.*)', output).group(1)
@ -171,7 +166,7 @@ class ServerData:
# Get the output of nvme id-ctrl command # Get the output of nvme id-ctrl command
output = subprocess.check_output(['nvme', 'id-ctrl', device_path], stderr=subprocess.STDOUT, universal_newlines=True) output = subprocess.check_output(['nvme', 'id-ctrl', device_path], stderr=subprocess.STDOUT, universal_newlines=True)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
print("Failed to get nvme id-ctrl output for {}: {}".format(device_path, e)) print(f"Failed to get nvme id-ctrl output for {device_path}: {e}")
continue continue
# Split the output into lines # Split the output into lines
@ -217,10 +212,7 @@ class ServerData:
if section['DMIType'] == 4: # 4 corresponds to processor if section['DMIType'] == 4: # 4 corresponds to processor
core_count = int(section.get('Core Count', '0')) core_count = int(section.get('Core Count', '0'))
thread_count = int(section.get('Thread Count', '0')) thread_count = int(section.get('Thread Count', '0'))
if thread_count: cpu_count = core_count * thread_count
cpu_count += thread_count
else:
cpu_count += core_count
if cpu_count == 0: if cpu_count == 0:
with open('/proc/cpuinfo', 'r') as f: with open('/proc/cpuinfo', 'r') as f:
cpuinfo = f.read() cpuinfo = f.read()
@ -241,77 +233,16 @@ class ServerData:
logging.error("Failed to get public IP: {}".format(e)) logging.error("Failed to get public IP: {}".format(e))
return '127.0.0.1' return '127.0.0.1'
def get_os_release_info(self): def get_os(self):
os_release_info = {} os_id = 27
logging.info("OS ID: {}".format(os_id))
# reading from /etc/os-release return os_id
try:
with open('/etc/os-release') as f:
lines = f.read().splitlines()
os_release_info = {line.split('=')[0]: line.split('=')[1].strip('"') for line in lines if '=' in line}
except FileNotFoundError:
logging.warning("/etc/os-release not found, trying /etc/VERSION")
except Exception as e:
logging.error("Failed to read /etc/os-release: {}".format(e))
return {}
# If /etc/os-release is not found or empty, fallback to /etc/VERSION def create_post_data(self):
if not os_release_info:
try:
with open('/etc/VERSION') as f:
lines = f.read().splitlines()
for line in lines:
if '=' in line:
key, value = line.split('=', 1)
os_release_info[key.strip()] = value.strip()
except Exception as e:
logging.error("Failed to read /etc/VERSION: {}".format(e))
return {}
return os_release_info
def get_os_id(self, os_list):
os_info = self.get_os_release_info()
if not os_info:
logging.error("No OS release info found.")
for os_entry in os_list:
if os_entry['name'].lower() in ["other", "custom"]:
return os_entry['id']
return 1
if 'ID' in os_info and 'VERSION_ID' in os_info:
current_os = (os_info.get('ID', 'Unknown') + " " + os_info.get('VERSION_ID', '').strip()).strip()
else:
current_os = (os_info.get('os_name', 'Unknown') +" "+ os_info.get('productversion', '').strip()).strip().lower()
for os_entry in os_list:
if current_os in os_entry['name'].lower():
return os_entry['id']
# Fallback checks for common OS names if full name doesn't match
for os_entry in os_list:
if 'ubuntu' in current_os and 'ubuntu' in os_entry['name'].lower():
return os_entry['id']
elif 'centos' in current_os and 'centos' in os_entry['name'].lower():
return os_entry['id']
elif 'fedora' in current_os and 'fedora' in os_entry['name'].lower():
return os_entry['id']
# Default to 'other' or 'custom' if no match found
for os_entry in os_list:
if os_entry['name'].lower() in ["other", "custom"]:
return os_entry['id']
return 1
def create_post_data(self, os_list):
ram, disk = self.get_ram_and_disk() ram, disk = self.get_ram_and_disk()
post_data = { post_data = {
"server_type": 1, "server_type": 1,
"os_id": self.get_os_id(os_list), "os_id": self.get_os(),
"provider_id": 10, "provider_id": 10,
"location_id": 15, "location_id": 15,
"ssh_port": 22, "ssh_port": 22,
@ -359,14 +290,8 @@ class ServerData:
size = ram.get('Size', 'Unknown') size = ram.get('Size', 'Unknown')
speed = ram.get('Speed', 'Unknown') speed = ram.get('Speed', 'Unknown')
configured_speed = ram.get('Configured Memory Speed', 'Unknown') configured_speed = ram.get('Configured Memory Speed', 'Unknown')
try: total_width = int(ram.get('Total Width', "0").split()[0])
total_width = int(ram.get('Total Width', "0").split()[0]) data_width = int(ram.get('Data Width', "0").split()[0])
except ValueError:
total_width = 0
try:
data_width = int(ram.get('Data Width', "0").split()[0])
except ValueError:
data_width = 0
ecc = 'Yes' if total_width > data_width else 'No' ecc = 'Yes' if total_width > data_width else 'No'
serial_number = ram.get('Serial Number', 'Unknown') serial_number = ram.get('Serial Number', 'Unknown')
ram_type = ram.get('Type', 'Unknown') ram_type = ram.get('Type', 'Unknown')
@ -479,11 +404,6 @@ class ServerManager:
return self.update_note(note_data, server_id) return self.update_note(note_data, server_id)
else: else:
return self.create_note(note_data) return self.create_note(note_data)
def get_os_list(self):
os_list = self.send_request('GET', '/api/os')
logging.info("OS list fetched successfully") if os_list else logging.error("Failed to fetch OS list")
return os_list or []
def validate_env_vars(): def validate_env_vars():
api_key = os.getenv('AGENT_API') api_key = os.getenv('AGENT_API')
@ -499,17 +419,14 @@ def main():
host, api_key = validate_env_vars() host, api_key = validate_env_vars()
server_manager = ServerManager(host, api_key)
server_data = ServerData() server_data = ServerData()
os_list = server_manager.get_os_list() post_data = server_data.create_post_data()
post_data = server_data.create_post_data(os_list)
server_manager = ServerManager(host, api_key)
server_id = server_manager.upsert_server(post_data) server_id = server_manager.upsert_server(post_data)
logging.info('Server id: {}'.format(server_id)) logging.info('Server id: {}'.format(server_id))
note_data = server_data.create_note_data() note_data = server_data.create_note_data()
server_manager.upsert_note(note_data, server_id) server_manager.upsert_note(note_data, server_id)