]> git.proxmox.com Git - proxmox-backup.git/blame - src/api2/config/media_pool.rs
fix non-camel-case enums
[proxmox-backup.git] / src / api2 / config / media_pool.rs
CommitLineData
05e90d64 1use ::serde::{Deserialize, Serialize};
dc7a5b34 2use anyhow::Error;
05e90d64 3
dc7a5b34 4use proxmox_router::{http_bail, Permission, Router, RpcEnvironment};
8d6425aa 5use proxmox_schema::{api, param_bail};
05e90d64 6
aad2d162 7use pbs_api_types::{
dc7a5b34
TL
8 Authid, MediaPoolConfig, MediaPoolConfigUpdater, MEDIA_POOL_NAME_SCHEMA, PRIV_TAPE_AUDIT,
9 PRIV_TAPE_MODIFY,
aad2d162
DM
10};
11
ba3d7e19 12use pbs_config::CachedUserInfo;
05e90d64
DM
13
14#[api(
bdb62b20 15 protected: true,
05e90d64
DM
16 input: {
17 properties: {
db04d10d
DM
18 config: {
19 type: MediaPoolConfig,
20 flatten: true,
1e93fbb5 21 },
05e90d64
DM
22 },
23 },
8cd63df0
DM
24 access: {
25 permission: &Permission::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY, false),
26 },
05e90d64
DM
27)]
28/// Create a new media pool
dc7a5b34 29pub fn create_pool(config: MediaPoolConfig) -> Result<(), Error> {
aad2d162 30 let _lock = pbs_config::media_pool::lock()?;
05e90d64 31
aad2d162 32 let (mut section_config, _digest) = pbs_config::media_pool::config()?;
05e90d64 33
db04d10d 34 if section_config.sections.get(&config.name).is_some() {
8d6425aa 35 param_bail!("name", "Media pool '{}' already exists", config.name);
05e90d64
DM
36 }
37
db04d10d 38 section_config.set_data(&config.name, "pool", &config)?;
05e90d64 39
aad2d162 40 pbs_config::media_pool::save_config(&section_config)?;
05e90d64
DM
41
42 Ok(())
43}
44
45#[api(
46 returns: {
47 description: "The list of configured media pools (with config digest).",
48 type: Array,
49 items: {
50 type: MediaPoolConfig,
51 },
52 },
8cd63df0
DM
53 access: {
54 description: "List configured media pools filtered by Tape.Audit privileges",
55 permission: &Permission::Anybody,
56 },
05e90d64
DM
57)]
58/// List media pools
41c1a179 59pub fn list_pools(rpcenv: &mut dyn RpcEnvironment) -> Result<Vec<MediaPoolConfig>, Error> {
8cd63df0
DM
60 let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
61 let user_info = CachedUserInfo::new()?;
05e90d64 62
aad2d162 63 let (config, digest) = pbs_config::media_pool::config()?;
05e90d64 64
8cd63df0
DM
65 let list = config.convert_to_typed_array::<MediaPoolConfig>("pool")?;
66
dc7a5b34 67 let list = list
8cd63df0
DM
68 .into_iter()
69 .filter(|pool| {
70 let privs = user_info.lookup_privs(&auth_id, &["tape", "pool", &pool.name]);
71 privs & PRIV_TAPE_AUDIT != 0
72 })
73 .collect();
05e90d64 74
16f6766a 75 rpcenv["digest"] = hex::encode(digest).into();
05e90d64
DM
76
77 Ok(list)
78}
79
80#[api(
81 input: {
82 properties: {
83 name: {
84 schema: MEDIA_POOL_NAME_SCHEMA,
85 },
86 },
87 },
88 returns: {
89 type: MediaPoolConfig,
90 },
8cd63df0
DM
91 access: {
92 permission: &Permission::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_AUDIT, false),
93 },
05e90d64
DM
94)]
95/// Get media pool configuration
9700d537 96pub fn get_config(name: String) -> Result<MediaPoolConfig, Error> {
aad2d162 97 let (config, _digest) = pbs_config::media_pool::config()?;
05e90d64
DM
98
99 let data: MediaPoolConfig = config.lookup("pool", &name)?;
100
101 Ok(data)
102}
103
104#[api()]
105#[derive(Serialize, Deserialize)]
05e90d64 106/// Deletable property name
9700d537 107pub enum DeletableProperty {
05e90d64 108 /// Delete media set allocation policy.
a2055c38 109 Allocation,
05e90d64 110 /// Delete pool retention policy
a2055c38 111 Retention,
05e90d64 112 /// Delete media set naming template
a2055c38 113 Template,
1e93fbb5 114 /// Delete encryption fingerprint
a2055c38 115 Encrypt,
db04d10d 116 /// Delete comment
a2055c38 117 Comment,
05e90d64
DM
118}
119
120#[api(
bdb62b20 121 protected: true,
05e90d64
DM
122 input: {
123 properties: {
124 name: {
125 schema: MEDIA_POOL_NAME_SCHEMA,
126 },
dbda1513
DM
127 update: {
128 type: MediaPoolConfigUpdater,
129 flatten: true,
db04d10d 130 },
05e90d64
DM
131 delete: {
132 description: "List of properties to delete.",
133 type: Array,
134 optional: true,
135 items: {
136 type: DeletableProperty,
137 }
138 },
139 },
140 },
8cd63df0
DM
141 access: {
142 permission: &Permission::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_MODIFY, false),
143 },
05e90d64
DM
144)]
145/// Update media pool settings
9700d537 146pub fn update_pool(
05e90d64 147 name: String,
dbda1513 148 update: MediaPoolConfigUpdater,
05e90d64
DM
149 delete: Option<Vec<DeletableProperty>>,
150) -> Result<(), Error> {
aad2d162 151 let _lock = pbs_config::media_pool::lock()?;
05e90d64 152
aad2d162 153 let (mut config, _digest) = pbs_config::media_pool::config()?;
05e90d64
DM
154
155 let mut data: MediaPoolConfig = config.lookup("pool", &name)?;
156
157 if let Some(delete) = delete {
158 for delete_prop in delete {
159 match delete_prop {
a2055c38 160 DeletableProperty::Allocation => {
dc7a5b34
TL
161 data.allocation = None;
162 }
a2055c38 163 DeletableProperty::Retention => {
dc7a5b34
TL
164 data.retention = None;
165 }
a2055c38 166 DeletableProperty::Template => {
dc7a5b34
TL
167 data.template = None;
168 }
a2055c38 169 DeletableProperty::Encrypt => {
dc7a5b34
TL
170 data.encrypt = None;
171 }
a2055c38 172 DeletableProperty::Comment => {
dc7a5b34
TL
173 data.comment = None;
174 }
05e90d64
DM
175 }
176 }
177 }
178
dc7a5b34
TL
179 if update.allocation.is_some() {
180 data.allocation = update.allocation;
181 }
182 if update.retention.is_some() {
183 data.retention = update.retention;
184 }
185 if update.template.is_some() {
186 data.template = update.template;
187 }
188 if update.encrypt.is_some() {
189 data.encrypt = update.encrypt;
190 }
05e90d64 191
dbda1513 192 if let Some(comment) = update.comment {
db04d10d
DM
193 let comment = comment.trim();
194 if comment.is_empty() {
195 data.comment = None;
196 } else {
197 data.comment = Some(comment.to_string());
198 }
199 }
200
05e90d64
DM
201 config.set_data(&name, "pool", &data)?;
202
aad2d162 203 pbs_config::media_pool::save_config(&config)?;
05e90d64
DM
204
205 Ok(())
206}
207
208#[api(
bdb62b20 209 protected: true,
05e90d64
DM
210 input: {
211 properties: {
212 name: {
213 schema: MEDIA_POOL_NAME_SCHEMA,
214 },
215 },
216 },
8cd63df0
DM
217 access: {
218 permission: &Permission::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_MODIFY, false),
219 },
05e90d64
DM
220)]
221/// Delete a media pool configuration
9700d537 222pub fn delete_pool(name: String) -> Result<(), Error> {
aad2d162 223 let _lock = pbs_config::media_pool::lock()?;
05e90d64 224
aad2d162 225 let (mut config, _digest) = pbs_config::media_pool::config()?;
05e90d64
DM
226
227 match config.sections.get(&name) {
dc7a5b34
TL
228 Some(_) => {
229 config.sections.remove(&name);
230 }
dcd1518e 231 None => http_bail!(NOT_FOUND, "delete pool '{}' failed - no such pool", name),
05e90d64
DM
232 }
233
aad2d162 234 pbs_config::media_pool::save_config(&config)?;
05e90d64
DM
235
236 Ok(())
237}
238
239const ITEM_ROUTER: Router = Router::new()
240 .get(&API_METHOD_GET_CONFIG)
241 .put(&API_METHOD_UPDATE_POOL)
242 .delete(&API_METHOD_DELETE_POOL);
243
05e90d64
DM
244pub const ROUTER: Router = Router::new()
245 .get(&API_METHOD_LIST_POOLS)
246 .post(&API_METHOD_CREATE_POOL)
247 .match_all("name", &ITEM_ROUTER);