WIP: Start implementing automatic node discovery from the K8s API
This commit is contained in:
parent
6e676c49d1
commit
f6b5fef439
@ -1,16 +1,79 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use k8s_openapi::api::core::v1::Node;
|
||||||
|
use kube::{Api, Client};
|
||||||
|
use kube::api::ListParams;
|
||||||
use proxmox_api::nodes::node::lxc::vmid::migrate;
|
use proxmox_api::nodes::node::lxc::vmid::migrate;
|
||||||
use proxmox_api::nodes::node::tasks::upid;
|
use proxmox_api::nodes::node::tasks::upid;
|
||||||
use sea_orm::*;
|
use sea_orm::*;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use log::{info};
|
use log::{info, debug};
|
||||||
use proxmox_api::types::VmId;
|
use proxmox_api::types::VmId;
|
||||||
use crate::api::entity::{locks, nodes};
|
use crate::api::entity::{locks, nodes};
|
||||||
use crate::api::entity::nodes::{NodeParams, P5xError};
|
use crate::api::entity::nodes::{Model as NodeModel, NodeParams, P5xError};
|
||||||
use crate::api::entity::oplogs::Op;
|
use crate::api::entity::oplogs::Op;
|
||||||
use crate::api::services::Services;
|
use crate::api::services::Services;
|
||||||
|
|
||||||
|
|
||||||
|
/** WIP: Read nodes from the K8s API and register them w/ P5x based on metadata labels. */
|
||||||
|
pub async fn discover_nodes(
|
||||||
|
svc: &Services<'_>,
|
||||||
|
) -> Result<(), P5xError> {
|
||||||
|
debug!(target: "p5x", "Attempting to discover K8s cluster nodes...");
|
||||||
|
|
||||||
|
let client = Client::try_default().await.map_err(P5xError::KubeError)?;
|
||||||
|
let nodes: Api<Node> = Api::all(client);
|
||||||
|
|
||||||
|
let lp = ListParams::default();
|
||||||
|
let nodes = nodes.list(&lp).await.map_err(P5xError::KubeError)?;
|
||||||
|
for node in nodes {
|
||||||
|
let name = node.metadata.name.unwrap_or("(unknown)".to_string());
|
||||||
|
|
||||||
|
// Get the labels for the node
|
||||||
|
let labels = node.metadata.labels;
|
||||||
|
if labels.is_none() {
|
||||||
|
debug!(target: "p5x", "Skipping node {name}: could not load labels");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let labels = labels.unwrap();
|
||||||
|
|
||||||
|
// Check if it has the required pve_host and pve_id labels:
|
||||||
|
let pve_host = labels.get("p5x.garrettmills.dev/pve-host");
|
||||||
|
let pve_id = labels.get("p5x.garrettmills.dev/pve-id");
|
||||||
|
if pve_host.is_none() || pve_id.is_none() {
|
||||||
|
debug!(target: "p5x", "Skipping node {name}: missing required pve-host or pve-id label(s)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pve_host = pve_host.unwrap();
|
||||||
|
let pve_id: Result<i32, _> = pve_id.unwrap().parse();
|
||||||
|
if pve_id.is_err() {
|
||||||
|
debug!(target: "p5x", "Skipping node {name}: could not parse pve-id into i32");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let pve_id = pve_id.unwrap();
|
||||||
|
|
||||||
|
// Check if the node has been explicitly excluded from p5x management
|
||||||
|
let ignore = labels.get("p5x.garrettmills.dev/ignore");
|
||||||
|
if ignore.is_some() {
|
||||||
|
debug!(target: "p5x", "Skipping node {name}: found explicit ignore label");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the node is already registered
|
||||||
|
let existing = NodeModel::from_pve(svc, pve_host, pve_id).await?;
|
||||||
|
if existing.is_some() {
|
||||||
|
debug!(target: "p5x", "Skipping node {name}: already registered");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
info!(target: "p5x", "Discovered node {name} ({pve_host}:{pve_id}). Attempting to register it.");
|
||||||
|
// fixme: WIP
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Register an existing LXC container with P5x. */
|
/** Register an existing LXC container with P5x. */
|
||||||
pub async fn register_node(
|
pub async fn register_node(
|
||||||
svc: &Services<'_>,
|
svc: &Services<'_>,
|
||||||
|
@ -301,6 +301,15 @@ pub struct Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
|
pub async fn from_pve(svc: &Services<'_>, pve_host: &str, pve_id: i32) -> Result<Option<Model>, P5xError> {
|
||||||
|
Entity::find()
|
||||||
|
.filter(Column::PveHost.eq(pve_host))
|
||||||
|
.filter(Column::PveId.eq(pve_id))
|
||||||
|
.one(svc.db)
|
||||||
|
.await
|
||||||
|
.map_err(P5xError::DbErr)
|
||||||
|
}
|
||||||
|
|
||||||
/** Get the VM ID used by the Proxmox API library. */
|
/** Get the VM ID used by the Proxmox API library. */
|
||||||
pub fn vm_id(&self) -> VmId {
|
pub fn vm_id(&self) -> VmId {
|
||||||
VmId::new(i64::from(self.pve_id)).unwrap()
|
VmId::new(i64::from(self.pve_id)).unwrap()
|
||||||
|
Loading…
Reference in New Issue
Block a user