mirror of
https://github.com/mayanayza/netvisor.git
synced 2025-12-10 08:24:08 -06:00
docker discovery working, updated rust to 1.90
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
use crate::{daemon::{discovery::handlers as discovery_handlers, runtime::{types::DaemonAppState}}, server::shared::types::api::{ApiResponse, ApiResult}};
|
||||
use crate::{
|
||||
daemon::{discovery::handlers as discovery_handlers, runtime::types::DaemonAppState},
|
||||
server::shared::types::api::{ApiResponse, ApiResult},
|
||||
};
|
||||
use axum::{routing::get, Json, Router};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -14,4 +17,4 @@ async fn get_health() -> ApiResult<Json<ApiResponse<String>>> {
|
||||
Ok(Json(ApiResponse::success(
|
||||
"Netvisor Daemon Running".to_string(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,10 +90,8 @@ impl ServiceDefinition for Box<dyn ServiceDefinition> {
|
||||
|
||||
impl ServiceDefinitionExt for Box<dyn ServiceDefinition> {
|
||||
fn is_infra_service(&self) -> bool {
|
||||
self.is_dns_resolver()
|
||||
|| self.is_gateway()
|
||||
|| self.is_reverse_proxy()
|
||||
// || self.is_docker_daemon()
|
||||
self.is_dns_resolver() || self.is_gateway() || self.is_reverse_proxy()
|
||||
// || self.is_docker_daemon()
|
||||
}
|
||||
|
||||
fn discovery_ports(&self) -> Vec<PortBase> {
|
||||
|
||||
@@ -9,9 +9,9 @@ use axum::{
|
||||
routing::{delete, get, post, put},
|
||||
Router,
|
||||
};
|
||||
use validator::Validate;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
use validator::Validate;
|
||||
|
||||
pub fn create_router() -> Router<Arc<AppState>> {
|
||||
Router::new()
|
||||
@@ -25,7 +25,6 @@ async fn create_subnet(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Json(request): Json<Subnet>,
|
||||
) -> ApiResult<Json<ApiResponse<Subnet>>> {
|
||||
|
||||
tracing::info!("Received subnet creation request: {:?}", request);
|
||||
|
||||
if let Err(validation_errors) = request.base.validate() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::server::{
|
||||
config::AppState,
|
||||
shared::types::api::{ApiResponse, ApiResult}, topology::types::api::TopologyRequestOptions,
|
||||
shared::types::api::{ApiResponse, ApiResult},
|
||||
topology::types::api::TopologyRequestOptions,
|
||||
};
|
||||
use axum::{extract::State, response::Json, routing::post, Router};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -66,7 +66,7 @@ impl EdgeBuilder {
|
||||
source_is_infra && source_needs_infra_constraint,
|
||||
target_is_infra && target_needs_infra_constraint,
|
||||
);
|
||||
|
||||
|
||||
// Don't label edges if they are within a subnet (avoid clutter) or between subnets that have been
|
||||
// consolidated (ie docker bridge subnets)
|
||||
let label = if source_subnet == target_subnet
|
||||
|
||||
@@ -40,7 +40,10 @@ impl TopologyService {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn build_graph(&self, options: TopologyRequestOptions) -> Result<Graph<Node, Edge>, Error> {
|
||||
pub async fn build_graph(
|
||||
&self,
|
||||
options: TopologyRequestOptions,
|
||||
) -> Result<Graph<Node, Edge>, Error> {
|
||||
// Fetch all data
|
||||
let hosts = self.host_service.get_all_hosts().await?;
|
||||
let subnets = self.subnet_service.get_all_subnets().await?;
|
||||
@@ -57,8 +60,11 @@ impl TopologyService {
|
||||
|
||||
// Create nodes with layout
|
||||
let mut layout_planner = SubnetLayoutPlanner::new();
|
||||
let (subnet_layouts, child_nodes) =
|
||||
layout_planner.create_subnet_child_nodes(&ctx, &all_edges, options.group_docker_bridges_by_host);
|
||||
let (subnet_layouts, child_nodes) = layout_planner.create_subnet_child_nodes(
|
||||
&ctx,
|
||||
&all_edges,
|
||||
options.group_docker_bridges_by_host,
|
||||
);
|
||||
|
||||
// Get relocation info from layout planner
|
||||
let relocation_map = layout_planner.get_handle_relocation_map();
|
||||
|
||||
@@ -59,9 +59,10 @@ impl SubnetLayoutPlanner {
|
||||
&mut self,
|
||||
ctx: &TopologyContext,
|
||||
all_edges: &[Edge],
|
||||
group_docker_bridges_by_host: bool
|
||||
group_docker_bridges_by_host: bool,
|
||||
) -> (HashMap<Uuid, SubnetLayout>, Vec<Node>) {
|
||||
let children_by_subnet = self.group_children_by_subnet(ctx, all_edges, group_docker_bridges_by_host);
|
||||
let children_by_subnet =
|
||||
self.group_children_by_subnet(ctx, all_edges, group_docker_bridges_by_host);
|
||||
let mut child_nodes = Vec::new();
|
||||
|
||||
let subnet_sizes: HashMap<Uuid, SubnetLayout> = children_by_subnet
|
||||
@@ -83,7 +84,7 @@ impl SubnetLayoutPlanner {
|
||||
&mut self,
|
||||
ctx: &TopologyContext,
|
||||
all_edges: &[Edge],
|
||||
group_docker_bridges_by_host: bool
|
||||
group_docker_bridges_by_host: bool,
|
||||
) -> HashMap<Uuid, Vec<SubnetChild>> {
|
||||
let mut children_by_subnet: HashMap<Uuid, Vec<SubnetChild>> = HashMap::new();
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ impl SubnetPositioner {
|
||||
|
||||
fn calculate_median(values: &mut [f64]) -> f64 {
|
||||
values.sort_by(|a, b| a.partial_cmp(b).unwrap());
|
||||
if values.len() % 2 == 0 {
|
||||
if values.len().is_multiple_of(2) {
|
||||
let mid = values.len() / 2;
|
||||
(values[mid - 1] + values[mid]) / 2.0
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Default)]
|
||||
pub struct TopologyRequestOptions {
|
||||
pub group_docker_bridges_by_host: bool
|
||||
}
|
||||
pub group_docker_bridges_by_host: bool,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
pub mod api;
|
||||
pub mod base;
|
||||
pub mod edges;
|
||||
pub mod nodes;
|
||||
pub mod api;
|
||||
@@ -10,7 +10,7 @@ use netvisor::server::shared::types::metadata::HasId;
|
||||
use uuid::Uuid;
|
||||
|
||||
struct ContainerManager {
|
||||
container_process: Option<Child>
|
||||
container_process: Option<Child>,
|
||||
}
|
||||
|
||||
/// Container lifecycle management
|
||||
@@ -23,16 +23,18 @@ impl ContainerManager {
|
||||
|
||||
fn start(&mut self) -> Result<(), String> {
|
||||
println!("Starting containers with docker compose...");
|
||||
|
||||
|
||||
// Start containers and wait for them to be healthy
|
||||
// Don't use -d, let docker compose wait for health before returning
|
||||
let status = Command::new("docker")
|
||||
.args([
|
||||
"compose",
|
||||
"-f", "docker-compose.yml",
|
||||
"-f", "docker-compose.dev.yml",
|
||||
"-f",
|
||||
"docker-compose.yml",
|
||||
"-f",
|
||||
"docker-compose.dev.yml",
|
||||
"up",
|
||||
"--wait", // Wait for services to be healthy before returning
|
||||
"--wait", // Wait for services to be healthy before returning
|
||||
])
|
||||
.current_dir("..")
|
||||
.status()
|
||||
@@ -45,7 +47,7 @@ impl ContainerManager {
|
||||
println!("✅ Server and daemon are healthy!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn cleanup(&mut self) {
|
||||
println!("\nCleaning up containers...");
|
||||
|
||||
@@ -190,10 +192,7 @@ async fn check_daemon_registered(client: &reqwest::Client) -> Result<Daemon, Str
|
||||
}
|
||||
|
||||
/// Start discovery and wait for it to complete
|
||||
async fn run_discovery_and_wait(
|
||||
client: &reqwest::Client,
|
||||
daemon_id: Uuid,
|
||||
) -> Result<(), String> {
|
||||
async fn run_discovery_and_wait(client: &reqwest::Client, daemon_id: Uuid) -> Result<(), String> {
|
||||
// Initiate discovery
|
||||
println!("\n=== Starting Discovery ===");
|
||||
let response = client
|
||||
@@ -212,8 +211,7 @@ async fn run_discovery_and_wait(
|
||||
.unwrap_or_else(|_| "Could not read body".to_string());
|
||||
return Err(format!(
|
||||
"Discovery initiation failed with status {}: {}",
|
||||
status,
|
||||
body
|
||||
status, body
|
||||
));
|
||||
}
|
||||
|
||||
@@ -293,7 +291,7 @@ async fn run_discovery_and_wait(
|
||||
/// Check for Home Assistant service
|
||||
async fn check_for_home_assistant_service(client: &reqwest::Client) -> Result<Service, String> {
|
||||
println!("\n=== Checking for Home Assistant Service ===");
|
||||
|
||||
|
||||
let services = retry_api_request("fetch services", 10, 2, || {
|
||||
let client = client.clone();
|
||||
async move {
|
||||
@@ -339,7 +337,8 @@ async fn check_for_home_assistant_service(client: &reqwest::Client) -> Result<Se
|
||||
.await?;
|
||||
|
||||
// Find Home Assistant service
|
||||
let home_assistant_service = services.clone()
|
||||
let home_assistant_service = services
|
||||
.clone()
|
||||
.into_iter()
|
||||
.find(|s| s.base.service_definition.id() == HomeAssistant.id())
|
||||
.ok_or_else(|| {
|
||||
@@ -395,4 +394,4 @@ async fn test_container_daemon_server_integration() {
|
||||
println!(" ✓ Home Assistant service discovered");
|
||||
|
||||
// Cleanup happens automatically via Drop trait
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import { type Node, type Edge } from '@xyflow/svelte';
|
||||
import '@xyflow/svelte/dist/style.css';
|
||||
import { getDistanceToNode, getNextHandle, topology } from '../store';
|
||||
import { edgeTypes, entities } from '$lib/shared/stores/metadata';
|
||||
import { edgeTypes } from '$lib/shared/stores/metadata';
|
||||
import { pushError } from '$lib/shared/stores/feedback';
|
||||
|
||||
// Import custom node components
|
||||
@@ -77,7 +77,6 @@
|
||||
const edgeLabel = edgeTypes.getName(edgeType);
|
||||
let edgeMetadata = edgeTypes.getMetadata(edgeType);
|
||||
let edgeColorHelper = edgeTypes.getColorHelper(edgeType);
|
||||
let hostColorHelper = entities.getColorHelper('Host');
|
||||
|
||||
const dashArray = edgeMetadata.is_dashed ? 'stroke-dasharray: 5,5;' : '';
|
||||
const markerStart = !edgeMetadata.has_start_marker
|
||||
@@ -93,12 +92,11 @@
|
||||
color: edgeColorHelper.rgb
|
||||
} as EdgeMarkerType);
|
||||
|
||||
const labelStyle =
|
||||
edgeMetadata.style_label_like_nodes
|
||||
? `background: ${twColorToRgba(edgeColorHelper.bg)};
|
||||
const labelStyle = edgeMetadata.style_label_like_nodes
|
||||
? `background: ${twColorToRgba(edgeColorHelper.bg)};
|
||||
color: ${edgeColorHelper.rgb};
|
||||
border: 2px solid ${twColorToRgba(edgeColorHelper.border)};`
|
||||
: 'background: #374151; color: #f3f4f6; border: 1px solid #4b5563;';
|
||||
: 'background: #374151; color: #f3f4f6; border: 1px solid #4b5563;';
|
||||
|
||||
const data: CustomEdgeData = {
|
||||
edgeType: edgeType,
|
||||
|
||||
@@ -55,5 +55,5 @@ export interface CustomNodeData extends Record<string, unknown> {
|
||||
}
|
||||
|
||||
export interface TopologyRequestOptions {
|
||||
group_docker_bridges_by_host: boolean
|
||||
}
|
||||
group_docker_bridges_by_host: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user