]> git.proxmox.com Git - proxmox-backup.git/blob - src/api2/admin/verify.rs
moved tape_job.rs to pbs_config workspace
[proxmox-backup.git] / src / api2 / admin / verify.rs
1 //! Datastore Verify Job Management
2
3 use anyhow::{format_err, Error};
4 use serde_json::Value;
5
6 use proxmox::api::router::SubdirMap;
7 use proxmox::{list_subdirs_api_method, sortable};
8 use proxmox::api::{api, ApiMethod, Permission, Router, RpcEnvironment};
9
10 use pbs_api_types::{VerificationJobConfig, VerificationJobStatus, JOB_ID_SCHEMA, Authid};
11
12 use crate::{
13 api2::types::{
14 DATASTORE_SCHEMA,
15 },
16 server::{
17 do_verification_job,
18 jobstate::{
19 Job,
20 JobState,
21 compute_schedule_status,
22 },
23 },
24 config::{
25 verify,
26 acl::{
27 PRIV_DATASTORE_AUDIT,
28 PRIV_DATASTORE_VERIFY,
29 },
30 cached_user_info::CachedUserInfo,
31 },
32 };
33
34
35 #[api(
36 input: {
37 properties: {
38 store: {
39 schema: DATASTORE_SCHEMA,
40 optional: true,
41 },
42 },
43 },
44 returns: {
45 description: "List configured jobs and their status (filtered by access)",
46 type: Array,
47 items: { type: VerificationJobStatus },
48 },
49 access: {
50 permission: &Permission::Anybody,
51 description: "Requires Datastore.Audit or Datastore.Verify on datastore.",
52 },
53 )]
54 /// List all verification jobs
55 pub fn list_verification_jobs(
56 store: Option<String>,
57 _param: Value,
58 mut rpcenv: &mut dyn RpcEnvironment,
59 ) -> Result<Vec<VerificationJobStatus>, Error> {
60 let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
61 let user_info = CachedUserInfo::new()?;
62
63 let required_privs = PRIV_DATASTORE_AUDIT | PRIV_DATASTORE_VERIFY;
64
65 let (config, digest) = verify::config()?;
66
67 let job_config_iter = config
68 .convert_to_typed_array("verification")?
69 .into_iter()
70 .filter(|job: &VerificationJobConfig| {
71 let privs = user_info.lookup_privs(&auth_id, &["datastore", &job.store]);
72 if privs & required_privs == 0 {
73 return false;
74 }
75
76 if let Some(store) = &store {
77 &job.store == store
78 } else {
79 true
80 }
81 });
82
83 let mut list = Vec::new();
84
85 for job in job_config_iter {
86 let last_state = JobState::load("verificationjob", &job.id)
87 .map_err(|err| format_err!("could not open statefile for {}: {}", &job.id, err))?;
88
89 let status = compute_schedule_status(&last_state, job.schedule.as_deref())?;
90
91 list.push(VerificationJobStatus { config: job, status });
92 }
93
94 rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into();
95
96 Ok(list)
97 }
98
99 #[api(
100 input: {
101 properties: {
102 id: {
103 schema: JOB_ID_SCHEMA,
104 }
105 }
106 },
107 access: {
108 permission: &Permission::Anybody,
109 description: "Requires Datastore.Verify on job's datastore.",
110 },
111 )]
112 /// Runs a verification job manually.
113 pub fn run_verification_job(
114 id: String,
115 _info: &ApiMethod,
116 rpcenv: &mut dyn RpcEnvironment,
117 ) -> Result<String, Error> {
118 let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
119 let user_info = CachedUserInfo::new()?;
120
121 let (config, _digest) = verify::config()?;
122 let verification_job: VerificationJobConfig = config.lookup("verification", &id)?;
123
124 user_info.check_privs(&auth_id, &["datastore", &verification_job.store], PRIV_DATASTORE_VERIFY, true)?;
125
126 let job = Job::new("verificationjob", &id)?;
127
128 let upid_str = do_verification_job(job, verification_job, &auth_id, None)?;
129
130 Ok(upid_str)
131 }
132
133 #[sortable]
134 const VERIFICATION_INFO_SUBDIRS: SubdirMap = &[("run", &Router::new().post(&API_METHOD_RUN_VERIFICATION_JOB))];
135
136 const VERIFICATION_INFO_ROUTER: Router = Router::new()
137 .get(&list_subdirs_api_method!(VERIFICATION_INFO_SUBDIRS))
138 .subdirs(VERIFICATION_INFO_SUBDIRS);
139
140 pub const ROUTER: Router = Router::new()
141 .get(&API_METHOD_LIST_VERIFICATION_JOBS)
142 .match_all("id", &VERIFICATION_INFO_ROUTER);