nzrd: don't store ci-metadata
This will be handled entirely in omyacid.
This commit is contained in:
parent
3d0ea1f2ef
commit
da51722c54
|
@ -1,3 +1,5 @@
|
||||||
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
use model::{CreateStatus, Instance, Subnet};
|
use model::{CreateStatus, Instance, Subnet};
|
||||||
|
|
||||||
pub mod args;
|
pub mod args;
|
||||||
|
@ -6,6 +8,15 @@ pub mod model;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
|
|
||||||
pub use hickory_proto;
|
pub use hickory_proto;
|
||||||
|
use net::mac::MacAddr;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub enum InstanceQuery {
|
||||||
|
Name(String),
|
||||||
|
MacAddr(MacAddr),
|
||||||
|
Ipv4Addr(Ipv4Addr),
|
||||||
|
}
|
||||||
|
|
||||||
#[tarpc::service]
|
#[tarpc::service]
|
||||||
pub trait Nazrin {
|
pub trait Nazrin {
|
||||||
|
@ -18,6 +29,8 @@ pub trait Nazrin {
|
||||||
/// This should involve deleting all related disks and clearing
|
/// This should involve deleting all related disks and clearing
|
||||||
/// the lease information from the subnet data, if any.
|
/// the lease information from the subnet data, if any.
|
||||||
async fn delete_instance(name: String) -> Result<(), String>;
|
async fn delete_instance(name: String) -> Result<(), String>;
|
||||||
|
/// Gets a single instance by the given InstanceQuery.
|
||||||
|
async fn find_instance(query: InstanceQuery) -> Result<Option<Instance>, String>;
|
||||||
/// Gets a list of existing instances.
|
/// Gets a list of existing instances.
|
||||||
async fn get_instances(with_status: bool) -> Result<Vec<Instance>, String>;
|
async fn get_instances(with_status: bool) -> Result<Vec<Instance>, String>;
|
||||||
/// Cleans up unusable entries in the database.
|
/// Cleans up unusable entries in the database.
|
||||||
|
@ -34,4 +47,20 @@ pub trait Nazrin {
|
||||||
async fn get_subnets() -> Result<Vec<Subnet>, String>;
|
async fn get_subnets() -> Result<Vec<Subnet>, String>;
|
||||||
/// Deletes an existing subnet.
|
/// Deletes an existing subnet.
|
||||||
async fn delete_subnet(interface: String) -> Result<(), String>;
|
async fn delete_subnet(interface: String) -> Result<(), String>;
|
||||||
|
// Gets the cloud-init user-data for the given instance.
|
||||||
|
async fn get_instance_userdata(id: i32) -> Result<Vec<u8>, String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new NazrinClient.
|
||||||
|
pub fn new_client(sock: tokio::net::UnixStream) -> NazrinClient {
|
||||||
|
use tarpc::tokio_serde::formats::Bincode;
|
||||||
|
use tarpc::tokio_util::codec::LengthDelimitedCodec;
|
||||||
|
|
||||||
|
let framed_io = LengthDelimitedCodec::builder()
|
||||||
|
.length_field_type::<u32>()
|
||||||
|
.new_framed(sock);
|
||||||
|
let transport = tarpc::serde_transport::new(framed_io, Bincode::default());
|
||||||
|
NazrinClient::new(Default::default(), transport).spawn()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use tarpc::context::current as default_ctx;
|
||||||
|
|
1
nzrd/migrations/2024081101_no_cimeta/down.sql
Normal file
1
nzrd/migrations/2024081101_no_cimeta/down.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE instances ADD COLUMN ci_metadata TEXT NOT NULL;
|
1
nzrd/migrations/2024081101_no_cimeta/up.sql
Normal file
1
nzrd/migrations/2024081101_no_cimeta/up.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE instances DROP COLUMN ci_metadata;
|
|
@ -1,149 +0,0 @@
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
|
|
||||||
use hickory_server::proto::rr::Name;
|
|
||||||
use serde::Serialize;
|
|
||||||
use serde_with::skip_serializing_none;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use nzr_api::net::{cidr::CidrV4, mac::MacAddr};
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub struct Metadata<'a> {
|
|
||||||
instance_id: &'a str,
|
|
||||||
local_hostname: &'a str,
|
|
||||||
public_keys: Option<Vec<&'a String>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Metadata<'a> {
|
|
||||||
pub fn new(instance_id: &'a str) -> Self {
|
|
||||||
Self {
|
|
||||||
instance_id,
|
|
||||||
local_hostname: instance_id,
|
|
||||||
public_keys: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ssh_pubkeys(mut self, pubkeys: &'a [String]) -> Self {
|
|
||||||
self.public_keys = Some(pubkeys.iter().filter(|i| !i.is_empty()).collect());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct NetworkMeta<'a> {
|
|
||||||
version: u32,
|
|
||||||
ethernets: HashMap<String, EtherNic<'a>>,
|
|
||||||
#[serde(skip)]
|
|
||||||
ethnum: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> NetworkMeta<'a> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
version: 2,
|
|
||||||
ethernets: HashMap::new(),
|
|
||||||
ethnum: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Define a NIC with a static address.
|
|
||||||
pub fn static_nic(
|
|
||||||
mut self,
|
|
||||||
match_data: EtherMatch<'a>,
|
|
||||||
cidr: &'a CidrV4,
|
|
||||||
gateway: &'a Ipv4Addr,
|
|
||||||
dns: DNSMeta<'a>,
|
|
||||||
) -> Self {
|
|
||||||
self.ethernets.insert(
|
|
||||||
format!("eth{}", self.ethnum),
|
|
||||||
EtherNic {
|
|
||||||
r#match: match_data,
|
|
||||||
addresses: Some(vec![cidr]),
|
|
||||||
gateway4: Some(gateway),
|
|
||||||
dhcp4: false,
|
|
||||||
nameservers: Some(dns),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
self.ethnum += 1;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn dhcp_nic(mut self, match_data: EtherMatch<'a>) -> Self {
|
|
||||||
self.ethernets.insert(
|
|
||||||
format!("eth{}", self.ethnum),
|
|
||||||
EtherNic {
|
|
||||||
r#match: match_data,
|
|
||||||
addresses: None,
|
|
||||||
gateway4: None,
|
|
||||||
dhcp4: true,
|
|
||||||
nameservers: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
self.ethnum += 1;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct Ethernets<'a> {
|
|
||||||
nics: Vec<EtherNic<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct EtherNic<'a> {
|
|
||||||
r#match: EtherMatch<'a>,
|
|
||||||
addresses: Option<Vec<&'a CidrV4>>,
|
|
||||||
gateway4: Option<&'a Ipv4Addr>,
|
|
||||||
dhcp4: bool,
|
|
||||||
nameservers: Option<DNSMeta<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[skip_serializing_none]
|
|
||||||
#[derive(Default, Debug, Serialize)]
|
|
||||||
pub struct EtherMatch<'a> {
|
|
||||||
name: Option<&'a str>,
|
|
||||||
macaddress: Option<&'a MacAddr>,
|
|
||||||
driver: Option<&'a str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> EtherMatch<'a> {
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn name(name: &'a str) -> Self {
|
|
||||||
Self {
|
|
||||||
name: Some(name),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mac_addr(addr: &'a MacAddr) -> Self {
|
|
||||||
Self {
|
|
||||||
macaddress: Some(addr),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn driver(driver: &'a str) -> Self {
|
|
||||||
Self {
|
|
||||||
driver: Some(driver),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct DNSMeta<'a> {
|
|
||||||
search: Vec<Name>,
|
|
||||||
addresses: &'a Vec<Ipv4Addr>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> DNSMeta<'a> {
|
|
||||||
pub fn with_addrs(search: Option<Vec<Name>>, addrs: &'a Vec<Ipv4Addr>) -> Self {
|
|
||||||
Self {
|
|
||||||
addresses: addrs,
|
|
||||||
search: search.unwrap_or_default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,6 @@ use nzr_virt::{datasize, dom, vol};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::cloud::Metadata;
|
|
||||||
use crate::ctrl::vm::Progress;
|
use crate::ctrl::vm::Progress;
|
||||||
use crate::ctx::Context;
|
use crate::ctx::Context;
|
||||||
use crate::model::{Instance, Subnet};
|
use crate::model::{Instance, Subnet};
|
||||||
|
@ -86,14 +85,7 @@ pub async fn new_instance(
|
||||||
};
|
};
|
||||||
|
|
||||||
// generate cloud-init data
|
// generate cloud-init data
|
||||||
let ci_meta = {
|
let db_inst = Instance::insert(&ctx, &args.name, &subnet, lease.clone(), None).await?;
|
||||||
let m = Metadata::new(&args.name).ssh_pubkeys(&args.ssh_keys);
|
|
||||||
serde_yaml::to_string(&m)
|
|
||||||
.map_err(|err| cmd_error!("Couldn't generate cloud-init metadata: {err}"))
|
|
||||||
}?;
|
|
||||||
|
|
||||||
let db_inst =
|
|
||||||
Instance::insert(&ctx, &args.name, &subnet, lease.clone(), ci_meta, None).await?;
|
|
||||||
|
|
||||||
progress!(prog_task, 30.0, "Creating instance images...");
|
progress!(prog_task, 30.0, "Creating instance images...");
|
||||||
// create primary volume from base image
|
// create primary volume from base image
|
||||||
|
|
|
@ -12,6 +12,10 @@ use crate::dns::ZoneData;
|
||||||
use nzr_api::config::Config;
|
use nzr_api::config::Config;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");
|
const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");
|
||||||
|
|
||||||
pub struct PoolRefs {
|
pub struct PoolRefs {
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
mod cloud;
|
|
||||||
mod cmd;
|
mod cmd;
|
||||||
mod ctrl;
|
mod ctrl;
|
||||||
mod ctx;
|
mod ctx;
|
||||||
mod dns;
|
mod dns;
|
||||||
mod model;
|
mod model;
|
||||||
mod rpc;
|
mod rpc;
|
||||||
#[cfg(test)]
|
|
||||||
mod test;
|
|
||||||
|
|
||||||
use hickory_server::ServerFuture;
|
use hickory_server::ServerFuture;
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use log::*;
|
use log::*;
|
||||||
use model::{Instance, Subnet};
|
use model::{Instance, Subnet};
|
||||||
use nzr_api::config;
|
use nzr_api::config;
|
||||||
use std::str::FromStr;
|
use std::{net::IpAddr, str::FromStr};
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::UdpSocket;
|
||||||
|
|
||||||
#[tokio::main(flavor = "multi_thread")]
|
#[tokio::main(flavor = "multi_thread")]
|
||||||
|
@ -62,7 +59,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
// DNS init
|
// DNS init
|
||||||
let mut dns_listener = ServerFuture::new(ctx.zones.catalog());
|
let mut dns_listener = ServerFuture::new(ctx.zones.catalog());
|
||||||
let dns_socket = UdpSocket::bind(ctx.config.dns.listen_addr.as_str()).await?;
|
let dns_socket = {
|
||||||
|
let dns_ip: IpAddr = ctx.config.dns.listen_addr.parse()?;
|
||||||
|
UdpSocket::bind((dns_ip, ctx.config.dns.port)).await?
|
||||||
|
};
|
||||||
dns_listener.register_socket(dns_socket);
|
dns_listener.register_socket(dns_socket);
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use std::{net::Ipv4Addr, str::FromStr};
|
use std::{net::Ipv4Addr, str::FromStr};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test;
|
||||||
pub mod tx;
|
pub mod tx;
|
||||||
|
|
||||||
use diesel::{associations::HasTable, prelude::*};
|
use diesel::{associations::HasTable, prelude::*};
|
||||||
|
@ -33,7 +35,6 @@ diesel::table! {
|
||||||
mac_addr -> Text,
|
mac_addr -> Text,
|
||||||
subnet_id -> Integer,
|
subnet_id -> Integer,
|
||||||
host_num -> Integer,
|
host_num -> Integer,
|
||||||
ci_metadata -> Text,
|
|
||||||
ci_userdata -> Nullable<Binary>,
|
ci_userdata -> Nullable<Binary>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +72,6 @@ pub struct Instance {
|
||||||
pub mac_addr: MacAddr,
|
pub mac_addr: MacAddr,
|
||||||
pub subnet_id: i32,
|
pub subnet_id: i32,
|
||||||
pub host_num: i32,
|
pub host_num: i32,
|
||||||
pub ci_metadata: String,
|
|
||||||
pub ci_userdata: Option<Vec<u8>>,
|
pub ci_userdata: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,17 @@ impl Instance {
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get(ctx: &Context, id: i32) -> Result<Option<Self>, ModelError> {
|
||||||
|
ctx.spawn_db(move |mut db| {
|
||||||
|
self::instances::table
|
||||||
|
.find(id)
|
||||||
|
.load::<Instance>(&mut db)
|
||||||
|
.map(|m| m.into_iter().next())
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
.map_err(ModelError::Db)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn all_in_subnet(ctx: &Context, net: &Subnet) -> Result<Vec<Self>, ModelError> {
|
pub async fn all_in_subnet(ctx: &Context, net: &Subnet) -> Result<Vec<Self>, ModelError> {
|
||||||
let subnet = net.clone();
|
let subnet = net.clone();
|
||||||
|
|
||||||
|
@ -122,6 +133,19 @@ impl Instance {
|
||||||
Ok(res.into_iter().next())
|
Ok(res.into_iter().next())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets an Instance model with the given MAC address.
|
||||||
|
pub async fn get_by_mac(ctx: &Context, addr: MacAddr) -> Result<Option<Self>, ModelError> {
|
||||||
|
ctx.spawn_db(move |mut db| {
|
||||||
|
use self::instances::dsl::{instances, mac_addr};
|
||||||
|
instances
|
||||||
|
.filter(mac_addr.eq(addr))
|
||||||
|
.select(Instance::as_select())
|
||||||
|
.load::<Instance>(&mut db)
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
.map_or_else(|e| Err(ModelError::Db(e)), |m| Ok(m.into_iter().next()))
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets an Instance model by the IPv4 address that has been assigned to it.
|
/// Gets an Instance model by the IPv4 address that has been assigned to it.
|
||||||
pub async fn get_by_ip4(ctx: &Context, ip_addr: Ipv4Addr) -> Result<Option<Self>, ModelError> {
|
pub async fn get_by_ip4(ctx: &Context, ip_addr: Ipv4Addr) -> Result<Option<Self>, ModelError> {
|
||||||
use self::instances::dsl::host_num;
|
use self::instances::dsl::host_num;
|
||||||
|
@ -157,7 +181,6 @@ impl Instance {
|
||||||
name: impl AsRef<str>,
|
name: impl AsRef<str>,
|
||||||
subnet: &Subnet,
|
subnet: &Subnet,
|
||||||
lease: nzr_api::model::Lease,
|
lease: nzr_api::model::Lease,
|
||||||
ci_meta: impl Into<String>,
|
|
||||||
ci_user: Option<Vec<u8>>,
|
ci_user: Option<Vec<u8>>,
|
||||||
) -> Result<Self, ModelError> {
|
) -> Result<Self, ModelError> {
|
||||||
// Get highest host addr + 1 for our addr
|
// Get highest host addr + 1 for our addr
|
||||||
|
@ -169,7 +192,6 @@ impl Instance {
|
||||||
|
|
||||||
let wanted_name = name.as_ref().to_owned();
|
let wanted_name = name.as_ref().to_owned();
|
||||||
let netid = subnet.id;
|
let netid = subnet.id;
|
||||||
let ci_meta = ci_meta.into();
|
|
||||||
|
|
||||||
if addr_num > subnet.end_host {
|
if addr_num > subnet.end_host {
|
||||||
Err(cidr::Error::HostBitsTooLarge)?;
|
Err(cidr::Error::HostBitsTooLarge)?;
|
||||||
|
@ -184,7 +206,6 @@ impl Instance {
|
||||||
mac_addr.eq(lease.mac_addr),
|
mac_addr.eq(lease.mac_addr),
|
||||||
subnet_id.eq(netid),
|
subnet_id.eq(netid),
|
||||||
host_num.eq(addr_num),
|
host_num.eq(addr_num),
|
||||||
ci_metadata.eq(ci_meta),
|
|
||||||
ci_userdata.eq(ci_user),
|
ci_userdata.eq(ci_user),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
14
nzrd/src/model/test.rs
Normal file
14
nzrd/src/model/test.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
use diesel::Connection;
|
||||||
|
use diesel_migrations::MigrationHarness;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn migrations() {
|
||||||
|
let mut sql = diesel::SqliteConnection::establish(":memory:").unwrap();
|
||||||
|
let pending = sql.pending_migrations(crate::ctx::MIGRATIONS).unwrap();
|
||||||
|
assert!(!pending.is_empty(), "No migrations found");
|
||||||
|
for migration in pending {
|
||||||
|
sql.run_migration(&migration).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
sql.revert_all_migrations(crate::ctx::MIGRATIONS).unwrap();
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
use futures::{future, StreamExt};
|
use futures::{future, StreamExt};
|
||||||
use nzr_api::{args, model, Nazrin};
|
use nzr_api::{args, model, InstanceQuery, Nazrin};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tarpc::server::{BaseChannel, Channel};
|
use tarpc::server::{BaseChannel, Channel};
|
||||||
use tarpc::tokio_serde::formats::Bincode;
|
use tarpc::tokio_serde::formats::Bincode;
|
||||||
|
@ -114,6 +114,27 @@ impl Nazrin for NzrServer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn find_instance(
|
||||||
|
self,
|
||||||
|
_: tarpc::context::Context,
|
||||||
|
query: nzr_api::InstanceQuery,
|
||||||
|
) -> Result<Option<model::Instance>, String> {
|
||||||
|
let res = match query {
|
||||||
|
InstanceQuery::Name(name) => Instance::get_by_name(&self.ctx, name).await,
|
||||||
|
InstanceQuery::MacAddr(addr) => Instance::get_by_mac(&self.ctx, addr).await,
|
||||||
|
InstanceQuery::Ipv4Addr(addr) => Instance::get_by_ip4(&self.ctx, addr).await,
|
||||||
|
}
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
if let Some(inst) = res {
|
||||||
|
inst.api_model(&self.ctx)
|
||||||
|
.await
|
||||||
|
.map_or_else(|e| Err(e.to_string()), |m| Ok(Some(m)))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_instances(
|
async fn get_instances(
|
||||||
self,
|
self,
|
||||||
_: tarpc::context::Context,
|
_: tarpc::context::Context,
|
||||||
|
@ -216,6 +237,21 @@ impl Nazrin for NzrServer {
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_instance_userdata(
|
||||||
|
self,
|
||||||
|
_: tarpc::context::Context,
|
||||||
|
id: i32,
|
||||||
|
) -> Result<Vec<u8>, String> {
|
||||||
|
let Some(db_model) = Instance::get(&self.ctx, id)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())?
|
||||||
|
else {
|
||||||
|
return Err("Instance doesn't exist".to_owned());
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(db_model.ci_userdata.unwrap_or_default())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
use std::{net::Ipv4Addr, str::FromStr};
|
|
||||||
|
|
||||||
use crate::cloud::*;
|
|
||||||
use nzr_api::net::{cidr::CidrV4, mac::MacAddr};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn cloud_metadata() {
|
|
||||||
let expected = r#"
|
|
||||||
instance-id: my-instance
|
|
||||||
local-hostname: my-instance
|
|
||||||
public-keys:
|
|
||||||
- ssh-key 123456 admin@laptop
|
|
||||||
"#
|
|
||||||
.trim_start();
|
|
||||||
let pubkeys = vec!["ssh-key 123456 admin@laptop".to_owned(), "".to_owned()];
|
|
||||||
let meta = Metadata::new("my-instance").ssh_pubkeys(&pubkeys);
|
|
||||||
|
|
||||||
let meta_xml = serde_yaml::to_string(&meta).unwrap();
|
|
||||||
assert_eq!(meta_xml, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn cloud_netdata() {
|
|
||||||
let expected = r#"
|
|
||||||
version: 2
|
|
||||||
ethernets:
|
|
||||||
eth0:
|
|
||||||
match:
|
|
||||||
macaddress: 02:15:42:0b:ee:01
|
|
||||||
addresses:
|
|
||||||
- 192.0.2.69/24
|
|
||||||
gateway4: 192.0.2.1
|
|
||||||
dhcp4: false
|
|
||||||
nameservers:
|
|
||||||
search: []
|
|
||||||
addresses:
|
|
||||||
- 192.0.2.1
|
|
||||||
"#
|
|
||||||
.trim_start();
|
|
||||||
let mac_addr = MacAddr::new(0x02, 0x15, 0x42, 0x0b, 0xee, 0x01);
|
|
||||||
let cidr = CidrV4::from_str("192.0.2.69/24").unwrap();
|
|
||||||
let gateway = Ipv4Addr::from_str("192.0.2.1").unwrap();
|
|
||||||
|
|
||||||
let dns = vec![gateway];
|
|
||||||
let netconfig = NetworkMeta::new().static_nic(
|
|
||||||
EtherMatch::mac_addr(&mac_addr),
|
|
||||||
&cidr,
|
|
||||||
&gateway,
|
|
||||||
DNSMeta::with_addrs(None, &dns),
|
|
||||||
);
|
|
||||||
|
|
||||||
let net_xml = serde_yaml::to_string(&netconfig).unwrap();
|
|
||||||
assert_eq!(net_xml, expected);
|
|
||||||
}
|
|
Loading…
Reference in a new issue