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 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::tasks::upid;
|
||||
use sea_orm::*;
|
||||
use tokio::time::sleep;
|
||||
use log::{info};
|
||||
use log::{info, debug};
|
||||
use proxmox_api::types::VmId;
|
||||
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::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. */
|
||||
pub async fn register_node(
|
||||
svc: &Services<'_>,
|
||||
|
@ -301,6 +301,15 @@ pub struct 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. */
|
||||
pub fn vm_id(&self) -> VmId {
|
||||
VmId::new(i64::from(self.pve_id)).unwrap()
|
||||
|
Loading…
Reference in New Issue
Block a user