1 use anyhow
::{bail, Error}
;
2 use ::serde
::{Deserialize, Serialize}
;
4 use proxmox_router
::{Router, RpcEnvironment, Permission}
;
5 use proxmox_schema
::api
;
8 Authid
, MediaPoolConfig
, MediaPoolConfigUpdater
, MEDIA_POOL_NAME_SCHEMA
,
9 PRIV_TAPE_AUDIT
, PRIV_TAPE_MODIFY
,
12 use pbs_config
::CachedUserInfo
;
19 type: MediaPoolConfig
,
25 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
28 /// Create a new media pool
30 config
: MediaPoolConfig
,
31 ) -> Result
<(), Error
> {
33 let _lock
= pbs_config
::media_pool
::lock()?
;
35 let (mut section_config
, _digest
) = pbs_config
::media_pool
::config()?
;
37 if section_config
.sections
.get(&config
.name
).is_some() {
38 bail
!("Media pool '{}' already exists", config
.name
);
41 section_config
.set_data(&config
.name
, "pool", &config
)?
;
43 pbs_config
::media_pool
::save_config(§ion_config
)?
;
50 description
: "The list of configured media pools (with config digest).",
53 type: MediaPoolConfig
,
57 description
: "List configured media pools filtered by Tape.Audit privileges",
58 permission
: &Permission
::Anybody
,
63 mut rpcenv
: &mut dyn RpcEnvironment
,
64 ) -> Result
<Vec
<MediaPoolConfig
>, Error
> {
65 let auth_id
: Authid
= rpcenv
.get_auth_id().unwrap().parse()?
;
66 let user_info
= CachedUserInfo
::new()?
;
68 let (config
, digest
) = pbs_config
::media_pool
::config()?
;
70 let list
= config
.convert_to_typed_array
::<MediaPoolConfig
>("pool")?
;
75 let privs
= user_info
.lookup_privs(&auth_id
, &["tape", "pool", &pool
.name
]);
76 privs
& PRIV_TAPE_AUDIT
!= 0
80 rpcenv
["digest"] = proxmox
::tools
::digest_to_hex(&digest
).into();
89 schema
: MEDIA_POOL_NAME_SCHEMA
,
94 type: MediaPoolConfig
,
97 permission
: &Permission
::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_AUDIT
, false),
100 /// Get media pool configuration
101 pub fn get_config(name
: String
) -> Result
<MediaPoolConfig
, Error
> {
103 let (config
, _digest
) = pbs_config
::media_pool
::config()?
;
105 let data
: MediaPoolConfig
= config
.lookup("pool", &name
)?
;
111 #[derive(Serialize, Deserialize)]
112 #[allow(non_camel_case_types)]
113 /// Deletable property name
114 pub enum DeletableProperty
{
115 /// Delete media set allocation policy.
117 /// Delete pool retention policy
119 /// Delete media set naming template
121 /// Delete encryption fingerprint
132 schema
: MEDIA_POOL_NAME_SCHEMA
,
135 type: MediaPoolConfigUpdater
,
139 description
: "List of properties to delete.",
143 type: DeletableProperty
,
149 permission
: &Permission
::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_MODIFY
, false),
152 /// Update media pool settings
155 update
: MediaPoolConfigUpdater
,
156 delete
: Option
<Vec
<DeletableProperty
>>,
157 ) -> Result
<(), Error
> {
159 let _lock
= pbs_config
::media_pool
::lock()?
;
161 let (mut config
, _digest
) = pbs_config
::media_pool
::config()?
;
163 let mut data
: MediaPoolConfig
= config
.lookup("pool", &name
)?
;
165 if let Some(delete
) = delete
{
166 for delete_prop
in delete
{
168 DeletableProperty
::allocation
=> { data.allocation = None; }
,
169 DeletableProperty
::retention
=> { data.retention = None; }
,
170 DeletableProperty
::template
=> { data.template = None; }
,
171 DeletableProperty
::encrypt
=> { data.encrypt = None; }
,
172 DeletableProperty
::comment
=> { data.comment = None; }
,
177 if update
.allocation
.is_some() { data.allocation = update.allocation; }
178 if update
.retention
.is_some() { data.retention = update.retention; }
179 if update
.template
.is_some() { data.template = update.template; }
180 if update
.encrypt
.is_some() { data.encrypt = update.encrypt; }
182 if let Some(comment
) = update
.comment
{
183 let comment
= comment
.trim();
184 if comment
.is_empty() {
187 data
.comment
= Some(comment
.to_string());
191 config
.set_data(&name
, "pool", &data
)?
;
193 pbs_config
::media_pool
::save_config(&config
)?
;
203 schema
: MEDIA_POOL_NAME_SCHEMA
,
208 permission
: &Permission
::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_MODIFY
, false),
211 /// Delete a media pool configuration
212 pub fn delete_pool(name
: String
) -> Result
<(), Error
> {
214 let _lock
= pbs_config
::media_pool
::lock()?
;
216 let (mut config
, _digest
) = pbs_config
::media_pool
::config()?
;
218 match config
.sections
.get(&name
) {
219 Some(_
) => { config.sections.remove(&name); }
,
220 None
=> bail
!("delete pool '{}' failed - no such pool", name
),
223 pbs_config
::media_pool
::save_config(&config
)?
;
228 const ITEM_ROUTER
: Router
= Router
::new()
229 .get(&API_METHOD_GET_CONFIG
)
230 .put(&API_METHOD_UPDATE_POOL
)
231 .delete(&API_METHOD_DELETE_POOL
);
234 pub const ROUTER
: Router
= Router
::new()
235 .get(&API_METHOD_LIST_POOLS
)
236 .post(&API_METHOD_CREATE_POOL
)
237 .match_all("name", &ITEM_ROUTER
);