Skip to content

Commit

Permalink
implement machine search for post/patch distinguation
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteOtter committed Feb 13, 2024
1 parent cab0960 commit dfa0ae1
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 51 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ toml = "0.7.6"
# This may not work in your environment. You can get your schema by visiting
# https://your.netbox-instance.com/api/schema.
# The yaml file will be downloaded and you can generate your client by using https://github.com/The-Nazara-Project/Thanix.
thanix_client = "0.6.0"
thanix_client = "0.7.0"
# Uncomment this line if you are using a custom thanix client implementation.
# Change the path to be relative to this Cargo.toml file.
# thanix_client = { path = "path/to/your/client/" }
Expand Down
42 changes: 21 additions & 21 deletions src/collectors/dmi_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ use std::{
/// * cpu_information: [`CpuInformation`](struct.CpuInformation) - Information about the processor(s).
#[derive(Serialize, Debug)]
pub struct DmiInformation {
system_information: SystemInformation,
chassis_information: ChassisInformation,
cpu_information: CpuInformation,
pub system_information: SystemInformation,
pub chassis_information: ChassisInformation,
pub cpu_information: CpuInformation,
}

/// ## SystemInformation
Expand All @@ -44,12 +44,12 @@ pub struct DmiInformation {
/// * serial: `String` - The serial number of the machine.
/// * is_virtual: `bool` - Whether the machine is a virtual machine or not.
#[derive(Serialize, Debug)]
struct SystemInformation {
vendor: String,
model: String,
uuid: String,
serial: String,
is_virtual: bool,
pub struct SystemInformation {
pub vendor: String,
pub model: String,
pub uuid: String,
pub serial: String,
pub is_virtual: bool,
}

/// ## Chassis Information
Expand All @@ -62,10 +62,10 @@ struct SystemInformation {
/// * asset: `String`- Type of asset.
/// * chassis_serial: `Serial` - Serial number of the chassis.
#[derive(Serialize, Debug)]
struct ChassisInformation {
chassis_type: String,
asset: String,
chassis_serial: String,
pub struct ChassisInformation {
pub chassis_type: String,
pub asset: String,
pub chassis_serial: String,
}

/// ## CpuInformation
Expand All @@ -82,14 +82,14 @@ struct ChassisInformation {
/// * voltage: `String` - The voltage the CPU runs at.
/// * status: `String` - Shows if the socket is enabled/disabled and populated/empty.
#[derive(Serialize, Debug)]
struct CpuInformation {
version: String,
core_count: String,
cores_enabled: String,
thread_count: String,
max_speed: String,
voltage: String,
status: String,
pub struct CpuInformation {
pub version: String,
pub core_count: String,
pub cores_enabled: String,
pub thread_count: String,
pub max_speed: String,
pub voltage: String,
pub status: String,
}

/// List of possible system parameters to collect dmi information from.
Expand Down
36 changes: 27 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub mod configuration;
pub mod publisher;

use clap::Parser;
use collectors::{dmi_collector, network_collector};
use collectors::{dmi_collector::{self, DmiInformation}, network_collector::{self, NetworkInformation}};
use configuration::config_parser::set_up_configuration;
use publisher::publisher::*;
use reqwest::blocking::Client;
Expand All @@ -12,6 +12,22 @@ use thanix_client::util::ThanixClient;

use crate::publisher::publisher_exceptions::NetBoxApiError;


/// The Machine struct
///
/// This struct represents your machine.
/// It holds all information collected and allows for sharing this
/// information between Nazara's modules.
///
/// It is used in places where it is necessary to have access to various
/// pieces of collected information from a single source of truth.
/// It will also be translated into the proper API type by the translator.
pub struct Machine {
pub name: Option<String>,
pub dmi_information: DmiInformation,
pub network_information: Vec<NetworkInformation>,
}

/// The arguments that Nazara expects to get via the cli.
///
/// Arguments can be passed like this:
Expand Down Expand Up @@ -76,7 +92,7 @@ fn main() {
let config = match set_up_configuration(
args.uri,
args.token,
args.name,
args.name.clone(),
args.location,
args.device_role,
) {
Expand All @@ -93,22 +109,24 @@ fn main() {
client: Client::new(),
};


match probe(&client) {
Ok(()) => {}
Err(err) => println!("{}", err),
};

// println!("Configuration: \n{:#?}", config);

// println!("Uri: {}\nToken: {}", args.uri.clone().unwrap(), args.token.clone().unwrap());

let dmi_information: dmi_collector::DmiInformation = dmi_collector::construct_dmi_information();

// println!("{:#?}", dmi_information);

let network_information = network_collector::construct_network_information().unwrap();

let _ = register_machine(&client);

let machine: Machine = Machine {
name: args.name,
dmi_information,
network_information
};

let _ = register_machine(&client, machine);

// println!("{:#?}", network_information);

Expand Down
92 changes: 72 additions & 20 deletions src/publisher/publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,35 @@
//! Based on the conditions in this logic it is decided whether to use the machine or VM endpoints, to create a new
//! machine or update an existing one.
//!
//! The actual request logic will be provided by the `thanix_client` crate.
//!
//! The `api_client` module will provide the actual client and request logic.
use std::ops::Deref;

use serde::{Deserialize, Serialize};
use thanix_client::{
paths::{self, DcimDevicesListQuery},
types::{DeviceWithConfigContext, PaginatedDeviceWithConfigContextList},
types::{
DeviceWithConfigContext, PaginatedDeviceWithConfigContextList,
WritableDeviceWithConfigContextRequest,
},
util::ThanixClient,
};

use crate::publisher::api_client::test_connection;
use crate::{
collectors::{dmi_collector::DmiInformation, network_collector::NetworkInformation},
publisher::api_client::test_connection, Machine,
};

use super::publisher_exceptions::NetBoxApiError;

/// Test connection to NetBox.
///
/// # Paramters
///
/// - `client: &ThanixClient` - Reference to a `thanix_client` instance
///
/// # Returns
///
/// - `Result<(), NetBoxApiError` - Either returns an empty Ok() or a new instance of `NetBoxApiError`
pub fn probe(client: &ThanixClient) -> Result<(), NetBoxApiError> {
println!("Probing connection to NetBox...");

Expand All @@ -30,9 +45,22 @@ pub fn probe(client: &ThanixClient) -> Result<(), NetBoxApiError> {
}
}

pub fn register_machine(client: &ThanixClient) -> Result<(), NetBoxApiError> {
/// Register this machine in NetBox.
///
/// # Parameters
///
/// - `client: &ThanixClient` - Reference to a `thanix_client` instance
///
/// # Returns
///
/// TODO
pub fn register_machine(
client: &ThanixClient,
machine: Machine
) -> Result<(), NetBoxApiError> {
println!("Starting registration process. This may take a while...");
get_machines(client);
let machines: Vec<DeviceWithConfigContext> = get_machines(client);
search_for_matches(machine, &machines);
Ok(())
}

Expand All @@ -50,40 +78,64 @@ pub fn register_machine(client: &ThanixClient) -> Result<(), NetBoxApiError> {
///
/// # Returns
///
/// - `device_list: Vec<DeviceWithConfigContext>` - Returns a list of `DeviceWithConfigContext` objects.
///
/// # Panics
///
/// The function panics, when the request returns an error.
fn get_machines(client: &ThanixClient) {
fn get_machines(client: &ThanixClient) -> Vec<DeviceWithConfigContext> {
println!("Retrieving list of machines...");

match paths::dcim_devices_list(client, paths::DcimDevicesListQuery::default()) {
match paths::dcim_devices_list(client, DcimDevicesListQuery::default()) {
Ok(response) => {
println!("List received. Analyzing...");
let debug_json = response.text().unwrap();

// Write the JSON string into a file
std::fs::write("output.txt", &debug_json).unwrap();
//println!("{:?}", &debug_json);
let response_text: PaginatedDeviceWithConfigContextList =
let response_content: PaginatedDeviceWithConfigContextList =
serde_json::from_str(&debug_json).unwrap();

// Convert the Rust object back into a JSON string
let json_string = serde_json::to_string_pretty(&response_text).unwrap();
let device_list: Vec<DeviceWithConfigContext> = response_content.results;

// println!("Response \n -------\n\t{:?}", &json_string)
return device_list;
}
Err(err) => panic!("{}", err),
}
}

/// Searches for matching device in list of machines.
///
/// Primary search parameters are the device's **serial number** and **UUID** acquired by `dmidecode`.
///
/// If a name has been provided, it is assumed that you do want to use this as primary search vector.
/// (Maybe because for your use case serial numbers or UUIDs are not reliable.)
///
/// # Parameters
///
/// - `machine: `Machine`` - Instance of a `Machine` containing all the local machines information.
/// - `device_list: &Vec<DeviceWithConfigContext>` - List of all devices.
///
/// # Returns
///
/// - `bool` - Depending on if the device has been found or not.
fn search_for_matches(list: &Vec<DeviceWithConfigContext>) -> bool {
true
fn search_for_matches(
machine: Machine,
device_list: &Vec<DeviceWithConfigContext>,
) -> bool {
if machine.name.is_none() {
for device in device_list {
if machine.dmi_information.system_information.serial == device.serial {
println!("\x1b[32m[success]\x1b[0m Machine found using serial number!");
return true;
}
}
return false;
}
for device in device_list {
if device.name == machine.name {
println!("\x1b[32m[success]\x1b[0m Machine found using name!");
return true;
}
}
println!("\x1b[32m[info]\x1b[0m Machine not found in registered machines.");
false
}

/// Determine Error code based on response.
fn determine_resp_code() {}

0 comments on commit dfa0ae1

Please sign in to comment.