use crate::{
Machine,
collectors::network::NetworkInformation,
configuration::parser::{CommonConfig, DeviceConfig, VmConfig},
constants::{DHCP_TAG_REQUEST, NAZARA_TAG_REQUEST},
};
use serde_json::{Value, json};
use std::{collections::HashMap, net::IpAddr};
use thanix_client::types::{
PatchedWritableDeviceWithConfigContextRequest,
PatchedWritableVirtualMachineWithConfigContextRequest, WritableDeviceWithConfigContextRequest,
WritableIPAddressRequest, WritableInterfaceRequest, WritableVMInterfaceRequest,
WritableVirtualMachineWithConfigContextRequest,
};
pub fn information_to_device(
machine: &Machine,
common: &CommonConfig,
device: &DeviceConfig,
) -> WritableDeviceWithConfigContextRequest {
WritableDeviceWithConfigContextRequest {
name: Some(compute_effective_name(
&common.name,
&machine.dmi_information.system_information.hostname,
)),
device_type: Value::from(device.device_type),
role: Value::from(device.role),
serial: machine.dmi_information.system_information.serial.clone(),
site: Value::from(device.site),
status: common.status.clone(),
comments: common.comments.clone(),
custom_fields: machine.custom_information.clone(),
description: common.description.clone(),
..Default::default()
}
}
pub fn information_to_existing_device(
machine: &Machine,
common: &CommonConfig,
device: &DeviceConfig,
) -> PatchedWritableDeviceWithConfigContextRequest {
PatchedWritableDeviceWithConfigContextRequest {
name: Some(Some(compute_effective_name(
&common.name,
&machine.dmi_information.system_information.hostname,
))),
device_type: Some(Value::from(device.device_type)),
role: Some(Value::from(device.role)),
serial: Some(machine.dmi_information.system_information.serial.clone()),
site: Some(Value::from(device.site)),
status: Some(common.status.clone()),
description: Some(common.description.clone()),
comments: Some(common.comments.clone()),
custom_fields: Some(machine.custom_information.clone()),
..Default::default()
}
}
pub fn information_to_vm(
machine: &Machine,
common: &CommonConfig,
vm: &VmConfig,
) -> WritableVirtualMachineWithConfigContextRequest {
WritableVirtualMachineWithConfigContextRequest {
name: compute_effective_name(
&common.name,
&machine.dmi_information.system_information.hostname,
),
serial: machine.dmi_information.system_information.serial.clone(),
status: common.status.clone(),
comments: common.comments.clone(),
custom_fields: machine.custom_information.clone(),
description: common.description.clone(),
cluster: Some(Value::from(vm.cluster)),
vcpus: machine
.dmi_information
.cpu_information
.core_count
.parse()
.ok(),
..Default::default()
}
}
pub fn information_to_existing_vm(
machine: &Machine,
common: &CommonConfig,
vm: &VmConfig,
) -> PatchedWritableVirtualMachineWithConfigContextRequest {
PatchedWritableVirtualMachineWithConfigContextRequest {
name: Some(compute_effective_name(
&common.name,
&machine.dmi_information.system_information.hostname,
)),
serial: Some(machine.dmi_information.system_information.serial.clone()),
status: Some(common.status.clone()),
comments: Some(common.comments.clone()),
custom_fields: Some(machine.custom_information.clone()),
description: Some(common.description.clone()),
cluster: Some(Some(Value::from(vm.cluster))),
vcpus: Some(
machine
.dmi_information
.cpu_information
.core_count
.parse()
.ok(),
),
..Default::default()
}
}
pub fn information_to_interface(
config_data: &CommonConfig,
interface: &NetworkInformation,
device_id: &i64,
) -> WritableInterfaceRequest {
status!(
"Creating Network Interface payload for '{}'...",
&interface.name
);
let mut payload = WritableInterfaceRequest::default();
payload.device = Value::from(device_id.to_owned());
payload.name = interface.name.clone();
if let Some(x) = &interface.mac_addr {
payload.primary_mac_address = Some(json!({"mac_address": x}));
}
payload.speed = Some(interface.interface_speed.unwrap_or_default());
payload.description = config_data.comments.clone();
payload.mark_connected = interface.is_connected;
payload.enabled = true;
payload.custom_fields = Some(HashMap::new());
payload.r#type = String::from("other");
payload
}
pub fn information_to_vm_interface(
config_data: &CommonConfig,
interface: &NetworkInformation,
device_id: &i64,
) -> WritableVMInterfaceRequest {
status!(
"Creating Network Interface payload for '{}'...",
&interface.name
);
let mut payload = WritableVMInterfaceRequest::default();
payload.virtual_machine = Value::from(device_id.to_owned());
payload.name = interface.name.clone();
if let Some(x) = &interface.mac_addr {
payload.primary_mac_address = Some(json!({"mac_address": x}));
}
payload.description = config_data.comments.clone();
payload.enabled = true;
payload.custom_fields = Some(HashMap::new());
payload
}
pub fn information_to_ip(
interface_address: IpAddr,
interface_id: i64,
is_vm: bool,
) -> WritableIPAddressRequest {
status!("Creating IP Address payload...");
WritableIPAddressRequest {
address: format!("{interface_address}"),
status: String::from("active"),
assigned_object_type: Some(String::from(if is_vm {
"virtualization.vminterface"
} else {
"dcim.interface"
})),
assigned_object_id: Some(interface_id as u64),
description: String::from("This Address was automatically created by Nazara."),
comments: String::from("Automatically created by Nazara."),
custom_fields: Some(HashMap::new()),
tags: vec![NAZARA_TAG_REQUEST.clone()],
..Default::default()
}
}
pub fn information_to_dhcp_ip(
interface_address: IpAddr,
interface_id: i64,
is_vm: bool,
) -> WritableIPAddressRequest {
let mut payload = information_to_ip(interface_address, interface_id, is_vm);
payload.description = "Observed via DHCP (managed externally)".to_string();
payload.comments =
"This IP was observed on the host and may change. Managed by DHCP.".to_string();
payload.tags = vec![DHCP_TAG_REQUEST.clone(), NAZARA_TAG_REQUEST.clone()];
payload
}
pub fn compute_effective_name(config_name: &Option<String>, hostname: &str) -> String {
match config_name {
Some(name) => {
if name.ends_with('@') {
format!("{}{}", name, hostname)
} else {
name.clone()
}
}
None => hostname.to_string(),
}
}