1mod address;
5mod netlink;
6mod subnet;
7
8use self::address::Address;
9use crate::vm::VM;
10
11use anyhow::Result;
12use async_trait::async_trait;
13use serde::{Deserialize, Serialize};
14use std::{collections::HashMap, path::PathBuf};
15
16pub trait Network<'a>: Send + Clone + Default + Serialize + Deserialize<'a> {
17 fn name(&self) -> String;
18 fn set_name(&self, name: String) -> Self;
19
20 fn index(&self) -> Option<u32>;
22 fn set_index(&self, index: u32) -> Self;
23}
24
25pub trait NetworkInterface: Send + Default {
26 fn name(&self) -> String;
27 fn addresses(&self) -> Vec<Address>;
28
29 fn peer_name(&self) -> Option<String>;
31 fn index(&self) -> Option<u32>;
32 fn id(&self) -> Option<u32>;
33}
34
35#[async_trait]
36pub trait NetworkManager<'a, I, N>
37where
38 Self: Clone,
39 I: NetworkInterface,
40 N: Network<'a>,
41{
42 async fn create_network(&self, name: &str) -> Result<N>;
43 async fn delete_network(&self, network: N) -> Result<()>;
44 async fn exists_network(&self, network: N) -> Result<bool>;
45 async fn create_interface(&self, network: N, id: u32) -> Result<I>;
46 async fn delete_interface(&self, interface: I) -> Result<()>;
47 async fn exists_interface(&self, interface: I) -> Result<bool>;
48 async fn bind(&self, network: N, interface: I) -> Result<()>;
49 async fn unbind(&self, interface: I) -> Result<()>;
50 async fn add_address(&self, interface: I, address: &Address) -> Result<()>;
51}
52
53pub trait VMInterface<N>
54where
55 Self: Default,
56 N: Network<'static>,
57{
58 fn add_to_network(&self, network: N) -> Result<()>;
59 fn remove_from_network(&self, network: N) -> Result<()>;
60 fn configure_addresses(&self, addresses: Vec<Address>) -> Result<()>;
61}
62
63#[derive(Debug, Clone, Default)]
64pub struct VMNetwork<V, I, N>
65where
66 N: Network<'static>,
67 V: VMInterface<N>,
68 I: NetworkInterface,
69{
70 network: N,
71 vms: HashMap<String, VM>,
72 vm: std::marker::PhantomData<V>,
73 interface: std::marker::PhantomData<I>,
74}
75
76impl<V, T, N> VMNetwork<V, T, N>
77where
78 N: Network<'static>,
79 V: VMInterface<N>,
80 T: NetworkInterface,
81{
82 pub fn add_vm(&mut self, vm: &VM) -> Result<()> {
83 self.vms.insert(vm.name(), vm.clone());
84 Ok(())
85 }
86
87 pub fn remove_vm(&mut self, vm: &VM) -> Result<()> {
88 self.vms.remove(&vm.name());
89 Ok(())
90 }
91
92 pub fn list(&self) -> Result<Vec<VM>> {
93 Ok(self.vms.values().map(Clone::clone).collect::<Vec<VM>>())
94 }
95
96 pub fn network(&self) -> N {
97 self.network.clone()
98 }
99}
100
101pub type NetworkMap = HashMap<String, Vec<String>>;
102pub type NetworkIndexMap = HashMap<String, u32>;
103
104#[derive(Debug, Clone, Default, Serialize, Deserialize)]
105pub struct NetworkConfig {
106 networks: NetworkMap,
107 indexes: NetworkIndexMap,
108}
109
110pub type VMNetworkMap<V, T, N> = HashMap<String, VMNetwork<V, T, N>>;
111
112pub struct NetworkList<V, M, T, N>
113where
114 N: Network<'static>,
115 V: VMInterface<N>,
116 M: NetworkManager<'static, T, N>,
117 T: NetworkInterface,
118{
119 networks: VMNetworkMap<V, T, N>,
120 manager: M,
121}
122
123impl<V, M, T, N> NetworkList<V, M, T, N>
124where
125 N: Network<'static>,
126 V: VMInterface<N>,
127 M: NetworkManager<'static, T, N>,
128 T: NetworkInterface,
129{
130 pub fn create(&self, _: String) -> Result<()> {
131 Ok(())
132 }
133
134 pub fn teardown(&self, _: String) -> Result<()> {
135 Ok(())
136 }
137
138 pub fn save(&self, filename: PathBuf) -> Result<()> {
139 let mut config = NetworkConfig::default();
140
141 for (name, network) in &self.networks {
142 config.networks.insert(
143 name.to_string(),
144 network
145 .list()?
146 .iter()
147 .map(|n| n.name())
148 .collect::<Vec<String>>(),
149 );
150
151 config.indexes.insert(
152 network.network().name(),
153 network.network().index().unwrap_or_default(),
154 );
155 }
156
157 Ok(std::fs::write(filename, toml::to_string(&config)?)?)
158 }
159
160 pub fn load(manager: M, filename: PathBuf) -> Result<Self> {
161 let map: NetworkConfig = toml::from_str(&std::fs::read_to_string(filename)?)?;
162 let mut networks = VMNetworkMap::default();
163
164 for (key, vms) in map.networks {
165 let mut tmp: HashMap<String, VM> = HashMap::default();
166 for vm in vms {
167 tmp.insert(vm.clone(), vm.clone().into());
168 }
169
170 networks.insert(
171 key.to_string(),
172 VMNetwork {
173 network: N::default()
174 .set_name(key.to_string())
175 .set_index(map.indexes.get(&key).map_or_else(|| 0, |x| *x)),
176 vms: tmp,
177 ..Default::default()
178 },
179 );
180 }
181
182 Ok(Self { networks, manager })
183 }
184
185 pub fn manager(&self) -> M {
186 self.manager.clone()
187 }
188}
189
190impl<V, M, T, N> std::ops::Deref for NetworkList<V, M, T, N>
191where
192 N: Network<'static>,
193 V: VMInterface<N>,
194 M: NetworkManager<'static, T, N>,
195 T: NetworkInterface,
196{
197 type Target = HashMap<String, VMNetwork<V, T, N>>;
198
199 fn deref(&self) -> &Self::Target {
200 &self.networks
201 }
202}
203
204impl<V, M, T, N> std::ops::DerefMut for NetworkList<V, M, T, N>
205where
206 N: Network<'static>,
207 V: VMInterface<N>,
208 M: NetworkManager<'static, T, N>,
209 T: NetworkInterface,
210{
211 fn deref_mut(&mut self) -> &mut Self::Target {
212 &mut self.networks
213 }
214}