1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use minerva_data::db;
use minerva_data::{
encryption,
syslog::{NewLog, OpType},
user::{NewUser, User},
};
use std::env;
pub async fn database_spinlock(server: &str) {
let mut lock = true;
while lock {
let conn = db::try_make_single_connection("postgres", server);
if conn.is_ok() {
lock = false;
} else {
tokio::time::sleep(tokio::time::Duration::from_millis(2000)).await;
}
}
}
pub fn create_database(tenant: &str, server: &str) {
println!("{}: Creating database...", tenant);
db::create_database(tenant, server)
.map_err(|e| panic!("{}: Error while creating database: {}", tenant, e))
.unwrap();
}
pub fn run_migrations(tenant: &str, server: &str) {
let connection = db::make_single_connection(tenant, server);
println!("{}: Running pending database migrations...", tenant);
diesel_migrations::run_pending_migrations(&connection)
.map_err(|e| panic!("{}: Error while running database migrations: {}", tenant, e))
.unwrap();
println!("Migrations ran successfully.");
}
pub fn create_admin_user(tenant: &str, server: &str) {
use diesel::prelude::*;
use minerva_data::schema::syslog;
use minerva_data::schema::user::{self, dsl::*};
println!("{}: Creating user for Administrator...", tenant);
let connection = db::make_single_connection(tenant, server);
if user
.filter(login.eq("admin"))
.first::<User>(&connection)
.optional()
.map_err(|e| panic!("{}: Error fetching \"admin\" user: {}", tenant, e))
.unwrap()
.is_some()
{
println!("{}: Administrator is already registered.", tenant);
return;
}
let pw = env::var("ADMIN_PASSWORD").unwrap_or_else(|_| String::from("admin"));
let admin_data = NewUser {
login: "admin".to_string(),
name: "Administrator".to_string(),
email: None,
pwhash: encryption::generate_hash(&pw),
};
connection
.build_transaction()
.read_write()
.run::<(), diesel::result::Error, _>(|| {
let result = diesel::insert_into(user::table)
.values(&admin_data)
.get_result::<User>(&connection)?;
diesel::insert_into(syslog::table)
.values(&NewLog {
service: "RUNONCE".to_string(),
requestor: "runonce".to_string(),
entity: "user".to_string(),
operation: OpType::Insert,
datetime: chrono::offset::Utc::now(),
description: Some(format!("Add administrator ID {}", result.id)),
})
.execute(&connection)?;
Ok(())
})
.map_err(|e| panic!("{}: Error registering user \"admin\": {}", tenant, e))
.unwrap();
}