forked from NationTech/harmony
chore(harmony): Use Cargo workspaces for core harmony and client specific implementation
This commit is contained in:
18
harmony-rs/harmony/Cargo.toml
Normal file
18
harmony-rs/harmony/Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "harmony"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
libredfish = "0.1.1"
|
||||
reqwest = {version = "0.11", features = ["blocking", "json"] }
|
||||
russh = "0.45.0"
|
||||
rust-ipmi = "0.1.1"
|
||||
semver = "1.0.23"
|
||||
serde = { version = "1.0.209", features = ["derive"] }
|
||||
serde_json = "1.0.127"
|
||||
tokio = { version = "1.40.0", features = ["io-std"] }
|
||||
derive-new = { workspace = true }
|
||||
log = { workspace = true }
|
||||
env_logger = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
0
harmony-rs/harmony/src/domain/cluster/mod.rs
Normal file
0
harmony-rs/harmony/src/domain/cluster/mod.rs
Normal file
12
harmony-rs/harmony/src/domain/data/id.rs
Normal file
12
harmony-rs/harmony/src/domain/data/id.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Id {
|
||||
value: String,
|
||||
}
|
||||
|
||||
impl Id {
|
||||
pub fn from_string(value: String) -> Self {
|
||||
Self { value }
|
||||
}
|
||||
}
|
||||
4
harmony-rs/harmony/src/domain/data/mod.rs
Normal file
4
harmony-rs/harmony/src/domain/data/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
mod id;
|
||||
mod version;
|
||||
pub use id::*;
|
||||
pub use version::*;
|
||||
76
harmony-rs/harmony/src/domain/data/version.rs
Normal file
76
harmony-rs/harmony/src/domain/data/version.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Version {
|
||||
value: semver::Version,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VersionError {
|
||||
msg: String,
|
||||
}
|
||||
|
||||
impl From<semver::Error> for VersionError {
|
||||
fn from(value: semver::Error) -> Self {
|
||||
Self {
|
||||
msg: value.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Version {
|
||||
pub fn from(val: &str) -> Result<Self, VersionError> {
|
||||
Ok(Self {
|
||||
value: semver::Version::parse(val)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::Deserialize<'de> for Version {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
semver::Version::parse(&s)
|
||||
.map(|value| Version { value })
|
||||
.map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for Version {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.value.to_string().serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Version {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
return self.value.fmt(f);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn version_serialize_deserialize() {
|
||||
let v = "10.0.1331-ababa+b123";
|
||||
let version = Version {
|
||||
value: semver::Version::parse(v).unwrap(),
|
||||
};
|
||||
|
||||
let s = serde_json::to_string(&version).unwrap();
|
||||
let version2: Version = serde_json::from_str(&s).unwrap();
|
||||
|
||||
assert_eq!(version2.value.major, 10);
|
||||
assert_eq!(version2.value.minor, 0);
|
||||
assert_eq!(version2.value.patch, 1331);
|
||||
assert_eq!(version2.value.build.to_string(), "b123");
|
||||
assert_eq!(version2.value.pre.to_string(), "ababa");
|
||||
assert_eq!(version2.value.to_string(), v);
|
||||
}
|
||||
}
|
||||
33
harmony-rs/harmony/src/domain/executors/mod.rs
Normal file
33
harmony-rs/harmony/src/domain/executors/mod.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
use std::fmt;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub struct ExecutorResult {
|
||||
message: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ExecutorError {
|
||||
NetworkError(String),
|
||||
AuthenticationError(String),
|
||||
ConfigurationError(String),
|
||||
UnexpectedError(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for ExecutorError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ExecutorError::NetworkError(msg) => write!(f, "Network error: {}", msg),
|
||||
ExecutorError::AuthenticationError(msg) => write!(f, "Authentication error: {}", msg),
|
||||
ExecutorError::ConfigurationError(msg) => write!(f, "Configuration error: {}", msg),
|
||||
ExecutorError::UnexpectedError(msg) => write!(f, "Unexpected error: {}", msg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for ExecutorError {}
|
||||
|
||||
#[async_trait]
|
||||
pub trait SshClient {
|
||||
async fn test_connection(&self, username: String, password: String) -> Result<(), ExecutorError>;
|
||||
}
|
||||
15
harmony-rs/harmony/src/domain/filter.rs
Normal file
15
harmony-rs/harmony/src/domain/filter.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
use derive_new::new;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FilterKind {
|
||||
Label,
|
||||
Kind,
|
||||
}
|
||||
|
||||
pub type FilterValue = String;
|
||||
|
||||
#[derive(Debug, new, Clone)]
|
||||
pub struct Filter {
|
||||
kind: FilterKind,
|
||||
value: FilterValue,
|
||||
}
|
||||
0
harmony-rs/harmony/src/domain/hardware/building.rs
Normal file
0
harmony-rs/harmony/src/domain/hardware/building.rs
Normal file
0
harmony-rs/harmony/src/domain/hardware/host.rs
Normal file
0
harmony-rs/harmony/src/domain/hardware/host.rs
Normal file
76
harmony-rs/harmony/src/domain/hardware/mod.rs
Normal file
76
harmony-rs/harmony/src/domain/hardware/mod.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use derive_new::new;
|
||||
|
||||
pub type HostGroup = Vec<Host>;
|
||||
pub type SwitchGroup = Vec<Switch>;
|
||||
pub type FirewallGroup = Vec<Firewall>;
|
||||
#[derive(Debug)]
|
||||
pub struct Host {
|
||||
pub category: HostCategory,
|
||||
pub network: Vec<NetworkInterface>,
|
||||
pub storage: Vec<Storage>,
|
||||
pub labels: Vec<Label>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum HostCategory {
|
||||
Server,
|
||||
Firewall,
|
||||
Switch,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NetworkInterface {
|
||||
speed: u64,
|
||||
mac_address: MacAddress,
|
||||
plugged_in: bool,
|
||||
}
|
||||
type MacAddress = String;
|
||||
#[derive(Debug)]
|
||||
pub enum StorageConnectionType {
|
||||
Sata3g,
|
||||
Sata6g,
|
||||
Sas6g,
|
||||
Sas12g,
|
||||
PCIE,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub enum StorageKind {
|
||||
SSD,
|
||||
NVME,
|
||||
HDD,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct Storage {
|
||||
connection: StorageConnectionType,
|
||||
kind: StorageKind,
|
||||
size: u64,
|
||||
serial: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Switch {
|
||||
interface: Vec<NetworkInterface>,
|
||||
management_interface: NetworkInterface,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Firewall {}
|
||||
#[derive(Debug)]
|
||||
pub struct Label;
|
||||
pub type Address = String;
|
||||
|
||||
#[derive(new, Debug)]
|
||||
pub struct Location {
|
||||
pub address: Address,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Location {
|
||||
#[cfg(test)]
|
||||
pub fn test_building() -> Location {
|
||||
Self {
|
||||
address: String::new(),
|
||||
name: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
0
harmony-rs/harmony/src/domain/hardware/rack.rs
Normal file
0
harmony-rs/harmony/src/domain/hardware/rack.rs
Normal file
0
harmony-rs/harmony/src/domain/hardware/switch.rs
Normal file
0
harmony-rs/harmony/src/domain/hardware/switch.rs
Normal file
0
harmony-rs/harmony/src/domain/hardware/ups.rs
Normal file
0
harmony-rs/harmony/src/domain/hardware/ups.rs
Normal file
45
harmony-rs/harmony/src/domain/interpret/mod.rs
Normal file
45
harmony-rs/harmony/src/domain/interpret/mod.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
use super::{
|
||||
data::{Id, Version},
|
||||
inventory::Inventory,
|
||||
score::Score,
|
||||
};
|
||||
|
||||
pub enum InterpretName {
|
||||
OPNSenseDHCP,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for InterpretName {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
InterpretName::OPNSenseDHCP => f.write_str("OPNSenseDHCP"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Interpret {
|
||||
fn execute(&self, inventory: &Inventory) -> Result<Outcome, InterpretError>;
|
||||
fn get_name(&self) -> InterpretName;
|
||||
fn get_version(&self) -> Version;
|
||||
fn get_status(&self) -> InterpretStatus;
|
||||
fn get_children(&self) -> Vec<Id>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Outcome {
|
||||
status: InterpretStatus,
|
||||
message: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum InterpretStatus {
|
||||
SUCCESS,
|
||||
FAILURE,
|
||||
RUNNING,
|
||||
QUEUED,
|
||||
BLOCKED,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterpretError {
|
||||
msg: String,
|
||||
}
|
||||
40
harmony-rs/harmony/src/domain/inventory/mod.rs
Normal file
40
harmony-rs/harmony/src/domain/inventory/mod.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
#[derive(Debug, new, Clone)]
|
||||
pub struct InventoryFilter {
|
||||
target: Vec<Filter>,
|
||||
}
|
||||
|
||||
pub struct InventorySlice;
|
||||
|
||||
impl InventoryFilter {
|
||||
pub fn apply(&self, _inventory: &Inventory) -> InventorySlice {
|
||||
// TODO apply inventory filter, refactor as a slice
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
use derive_new::new;
|
||||
|
||||
use super::{
|
||||
filter::Filter,
|
||||
hardware::{Location, FirewallGroup, HostGroup, SwitchGroup},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Inventory {
|
||||
pub location: Location,
|
||||
pub host: HostGroup,
|
||||
pub switch: SwitchGroup,
|
||||
pub firewall: FirewallGroup,
|
||||
}
|
||||
|
||||
impl Inventory {
|
||||
#[cfg(test)]
|
||||
pub fn empty_inventory() -> Self {
|
||||
Self {
|
||||
location: Location::test_building(),
|
||||
host: HostGroup::new(),
|
||||
switch: SwitchGroup::new(),
|
||||
firewall: FirewallGroup::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
38
harmony-rs/harmony/src/domain/maestro/mod.rs
Normal file
38
harmony-rs/harmony/src/domain/maestro/mod.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use derive_new::new;
|
||||
use log::info;
|
||||
|
||||
use super::{interpret::Interpret, inventory::Inventory, score::Score};
|
||||
|
||||
#[derive(new)]
|
||||
pub struct Maestro {
|
||||
inventory: Inventory,
|
||||
}
|
||||
|
||||
impl Maestro {
|
||||
pub fn start(&mut self) {
|
||||
info!("Starting Maestro");
|
||||
self.load_score();
|
||||
self.load_inventory();
|
||||
self.launch_interprets();
|
||||
}
|
||||
|
||||
fn load_score(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn load_inventory(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn launch_interprets(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn interpret<S: Score>(&self, score: S) {
|
||||
info!("Running score {score:?}");
|
||||
let interpret: S::InterpretType = score.create_interpret();
|
||||
info!("Launching interpret {interpret:?}");
|
||||
let result = interpret.execute(&self.inventory);
|
||||
info!("Got result {result:?}");
|
||||
}
|
||||
}
|
||||
9
harmony-rs/harmony/src/domain/mod.rs
Normal file
9
harmony-rs/harmony/src/domain/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
pub mod data;
|
||||
pub mod executors;
|
||||
pub mod filter;
|
||||
pub mod hardware;
|
||||
pub mod interpret;
|
||||
pub mod inventory;
|
||||
pub mod maestro;
|
||||
pub mod score;
|
||||
pub mod topology;
|
||||
7
harmony-rs/harmony/src/domain/score.rs
Normal file
7
harmony-rs/harmony/src/domain/score.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use super::{interpret::Interpret, inventory::InventorySlice};
|
||||
|
||||
pub trait Score: Send + Sync + std::fmt::Debug {
|
||||
type InterpretType: Interpret + std::fmt::Debug;
|
||||
fn get_inventory_filter(&self) -> InventorySlice;
|
||||
fn create_interpret(self) -> Self::InterpretType;
|
||||
}
|
||||
13
harmony-rs/harmony/src/domain/topology/mod.rs
Normal file
13
harmony-rs/harmony/src/domain/topology/mod.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
use std::net::IpAddr;
|
||||
|
||||
use super::hardware::HostGroup;
|
||||
|
||||
pub struct OKDHACluster {
|
||||
firewall: HostGroup,
|
||||
control_plane: HostGroup,
|
||||
workers: HostGroup,
|
||||
ceph_hosts: HostGroup,
|
||||
switch: HostGroup,
|
||||
}
|
||||
|
||||
pub struct IpAddress(IpAddr);
|
||||
0
harmony-rs/harmony/src/infra/executors/boot/mod.rs
Normal file
0
harmony-rs/harmony/src/infra/executors/boot/mod.rs
Normal file
2
harmony-rs/harmony/src/infra/executors/mod.rs
Normal file
2
harmony-rs/harmony/src/infra/executors/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod russh;
|
||||
|
||||
0
harmony-rs/harmony/src/infra/executors/power/mod.rs
Normal file
0
harmony-rs/harmony/src/infra/executors/power/mod.rs
Normal file
41
harmony-rs/harmony/src/infra/executors/russh/mod.rs
Normal file
41
harmony-rs/harmony/src/infra/executors/russh/mod.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
|
||||
use russh::{client, keys::key};
|
||||
|
||||
use crate::domain::executors::{ExecutorError, SshClient};
|
||||
|
||||
pub struct RusshClient;
|
||||
|
||||
#[async_trait]
|
||||
impl SshClient for RusshClient {
|
||||
async fn test_connection(&self, _username: String, _password: String) -> Result<(), crate::domain::executors::ExecutorError> {
|
||||
let config = client::Config::default();
|
||||
let c = Client{};
|
||||
let _client = client::connect(Arc::new(config), ("192.168.12.1", 22), c).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct Client {}
|
||||
|
||||
// More SSH event handlers
|
||||
// can be defined in this trait
|
||||
// In this example, we're only using Channel, so these aren't needed.
|
||||
#[async_trait]
|
||||
impl client::Handler for Client {
|
||||
type Error = ExecutorError;
|
||||
|
||||
async fn check_server_key(
|
||||
&mut self,
|
||||
_server_public_key: &key::PublicKey,
|
||||
) -> Result<bool, Self::Error> {
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<russh::Error> for ExecutorError {
|
||||
fn from(_value: russh::Error) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
1
harmony-rs/harmony/src/infra/mod.rs
Normal file
1
harmony-rs/harmony/src/infra/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod executors;
|
||||
3
harmony-rs/harmony/src/lib.rs
Normal file
3
harmony-rs/harmony/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod domain;
|
||||
pub mod infra;
|
||||
pub mod modules;
|
||||
19
harmony-rs/harmony/src/main.rs
Normal file
19
harmony-rs/harmony/src/main.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use harmony::{
|
||||
domain::{
|
||||
inventory::{Inventory, InventoryFilter},
|
||||
maestro::Maestro,
|
||||
},
|
||||
modules::opnsense_dhcp::OPNSenseDhcpScore,
|
||||
};
|
||||
|
||||
pub fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let maestro = Maestro::new(get_inventory());
|
||||
let score = OPNSenseDhcpScore::new(InventoryFilter::new(vec![]));
|
||||
maestro.interpret(score);
|
||||
}
|
||||
|
||||
fn get_inventory() -> Inventory {
|
||||
todo!()
|
||||
}
|
||||
16
harmony-rs/harmony/src/main_ipmi.rs
Normal file
16
harmony-rs/harmony/src/main_ipmi.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
use rust_ipmi::{IPMIClient, NetFn};
|
||||
fn main() {
|
||||
let connection_string = "192.168.11.132:443";
|
||||
println!("Hello, world! {}", connection_string);
|
||||
let mut client: IPMIClient = IPMIClient::new(connection_string).expect("Failed to create ipmi client");
|
||||
|
||||
client.establish_connection("root", "YOUR_PASSWORD")
|
||||
.expect("Failed to establish connection with the BMC");
|
||||
|
||||
let response = client.send_raw_request(NetFn::App, 0x3b, Some(vec![0x04]));
|
||||
|
||||
match response {
|
||||
Ok(response) => println!("{}", response),
|
||||
Err(err) => println!("Got error {:?}", err),
|
||||
}
|
||||
}
|
||||
20
harmony-rs/harmony/src/main_redfish.rs
Normal file
20
harmony-rs/harmony/src/main_redfish.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use libredfish::{Config, Redfish};
|
||||
use reqwest::blocking::Client;
|
||||
|
||||
pub fn main() {
|
||||
let client = Client::builder().danger_accept_invalid_certs(true).build().expect("Failed to build reqwest client");
|
||||
let redfish = Redfish::new(
|
||||
client,
|
||||
Config {
|
||||
user: Some(String::from("Administrator")),
|
||||
endpoint: String::from("10.10.8.104/redfish/v1"),
|
||||
// password: Some(String::from("YOUR_PASSWORD")),
|
||||
password: Some(String::from("wrongpass")),
|
||||
port: None,
|
||||
},
|
||||
);
|
||||
|
||||
let response = redfish.get_power_status().expect("Failed redfish request");
|
||||
|
||||
println!("Got power {:?}", response);
|
||||
}
|
||||
1
harmony-rs/harmony/src/modules/mod.rs
Normal file
1
harmony-rs/harmony/src/modules/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod opnsense_dhcp;
|
||||
119
harmony-rs/harmony/src/modules/opnsense_dhcp.rs
Normal file
119
harmony-rs/harmony/src/modules/opnsense_dhcp.rs
Normal file
@@ -0,0 +1,119 @@
|
||||
use derive_new::new;
|
||||
use log::info;
|
||||
|
||||
use crate::{domain::{
|
||||
data::{Id, Version}, hardware::NetworkInterface, interpret::{InterpretError, InterpretStatus, Outcome}, inventory::Inventory, topology::IpAddress
|
||||
}, infra::executors::russh::RusshClient};
|
||||
|
||||
use crate::domain::{
|
||||
interpret::Interpret, interpret::InterpretName, inventory::InventoryFilter,
|
||||
inventory::InventorySlice, score::Score,
|
||||
};
|
||||
|
||||
use crate::domain::executors::{ExecutorError, ExecutorResult};
|
||||
#[derive(Debug, new)]
|
||||
pub struct OPNSenseDhcpScore {
|
||||
inventory_filter: InventoryFilter,
|
||||
}
|
||||
|
||||
impl Score for OPNSenseDhcpScore {
|
||||
type InterpretType = OPNSenseDhcpInterpret;
|
||||
|
||||
fn get_inventory_filter(&self) -> InventorySlice {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn create_interpret(self) -> OPNSenseDhcpInterpret {
|
||||
OPNSenseDhcpInterpret::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// https://docs.opnsense.org/manual/dhcp.html#advanced-settings
|
||||
#[derive(Debug)]
|
||||
pub struct OPNSenseDhcpInterpret {
|
||||
score: OPNSenseDhcpScore,
|
||||
version: Version,
|
||||
id: Id,
|
||||
name: String,
|
||||
status: InterpretStatus,
|
||||
}
|
||||
|
||||
impl OPNSenseDhcpInterpret {
|
||||
pub fn new(score: OPNSenseDhcpScore) -> Self {
|
||||
let version = Version::from("1.0.0").expect("Version should be valid");
|
||||
let name = "OPNSenseDhcpScore".to_string();
|
||||
let id = Id::from_string(format!("{name}_{version}"));
|
||||
|
||||
Self {
|
||||
version,
|
||||
id,
|
||||
name,
|
||||
score,
|
||||
status: InterpretStatus::QUEUED,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpret for OPNSenseDhcpInterpret {
|
||||
fn get_name(&self) -> InterpretName {
|
||||
InterpretName::OPNSenseDHCP
|
||||
}
|
||||
|
||||
fn get_version(&self) -> crate::domain::data::Version {
|
||||
self.version.clone()
|
||||
}
|
||||
|
||||
fn get_status(&self) -> InterpretStatus {
|
||||
self.status.clone()
|
||||
}
|
||||
|
||||
fn get_children(&self) -> Vec<crate::domain::data::Id> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn execute(&self, _inventory: &Inventory) -> Result<Outcome, InterpretError> {
|
||||
info!("Executing {} on inventory {_inventory:?}", self.get_name());
|
||||
let _ssh_client = RusshClient{};
|
||||
// ssh_client.test_connection("username", "password");
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait OPNSenseDhcpConfigEditor {
|
||||
fn add_static_host(
|
||||
&self,
|
||||
opnsense_host: IpAddress,
|
||||
credentials: OPNSenseCredentials,
|
||||
interface: NetworkInterface,
|
||||
address: IpAddress,
|
||||
) -> Result<ExecutorResult, ExecutorError>;
|
||||
}
|
||||
|
||||
pub struct OPNSenseCredentials {
|
||||
pub user: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
#[test]
|
||||
fn opnsense_dns_score_should_do_nothing_on_empty_inventory() {
|
||||
todo!();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opnsense_dns_score_should_set_entry_for_bootstrap_node() {
|
||||
todo!();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opnsense_dns_score_should_set_entry_for_control_plane_members() {
|
||||
todo!();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opnsense_dns_score_should_set_entry_for_workers() {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user