1 use anyhow
::{bail, Error}
;
2 use ::serde
::{Deserialize, Serialize}
;
16 MEDIA_POOL_NAME_SCHEMA
,
18 MediaPoolConfigUpdater
,
22 cached_user_info
::CachedUserInfo
,
35 type: MediaPoolConfig
,
41 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
44 /// Create a new media pool
46 config
: MediaPoolConfig
,
47 ) -> Result
<(), Error
> {
49 let _lock
= config
::media_pool
::lock()?
;
51 let (mut section_config
, _digest
) = config
::media_pool
::config()?
;
53 if section_config
.sections
.get(&config
.name
).is_some() {
54 bail
!("Media pool '{}' already exists", config
.name
);
57 section_config
.set_data(&config
.name
, "pool", &config
)?
;
59 config
::media_pool
::save_config(§ion_config
)?
;
66 description
: "The list of configured media pools (with config digest).",
69 type: MediaPoolConfig
,
73 description
: "List configured media pools filtered by Tape.Audit privileges",
74 permission
: &Permission
::Anybody
,
79 mut rpcenv
: &mut dyn RpcEnvironment
,
80 ) -> Result
<Vec
<MediaPoolConfig
>, Error
> {
81 let auth_id
: Authid
= rpcenv
.get_auth_id().unwrap().parse()?
;
82 let user_info
= CachedUserInfo
::new()?
;
84 let (config
, digest
) = config
::media_pool
::config()?
;
86 let list
= config
.convert_to_typed_array
::<MediaPoolConfig
>("pool")?
;
91 let privs
= user_info
.lookup_privs(&auth_id
, &["tape", "pool", &pool
.name
]);
92 privs
& PRIV_TAPE_AUDIT
!= 0
96 rpcenv
["digest"] = proxmox
::tools
::digest_to_hex(&digest
).into();
105 schema
: MEDIA_POOL_NAME_SCHEMA
,
110 type: MediaPoolConfig
,
113 permission
: &Permission
::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_AUDIT
, false),
116 /// Get media pool configuration
117 pub fn get_config(name
: String
) -> Result
<MediaPoolConfig
, Error
> {
119 let (config
, _digest
) = config
::media_pool
::config()?
;
121 let data
: MediaPoolConfig
= config
.lookup("pool", &name
)?
;
127 #[derive(Serialize, Deserialize)]
128 #[allow(non_camel_case_types)]
129 /// Deletable property name
130 pub enum DeletableProperty
{
131 /// Delete media set allocation policy.
133 /// Delete pool retention policy
135 /// Delete media set naming template
137 /// Delete encryption fingerprint
148 schema
: MEDIA_POOL_NAME_SCHEMA
,
151 type: MediaPoolConfigUpdater
,
155 description
: "List of properties to delete.",
159 type: DeletableProperty
,
165 permission
: &Permission
::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_MODIFY
, false),
168 /// Update media pool settings
171 update
: MediaPoolConfigUpdater
,
172 delete
: Option
<Vec
<DeletableProperty
>>,
173 ) -> Result
<(), Error
> {
175 let _lock
= config
::media_pool
::lock()?
;
177 let (mut config
, _digest
) = config
::media_pool
::config()?
;
179 let mut data
: MediaPoolConfig
= config
.lookup("pool", &name
)?
;
181 if let Some(delete
) = delete
{
182 for delete_prop
in delete
{
184 DeletableProperty
::allocation
=> { data.allocation = None; }
,
185 DeletableProperty
::retention
=> { data.retention = None; }
,
186 DeletableProperty
::template
=> { data.template = None; }
,
187 DeletableProperty
::encrypt
=> { data.encrypt = None; }
,
188 DeletableProperty
::comment
=> { data.comment = None; }
,
193 if update
.allocation
.is_some() { data.allocation = update.allocation; }
194 if update
.retention
.is_some() { data.retention = update.retention; }
195 if update
.template
.is_some() { data.template = update.template; }
196 if update
.encrypt
.is_some() { data.encrypt = update.encrypt; }
198 if let Some(comment
) = update
.comment
{
199 let comment
= comment
.trim();
200 if comment
.is_empty() {
203 data
.comment
= Some(comment
.to_string());
207 config
.set_data(&name
, "pool", &data
)?
;
209 config
::media_pool
::save_config(&config
)?
;
219 schema
: MEDIA_POOL_NAME_SCHEMA
,
224 permission
: &Permission
::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_MODIFY
, false),
227 /// Delete a media pool configuration
228 pub fn delete_pool(name
: String
) -> Result
<(), Error
> {
230 let _lock
= config
::media_pool
::lock()?
;
232 let (mut config
, _digest
) = config
::media_pool
::config()?
;
234 match config
.sections
.get(&name
) {
235 Some(_
) => { config.sections.remove(&name); }
,
236 None
=> bail
!("delete pool '{}' failed - no such pool", name
),
239 config
::media_pool
::save_config(&config
)?
;
244 const ITEM_ROUTER
: Router
= Router
::new()
245 .get(&API_METHOD_GET_CONFIG
)
246 .put(&API_METHOD_UPDATE_POOL
)
247 .delete(&API_METHOD_DELETE_POOL
);
250 pub const ROUTER
: Router
= Router
::new()
251 .get(&API_METHOD_LIST_POOLS
)
252 .post(&API_METHOD_CREATE_POOL
)
253 .match_all("name", &ITEM_ROUTER
);