use crate::inventory::options::storage_type::StorageType;
use crate::inventory::types::Environment;
use clap::ValueEnum;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Deserialize, Serialize, Clone, Default, ValueEnum)]
pub enum ParameterKeyStyle {
#[default]
None,
Ansible,
}
pub trait StorageOptionsTrait {
fn inventory_path(&self) -> PathBuf;
fn parameter_key_style(&self) -> ParameterKeyStyle;
fn compose_node_name(&self) -> bool;
fn default_environment(&self) -> Environment;
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct YamlFsStorageOptions {
pub inventory_base_uri: String,
pub nodes_uri: String,
pub classes_uri: String,
pub parameter_key_style: ParameterKeyStyle,
pub compose_node_name: bool,
pub default_environment: Environment,
}
impl YamlFsStorageOptions {
pub fn build(inventory_base_uri: String) -> Self {
Self {
inventory_base_uri,
..Self::default()
}
}
pub fn build_with_options(
inventory_base_uri: String,
nodes_uri: String,
classes_uri: String,
parameter_key_style: ParameterKeyStyle,
compose_node_name: bool,
default_environment: Environment,
) -> Self {
Self {
inventory_base_uri,
nodes_uri,
classes_uri,
parameter_key_style,
compose_node_name,
default_environment,
}
}
pub fn nodes_path(&self) -> PathBuf {
PathBuf::from(&self.inventory_base_uri).join(PathBuf::from(&self.nodes_uri))
}
pub fn classes_path(&self) -> PathBuf {
PathBuf::from(&self.inventory_base_uri).join(PathBuf::from(&self.classes_uri))
}
}
impl StorageOptionsTrait for YamlFsStorageOptions {
fn inventory_path(&self) -> PathBuf {
PathBuf::from(&self.inventory_base_uri)
}
fn parameter_key_style(&self) -> ParameterKeyStyle {
self.parameter_key_style.clone()
}
fn compose_node_name(&self) -> bool {
self.compose_node_name
}
fn default_environment(&self) -> Environment {
self.default_environment.clone()
}
}
impl Default for YamlFsStorageOptions {
fn default() -> Self {
Self {
inventory_base_uri: String::from("/etc/reclass"),
nodes_uri: "nodes".to_string(),
classes_uri: "classes".to_string(),
parameter_key_style: ParameterKeyStyle::default(),
compose_node_name: false,
default_environment: Environment::default(),
}
}
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct YamlFileStorageOptions {
pub inventory_file: String,
pub parameter_key_style: ParameterKeyStyle,
pub default_environment: Environment,
}
impl YamlFileStorageOptions {
pub fn build(inventory_file: String) -> Self {
Self {
inventory_file,
parameter_key_style: ParameterKeyStyle::default(),
default_environment: Environment::default(),
}
}
}
impl StorageOptionsTrait for YamlFileStorageOptions {
fn inventory_path(&self) -> PathBuf {
PathBuf::from(&self.inventory_file)
}
fn parameter_key_style(&self) -> ParameterKeyStyle {
self.parameter_key_style.clone()
}
fn compose_node_name(&self) -> bool {
false
}
fn default_environment(&self) -> Environment {
self.default_environment.clone()
}
}
impl Default for YamlFileStorageOptions {
fn default() -> Self {
Self {
inventory_file: String::from("/etc/reclass/inventory.yml"),
parameter_key_style: ParameterKeyStyle::default(),
default_environment: Environment::default(),
}
}
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct StorageOptions {
pub storage_type: StorageType,
pub yaml_fs_options: YamlFsStorageOptions,
pub yaml_file_options: YamlFileStorageOptions,
}
impl StorageOptions {
pub fn build(storage_type: StorageType, inventory_base_uri: String) -> Self {
Self {
storage_type,
yaml_fs_options: YamlFsStorageOptions::build(inventory_base_uri),
..Self::default()
}
}
pub fn inventory_path(&self) -> PathBuf {
match self.storage_type {
StorageType::YamlFs => self.yaml_fs_options.inventory_path(),
StorageType::YamlFile => self.yaml_file_options.inventory_path(),
}
}
pub fn nodes_path(&self) -> PathBuf {
self.yaml_fs_options.nodes_path()
}
pub fn classes_path(&self) -> PathBuf {
self.yaml_fs_options.classes_path()
}
pub fn yaml_fs_options(&self) -> &YamlFsStorageOptions {
&self.yaml_fs_options
}
pub fn yaml_file_options(&self) -> &YamlFileStorageOptions {
&self.yaml_file_options
}
}
impl StorageOptionsTrait for StorageOptions {
fn inventory_path(&self) -> PathBuf {
match self.storage_type {
StorageType::YamlFs => self.yaml_fs_options.inventory_path(),
StorageType::YamlFile => self.yaml_file_options.inventory_path(),
}
}
fn parameter_key_style(&self) -> ParameterKeyStyle {
self.yaml_fs_options.parameter_key_style()
}
fn compose_node_name(&self) -> bool {
self.yaml_fs_options.compose_node_name()
}
fn default_environment(&self) -> Environment {
self.yaml_fs_options.default_environment()
}
}
impl Default for StorageOptions {
fn default() -> Self {
Self {
storage_type: StorageType::YamlFs,
yaml_fs_options: YamlFsStorageOptions::default(),
yaml_file_options: YamlFileStorageOptions::default(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_paths() {
let storage_options = StorageOptions::build(StorageType::YamlFs, String::from("/tmp"));
assert_eq!(storage_options.inventory_path(), PathBuf::from("/tmp"));
assert_eq!(storage_options.nodes_path(), PathBuf::from("/tmp/nodes"));
assert_eq!(
storage_options.classes_path(),
PathBuf::from("/tmp/classes")
);
}
#[test]
fn mixed() {
let storage_options = StorageOptions {
yaml_fs_options: YamlFsStorageOptions {
nodes_uri: "/tmp/nodes".to_string(),
..YamlFsStorageOptions::default()
},
..StorageOptions::default()
};
assert_eq!(
storage_options.inventory_path(),
PathBuf::from("/etc/reclass")
);
assert_eq!(storage_options.nodes_path(), PathBuf::from("/tmp/nodes"));
assert_eq!(
storage_options.classes_path(),
PathBuf::from("/etc/reclass/classes")
);
}
#[test]
fn test_paths_absolut() {
let storage_options = StorageOptions {
yaml_fs_options: YamlFsStorageOptions {
nodes_uri: "/tmp/nodes".to_string(),
classes_uri: "/tmp/classes".to_string(),
..YamlFsStorageOptions::default()
},
..StorageOptions::default()
};
assert_eq!(
storage_options.inventory_path(),
PathBuf::from("/etc/reclass")
);
assert_eq!(storage_options.nodes_path(), PathBuf::from("/tmp/nodes"));
assert_eq!(
storage_options.classes_path(),
PathBuf::from("/tmp/classes")
);
}
}