admin
This commit is contained in:
@@ -1,19 +0,0 @@
|
|||||||
use argon2::{
|
|
||||||
password_hash::{PasswordHasher, SaltString},
|
|
||||||
Argon2,
|
|
||||||
};
|
|
||||||
use rand::thread_rng;
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let password = env::args()
|
|
||||||
.nth(1)
|
|
||||||
.expect("Usage: cargo run --example hash_password <password>");
|
|
||||||
let salt = SaltString::generate(&mut thread_rng());
|
|
||||||
let argon2 = Argon2::default();
|
|
||||||
let hash = argon2
|
|
||||||
.hash_password(password.as_bytes(), &salt)
|
|
||||||
.expect("hashing failed")
|
|
||||||
.to_string();
|
|
||||||
println!("{}", hash);
|
|
||||||
}
|
|
||||||
+372
-34
@@ -1,8 +1,12 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, bail, Context, Result};
|
||||||
use diesel::prelude::*;
|
use argon2::{
|
||||||
|
password_hash::{PasswordHasher, SaltString},
|
||||||
|
Argon2,
|
||||||
|
};
|
||||||
|
use diesel::{dsl::exists, prelude::*, select};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use reqwest::{Client, Method, StatusCode};
|
use reqwest::{Client, Method, StatusCode};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
@@ -11,43 +15,74 @@ use uuid::Uuid;
|
|||||||
use backend::{
|
use backend::{
|
||||||
config::AppConfig,
|
config::AppConfig,
|
||||||
db::{self, PgPool},
|
db::{self, PgPool},
|
||||||
models::{DocumentAsset, DocumentAssetObject, Tenant},
|
models::{DocumentAsset, DocumentAssetObject, NewUser, NewUserMembership, Tenant, User},
|
||||||
s3,
|
s3,
|
||||||
schema::{document_asset_objects, document_assets, tenants},
|
schema::{document_asset_objects, document_assets, tenants, user_memberships, users},
|
||||||
storage::{ObjectStorage, S3Storage, TenantStorage},
|
storage::{ObjectStorage, S3Storage, TenantStorage},
|
||||||
utils::tracing::init_tracing,
|
utils::tracing::init_tracing,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use rand::rngs::OsRng;
|
||||||
|
|
||||||
static QUICKWIT_INDEX_TEMPLATE: Lazy<serde_json::Value> = Lazy::new(|| {
|
static QUICKWIT_INDEX_TEMPLATE: Lazy<serde_json::Value> = Lazy::new(|| {
|
||||||
json!({
|
json!({
|
||||||
"version": "0.8",
|
"version": "0.8",
|
||||||
"index_id": "documents",
|
"index_id": "documents",
|
||||||
"doc_mapping": {
|
"doc_mapping": {
|
||||||
"tokenizers": [
|
"tokenizers": [
|
||||||
{
|
{
|
||||||
"name": "substring",
|
"name": "substring",
|
||||||
"type": "ngram",
|
"type": "ngram",
|
||||||
"min_gram": 2,
|
"min_gram": 2,
|
||||||
"max_gram": 20,
|
"max_gram": 20,
|
||||||
"prefix_only": false
|
"prefix_only": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"field_mappings": [
|
"field_mappings": [
|
||||||
{ "name": "tenant_id", "type": "text", "stored": true },
|
{ "name": "tenant_id", "type": "text", "stored": true },
|
||||||
{ "name": "document_id", "type": "text", "stored": true },
|
{ "name": "document_id", "type": "text", "stored": true },
|
||||||
{ "name": "version_id", "type": "text", "stored": true },
|
{ "name": "version_id", "type": "text", "stored": true },
|
||||||
{ "name": "title", "type": "text", "tokenizer": "substring", "stored": true },
|
{ "name": "title", "type": "text", "tokenizer": "substring", "stored": true },
|
||||||
{ "name": "text", "type": "text", "tokenizer": "substring", "record": "position" }
|
{ "name": "text", "type": "text", "tokenizer": "substring", "record": "position" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"search_settings": {
|
"search_settings": {
|
||||||
"default_search_fields": ["title", "text"]
|
"default_search_fields": ["title", "text"]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Command {
|
enum Command {
|
||||||
|
CreateUser {
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
},
|
||||||
|
SetPassword {
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
},
|
||||||
|
ListUsers,
|
||||||
|
DeleteUser {
|
||||||
|
username: String,
|
||||||
|
},
|
||||||
|
CreateTenant {
|
||||||
|
slug: String,
|
||||||
|
storage_root: Option<String>,
|
||||||
|
quickwit_index: Option<String>,
|
||||||
|
},
|
||||||
|
DeleteTenant {
|
||||||
|
slug: String,
|
||||||
|
},
|
||||||
|
AddUserToTenant {
|
||||||
|
username: String,
|
||||||
|
slug: String,
|
||||||
|
role: Option<String>,
|
||||||
|
},
|
||||||
|
RemoveUserFromTenant {
|
||||||
|
username: String,
|
||||||
|
slug: String,
|
||||||
|
},
|
||||||
ListTenants,
|
ListTenants,
|
||||||
DeleteAssets(String),
|
DeleteAssets(String),
|
||||||
QuickwitCreate(String),
|
QuickwitCreate(String),
|
||||||
@@ -56,12 +91,53 @@ enum Command {
|
|||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
fn usage() -> &'static str {
|
fn usage() -> &'static str {
|
||||||
"Usage: admin <list-tenants|delete-assets <slug>|quickwit-create-index <slug>|quickwit-delete-index <slug>>"
|
"Usage: admin\n\
|
||||||
|
create-user <username> <password>\n\
|
||||||
|
set-password <username> <password>\n\
|
||||||
|
list-users\n\
|
||||||
|
delete-user <username>\n\
|
||||||
|
create-tenant <slug> [storage_root] [quickwit_index]\n\
|
||||||
|
delete-tenant <slug>\n\
|
||||||
|
add-user-to-tenant <username> <slug> [role]\n\
|
||||||
|
remove-user-from-tenant <username> <slug>\n\
|
||||||
|
list-tenants\n\
|
||||||
|
delete-assets <slug>\n\
|
||||||
|
quickwit-create-index <slug>\n\
|
||||||
|
quickwit-delete-index <slug>"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse() -> Result<Self> {
|
fn parse() -> Result<Self> {
|
||||||
let mut args = env::args().skip(1);
|
let mut args = env::args().skip(1);
|
||||||
match args.next().as_deref() {
|
match args.next().as_deref() {
|
||||||
|
Some("create-user") => Ok(Self::CreateUser {
|
||||||
|
username: args.next().ok_or_else(|| anyhow!("username required"))?,
|
||||||
|
password: args.next().ok_or_else(|| anyhow!("password required"))?,
|
||||||
|
}),
|
||||||
|
Some("set-password") => Ok(Self::SetPassword {
|
||||||
|
username: args.next().ok_or_else(|| anyhow!("username required"))?,
|
||||||
|
password: args.next().ok_or_else(|| anyhow!("password required"))?,
|
||||||
|
}),
|
||||||
|
Some("list-users") => Ok(Self::ListUsers),
|
||||||
|
Some("delete-user") => Ok(Self::DeleteUser {
|
||||||
|
username: args.next().ok_or_else(|| anyhow!("username required"))?,
|
||||||
|
}),
|
||||||
|
Some("create-tenant") => Ok(Self::CreateTenant {
|
||||||
|
slug: args.next().ok_or_else(|| anyhow!("tenant slug required"))?,
|
||||||
|
storage_root: args.next(),
|
||||||
|
quickwit_index: args.next(),
|
||||||
|
}),
|
||||||
|
Some("delete-tenant") => Ok(Self::DeleteTenant {
|
||||||
|
slug: args.next().ok_or_else(|| anyhow!("tenant slug required"))?,
|
||||||
|
}),
|
||||||
|
Some("add-user-to-tenant") => Ok(Self::AddUserToTenant {
|
||||||
|
username: args.next().ok_or_else(|| anyhow!("username required"))?,
|
||||||
|
slug: args.next().ok_or_else(|| anyhow!("tenant slug required"))?,
|
||||||
|
role: args.next(),
|
||||||
|
}),
|
||||||
|
Some("remove-user-from-tenant") => Ok(Self::RemoveUserFromTenant {
|
||||||
|
username: args.next().ok_or_else(|| anyhow!("username required"))?,
|
||||||
|
slug: args.next().ok_or_else(|| anyhow!("tenant slug required"))?,
|
||||||
|
}),
|
||||||
Some("list-tenants") => Ok(Self::ListTenants),
|
Some("list-tenants") => Ok(Self::ListTenants),
|
||||||
Some("delete-assets") => Ok(Self::DeleteAssets(
|
Some("delete-assets") => Ok(Self::DeleteAssets(
|
||||||
args.next().ok_or_else(|| anyhow!("tenant slug required"))?,
|
args.next().ok_or_else(|| anyhow!("tenant slug required"))?,
|
||||||
@@ -85,6 +161,24 @@ async fn main() -> Result<()> {
|
|||||||
let pool = db::init_pool_with_size(&config.database_url, config.database_max_pool_size)?;
|
let pool = db::init_pool_with_size(&config.database_url, config.database_max_pool_size)?;
|
||||||
|
|
||||||
match command {
|
match command {
|
||||||
|
Command::CreateUser { username, password } => create_user(&pool, &username, &password)?,
|
||||||
|
Command::SetPassword { username, password } => set_password(&pool, &username, &password)?,
|
||||||
|
Command::ListUsers => list_users(&pool)?,
|
||||||
|
Command::DeleteUser { username } => delete_user(&pool, &username)?,
|
||||||
|
Command::CreateTenant {
|
||||||
|
slug,
|
||||||
|
storage_root,
|
||||||
|
quickwit_index,
|
||||||
|
} => create_tenant(&pool, &slug, storage_root, quickwit_index)?,
|
||||||
|
Command::DeleteTenant { slug } => delete_tenant(&pool, &slug)?,
|
||||||
|
Command::AddUserToTenant {
|
||||||
|
username,
|
||||||
|
slug,
|
||||||
|
role,
|
||||||
|
} => add_user_to_tenant(&pool, &username, &slug, role.as_deref())?,
|
||||||
|
Command::RemoveUserFromTenant { username, slug } => {
|
||||||
|
remove_user_from_tenant(&pool, &username, &slug)?
|
||||||
|
}
|
||||||
Command::ListTenants => list_tenants(&pool)?,
|
Command::ListTenants => list_tenants(&pool)?,
|
||||||
Command::DeleteAssets(slug) => delete_assets_for_tenant(&config, &pool, &slug).await?,
|
Command::DeleteAssets(slug) => delete_assets_for_tenant(&config, &pool, &slug).await?,
|
||||||
Command::QuickwitCreate(slug) => {
|
Command::QuickwitCreate(slug) => {
|
||||||
@@ -98,6 +192,250 @@ async fn main() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_user(pool: &PgPool, username: &str, password: &str) -> Result<()> {
|
||||||
|
if username.trim().is_empty() {
|
||||||
|
bail!("username must not be empty");
|
||||||
|
}
|
||||||
|
if password.is_empty() {
|
||||||
|
bail!("password must not be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut conn = pool.get().context("failed to get database connection")?;
|
||||||
|
let exists: bool =
|
||||||
|
select(exists(users::table.filter(users::username.eq(username)))).get_result(&mut conn)?;
|
||||||
|
if exists {
|
||||||
|
bail!("user '{}' already exists", username);
|
||||||
|
}
|
||||||
|
|
||||||
|
let password_hash = hash_password(password)?;
|
||||||
|
let new_user = NewUser {
|
||||||
|
id: Uuid::new_v4(),
|
||||||
|
username: username.to_string(),
|
||||||
|
password_hash,
|
||||||
|
};
|
||||||
|
|
||||||
|
diesel::insert_into(users::table)
|
||||||
|
.values(&new_user)
|
||||||
|
.execute(&mut conn)?;
|
||||||
|
|
||||||
|
println!("created user '{}' (id: {})", username, new_user.id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_password(pool: &PgPool, username: &str, password: &str) -> Result<()> {
|
||||||
|
if password.is_empty() {
|
||||||
|
bail!("password must not be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut conn = pool.get().context("failed to get database connection")?;
|
||||||
|
let password_hash = hash_password(password)?;
|
||||||
|
|
||||||
|
let updated = diesel::update(users::table.filter(users::username.eq(username)))
|
||||||
|
.set(users::password_hash.eq(password_hash))
|
||||||
|
.execute(&mut conn)?;
|
||||||
|
|
||||||
|
if updated == 0 {
|
||||||
|
bail!("user '{}' not found", username);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("updated password for '{}'", username);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash_password(password: &str) -> Result<String> {
|
||||||
|
let salt = SaltString::generate(&mut OsRng);
|
||||||
|
let hash = Argon2::default()
|
||||||
|
.hash_password(password.as_bytes(), &salt)
|
||||||
|
.map_err(|err| anyhow!(err))?;
|
||||||
|
Ok(hash.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn list_users(pool: &PgPool) -> Result<()> {
|
||||||
|
let mut conn = pool.get().context("failed to get database connection")?;
|
||||||
|
|
||||||
|
let users_list: Vec<User> = users::table.order(users::username.asc()).load(&mut conn)?;
|
||||||
|
if users_list.is_empty() {
|
||||||
|
println!("No users found.");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
for user in users_list {
|
||||||
|
let memberships: Vec<(Uuid, String, String)> = user_memberships::table
|
||||||
|
.inner_join(tenants::table)
|
||||||
|
.filter(user_memberships::user_id.eq(user.id))
|
||||||
|
.select((tenants::id, tenants::slug, user_memberships::role))
|
||||||
|
.order((tenants::slug.asc(), user_memberships::role.asc()))
|
||||||
|
.load(&mut conn)?;
|
||||||
|
|
||||||
|
if memberships.is_empty() {
|
||||||
|
println!("{} ({})", user.username, user.id);
|
||||||
|
} else {
|
||||||
|
let details: Vec<String> = memberships
|
||||||
|
.into_iter()
|
||||||
|
.map(|(_, slug, role)| format!("{}: {}", slug, role))
|
||||||
|
.collect();
|
||||||
|
println!("{} ({}) -> {}", user.username, user.id, details.join(", "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_user(pool: &PgPool, username: &str) -> Result<()> {
|
||||||
|
let mut conn = pool.get().context("failed to get database connection")?;
|
||||||
|
|
||||||
|
let user: User = users::table
|
||||||
|
.filter(users::username.eq(username))
|
||||||
|
.first(&mut conn)
|
||||||
|
.optional()?
|
||||||
|
.ok_or_else(|| anyhow!("user '{}' not found", username))?;
|
||||||
|
|
||||||
|
diesel::delete(user_memberships::table.filter(user_memberships::user_id.eq(user.id)))
|
||||||
|
.execute(&mut conn)?;
|
||||||
|
diesel::delete(users::table.filter(users::id.eq(user.id))).execute(&mut conn)?;
|
||||||
|
|
||||||
|
println!("deleted user '{}'", username);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_tenant(
|
||||||
|
pool: &PgPool,
|
||||||
|
slug: &str,
|
||||||
|
storage_root_arg: Option<String>,
|
||||||
|
quickwit_index_arg: Option<String>,
|
||||||
|
) -> Result<()> {
|
||||||
|
if slug.trim().is_empty() {
|
||||||
|
bail!("tenant slug must not be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut conn = pool.get().context("failed to get database connection")?;
|
||||||
|
let exists: bool =
|
||||||
|
select(exists(tenants::table.filter(tenants::slug.eq(slug)))).get_result(&mut conn)?;
|
||||||
|
if exists {
|
||||||
|
bail!("tenant '{}' already exists", slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = Uuid::new_v4();
|
||||||
|
let storage_root = storage_root_arg
|
||||||
|
.map(|mut s| {
|
||||||
|
if s.is_empty() {
|
||||||
|
format!("tenants/{}/", id)
|
||||||
|
} else {
|
||||||
|
if !s.ends_with('/') {
|
||||||
|
s.push('/');
|
||||||
|
}
|
||||||
|
s
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| format!("tenants/{}/", id));
|
||||||
|
let quickwit_index = quickwit_index_arg.unwrap_or_else(|| format!("documents-{}", id));
|
||||||
|
|
||||||
|
diesel::insert_into(tenants::table)
|
||||||
|
.values((
|
||||||
|
tenants::id.eq(id),
|
||||||
|
tenants::slug.eq(slug),
|
||||||
|
tenants::storage_root.eq(Some(storage_root.clone())),
|
||||||
|
tenants::quickwit_index.eq(Some(quickwit_index.clone())),
|
||||||
|
tenants::status.eq("active"),
|
||||||
|
tenants::config.eq(serde_json::json!({})),
|
||||||
|
))
|
||||||
|
.execute(&mut conn)?;
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"created tenant '{}' with id {}, storage_root '{}', quickwit_index '{}'",
|
||||||
|
slug, id, storage_root, quickwit_index
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_tenant(pool: &PgPool, slug: &str) -> Result<()> {
|
||||||
|
let mut conn = pool.get().context("failed to get database connection")?;
|
||||||
|
|
||||||
|
let tenant: Tenant = tenants::table
|
||||||
|
.filter(tenants::slug.eq(slug))
|
||||||
|
.first(&mut conn)
|
||||||
|
.optional()?
|
||||||
|
.ok_or_else(|| anyhow!("tenant '{}' not found", slug))?;
|
||||||
|
|
||||||
|
let member_exists: bool = select(exists(
|
||||||
|
user_memberships::table.filter(user_memberships::tenant_id.eq(tenant.id)),
|
||||||
|
))
|
||||||
|
.get_result(&mut conn)?;
|
||||||
|
if member_exists {
|
||||||
|
bail!("tenant '{}' still has user memberships", slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::delete(tenants::table.filter(tenants::id.eq(tenant.id))).execute(&mut conn)?;
|
||||||
|
println!("deleted tenant '{}'", slug);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_user_to_tenant(pool: &PgPool, username: &str, slug: &str, role: Option<&str>) -> Result<()> {
|
||||||
|
let mut conn = pool.get().context("failed to get database connection")?;
|
||||||
|
|
||||||
|
let user: User = users::table
|
||||||
|
.filter(users::username.eq(username))
|
||||||
|
.first(&mut conn)
|
||||||
|
.optional()?
|
||||||
|
.ok_or_else(|| anyhow!("user '{}' not found", username))?;
|
||||||
|
|
||||||
|
let tenant: Tenant = tenants::table
|
||||||
|
.filter(tenants::slug.eq(slug))
|
||||||
|
.first(&mut conn)
|
||||||
|
.optional()?
|
||||||
|
.ok_or_else(|| anyhow!("tenant '{}' not found", slug))?;
|
||||||
|
|
||||||
|
let membership = NewUserMembership {
|
||||||
|
id: Uuid::new_v4(),
|
||||||
|
user_id: user.id,
|
||||||
|
tenant_id: tenant.id,
|
||||||
|
role: role.unwrap_or("user").to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
diesel::insert_into(user_memberships::table)
|
||||||
|
.values(&membership)
|
||||||
|
.on_conflict((user_memberships::user_id, user_memberships::tenant_id))
|
||||||
|
.do_update()
|
||||||
|
.set(user_memberships::role.eq(&membership.role))
|
||||||
|
.execute(&mut conn)?;
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"added user '{}' to tenant '{}' with role '{}'",
|
||||||
|
username, slug, membership.role
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_user_from_tenant(pool: &PgPool, username: &str, slug: &str) -> Result<()> {
|
||||||
|
let mut conn = pool.get().context("failed to get database connection")?;
|
||||||
|
|
||||||
|
let user: User = users::table
|
||||||
|
.filter(users::username.eq(username))
|
||||||
|
.first(&mut conn)
|
||||||
|
.optional()?
|
||||||
|
.ok_or_else(|| anyhow!("user '{}' not found", username))?;
|
||||||
|
|
||||||
|
let tenant: Tenant = tenants::table
|
||||||
|
.filter(tenants::slug.eq(slug))
|
||||||
|
.first(&mut conn)
|
||||||
|
.optional()?
|
||||||
|
.ok_or_else(|| anyhow!("tenant '{}' not found", slug))?;
|
||||||
|
|
||||||
|
let removed = diesel::delete(
|
||||||
|
user_memberships::table
|
||||||
|
.filter(user_memberships::user_id.eq(user.id))
|
||||||
|
.filter(user_memberships::tenant_id.eq(tenant.id)),
|
||||||
|
)
|
||||||
|
.execute(&mut conn)?;
|
||||||
|
|
||||||
|
if removed == 0 {
|
||||||
|
println!("user '{}' was not a member of tenant '{}'", username, slug);
|
||||||
|
} else {
|
||||||
|
println!("removed user '{}' from tenant '{}'", username, slug);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn list_tenants(pool: &PgPool) -> Result<()> {
|
fn list_tenants(pool: &PgPool) -> Result<()> {
|
||||||
let mut conn = pool.get().context("failed to get database connection")?;
|
let mut conn = pool.get().context("failed to get database connection")?;
|
||||||
let tenants: Vec<Tenant> = tenants::table
|
let tenants: Vec<Tenant> = tenants::table
|
||||||
@@ -243,11 +581,11 @@ async fn quickwit_index(
|
|||||||
let lookup_status = lookup.status();
|
let lookup_status = lookup.status();
|
||||||
if !lookup_status.is_success() {
|
if !lookup_status.is_success() {
|
||||||
let body = lookup.text().await.unwrap_or_default();
|
let body = lookup.text().await.unwrap_or_default();
|
||||||
return Err(anyhow!(
|
bail!(
|
||||||
"quickwit reported conflict but index lookup failed with status {}: {}",
|
"quickwit reported conflict but index lookup failed with status {}: {}",
|
||||||
lookup_status,
|
lookup_status,
|
||||||
body
|
body
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
diesel::update(tenants::table.filter(tenants::id.eq(tenant.id)))
|
diesel::update(tenants::table.filter(tenants::id.eq(tenant.id)))
|
||||||
@@ -262,11 +600,11 @@ async fn quickwit_index(
|
|||||||
}
|
}
|
||||||
status => {
|
status => {
|
||||||
let body = response.text().await.unwrap_or_default();
|
let body = response.text().await.unwrap_or_default();
|
||||||
return Err(anyhow!(
|
bail!(
|
||||||
"quickwit create index failed with status {}: {}",
|
"quickwit create index failed with status {}: {}",
|
||||||
status,
|
status,
|
||||||
body
|
body
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -288,11 +626,11 @@ async fn quickwit_index(
|
|||||||
}
|
}
|
||||||
status => {
|
status => {
|
||||||
let body = response.text().await.unwrap_or_default();
|
let body = response.text().await.unwrap_or_default();
|
||||||
return Err(anyhow!(
|
bail!(
|
||||||
"quickwit delete index failed with status {}: {}",
|
"quickwit delete index failed with status {}: {}",
|
||||||
status,
|
status,
|
||||||
body
|
body
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user