sysmonk/
lib.rs

1#![allow(rustdoc::bare_urls)]
2#![doc = include_str!("../README.md")]
3
4#[macro_use]
5extern crate actix_web;
6
7use std::io;
8
9use actix_web::{middleware, web, App, HttpServer};
10
11/// Module for the structs and functions called during startup.
12mod constant;
13/// Module for all the API entry points.
14mod routes;
15/// Module to store all the helper functions.
16mod squire;
17/// Module to store all the HTML templates rendered using Jinja.
18mod templates;
19/// Module for functions related to system resources.
20mod resources;
21/// Module for legacy (but still useful for reference) functions
22mod legacy;
23
24/// Contains entrypoint and initializer settings to trigger the asynchronous `HTTPServer`
25///
26/// # Examples
27///
28/// ```no_run
29/// #[actix_rt::main]
30/// async fn main() {
31///     match sysmonk::start().await {
32///         Ok(_) => {
33///             println!("SysMonk session terminated")
34///         }
35///         Err(err) => {
36///             eprintln!("Error starting SysMonk: {}", err)
37///         }
38///     }
39/// }
40/// ```
41pub async fn start() -> io::Result<()> {
42    let metadata = constant::build_info();
43    let config = squire::startup::get_config(&metadata);
44
45    squire::startup::init_logger(config.debug, config.utc_logging, &metadata.crate_name);
46    println!("{}[v{}] - {}", &metadata.pkg_name, &metadata.pkg_version, &metadata.description);
47    squire::ascii_art::random();
48
49    // Create a dedicated clone, since it will be used within closure
50    let config_clone = config.clone();
51    let host = format!("{}:{}", config.host, config.port);
52    log::info!("{} [workers:{}] running on http://{} (Press CTRL+C to quit)",
53        &metadata.pkg_name, &config.workers, &host);
54    let jinja = templates::environment();
55    let fernet = constant::fernet_object();
56    let session = constant::session_info();
57    /*
58        || syntax is creating a closure that serves as the argument to the HttpServer::new() method.
59        The closure is defining the configuration for the Actix web server.
60        The purpose of the closure is to configure the server before it starts listening for incoming requests.
61     */
62    let application = move || {
63        App::new()  // Creates a new Actix web application
64            .app_data(web::Data::new(config_clone.clone()))
65            .app_data(web::Data::new(jinja.clone()))
66            .app_data(web::Data::new(fernet.clone()))
67            .app_data(web::Data::new(session.clone()))
68            .app_data(web::Data::new(metadata.clone()))
69            .wrap(squire::middleware::get_cors(config_clone.websites.clone()))
70            .wrap(middleware::Logger::default())  // Adds a default logger middleware to the application
71            .service(routes::basics::health)  // Registers a service for handling requests
72            .service(routes::basics::root)
73            .service(routes::basics::health)  // Registers a service for handling requests
74            .service(routes::auth::login)
75            .service(routes::monitor::monitor)
76            .service(routes::auth::logout)
77            .service(routes::auth::error)
78            .configure(routes::configure_websocket)
79    };
80    let server = HttpServer::new(application)
81        .workers(config.workers)
82        .max_connections(config.max_connections);
83    match server.bind(host) {
84        Ok(bound_server) => bound_server.run().await,
85        Err(err) => {
86            log::error!("Failed to bind server: {}", err);
87            Err(err)
88        }
89    }
90}