Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2882826
mod.rs
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
mod.rs
View Options
mod
docs
;
mod
fairing
;
mod
helpers
;
mod
routes
;
mod
structs
;
use
crate
::
webui
::{
self
,
assets
::
NamedFile
};
use
helpers
::{
create_status
,
NotFound
};
use
include_dir
::{
include_dir
,
Dir
};
use
lazy_static
::
lazy_static
;
use
pmc
::{
config
,
process
};
use
prometheus
::{
opts
,
register_counter
,
register_gauge
,
register_histogram
,
register_histogram_vec
};
use
prometheus
::{
Counter
,
Gauge
,
Histogram
,
HistogramVec
};
use
serde_json
::{
json
,
Value
};
use
std
::
sync
::
atomic
::{
AtomicBool
,
Ordering
};
use
structs
::
ErrorMessage
;
use
tera
::
Context
;
use
utoipa
::{
openapi
::
security
::{
ApiKey
,
ApiKeyValue
,
SecurityScheme
},
Modify
,
OpenApi
,
};
use
rocket
::{
catch
,
http
::{
ContentType
,
Status
},
outcome
::
Outcome
,
request
::{
self
,
FromRequest
,
Request
},
serde
::
json
::
Json
,
State
,
};
lazy_static
!
{
pub
static
ref
HTTP_COUNTER
:
Counter
=
register_counter
!
(
opts
!
(
"http_requests_total"
,
"Number of HTTP requests made."
)).
unwrap
();
pub
static
ref
DAEMON_START_TIME
:
Gauge
=
register_gauge
!
(
opts
!
(
"process_start_time_seconds"
,
"The uptime of the daemon."
)).
unwrap
();
pub
static
ref
DAEMON_MEM_USAGE
:
Histogram
=
register_histogram
!
(
"daemon_memory_usage"
,
"The memory usage graph of the daemon."
).
unwrap
();
pub
static
ref
DAEMON_CPU_PERCENTAGE
:
Histogram
=
register_histogram
!
(
"daemon_cpu_percentage"
,
"The cpu usage graph of the daemon."
).
unwrap
();
pub
static
ref
HTTP_REQ_HISTOGRAM
:
HistogramVec
=
register_histogram_vec
!
(
"http_request_duration_seconds"
,
"The HTTP request latencies in seconds."
,
&
[
"route"
]).
unwrap
();
}
#[derive(OpenApi)]
#[openapi(
modifiers(&SecurityAddon),
paths(
routes::action_handler,
routes::env_handler,
routes::info_handler,
routes::dump_handler,
routes::servers_handler,
routes::config_handler,
routes::list_handler,
routes::logs_handler,
routes::remote_list,
routes::remote_info,
routes::remote_metrics,
routes::remote_logs,
routes::remote_rename,
routes::remote_action,
routes::logs_raw_handler,
routes::metrics_handler,
routes::prometheus_handler,
routes::create_handler,
routes::rename_handler
),
components(schemas(
ErrorMessage,
process::Log,
process::Raw,
process::Info,
process::Stats,
process::Watch,
process::ItemSingle,
process::ProcessItem,
routes::Stats,
routes::Daemon,
routes::Version,
routes::ActionBody,
routes::ConfigBody,
routes::CreateBody,
routes::MetricsRoot,
routes::LogResponse,
routes::DocMemoryInfo,
routes::ActionResponse,
))
)]
struct
ApiDoc
;
struct
Logger
;
struct
AddCORS
;
struct
EnableWebUI
;
struct
SecurityAddon
;
struct
TeraState
{
path
:
String
,
tera
:
tera
::
Tera
,
}
impl
Modify
for
SecurityAddon
{
fn
modify
(
&
self
,
openapi
:
&
mut
utoipa
::
openapi
::
OpenApi
)
{
let
components
=
openapi
.
components
.
as_mut
().
unwrap
();
components
.
add_security_scheme
(
"api_key"
,
SecurityScheme
::
ApiKey
(
ApiKey
::
Header
(
ApiKeyValue
::
new
(
"token"
))))
}
}
#[catch(500)]
fn
internal_error
<'
m
>
()
->
Json
<
ErrorMessage
>
{
create_status
(
Status
::
InternalServerError
)
}
#[catch(400)]
fn
bad_request
<'
m
>
()
->
Json
<
ErrorMessage
>
{
create_status
(
Status
::
BadRequest
)
}
#[catch(405)]
fn
not_allowed
<'
m
>
()
->
Json
<
ErrorMessage
>
{
create_status
(
Status
::
MethodNotAllowed
)
}
#[catch(404)]
fn
not_found
<'
m
>
()
->
Json
<
ErrorMessage
>
{
create_status
(
Status
::
NotFound
)
}
#[catch(401)]
fn
unauthorized
<'
m
>
()
->
Json
<
ErrorMessage
>
{
create_status
(
Status
::
Unauthorized
)
}
#[rocket::async_trait]
impl
<'
r
>
FromRequest
<'
r
>
for
EnableWebUI
{
type
Error
=
();
async
fn
from_request
(
_req
:
&
'
r
Request
<'
_
>
)
->
request
::
Outcome
<
Self
,
Self
::
Error
>
{
let
webui
=
IS_WEBUI
.
load
(
Ordering
::
Acquire
);
if
webui
{
Outcome
::
Success
(
EnableWebUI
)
}
else
{
Outcome
::
Error
((
rocket
::
http
::
Status
::
NotFound
,
()))
}
}
}
#[rocket::async_trait]
impl
<'
r
>
FromRequest
<'
r
>
for
routes
::
Token
{
type
Error
=
();
async
fn
from_request
(
request
:
&
'
r
rocket
::
Request
<'
_
>
)
->
rocket
::
request
::
Outcome
<
Self
,
Self
::
Error
>
{
let
config
=
config
::
read
().
daemon
.
web
;
match
config
.
secure
{
Some
(
val
)
=>
{
if
!
val
.
enabled
{
return
Outcome
::
Success
(
routes
::
Token
);
}
if
let
Some
(
header_value
)
=
request
.
headers
().
get_one
(
"token"
)
{
if
header_value
==
val
.
token
{
return
Outcome
::
Success
(
routes
::
Token
);
}
}
Outcome
::
Error
((
rocket
::
http
::
Status
::
Unauthorized
,
()))
}
None
=>
return
Outcome
::
Success
(
routes
::
Token
),
}
}
}
static
IS_WEBUI
:
AtomicBool
=
AtomicBool
::
new
(
false
);
pub
async
fn
start
(
webui
:
bool
)
{
IS_WEBUI
.
store
(
webui
,
Ordering
::
Release
);
let
tera
=
webui
::
create_templates
();
let
s_path
=
config
::
read
().
get_path
().
trim_end_matches
(
'/'
).
to_string
();
let
routes
=
rocket
::
routes
!
[
embed
,
scalar
,
health
,
docs_json
,
static_assets
,
dynamic_assets
,
routes
::
login
,
routes
::
servers
,
routes
::
dashboard
,
routes
::
view_process
,
routes
::
server_status
,
routes
::
action_handler
,
routes
::
env_handler
,
routes
::
info_handler
,
routes
::
dump_handler
,
routes
::
remote_list
,
routes
::
remote_info
,
routes
::
remote_logs
,
routes
::
remote_rename
,
routes
::
remote_action
,
routes
::
servers_handler
,
routes
::
config_handler
,
routes
::
list_handler
,
routes
::
logs_handler
,
routes
::
logs_raw_handler
,
routes
::
metrics_handler
,
routes
::
remote_metrics
,
routes
::
stream_info
,
routes
::
stream_metrics
,
routes
::
prometheus_handler
,
routes
::
create_handler
,
routes
::
rename_handler
,
];
let
rocket
=
rocket
::
custom
(
config
::
read
().
get_address
())
.
attach
(
Logger
)
.
attach
(
AddCORS
)
.
manage
(
TeraState
{
path
:
tera
.
1
,
tera
:
tera
.
0
})
.
mount
(
format!
(
"{s_path}/"
),
routes
)
.
register
(
"/"
,
rocket
::
catchers
!
[
internal_error
,
bad_request
,
not_allowed
,
not_found
,
unauthorized
])
.
launch
()
.
await
;
if
let
Err
(
err
)
=
rocket
{
log
::
error
!
(
"failed to launch!
\n
{err}"
)
}
}
async
fn
render
(
name
:
&
str
,
state
:
&
State
<
TeraState
>
,
ctx
:
&
mut
Context
)
->
Result
<
String
,
NotFound
>
{
ctx
.
insert
(
"base_path"
,
&
state
.
path
);
ctx
.
insert
(
"build_version"
,
env!
(
"CARGO_PKG_VERSION"
));
state
.
tera
.
render
(
name
,
&
ctx
).
or
(
Err
(
helpers
::
not_found
(
"Page was not found"
)))
}
#[rocket::get(
"/assets/<name>"
)]
async
fn
dynamic_assets
(
name
:
String
)
->
Option
<
NamedFile
>
{
static
DIR
:
Dir
=
include_dir
!
(
"src/webui/dist/assets"
);
let
file
=
DIR
.
get_file
(
&
name
)
?
;
NamedFile
::
send
(
name
,
file
.
contents_utf8
()).
await
.
ok
()
}
#[rocket::get(
"/static/<name>"
)]
async
fn
static_assets
(
name
:
String
)
->
Option
<
NamedFile
>
{
static
DIR
:
Dir
=
include_dir
!
(
"src/daemon/static"
);
let
file
=
DIR
.
get_file
(
&
name
)
?
;
NamedFile
::
send
(
name
,
file
.
contents_utf8
()).
await
.
ok
()
}
#[rocket::get(
"/openapi.json"
)]
async
fn
docs_json
()
->
Value
{
json
!
(
ApiDoc
::
openapi
())
}
#[rocket::get(
"/docs/embed"
)]
async
fn
embed
()
->
(
ContentType
,
String
)
{
(
ContentType
::
HTML
,
docs
::
Docs
::
new
().
render
())
}
#[rocket::get(
"/docs"
)]
async
fn
scalar
(
state
:
&
State
<
TeraState
>
,
_webui
:
EnableWebUI
)
->
Result
<
(
ContentType
,
String
),
NotFound
>
{
Ok
((
ContentType
::
HTML
,
render
(
"docs"
,
&
state
,
&
mut
Context
::
new
()).
await
?
))
}
#[rocket::get(
"/health"
)]
async
fn
health
()
->
Value
{
json
!
({
"healthy"
:
true
})
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Mar 20, 3:43 AM (7 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
507320
Default Alt Text
mod.rs (7 KB)
Attached To
Mode
rPMC Process Management Controller
Attached
Detach File
Event Timeline
Log In to Comment