use crate::{
component::{ClusterContext, Component, Phase},
config::Config,
kubeconfig::KubeConfig,
network::Network,
node::Node,
process::{Process, ProcessState, Stoppable},
write_if_changed,
};
use anyhow::Result;
use std::fs::create_dir_all;
pub struct ProxyComponent;
impl Component for ProxyComponent {
fn name(&self) -> &str {
"Proxy"
}
fn phase(&self) -> Phase {
Phase::Controller
}
fn start(&self, ctx: &ClusterContext<'_>) -> ProcessState {
Proxy::start(ctx.config, ctx.network, ctx.kubeconfig)
}
}
pub struct Proxy {
process: Process,
}
impl Proxy {
pub fn start(config: &Config, network: &Network, kubeconfig: &KubeConfig) -> ProcessState {
let dir = config.root().join("proxy");
create_dir_all(&dir)?;
let yml = format!(
include_str!("assets/proxy.yml"),
kubeconfig.proxy().display(),
network.cluster_cidr(),
);
let cfg = dir.join("config.yml");
write_if_changed(&cfg, &yml)?;
let mut process = Process::start(
&dir,
"Proxy",
"kube-proxy",
&[
&format!("--config={}", cfg.display()),
&format!(
"--hostname-override={}",
if config.multi_node() {
Node::name(config, network, 0)
} else {
network.hostname().into()
}
),
],
)?;
process.wait_ready("Caches are synced")?;
Ok(Box::new(Proxy { process }))
}
}
impl Stoppable for Proxy {
fn stop(&mut self) -> Result<()> {
self.process.stop()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn config_template_renders() {
let yml = format!(
include_str!("assets/proxy.yml"),
"/tmp/proxy.kubeconfig", "10.10.0.0/18",
);
assert!(yml.contains("kind: KubeProxyConfiguration"));
assert!(yml.contains("kubeconfig: \"/tmp/proxy.kubeconfig\""));
assert!(yml.contains("clusterCIDR: \"10.10.0.0/18\""));
assert!(yml.contains("mode: \"iptables\""));
}
#[test]
fn component_metadata() {
let c = ProxyComponent;
assert_eq!(c.name(), "Proxy");
assert_eq!(c.phase(), Phase::Controller);
}
}