5
lnvps_db/migrations/20250305104739_referrals.sql
Normal file
5
lnvps_db/migrations/20250305104739_referrals.sql
Normal file
@ -0,0 +1,5 @@
|
||||
-- Add migration script here
|
||||
alter table users
|
||||
drop column contact_nip4;
|
||||
alter table vm
|
||||
add column ref_code varchar(20);
|
@ -14,9 +14,11 @@ pub struct User {
|
||||
pub pubkey: Vec<u8>,
|
||||
/// When this user first started using the service (first login)
|
||||
pub created: DateTime<Utc>,
|
||||
/// Users email address for notifications
|
||||
pub email: Option<String>,
|
||||
pub contact_nip4: bool,
|
||||
/// If user should be contacted via NIP-17 for notifications
|
||||
pub contact_nip17: bool,
|
||||
/// If user should be contacted via email for notifications
|
||||
pub contact_email: bool,
|
||||
}
|
||||
|
||||
@ -222,6 +224,8 @@ pub struct Vm {
|
||||
pub mac_address: String,
|
||||
/// Is the VM deleted
|
||||
pub deleted: bool,
|
||||
/// Referral code (recorded during ordering)
|
||||
pub ref_code: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(FromRow, Clone, Debug, Default)]
|
||||
|
@ -69,7 +69,7 @@ impl LNVpsDb for LNVpsDbMysql {
|
||||
}
|
||||
|
||||
async fn delete_user(&self, _id: u64) -> Result<()> {
|
||||
todo!()
|
||||
bail!("Deleting users is not supported")
|
||||
}
|
||||
|
||||
async fn insert_user_ssh_key(&self, new_key: &UserSshKey) -> Result<u64> {
|
||||
@ -247,7 +247,7 @@ impl LNVpsDb for LNVpsDbMysql {
|
||||
}
|
||||
|
||||
async fn insert_vm(&self, vm: &Vm) -> Result<u64> {
|
||||
Ok(sqlx::query("insert into vm(host_id,user_id,image_id,template_id,ssh_key_id,created,expires,disk_id,mac_address) values(?, ?, ?, ?, ?, ?, ?, ?, ?) returning id")
|
||||
Ok(sqlx::query("insert into vm(host_id,user_id,image_id,template_id,ssh_key_id,created,expires,disk_id,mac_address,ref_code) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?) returning id")
|
||||
.bind(vm.host_id)
|
||||
.bind(vm.user_id)
|
||||
.bind(vm.image_id)
|
||||
@ -257,6 +257,7 @@ impl LNVpsDb for LNVpsDbMysql {
|
||||
.bind(vm.expires)
|
||||
.bind(vm.disk_id)
|
||||
.bind(&vm.mac_address)
|
||||
.bind(&vm.ref_code)
|
||||
.fetch_one(&self.db)
|
||||
.await
|
||||
.map_err(Error::new)?
|
||||
|
@ -207,6 +207,7 @@ pub struct CreateVmRequest {
|
||||
pub template_id: u64,
|
||||
pub image_id: u64,
|
||||
pub ssh_key_id: u64,
|
||||
pub ref_code: Option<String>
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, JsonSchema)]
|
||||
|
@ -361,14 +361,20 @@ async fn v1_create_vm_order(
|
||||
auth: Nip98Auth,
|
||||
db: &State<Arc<dyn LNVpsDb>>,
|
||||
provisioner: &State<Arc<LNVpsProvisioner>>,
|
||||
req: Json<CreateVmRequest>,
|
||||
req: Json<CreateVmRequest>
|
||||
) -> ApiResult<ApiVmStatus> {
|
||||
let pubkey = auth.event.pubkey.to_bytes();
|
||||
let uid = db.upsert_user(&pubkey).await?;
|
||||
|
||||
let req = req.0;
|
||||
let rsp = provisioner
|
||||
.provision(uid, req.template_id, req.image_id, req.ssh_key_id)
|
||||
.provision(
|
||||
uid,
|
||||
req.template_id,
|
||||
req.image_id,
|
||||
req.ssh_key_id,
|
||||
req.ref_code,
|
||||
)
|
||||
.await?;
|
||||
ApiData::ok(vm_to_status(db, rsp, None).await?)
|
||||
}
|
||||
|
@ -173,7 +173,6 @@ impl LNVpsDb for MockDb {
|
||||
pubkey: pubkey.to_vec(),
|
||||
created: Utc::now(),
|
||||
email: None,
|
||||
contact_nip4: false,
|
||||
contact_nip17: false,
|
||||
contact_email: false,
|
||||
},
|
||||
@ -193,7 +192,6 @@ impl LNVpsDb for MockDb {
|
||||
u.email = user.email.clone();
|
||||
u.contact_email = user.contact_email;
|
||||
u.contact_nip17 = user.contact_nip17;
|
||||
u.contact_nip4 = user.contact_nip4;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -377,6 +375,7 @@ impl LNVpsDb for MockDb {
|
||||
disk_id: vm.disk_id,
|
||||
mac_address: vm.mac_address.clone(),
|
||||
deleted: false,
|
||||
ref_code: vm.ref_code.clone(),
|
||||
},
|
||||
);
|
||||
Ok(max_id + 1)
|
||||
|
@ -249,6 +249,7 @@ impl LNVpsProvisioner {
|
||||
template_id: u64,
|
||||
image_id: u64,
|
||||
ssh_key_id: u64,
|
||||
ref_code: Option<String>,
|
||||
) -> Result<Vm> {
|
||||
let user = self.db.get_user(user_id).await?;
|
||||
let template = self.db.get_vm_template(template_id).await?;
|
||||
@ -272,6 +273,7 @@ impl LNVpsProvisioner {
|
||||
|
||||
let client = get_host_client(&pick_host, &self.provisioner_config)?;
|
||||
let mut new_vm = Vm {
|
||||
id: 0,
|
||||
host_id: pick_host.id,
|
||||
user_id: user.id,
|
||||
image_id: image.id,
|
||||
@ -280,7 +282,9 @@ impl LNVpsProvisioner {
|
||||
created: Utc::now(),
|
||||
expires: Utc::now(),
|
||||
disk_id: pick_disk.id,
|
||||
..Default::default()
|
||||
mac_address: "NOT FILLED YET".to_string(),
|
||||
deleted: false,
|
||||
ref_code,
|
||||
};
|
||||
|
||||
// ask host client to generate the mac address
|
||||
@ -468,7 +472,9 @@ mod tests {
|
||||
};
|
||||
let ssh_key = db.insert_user_ssh_key(&new_key).await?;
|
||||
|
||||
let vm = provisioner.provision(user_id, 1, 1, ssh_key).await?;
|
||||
let vm = provisioner
|
||||
.provision(user_id, 1, 1, ssh_key, Some("mock-ref".to_string()))
|
||||
.await?;
|
||||
println!("{:?}", vm);
|
||||
provisioner.spawn_vm(vm.id).await?;
|
||||
|
||||
@ -477,6 +483,7 @@ mod tests {
|
||||
assert_eq!(1, arp.len());
|
||||
let arp = arp.first().unwrap();
|
||||
assert_eq!(&vm.mac_address, &arp.mac_address);
|
||||
assert_eq!(vm.ref_code, Some("mock-ref".to_string()));
|
||||
assert_eq!(ROUTER_BRIDGE, arp.interface.as_ref().unwrap());
|
||||
println!("{:?}", arp);
|
||||
|
||||
|
@ -241,9 +241,6 @@ impl Worker {
|
||||
sender.send(msg).await?;
|
||||
}
|
||||
}
|
||||
if user.contact_nip4 {
|
||||
// TODO: send nip4 dm
|
||||
}
|
||||
if user.contact_nip17 {
|
||||
if let Some(c) = self.nostr.as_ref() {
|
||||
let sig = c.signer().await?;
|
||||
|
Reference in New Issue
Block a user