add more tables
This commit is contained in:
parent
f9623edd38
commit
1dd72fd011
@ -1,4 +1,5 @@
|
||||
insert ignore into vm_host(id,kind,name,ip,cpu,memory,enabled,api_token) values(1, 0, "lab", "https://185.18.221.8:8006", 4, 4096*1024, 1, "root@pam!tester=c82f8a57-f876-4ca4-8610-c086d8d9d51c");
|
||||
insert ignore into vm_host_disk(id,host_id,name,size,kind,interface,enabled) values(1,1,"local-lvm",1000*1000*1000*100, 0, 0, 1);
|
||||
insert ignore into vm_host_disk(id,host_id,name,size,kind,interface,enabled) values(1,1,"local-lvm",1000*1000*1000*1000, 0, 0, 1);
|
||||
insert ignore into vm_os_image(id,name,enabled) values(1,"Ubuntu 24.04",1);
|
||||
insert ignore into ip_range(id,cidr,enabled) values(1,"185.18.221.80/28",1);
|
||||
insert ignore into ip_range(id,cidr,enabled) values(1,"185.18.221.80/28",1);
|
||||
insert ignore into vm_template(id,name,enabled,cpu,memory,disk_size,disk_id) values(1,"Basic",1,2,2048,1000*1000*1000*80,1);
|
@ -4,27 +4,43 @@ create table users
|
||||
pubkey binary(32) not null,
|
||||
created timestamp default current_timestamp
|
||||
);
|
||||
create unique index ix_user_pubkey on users (pubkey);
|
||||
create table vm_host
|
||||
create table user_ssh_key
|
||||
(
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
kind smallint unsigned not null,
|
||||
name varchar(100) not null,
|
||||
ip varchar(250) not null,
|
||||
name varchar(100) not null,
|
||||
user_id integer unsigned not null,
|
||||
created timestamp default current_timestamp,
|
||||
key varchar(2048) not null,
|
||||
|
||||
constraint fk_ssh_key_user_id foreign key (user_id) references users (id)
|
||||
);
|
||||
create unique index ix_user_pubkey on users (pubkey);
|
||||
create table vm_host_region
|
||||
(
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
name varchar(100) not null,
|
||||
enabled bit(1) not null,
|
||||
);
|
||||
create table vm_host
|
||||
(
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
kind smallint unsigned not null,
|
||||
name varchar(100) not null,
|
||||
ip varchar(250) not null,
|
||||
cpu bigint unsigned not null,
|
||||
memory bigint unsigned not null,
|
||||
enabled bit(1) not null,
|
||||
api_token varchar(200) not null
|
||||
enabled bit(1) not null,
|
||||
api_token varchar(200) not null
|
||||
);
|
||||
create table vm_host_disk
|
||||
(
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
host_id integer unsigned not null,
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
host_id integer unsigned not null,
|
||||
name varchar(50) not null,
|
||||
size bigint unsigned not null,
|
||||
kind smallint unsigned not null,
|
||||
interface smallint unsigned not null,
|
||||
enabled bit(1) not null,
|
||||
enabled bit(1) not null,
|
||||
|
||||
constraint fk_vm_host_disk foreign key (host_id) references vm_host (id)
|
||||
);
|
||||
@ -32,51 +48,81 @@ create table vm_os_image
|
||||
(
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
name varchar(200) not null,
|
||||
enabled bit(1) not null
|
||||
enabled bit(1) not null
|
||||
);
|
||||
create table ip_range
|
||||
(
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
cidr varchar(200) not null,
|
||||
enabled bit(1) not null
|
||||
enabled bit(1) not null
|
||||
);
|
||||
create table vm
|
||||
create table vm_cost_plan
|
||||
(
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
name varchar(200) not null,
|
||||
enabled bit(1) not null,
|
||||
created timestamp default current_timestamp,
|
||||
expires timestamp,
|
||||
amount integer unsigned not null,
|
||||
currency varchar(4) not null,
|
||||
interval integer unsigned not null,
|
||||
interval_type smallint unsigned not null,
|
||||
);
|
||||
create table vm_template
|
||||
(
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
host_id integer unsigned not null,
|
||||
user_id integer unsigned not null,
|
||||
image_id integer unsigned not null,
|
||||
name varchar(200) not null,
|
||||
enabled bit(1) not null,
|
||||
created timestamp default current_timestamp,
|
||||
expires timestamp not null,
|
||||
expires timestamp,
|
||||
cpu smallint unsigned not null,
|
||||
memory bigint unsigned not null,
|
||||
disk_size bigint unsigned not null,
|
||||
disk_id integer unsigned not null,
|
||||
disk_id integer unsigned not null,
|
||||
|
||||
constraint fk_vm_host foreign key (host_id) references vm_host (id),
|
||||
constraint fk_vm_user foreign key (user_id) references users (id),
|
||||
constraint fk_vm_image foreign key (image_id) references vm_os_image (id),
|
||||
constraint fk_vm_host_disk_id foreign key (disk_id) references vm_host_disk (id)
|
||||
constraint fk_vm_host_disk_id foreign key (disk_id) references vm_host_disk (id)
|
||||
);
|
||||
create table vm
|
||||
(
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
host_id integer unsigned not null,
|
||||
user_id integer unsigned not null,
|
||||
image_id integer unsigned not null,
|
||||
template_id integer unsigned not null,
|
||||
ssh_key_id integer unsigned not null,
|
||||
created timestamp default current_timestamp,
|
||||
expires timestamp not null,
|
||||
cpu smallint unsigned not null,
|
||||
memory bigint unsigned not null,
|
||||
disk_size bigint unsigned not null,
|
||||
disk_id integer unsigned not null,
|
||||
|
||||
constraint fk_vm_host foreign key (host_id) references vm_host (id),
|
||||
constraint fk_vm_user foreign key (user_id) references users (id),
|
||||
constraint fk_vm_image foreign key (image_id) references vm_os_image (id),
|
||||
constraint fk_vm_host_disk_id foreign key (disk_id) references vm_host_disk (id),
|
||||
constraint fk_vm_template_id foreign key (template_id) references vm_template (id),
|
||||
constraint fk_vm_ssh_key_id foreign key (ssh_key_id) references user_ssh_key (id)
|
||||
);
|
||||
create table vm_ip_assignment
|
||||
(
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
vm_id integer unsigned not null,
|
||||
ip_range_id integer unsigned not null,
|
||||
id integer unsigned not null auto_increment primary key,
|
||||
vm_id integer unsigned not null,
|
||||
ip_range_id integer unsigned not null,
|
||||
|
||||
constraint fk_vm_ip_assignment_vm foreign key (vm_id) references vm (id),
|
||||
constraint fk_vm_ip_range foreign key (ip_range_id) references ip_range (id)
|
||||
constraint fk_vm_ip_assignment_vm foreign key (vm_id) references vm (id),
|
||||
constraint fk_vm_ip_range foreign key (ip_range_id) references ip_range (id)
|
||||
);
|
||||
create table vm_payment
|
||||
(
|
||||
id binary(32) not null,
|
||||
vm_id integer unsigned not null,
|
||||
created timestamp default current_timestamp,
|
||||
expires timestamp not null,
|
||||
amount bigint unsigned not null,
|
||||
invoice varchar(2048) not null,
|
||||
time_value integer unsigned not null,
|
||||
is_paid bit(1) not null,
|
||||
id binary(32) not null,
|
||||
vm_id integer unsigned not null,
|
||||
created timestamp default current_timestamp,
|
||||
expires timestamp not null,
|
||||
amount bigint unsigned not null,
|
||||
invoice varchar(2048) not null,
|
||||
time_value integer unsigned not null,
|
||||
is_paid bit(1) not null,
|
||||
|
||||
constraint fk_vm_payment_vm foreign key (vm_id) references vm (id)
|
||||
);
|
30
src/api.rs
30
src/api.rs
@ -3,8 +3,9 @@ use crate::nip98::Nip98Auth;
|
||||
use crate::provisioner::Provisioner;
|
||||
use anyhow::Error;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{get, routes, Responder, Route, State};
|
||||
use serde::Serialize;
|
||||
use rocket::{get, post, routes, Data, Responder, Route, State};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::vm::VMSpec;
|
||||
|
||||
pub fn routes() -> Vec<Route> {
|
||||
routes![v1_list_vms]
|
||||
@ -37,6 +38,15 @@ impl From<Error> for ApiError {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CreateVmRequest {}
|
||||
|
||||
impl From<CreateVmRequest> for VMSpec {
|
||||
fn from(value: CreateVmRequest) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/api/v1/vms")]
|
||||
async fn v1_list_vms(auth: Nip98Auth, provisioner: &State<Provisioner>) -> ApiResult<Vec<db::Vm>> {
|
||||
let pubkey = auth.event.pubkey.to_bytes();
|
||||
@ -44,3 +54,19 @@ async fn v1_list_vms(auth: Nip98Auth, provisioner: &State<Provisioner>) -> ApiRe
|
||||
let vms = provisioner.list_vms(uid).await?;
|
||||
ApiData::ok(vms)
|
||||
}
|
||||
|
||||
#[get("/api/v1/vm/templates")]
|
||||
async fn v1_list_vm_templates(provisioner: &State<Provisioner>) -> ApiResult<Vec<db::VmTemplate>> {
|
||||
let vms = provisioner.list_vm_templates().await?;
|
||||
ApiData::ok(vms)
|
||||
}
|
||||
|
||||
#[post("/api/v1/vm", data = "<req>", format = "json")]
|
||||
async fn v1_provision_vm(auth: Nip98Auth, provisioner: &State<Provisioner>, req: Json<CreateVmRequest>) -> ApiResult<db::Vm> {
|
||||
let pubkey = auth.event.pubkey.to_bytes();
|
||||
let uid = provisioner.upsert_user(&pubkey).await?;
|
||||
|
||||
let req = req.0;
|
||||
let rsp = provisioner.provision(req.into()).await?;
|
||||
ApiData::ok(rsp)
|
||||
}
|
13
src/db.rs
13
src/db.rs
@ -76,6 +76,19 @@ pub struct IpRange {
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, FromRow, Clone, Debug)]
|
||||
pub struct VmTemplate {
|
||||
pub id: u64,
|
||||
pub name: String,
|
||||
pub enabled: bool,
|
||||
pub created: DateTime<Utc>,
|
||||
pub expires: Option<DateTime<Utc>>,
|
||||
pub cpu: u16,
|
||||
pub memory: u64,
|
||||
pub disk_size: u64,
|
||||
pub disk_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, FromRow, Clone, Debug)]
|
||||
pub struct Vm {
|
||||
/// Unique VM ID (Same in proxmox)
|
||||
|
@ -2,7 +2,7 @@ use crate::db;
|
||||
use crate::db::{VmHost, VmHostDisk};
|
||||
use crate::host::proxmox::ProxmoxClient;
|
||||
use crate::vm::VMSpec;
|
||||
use anyhow::Error;
|
||||
use anyhow::{Error, Result};
|
||||
use log::{info, warn};
|
||||
use sqlx::{MySqlPool, Row};
|
||||
|
||||
@ -17,7 +17,7 @@ impl Provisioner {
|
||||
}
|
||||
|
||||
/// Auto-discover resources
|
||||
pub async fn auto_discover(&self) -> Result<(), Error> {
|
||||
pub async fn auto_discover(&self) -> Result<()> {
|
||||
let hosts = self.list_hosts().await?;
|
||||
for host in hosts {
|
||||
let api = ProxmoxClient::new(host.ip.parse()?).with_api_token(&host.api_token);
|
||||
@ -58,12 +58,12 @@ impl Provisioner {
|
||||
}
|
||||
|
||||
/// Provision a new VM
|
||||
pub async fn provision(&self, spec: VMSpec) -> Result<db::Vm, Error> {
|
||||
pub async fn provision(&self, spec: VMSpec) -> Result<db::Vm> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Insert/Fetch user id
|
||||
pub async fn upsert_user(&self, pubkey: &[u8; 32]) -> Result<u64, Error> {
|
||||
pub async fn upsert_user(&self, pubkey: &[u8; 32]) -> Result<u64> {
|
||||
let res = sqlx::query("insert ignore into users(pubkey) values(?) returning id")
|
||||
.bind(pubkey.as_slice())
|
||||
.fetch_optional(&self.db)
|
||||
@ -79,8 +79,16 @@ impl Provisioner {
|
||||
}
|
||||
}
|
||||
|
||||
/// List VM templates
|
||||
pub async fn list_vm_templates(&self) -> Result<Vec<db::VmTemplate>> {
|
||||
sqlx::query_as("select * from vm_template where enabled = 1 and (expires is null or expires < now())")
|
||||
.fetch_all(&self.db)
|
||||
.await
|
||||
.map_err(Error::new)
|
||||
}
|
||||
|
||||
/// List VM's owned by a specific user
|
||||
pub async fn list_vms(&self, id: u64) -> Result<Vec<db::Vm>, Error> {
|
||||
pub async fn list_vms(&self, id: u64) -> Result<Vec<db::Vm>> {
|
||||
sqlx::query_as("select * from vm where user_id = ?")
|
||||
.bind(&id)
|
||||
.fetch_all(&self.db)
|
||||
@ -89,7 +97,7 @@ impl Provisioner {
|
||||
}
|
||||
|
||||
/// List VM's owned by a specific user
|
||||
pub async fn list_hosts(&self) -> Result<Vec<VmHost>, Error> {
|
||||
pub async fn list_hosts(&self) -> Result<Vec<VmHost>> {
|
||||
sqlx::query_as("select * from vm_host")
|
||||
.fetch_all(&self.db)
|
||||
.await
|
||||
@ -97,7 +105,7 @@ impl Provisioner {
|
||||
}
|
||||
|
||||
/// List VM's owned by a specific user
|
||||
pub async fn list_host_disks(&self, host_id: u64) -> Result<Vec<VmHostDisk>, Error> {
|
||||
pub async fn list_host_disks(&self, host_id: u64) -> Result<Vec<VmHostDisk>> {
|
||||
sqlx::query_as("select * from vm_host_disk where host_id = ?")
|
||||
.bind(&host_id)
|
||||
.fetch_all(&self.db)
|
||||
@ -106,7 +114,7 @@ impl Provisioner {
|
||||
}
|
||||
|
||||
/// Update host resources (usually from [auto_discover])
|
||||
pub async fn update_host(&self, host: VmHost) -> Result<(), Error> {
|
||||
pub async fn update_host(&self, host: VmHost) -> Result<()> {
|
||||
sqlx::query("update vm_host set name = ?, cpu = ?, memory = ? where id = ?")
|
||||
.bind(&host.name)
|
||||
.bind(&host.cpu)
|
||||
|
Loading…
x
Reference in New Issue
Block a user