1use std::net::Ipv4Addr;
2
3use serde::{Deserialize, Serialize};
4
5mod utils;
6pub use utils::{Error, XnodeDeployerError};
7
8#[cfg(feature = "hivelocity")]
9pub mod hivelocity;
10
11#[derive(Serialize, Deserialize, Debug)]
12pub struct DeployInput {
13 pub xnode_owner: Option<String>,
14 pub domain: Option<String>,
15 pub acme_email: Option<String>,
16 pub user_passwd: Option<String>,
17 pub encrypted: Option<String>,
18 pub initial_config: Option<String>,
19}
20
21pub enum OptionalSupport<T> {
22 NotSupported,
23 Supported(T),
24}
25
26pub trait XnodeDeployer: Send + Sync {
27 type ProviderOutput;
28
29 fn deploy(
31 &self,
32 input: DeployInput,
33 ) -> impl Future<Output = Result<Self::ProviderOutput, Error>> + Send;
34
35 fn undeploy(&self, xnode: Self::ProviderOutput) -> impl Future<Output = Option<Error>> + Send;
37
38 fn ipv4(
40 &self,
41 xnode: Self::ProviderOutput,
42 ) -> impl Future<Output = Result<OptionalSupport<Option<Ipv4Addr>>, Error>> + Send;
43}
44
45impl DeployInput {
46 pub fn cloud_init(&self) -> String {
47 let mut env = vec![];
48 for (name, content) in [
49 ("XNODE_OWNER", &self.xnode_owner),
50 ("DOMAIN", &self.domain),
51 ("ACME_EMAIL", &self.acme_email),
52 ("USER_PASSWD", &self.user_passwd),
53 ("ENCRYPTED", &self.encrypted),
54 ("INITIAL_CONFIG", &self.initial_config),
55 ] {
56 if let Some(content) = content {
57 env.push(format!("export {name}=\"{content}\" && "));
58 }
59 }
60
61 let env = env.join("");
62 format!(
63 "#cloud-config\nruncmd:\n - {env} curl https://raw.githubusercontent.com/Openmesh-Network/xnode-manager/main/os/install.sh | bash 2>&1 | tee /tmp/xnodeos.log"
64 )
65 }
66}