From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id EF5661FF0E4 for ; Tue, 28 Jul 2026 16:26:39 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 7FD46206D8; Tue, 28 Jul 2026 16:26:39 +0200 (CEST) Message-ID: Date: Tue, 28 Jul 2026 16:26:35 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird From: Christian Ebner Subject: Re: [PATCH proxmox-backup 1/2] manager: user: make 'user generate-token' accept --output-format To: Christoph Heiss , pbs-devel@lists.proxmox.com References: <20260716103108.724902-1-c.heiss@proxmox.com> <20260716103108.724902-2-c.heiss@proxmox.com> Content-Language: en-US, de-DE In-Reply-To: <20260716103108.724902-2-c.heiss@proxmox.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1785248759587 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.152 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_LOW -0.7 Sender listed at https://www.dnswl.org/, low trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 5FTT2BV7SH5Q4NUTB5ZVJJ3P6CXGNVMO X-Message-ID-Hash: 5FTT2BV7SH5Q4NUTB5ZVJJ3P6CXGNVMO X-MailFrom: c.ebner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: NACK: This introduces a regression, as now all the previously optional parameters cannot specified anymore since not declared in the api schema for the command. On 7/16/26 12:31 PM, Christoph Heiss wrote: > Needs a small wrapper (like most other commands) to parse the option and > print the result formatted appropriately. > > Before, when invoking 'proxmox-backup-manager user generate-token [..]', > the output would be a mix of human-readable and machine-readable: > > Result: { > "tokenid": "root@pam!my-token", > "value": ".." > } > > Signed-off-by: Christoph Heiss > --- > Ran across this while working on something else, definitely worth > fixing. > > src/bin/proxmox_backup_manager/user.rs | 39 ++++++++++++++++++++++++-- > 1 file changed, 37 insertions(+), 2 deletions(-) > > diff --git a/src/bin/proxmox_backup_manager/user.rs b/src/bin/proxmox_backup_manager/user.rs > index 87c1f4394..a429823de 100644 > --- a/src/bin/proxmox_backup_manager/user.rs > +++ b/src/bin/proxmox_backup_manager/user.rs > @@ -6,7 +6,7 @@ use std::collections::HashMap; > use proxmox_router::{ApiHandler, RpcEnvironment, cli::*}; > use proxmox_schema::api; > > -use pbs_api_types::{ACL_PATH_SCHEMA, Authid, Userid}; > +use pbs_api_types::{ACL_PATH_SCHEMA, Authid, Tokenname, Userid}; > > use proxmox_backup::api2; > > @@ -101,6 +101,41 @@ fn list_tokens(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result Ok(Value::Null) > } > > +#[api( > + input: { > + properties: { > + "output-format": { > + schema: OUTPUT_FORMAT, > + optional: true, > + }, > + userid: { > + type: Userid, > + }, > + "token-name": { > + type: Tokenname, > + }, need to re-declare all the api paramters for api2::access::user::API_METHOD_GENERATE_TOKEN as well. Also, I would prefer arg_params to be declared before optional ones here... > + } > + } > +)] > +/// Generate a new API token with given metadata > +fn generate_token(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result { > + let output_format = get_output_format(¶m); > + > + let info = &api2::access::user::API_METHOD_GENERATE_TOKEN; > + let mut data = match info.handler { > + ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, > + _ => unreachable!(), > + }; > + > + let options = default_table_format_options() > + .column(ColumnConfig::new("tokenid")) > + .column(ColumnConfig::new("value")); > + > + format_and_print_result_full(&mut data, &info.returns, &output_format, &options); > + > + Ok(Value::Null) > +} > + > #[api( > input: { > properties: { > @@ -219,7 +254,7 @@ pub fn user_commands() -> CommandLineInterface { > ) > .insert( > "generate-token", > - CliCommand::new(&api2::access::user::API_METHOD_GENERATE_TOKEN) > + CliCommand::new(&API_METHOD_GENERATE_TOKEN) > .arg_param(&["userid", "token-name"]) > .completion_cb("userid", pbs_config::user::complete_userid), > )