improve query handling in new_vm
enhanced transaction error handling bind all string input into NewVmReq submission query
This commit is contained in:
parent
5ccd432566
commit
05759a5149
87
src/db/vm.rs
87
src/db/vm.rs
@ -202,52 +202,67 @@ impl NewVmReq {
|
|||||||
|
|
||||||
pub async fn submit(self, db: &Surreal<Client>) -> Result<(), Error> {
|
pub async fn submit(self, db: &Surreal<Client>) -> Result<(), Error> {
|
||||||
let locked_nano = self.locked_nano;
|
let locked_nano = self.locked_nano;
|
||||||
let account = self.admin.key().to_string();
|
let tx_query = format!("
|
||||||
let vm_id = self.id.key().to_string();
|
|
||||||
let vm_node = self.vm_node.key().to_string();
|
|
||||||
// TODO: check for possible injection and maybe use .bind()
|
|
||||||
let query = format!(
|
|
||||||
"
|
|
||||||
BEGIN TRANSACTION;
|
BEGIN TRANSACTION;
|
||||||
UPDATE account:{account} SET balance -= {locked_nano};
|
|
||||||
IF account:{account}.balance < 0 {{
|
LET $account = $account_input;
|
||||||
THROW 'Insufficient funds.'
|
LET $new_vm_req = $new_vm_req_input;
|
||||||
}};
|
LET $vm_node = $vm_node_input;
|
||||||
UPDATE account:{account} SET tmp_locked += {locked_nano};
|
LET $hostname = $hostname_input;
|
||||||
RELATE
|
LET $dtrfs_url = $dtrfs_url_input;
|
||||||
account:{account}
|
LET $dtrfs_sha = $dtrfs_sha_input;
|
||||||
->new_vm_req:{vm_id}
|
LET $kernel_url = $kernel_url_input;
|
||||||
->vm_node:{vm_node}
|
LET $kernel_sha = $kernel_sha_input;
|
||||||
CONTENT {{
|
|
||||||
created_at: time::now(), hostname: '{}', vcpus: {}, memory_mb: {}, disk_size_gb: {},
|
UPDATE $account SET balance -= {locked_nano};
|
||||||
extra_ports: {:?}, public_ipv4: {:?}, public_ipv6: {:?},
|
IF $account.balance < 0 {{
|
||||||
dtrfs_url: '{}', dtrfs_sha: '{}', kernel_url: '{}', kernel_sha: '{}',
|
THROW 'Insufficient funds.'
|
||||||
price_per_unit: {}, locked_nano: {locked_nano}, error: ''
|
}};
|
||||||
}};
|
UPDATE $account SET tmp_locked += {locked_nano};
|
||||||
COMMIT TRANSACTION;
|
RELATE
|
||||||
",
|
$account
|
||||||
self.hostname,
|
->$new_vm_req
|
||||||
|
->$vm_node
|
||||||
|
CONTENT {{
|
||||||
|
created_at: time::now(), hostname: $hostname, vcpus: {}, memory_mb: {}, disk_size_gb: {},
|
||||||
|
extra_ports: {:?}, public_ipv4: {}, public_ipv6: {},
|
||||||
|
dtrfs_url: $dtrfs_url, dtrfs_sha: $dtrfs_sha, kernel_url: $kernel_url, kernel_sha: $kernel_sha,
|
||||||
|
price_per_unit: {}, locked_nano: {locked_nano}, error: ''
|
||||||
|
}};
|
||||||
|
|
||||||
|
COMMIT TRANSACTION;",
|
||||||
self.vcpus,
|
self.vcpus,
|
||||||
self.memory_mb,
|
self.memory_mb,
|
||||||
self.disk_size_gb,
|
self.disk_size_gb,
|
||||||
self.extra_ports,
|
self.extra_ports,
|
||||||
self.public_ipv4,
|
self.public_ipv4,
|
||||||
self.public_ipv6,
|
self.public_ipv6,
|
||||||
self.dtrfs_url,
|
|
||||||
self.dtrfs_sha,
|
|
||||||
self.kernel_url,
|
|
||||||
self.kernel_sha,
|
|
||||||
self.price_per_unit
|
self.price_per_unit
|
||||||
);
|
);
|
||||||
//let _: Vec<Self> = db.insert(NEW_VM_REQ).relation(self).await?;
|
let mut query_resp = db
|
||||||
let mut query_resp = db.query(query).await?;
|
.query(tx_query)
|
||||||
let resp_err = query_resp.take_errors();
|
.bind(("account_input", self.admin))
|
||||||
|
.bind(("new_vm_req_input", self.id))
|
||||||
|
.bind(("vm_node_input", self.vm_node))
|
||||||
|
.bind(("hostname_input", self.hostname))
|
||||||
|
.bind(("dtrfs_url_input", self.dtrfs_url))
|
||||||
|
.bind(("dtrfs_sha_input", self.dtrfs_sha))
|
||||||
|
.bind(("kernel_url_input", self.kernel_url))
|
||||||
|
.bind(("kernel_sha_input", self.kernel_sha))
|
||||||
|
.await?;
|
||||||
|
|
||||||
if let Some(surrealdb::Error::Api(surrealdb::error::Api::Query(tx_query_error))) =
|
let query_err = query_resp.take_errors();
|
||||||
resp_err.get(&1)
|
if !query_err.is_empty() {
|
||||||
{
|
let tx_fail_err_str =
|
||||||
log::error!("Transaction error: {tx_query_error}");
|
String::from("The query was not executed due to a failed transaction");
|
||||||
return Err(Error::InsufficientFunds);
|
|
||||||
|
if query_err.contains_key(&9) && query_err[&9].to_string() != tx_fail_err_str {
|
||||||
|
log::error!("Transaction error: {}", query_err[&9]);
|
||||||
|
return Err(Error::InsufficientFunds);
|
||||||
|
} else {
|
||||||
|
log::error!("Unknown error in submit_new_vm_req: {query_err:?}");
|
||||||
|
return Err(Error::Unknown("submit_new_vm_req".to_string()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user