use std::fmt;
use colored::*;
#[derive(Debug)]
pub enum NetInspectError {
KubernetesConnection(String),
PermissionDenied(String),
Configuration(String),
NetworkConnectivity(String),
InvalidInput(String),
ResourceNotFound(String),
Timeout(String),
Runtime(String),
}
impl fmt::Display for NetInspectError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NetInspectError::KubernetesConnection(msg) => {
write!(f, "{} {}", "Kubernetes Connection Error:".red().bold(), msg)
}
NetInspectError::PermissionDenied(msg) => {
write!(f, "{} {}", "Permission Denied:".yellow().bold(), msg)
}
NetInspectError::Configuration(msg) => {
write!(f, "{} {}", "Configuration Error:".purple().bold(), msg)
}
NetInspectError::NetworkConnectivity(msg) => {
write!(f, "{} {}", "Network Error:".red().bold(), msg)
}
NetInspectError::InvalidInput(msg) => {
write!(f, "{} {}", "Invalid Input:".yellow().bold(), msg)
}
NetInspectError::ResourceNotFound(msg) => {
write!(f, "{} {}", "Resource Not Found:".blue().bold(), msg)
}
NetInspectError::Timeout(msg) => {
write!(f, "{} {}", "Timeout:".red().bold(), msg)
}
NetInspectError::Runtime(msg) => {
write!(f, "{} {}", "Runtime Error:".red().bold(), msg)
}
}
}
}
impl std::error::Error for NetInspectError {}
impl NetInspectError {
pub fn exit_code(&self) -> i32 {
match self {
NetInspectError::KubernetesConnection(_) => 3,
NetInspectError::PermissionDenied(_) => 5,
NetInspectError::Configuration(_) => 2,
NetInspectError::NetworkConnectivity(_) => 4,
NetInspectError::InvalidInput(_) => 2,
NetInspectError::ResourceNotFound(_) => 4,
NetInspectError::Timeout(_) => 4,
NetInspectError::Runtime(_) => 1,
}
}
pub fn detailed_message(&self) -> String {
match self {
NetInspectError::KubernetesConnection(msg) => {
format!(
"{}\n{} Ensure kubeconfig is valid and cluster is accessible\n{} Check: kubectl cluster-info",
msg,
"💡 Troubleshooting:".cyan().bold(),
" •".blue()
)
}
NetInspectError::PermissionDenied(msg) => {
format!(
"{}\n{} Check RBAC permissions for your service account\n{} Required: pods/get, nodes/list",
msg,
"💡 Troubleshooting:".cyan().bold(),
" •".blue()
)
}
NetInspectError::Configuration(msg) => {
format!(
"{}\n{} Verify kubeconfig file and context\n{} Check: kubectl config current-context",
msg,
"💡 Troubleshooting:".cyan().bold(),
" •".blue()
)
}
NetInspectError::NetworkConnectivity(msg) => {
format!(
"{}\n{} Network connectivity issue detected\n{} Pod may not be running or port may be closed",
msg,
"💡 Troubleshooting:".cyan().bold(),
" •".blue()
)
}
NetInspectError::InvalidInput(msg) => {
format!(
"{}\n{} Check command syntax and arguments\n{} Use --help for usage information",
msg,
"💡 Troubleshooting:".cyan().bold(),
" •".blue()
)
}
NetInspectError::ResourceNotFound(msg) => {
format!(
"{}\n{} Verify resource exists in the specified namespace\n{} Check: kubectl get pods -n <namespace>",
msg,
"💡 Troubleshooting:".cyan().bold(),
" •".blue()
)
}
NetInspectError::Timeout(msg) => {
format!(
"{}\n{} Operation timed out - cluster may be slow or unreachable\n{} Try again or use kubectl directly to test connectivity",
msg,
"💡 Troubleshooting:".cyan().bold(),
" •".blue()
)
}
NetInspectError::Runtime(msg) => {
format!(
"{}\n{} Unexpected error occurred\n{} Please check logs and try again",
msg,
"💡 Troubleshooting:".cyan().bold(),
" •".blue()
)
}
}
}
}
impl From<kube::Error> for NetInspectError {
fn from(err: kube::Error) -> Self {
match err {
kube::Error::Api(api_err) => {
match api_err.code {
401 | 403 => NetInspectError::PermissionDenied(
format!("Kubernetes API access denied: {}", api_err.message)
),
404 => NetInspectError::ResourceNotFound(
format!("Resource not found: {}", api_err.message)
),
_ => NetInspectError::KubernetesConnection(
format!("Kubernetes API error: {}", api_err.message)
),
}
}
kube::Error::HttpError(http_err) => {
NetInspectError::KubernetesConnection(
format!("HTTP error connecting to Kubernetes: {}", http_err)
)
}
kube::Error::Auth(auth_err) => {
NetInspectError::PermissionDenied(
format!("Authentication failed: {}", auth_err)
)
}
kube::Error::Discovery(discovery_err) => {
NetInspectError::KubernetesConnection(
format!("Service discovery failed: {}", discovery_err)
)
}
_ => NetInspectError::KubernetesConnection(
format!("Kubernetes client error: {}", err)
),
}
}
}
impl From<reqwest::Error> for NetInspectError {
fn from(err: reqwest::Error) -> Self {
if err.is_timeout() {
NetInspectError::Timeout(
"HTTP request timed out - pod may be unreachable".to_string()
)
} else if err.is_connect() {
NetInspectError::NetworkConnectivity(
format!("Failed to connect to pod: {}", err)
)
} else {
NetInspectError::NetworkConnectivity(
format!("HTTP request failed: {}", err)
)
}
}
}
impl From<anyhow::Error> for NetInspectError {
fn from(err: anyhow::Error) -> Self {
NetInspectError::Runtime(err.to_string())
}
}
pub type NetInspectResult<T> = Result<T, NetInspectError>;