From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id A7E1768C32 for ; Fri, 10 Sep 2021 14:52:10 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 96FBA1546E for ; Fri, 10 Sep 2021 14:51:40 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id D1D1C1545F for ; Fri, 10 Sep 2021 14:51:39 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 62E594467A for ; Fri, 10 Sep 2021 14:43:37 +0200 (CEST) To: pbs-devel@lists.proxmox.com, Dominik Csapak References: <20210906105755.2651203-1-d.csapak@proxmox.com> <20210906105755.2651203-9-d.csapak@proxmox.com> From: Fabian Ebner Message-ID: <1508b04a-597b-9744-5e52-16a5c7c6af41@proxmox.com> Date: Fri, 10 Sep 2021 14:43:36 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 MIME-Version: 1.0 In-Reply-To: <20210906105755.2651203-9-d.csapak@proxmox.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-SPAM-LEVEL: Spam detection results: 0 AWL 1.346 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment NICE_REPLY_A -1.975 Looks like a legit reply (A) SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [datastore.rs] Subject: Re: [pbs-devel] [PATCH proxmox-backup 08/12] api2/admin/datastore: add get/set_protection X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Sep 2021 12:52:10 -0000 Am 06.09.21 um 12:57 schrieb Dominik Csapak: > for gettin/setting the protected flag for snapshots (akin to notes) > For notes, there is a 'show' command, but not for protected. Is there an other way to query the current protection of a single snapshot via proxmox-backup-client? I'm working on bug #3307, which is the same feature for PVE and for integration with the PBS plugin it would be nicer to query only the single snapshot. Or should I list the whole group and extract the info from there instead? > Signed-off-by: Dominik Csapak > --- > src/api2/admin/datastore.rs | 101 ++++++++++++++++++++++++++++++++++++ > 1 file changed, 101 insertions(+) > > diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs > index f88fd105..572c65a9 100644 > --- a/src/api2/admin/datastore.rs > +++ b/src/api2/admin/datastore.rs > @@ -1751,6 +1751,101 @@ pub fn set_notes( > Ok(()) > } > > +#[api( > + input: { > + properties: { > + store: { > + schema: DATASTORE_SCHEMA, > + }, > + "backup-type": { > + schema: BACKUP_TYPE_SCHEMA, > + }, > + "backup-id": { > + schema: BACKUP_ID_SCHEMA, > + }, > + "backup-time": { > + schema: BACKUP_TIME_SCHEMA, > + }, > + }, > + }, > + access: { > + permission: &Permission::Privilege(&["datastore", "{store}"], PRIV_DATASTORE_AUDIT | PRIV_DATASTORE_BACKUP, true), > + }, > +)] > +/// Query protection for a specific backup > +pub fn get_protection( > + store: String, > + backup_type: String, > + backup_id: String, > + backup_time: i64, > + rpcenv: &mut dyn RpcEnvironment, > +) -> Result { > + let datastore = DataStore::lookup_datastore(&store)?; > + > + let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; > + let backup_dir = BackupDir::new(backup_type, backup_id, backup_time)?; > + > + check_priv_or_backup_owner(&datastore, backup_dir.group(), &auth_id, PRIV_DATASTORE_AUDIT)?; > + > + let protected_path = backup_dir.protected_file(datastore.base_path()); > + > + Ok(protected_path.exists()) > +} > + > +#[api( > + input: { > + properties: { > + store: { > + schema: DATASTORE_SCHEMA, > + }, > + "backup-type": { > + schema: BACKUP_TYPE_SCHEMA, > + }, > + "backup-id": { > + schema: BACKUP_ID_SCHEMA, > + }, > + "backup-time": { > + schema: BACKUP_TIME_SCHEMA, > + }, > + protected: { > + description: "Enable/disable protection.", > + }, > + }, > + }, > + access: { > + permission: &Permission::Privilege(&["datastore", "{store}"], > + PRIV_DATASTORE_MODIFY | PRIV_DATASTORE_BACKUP, > + true), > + }, > +)] > +/// En- or disable protection for a specific backup > +pub fn set_protection( > + store: String, > + backup_type: String, > + backup_id: String, > + backup_time: i64, > + protected: bool, > + rpcenv: &mut dyn RpcEnvironment, > +) -> Result<(), Error> { > + let datastore = DataStore::lookup_datastore(&store)?; > + > + let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; > + let backup_dir = BackupDir::new(backup_type, backup_id, backup_time)?; > + > + check_priv_or_backup_owner(&datastore, backup_dir.group(), &auth_id, PRIV_DATASTORE_MODIFY)?; > + > + let protected_path = backup_dir.protected_file(datastore.base_path()); > + if protected { > + std::fs::File::create(protected_path) > + .map_err(|err| format_err!("could not create protection file: {}", err))?; > + } else { > + std::fs::remove_file(protected_path) > + .map_err(|err| format_err!("could not remove protection file: {}", err))?; > + } > + > + Ok(()) > +} > + > #[api( > input: { > properties: { > @@ -1899,6 +1994,12 @@ const DATASTORE_INFO_SUBDIRS: SubdirMap = &[ > .get(&API_METHOD_GET_NOTES) > .put(&API_METHOD_SET_NOTES) > ), > + ( > + "protected", > + &Router::new() > + .get(&API_METHOD_GET_PROTECTION) > + .put(&API_METHOD_SET_PROTECTION) > + ), > ( > "prune", > &Router::new() >