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",
|
||||
]
|
||||
|
||||
[[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]]
|
||||
name = "brotli"
|
||||
version = "8.0.2"
|
||||
@@ -2889,6 +2905,15 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "example-okd-system-reserved"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"harmony",
|
||||
"harmony_cli",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "example-openbao"
|
||||
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 kubelet_config;
|
||||
pub mod nmstate;
|
||||
pub mod route;
|
||||
|
||||
@@ -26,3 +26,4 @@ pub use bootstrap_06_installation_report::*;
|
||||
pub use bootstrap_persist_network_bond::*;
|
||||
pub mod crd;
|
||||
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