feat: create score + example to create a machineconfig resource to configured system reserved parameters #262
25
Cargo.lock
generated
25
Cargo.lock
generated
@@ -1262,6 +1262,22 @@ dependencies = [
|
|||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brocade-switch-oricom-configuration"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"brocade",
|
||||||
|
"env_logger",
|
||||||
|
"harmony",
|
||||||
|
"harmony_cli",
|
||||||
|
"harmony_macros",
|
||||||
|
"harmony_types",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "brotli"
|
name = "brotli"
|
||||||
version = "8.0.2"
|
version = "8.0.2"
|
||||||
@@ -2889,6 +2905,15 @@ dependencies = [
|
|||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "example-okd-system-reserved"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"harmony",
|
||||||
|
"harmony_cli",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "example-openbao"
|
name = "example-openbao"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|||||||
12
examples/okd_system_reserved/Cargo.toml
Normal file
12
examples/okd_system_reserved/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "example-okd-system-reserved"
|
||||||
|
edition = "2024"
|
||||||
|
version.workspace = true
|
||||||
|
readme.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
harmony = { path = "../../harmony" }
|
||||||
|
harmony_cli = { path = "../../harmony_cli" }
|
||||||
|
tokio = { workspace = true }
|
||||||
5
examples/okd_system_reserved/env.sh
Normal file
5
examples/okd_system_reserved/env.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export HARMONY_SECRET_NAMESPACE=okd-system-reserved-example
|
||||||
|
export HARMONY_SECRET_STORE=file
|
||||||
|
export HARMONY_DATABASE_URL=sqlite://harmony_okd_system_reserved.sqlite
|
||||||
|
export HARMONY_USE_LOCAL_K3D=false
|
||||||
|
export RUST_LOG=harmony=debug
|
||||||
25
examples/okd_system_reserved/src/main.rs
Normal file
25
examples/okd_system_reserved/src/main.rs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
use harmony::{
|
||||||
|
inventory::Inventory,
|
||||||
|
modules::okd::system_reserved_score::{MachineConfigPool, SystemReservedScore},
|
||||||
|
topology::K8sAnywhereTopology,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
harmony_cli::cli_logger::init();
|
||||||
|
|
||||||
|
let master_score = SystemReservedScore {
|
||||||
|
pool: MachineConfigPool::Master,
|
||||||
|
memory: "0.5Gi".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
harmony_cli::run(
|
||||||
|
Inventory::autoload(),
|
||||||
|
K8sAnywhereTopology::from_env(),
|
||||||
|
vec![Box::new(master_score)],
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
47
harmony/src/modules/okd/crd/kubelet_config.rs
Normal file
47
harmony/src/modules/okd/crd/kubelet_config.rs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
use k8s_openapi::apimachinery::pkg::apis::meta::v1::LabelSelector;
|
||||||
|
use kube::{CustomResource, api::ObjectMeta};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(CustomResource, Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[kube(
|
||||||
|
group = "machineconfiguration.openshift.io",
|
||||||
|
version = "v1",
|
||||||
|
kind = "KubeletConfig",
|
||||||
|
plural = "kubeletconfigs",
|
||||||
|
namespaced = false,
|
||||||
|
schema = "disabled"
|
||||||
|
)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct KubeletConfigSpec {
|
||||||
|
pub machine_config_pool_selector: LabelSelector,
|
||||||
|
pub kubelet_config: KubeletConfigInner,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for KubeletConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
metadata: ObjectMeta::default(),
|
||||||
|
spec: KubeletConfigSpec {
|
||||||
|
machine_config_pool_selector: LabelSelector::default(),
|
||||||
|
kubelet_config: KubeletConfigInner::default(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug, Default)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct KubeletConfigInner {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub system_reserved: Option<SystemReserved>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug, Default)]
|
||||||
|
pub struct SystemReserved {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub memory: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub cpu: Option<String>,
|
||||||
|
#[serde(rename = "ephemeral-storage", skip_serializing_if = "Option::is_none")]
|
||||||
|
pub ephemeral_storage: Option<String>,
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
pub mod ingresses_config;
|
pub mod ingresses_config;
|
||||||
|
pub mod kubelet_config;
|
||||||
pub mod nmstate;
|
pub mod nmstate;
|
||||||
pub mod route;
|
pub mod route;
|
||||||
|
|||||||
@@ -26,3 +26,4 @@ pub use bootstrap_06_installation_report::*;
|
|||||||
pub use bootstrap_persist_network_bond::*;
|
pub use bootstrap_persist_network_bond::*;
|
||||||
pub mod crd;
|
pub mod crd;
|
||||||
pub mod host_network;
|
pub mod host_network;
|
||||||
|
pub mod system_reserved_score;
|
||||||
|
|||||||
98
harmony/src/modules/okd/system_reserved_score.rs
Normal file
98
harmony/src/modules/okd/system_reserved_score.rs
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use k8s_openapi::apimachinery::pkg::apis::meta::v1::LabelSelector;
|
||||||
|
use kube::api::ObjectMeta;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
interpret::Interpret,
|
||||||
|
modules::{
|
||||||
|
k8s::resource::K8sResourceScore,
|
||||||
|
okd::crd::kubelet_config::{
|
||||||
|
KubeletConfig, KubeletConfigInner, KubeletConfigSpec, SystemReserved,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
score::Score,
|
||||||
|
topology::{K8sclient, Topology},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Serialize)]
|
||||||
|
pub enum MachineConfigPool {
|
||||||
|
Master,
|
||||||
|
Worker,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MachineConfigPool {
|
||||||
|
fn label_key(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Master => "pools.operator.machineconfiguration.openshift.io/master",
|
||||||
|
Self::Worker => "pools.operator.machineconfiguration.openshift.io/worker",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_resource_name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Master => "master-system-reserved",
|
||||||
|
Self::Worker => "worker-system-reserved",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct SystemReservedScore {
|
||||||
|
pub pool: MachineConfigPool,
|
||||||
|
pub memory: String,
|
||||||
|
pub cpu: Option<String>,
|
||||||
|
pub ephemeral_storage: Option<String>,
|
||||||
|
pub resource_name: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SystemReservedScore {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
pool: MachineConfigPool::Master,
|
||||||
|
memory: "3.5Gi".to_string(),
|
||||||
|
cpu: None,
|
||||||
|
ephemeral_storage: None,
|
||||||
|
resource_name: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Topology + K8sclient> Score<T> for SystemReservedScore {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"SystemReservedScore".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
||||||
|
let mut match_labels = BTreeMap::new();
|
||||||
|
match_labels.insert(self.pool.label_key().to_string(), String::new());
|
||||||
|
|
||||||
|
let name = self
|
||||||
|
.resource_name
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| self.pool.default_resource_name().to_string());
|
||||||
|
|
||||||
|
let kc = KubeletConfig {
|
||||||
|
metadata: ObjectMeta {
|
||||||
|
name: Some(name),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
spec: KubeletConfigSpec {
|
||||||
|
machine_config_pool_selector: LabelSelector {
|
||||||
|
match_labels: Some(match_labels),
|
||||||
|
match_expressions: None,
|
||||||
|
},
|
||||||
|
kubelet_config: KubeletConfigInner {
|
||||||
|
system_reserved: Some(SystemReserved {
|
||||||
|
memory: Some(self.memory.clone()),
|
||||||
|
cpu: self.cpu.clone(),
|
||||||
|
ephemeral_storage: self.ephemeral_storage.clone(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
K8sResourceScore::single(kc, None).create_interpret()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user