src/api2/node/services.rs: add access permissions
This commit is contained in:
parent
68ed0c629d
commit
1cf7bbf412
@ -4,12 +4,12 @@ use failure::*;
|
|||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
use proxmox::{sortable, identity, list_subdirs_api_method};
|
use proxmox::{sortable, identity, list_subdirs_api_method};
|
||||||
use proxmox::api::{ApiHandler, ApiMethod, Router, RpcEnvironment};
|
use proxmox::api::{api, Router, Permission};
|
||||||
use proxmox::api::router::SubdirMap;
|
use proxmox::api::router::SubdirMap;
|
||||||
use proxmox::api::schema::*;
|
use proxmox::api::schema::*;
|
||||||
|
|
||||||
use crate::api2::types::*;
|
use crate::api2::types::*;
|
||||||
use crate::tools;
|
use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_SYS_MODIFY};
|
||||||
|
|
||||||
static SERVICE_NAME_LIST: [&str; 7] = [
|
static SERVICE_NAME_LIST: [&str; 7] = [
|
||||||
"proxmox-backup",
|
"proxmox-backup",
|
||||||
@ -91,11 +91,45 @@ fn json_service_state(service: &str, status: Value) -> Value {
|
|||||||
Value::Null
|
Value::Null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
input: {
|
||||||
|
properties: {
|
||||||
|
node: {
|
||||||
|
schema: NODE_SCHEMA,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
description: "Returns a list of systemd services.",
|
||||||
|
type: Array,
|
||||||
|
items: {
|
||||||
|
description: "Service details.",
|
||||||
|
properties: {
|
||||||
|
service: {
|
||||||
|
schema: SERVICE_ID_SCHEMA,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
description: "systemd service name.",
|
||||||
|
},
|
||||||
|
desc: {
|
||||||
|
type: String,
|
||||||
|
description: "systemd service description.",
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
type: String,
|
||||||
|
description: "systemd service 'SubState'.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
permission: &Permission::Privilege(&[], PRIV_SYS_AUDIT, false),
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
/// Service list.
|
||||||
fn list_services(
|
fn list_services(
|
||||||
_param: Value,
|
_param: Value,
|
||||||
_info: &ApiMethod,
|
|
||||||
_rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<Value, Error> {
|
) -> Result<Value, Error> {
|
||||||
|
|
||||||
let mut list = vec![];
|
let mut list = vec![];
|
||||||
@ -115,21 +149,36 @@ fn list_services(
|
|||||||
Ok(Value::from(list))
|
Ok(Value::from(list))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
input: {
|
||||||
|
properties: {
|
||||||
|
node: {
|
||||||
|
schema: NODE_SCHEMA,
|
||||||
|
},
|
||||||
|
service: {
|
||||||
|
schema: SERVICE_ID_SCHEMA,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
permission: &Permission::Privilege(&[], PRIV_SYS_AUDIT, false),
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
/// Read service properties.
|
||||||
fn get_service_state(
|
fn get_service_state(
|
||||||
param: Value,
|
service: String,
|
||||||
_info: &ApiMethod,
|
_param: Value,
|
||||||
_rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<Value, Error> {
|
) -> Result<Value, Error> {
|
||||||
|
|
||||||
let service = tools::required_string_param(¶m, "service")?;
|
let service = service.as_str();
|
||||||
|
|
||||||
if !SERVICE_NAME_LIST.contains(&service) {
|
if !SERVICE_NAME_LIST.contains(&service) {
|
||||||
bail!("unknown service name '{}'", service);
|
bail!("unknown service name '{}'", service);
|
||||||
}
|
}
|
||||||
|
|
||||||
let status = get_full_service_state(service)?;
|
let status = get_full_service_state(&service)?;
|
||||||
|
|
||||||
Ok(json_service_state(service, status))
|
Ok(json_service_state(&service, status))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_service_command(service: &str, cmd: &str) -> Result<Value, Error> {
|
fn run_service_command(service: &str, cmd: &str) -> Result<Value, Error> {
|
||||||
@ -158,61 +207,117 @@ fn run_service_command(service: &str, cmd: &str) -> Result<Value, Error> {
|
|||||||
Ok(Value::Null)
|
Ok(Value::Null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
protected: true,
|
||||||
|
input: {
|
||||||
|
properties: {
|
||||||
|
node: {
|
||||||
|
schema: NODE_SCHEMA,
|
||||||
|
},
|
||||||
|
service: {
|
||||||
|
schema: SERVICE_ID_SCHEMA,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
permission: &Permission::Privilege(&[], PRIV_SYS_MODIFY, false),
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
/// Start service.
|
||||||
fn start_service(
|
fn start_service(
|
||||||
param: Value,
|
service: String,
|
||||||
_info: &ApiMethod,
|
_param: Value,
|
||||||
_rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<Value, Error> {
|
) -> Result<Value, Error> {
|
||||||
|
|
||||||
let service = tools::required_string_param(¶m, "service")?;
|
|
||||||
|
|
||||||
log::info!("starting service {}", service);
|
log::info!("starting service {}", service);
|
||||||
|
|
||||||
run_service_command(service, "start")
|
run_service_command(&service, "start")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
protected: true,
|
||||||
|
input: {
|
||||||
|
properties: {
|
||||||
|
node: {
|
||||||
|
schema: NODE_SCHEMA,
|
||||||
|
},
|
||||||
|
service: {
|
||||||
|
schema: SERVICE_ID_SCHEMA,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
permission: &Permission::Privilege(&[], PRIV_SYS_MODIFY, false),
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
/// Stop service.
|
||||||
fn stop_service(
|
fn stop_service(
|
||||||
param: Value,
|
service: String,
|
||||||
_info: &ApiMethod,
|
_param: Value,
|
||||||
_rpcenv: &mut dyn RpcEnvironment,
|
) -> Result<Value, Error> {
|
||||||
) -> Result<Value, Error> {
|
|
||||||
|
|
||||||
let service = tools::required_string_param(¶m, "service")?;
|
|
||||||
|
|
||||||
log::info!("stoping service {}", service);
|
log::info!("stoping service {}", service);
|
||||||
|
|
||||||
run_service_command(service, "stop")
|
run_service_command(&service, "stop")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
protected: true,
|
||||||
|
input: {
|
||||||
|
properties: {
|
||||||
|
node: {
|
||||||
|
schema: NODE_SCHEMA,
|
||||||
|
},
|
||||||
|
service: {
|
||||||
|
schema: SERVICE_ID_SCHEMA,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
permission: &Permission::Privilege(&[], PRIV_SYS_MODIFY, false),
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
/// Retart service.
|
||||||
fn restart_service(
|
fn restart_service(
|
||||||
param: Value,
|
service: String,
|
||||||
_info: &ApiMethod,
|
_param: Value,
|
||||||
_rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<Value, Error> {
|
) -> Result<Value, Error> {
|
||||||
|
|
||||||
let service = tools::required_string_param(¶m, "service")?;
|
|
||||||
|
|
||||||
log::info!("re-starting service {}", service);
|
log::info!("re-starting service {}", service);
|
||||||
|
|
||||||
if service == "proxmox-backup-proxy" {
|
if &service == "proxmox-backup-proxy" {
|
||||||
// special case, avoid aborting running tasks
|
// special case, avoid aborting running tasks
|
||||||
run_service_command(service, "reload")
|
run_service_command(&service, "reload")
|
||||||
} else {
|
} else {
|
||||||
run_service_command(service, "restart")
|
run_service_command(&service, "restart")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
protected: true,
|
||||||
|
input: {
|
||||||
|
properties: {
|
||||||
|
node: {
|
||||||
|
schema: NODE_SCHEMA,
|
||||||
|
},
|
||||||
|
service: {
|
||||||
|
schema: SERVICE_ID_SCHEMA,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
permission: &Permission::Privilege(&[], PRIV_SYS_MODIFY, false),
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
/// Reload service.
|
||||||
fn reload_service(
|
fn reload_service(
|
||||||
param: Value,
|
service: String,
|
||||||
_info: &ApiMethod,
|
_param: Value,
|
||||||
_rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<Value, Error> {
|
) -> Result<Value, Error> {
|
||||||
|
|
||||||
let service = tools::required_string_param(¶m, "service")?;
|
|
||||||
|
|
||||||
log::info!("reloading service {}", service);
|
log::info!("reloading service {}", service);
|
||||||
|
|
||||||
run_service_command(service, "reload")
|
run_service_command(&service, "reload")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -221,111 +326,33 @@ const SERVICE_ID_SCHEMA: Schema = StringSchema::new("Service ID.")
|
|||||||
.schema();
|
.schema();
|
||||||
|
|
||||||
#[sortable]
|
#[sortable]
|
||||||
const SERVICE_SUBDIRS: SubdirMap = &[
|
const SERVICE_SUBDIRS: SubdirMap = &sorted!([
|
||||||
(
|
(
|
||||||
"reload", &Router::new()
|
"reload", &Router::new()
|
||||||
.post(
|
.post(&API_METHOD_RELOAD_SERVICE)
|
||||||
&ApiMethod::new(
|
|
||||||
&ApiHandler::Sync(&reload_service),
|
|
||||||
&ObjectSchema::new(
|
|
||||||
"Reload service.",
|
|
||||||
&sorted!([
|
|
||||||
("node", false, &NODE_SCHEMA),
|
|
||||||
("service", false, &SERVICE_ID_SCHEMA),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
).protected(true)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"restart", &Router::new()
|
"restart", &Router::new()
|
||||||
.post(
|
.post(&API_METHOD_RESTART_SERVICE)
|
||||||
&ApiMethod::new(
|
|
||||||
&ApiHandler::Sync(&restart_service),
|
|
||||||
&ObjectSchema::new(
|
|
||||||
"Restart service.",
|
|
||||||
&sorted!([
|
|
||||||
("node", false, &NODE_SCHEMA),
|
|
||||||
("service", false, &SERVICE_ID_SCHEMA),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
).protected(true)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"start", &Router::new()
|
"start", &Router::new()
|
||||||
.post(
|
.post(&API_METHOD_START_SERVICE)
|
||||||
&ApiMethod::new(
|
|
||||||
&ApiHandler::Sync(&start_service),
|
|
||||||
&ObjectSchema::new(
|
|
||||||
"Start service.",
|
|
||||||
&sorted!([
|
|
||||||
("node", false, &NODE_SCHEMA),
|
|
||||||
("service", false, &SERVICE_ID_SCHEMA),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
).protected(true)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"state", &Router::new()
|
"state", &Router::new()
|
||||||
.get(
|
.get(&API_METHOD_GET_SERVICE_STATE)
|
||||||
&ApiMethod::new(
|
|
||||||
&ApiHandler::Sync(&get_service_state),
|
|
||||||
&ObjectSchema::new(
|
|
||||||
"Read service properties.",
|
|
||||||
&sorted!([
|
|
||||||
("node", false, &NODE_SCHEMA),
|
|
||||||
("service", false, &SERVICE_ID_SCHEMA),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"stop", &Router::new()
|
"stop", &Router::new()
|
||||||
.post(
|
.post(&API_METHOD_STOP_SERVICE)
|
||||||
&ApiMethod::new(
|
|
||||||
&ApiHandler::Sync(&stop_service),
|
|
||||||
&ObjectSchema::new(
|
|
||||||
"Stop service.",
|
|
||||||
&sorted!([
|
|
||||||
("node", false, &NODE_SCHEMA),
|
|
||||||
("service", false, &SERVICE_ID_SCHEMA),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
).protected(true)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
];
|
]);
|
||||||
|
|
||||||
const SERVICE_ROUTER: Router = Router::new()
|
const SERVICE_ROUTER: Router = Router::new()
|
||||||
.get(&list_subdirs_api_method!(SERVICE_SUBDIRS))
|
.get(&list_subdirs_api_method!(SERVICE_SUBDIRS))
|
||||||
.subdirs(SERVICE_SUBDIRS);
|
.subdirs(SERVICE_SUBDIRS);
|
||||||
|
|
||||||
#[sortable]
|
|
||||||
pub const ROUTER: Router = Router::new()
|
pub const ROUTER: Router = Router::new()
|
||||||
.get(
|
.get(&API_METHOD_LIST_SERVICES)
|
||||||
&ApiMethod::new(
|
|
||||||
&ApiHandler::Sync(&list_services),
|
|
||||||
&ObjectSchema::new(
|
|
||||||
"Service list.",
|
|
||||||
&sorted!([ ("node", false, &NODE_SCHEMA) ]),
|
|
||||||
)
|
|
||||||
).returns(
|
|
||||||
&ArraySchema::new(
|
|
||||||
"Returns a list of systemd services.",
|
|
||||||
&ObjectSchema::new(
|
|
||||||
"Service details.",
|
|
||||||
&sorted!([
|
|
||||||
("service", false, &SERVICE_ID_SCHEMA),
|
|
||||||
("name", false, &StringSchema::new("systemd service name.").schema()),
|
|
||||||
("desc", false, &StringSchema::new("systemd service description.").schema()),
|
|
||||||
("state", false, &StringSchema::new("systemd service 'SubState'.").schema()),
|
|
||||||
]),
|
|
||||||
).schema()
|
|
||||||
).schema()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.match_all("service", &SERVICE_ROUTER);
|
.match_all("service", &SERVICE_ROUTER);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user