Corsinvest / cv4pve-autosnap

Automatic snapshot tool for Proxmox VE
https://www.corsinvest.it/cv4pve
GNU General Public License v3.0
403 stars 50 forks source link

API tokens syntax is an unlucky choice #81

Closed meyergru closed 11 months ago

meyergru commented 11 months ago

What happened?

The syntax of API tokens is very unlucky. If you use something like this in your crontab:

SNAP_APITOKEN="USER@REALM!TOKENID=UUID"

* * * * * root cv4pve-autosnap --host="$SNAP_HOST" --api-token="$SNAP_APITOKEN" --vmid="$SNAP_VMID" snap --only-running --label="hourly" --keep="$SNAP_KEEP_HOURLY" > /dev/null

You will have a problem, since the second '=' will end the token string. No combination of quoting and escaping I have tried succeeded. It is possible to use this from a shell within single quotes, but his cannot be transferred into a crontab entry.

Expected behavior

This should work is the syntax of the string was slightly modified or if another parameter --api-token-base64 was used, such that special characters are eliminated.

Relevant log output

No response

Proxmox VE Version

8.0.4

Version (bug)

1.14.4

Version (working)

no

On what operating system are you experiencing the issue?

Linux

Pull Request

franklupo commented 11 months ago

Hi, This is a format user from Proxmox

meyergru commented 11 months ago

I know that, but the way it is given to the program makes it impossible to use. If the parameter format for cv4pve-autosnap was not like "--xxx=yyy", but "-x yyy", there was no problem if an API token like USER@REALM!TOKENID=UUID was provided.

The problem is the second '=', since after crontab expansion is used, all is left is "--api-token=USER@REALM!TOKENID=UUID" without any possibility of quoting it. That remaining string is cut off at the second '='.

franklupo commented 11 months ago

Hi, You can use wothout =, --api-token USER@REALM!TOKENID=UUID

meyergru commented 11 months ago

It tried, but within a crontab, it does not work. It is capped at the '='.

franklupo commented 11 months ago

In shell work?

franklupo commented 11 months ago

If you wanth can specify esternal file for parameters.

franklupo commented 11 months ago

https://github.com/Corsinvest/cv4pve-autosnap#execution-with-file-parameter

meyergru commented 11 months ago

Yes, it works in a shell because there, I can quote, which is not possible in a crontab entry. Here is the full example for /etc/cron.d/whatever:

PATH=/usr/bin:/bin:/usr/local/bin/
MAILTO="proxmox@test.de"

SNAP_HOST="127.0.0.1"
SNAP_USER="snapshot@pam"
SNAP_PASS="snappass"
SNAP_APITOKEN="snapshot@pam!snapshot=42cfa924-0c23-4b9f-9eba-db62c3984b33"

# "all" for all VMs, exceptions with "-105"
SNAP_VMID="all,-105'

SNAP_KEEP_HOURLY=23
SNAP_KEEP_DAILY=6
SNAP_KEEP_WEEKLY=4
SNAP_KEEP_MONTHLY=3

# hourly
#1 1-23  *       *       *       root    cv4pve-autosnap --host="$SNAP_HOST" --username="$SNAP_USER" --password="$SNAP_PASS" --vmid="$SNAP_VMID" snap --only-running --label="hourly" --keep="$SNAP_KEEP_HOURLY" > /dev/null
* *  *       *       *       root    cv4pve-autosnap --host="$SNAP_HOST" --api-token="$SNAP_APITOKEN" --vmid="$SNAP_VMID" snap --only-running --label="minute" --keep="$SNAP_KEEP_HOURLY"

As you can see, I commented out and modified the username/passwd version in order to send mail of the output and start once every minute. You have to modify MAILTO to get the results. I have tried every imaginable way of quoting and escaping - including using a space after --api-token, but this never works. And obviously, the user/pass and api-tokens are not real.

The example is from here: https://techlr.de/proxmox-automatische-snapshots-einrichten/ , thus there are a few lines missing. They all use the same parameters, so it is not really feasible to insert the API key literally everywhere.

Specifying in a file is difficult if you want to have it centrally in a crontab file, especially if you have multiple invocations. I would need 4 additional parameter files, although it would be a valid workaround.

franklupo commented 11 months ago

Try with ' symbol to esecute command 'cv4pve-autosnap ...'

meyergru commented 11 months ago

No, that is interpreted as one whole string when given to /bin/sh, also the expansions are not done within single quotes:

/bin/sh: 1: cv4pve-autosnap --host="$SNAP_HOST" --api-token="$SNAP_APITOKEN" --vmid="$SNAP_VMID" snap --only-running --label="minute" --keep="$SNAP_KEEP_HOURLY" : not found

meyergru commented 11 months ago

It is a fine line to keep expanding parameters and having the result kept together despite containing special characters.

Even the '!' is a problem there, because it has special meaning in a shell. That is why you need single quotes around the API token in an interactive shell.

franklupo commented 11 months ago

External file with all comman line is a solution

meyergru commented 11 months ago

As I wrote, I would have to specifiy 4 different files for the 4 periods in the original example crontab. However, one can also use @file with additional parameters. So, I modified the crontab entry to this:

PATH=/usr/bin:/bin:/usr/local/bin/
MAILTO="proxmox@test.de"

SNAP_CREDENTIALS=/etc/cv4pve-autosnap/credentials.conf

# "all" for all VMs, exceptions with "-123" possible, or just the following VMs: "123,124"
SNAP_VMID="all,-105"

SNAP_KEEP_HOURLY=23
SNAP_KEEP_DAILY=6
SNAP_KEEP_WEEKLY=4
SNAP_KEEP_MONTHLY=3

# hourly
1 1-23  *       *       *       root    cv4pve-autosnap @"$SNAP_CREDENTIALS" --vmid="$SNAP_VMID" snap --only-running --label="hourly" --keep="$SNAP_KEEP_HOURLY" > /dev/null

# weekly -> So; daily -> Mo-Sa
1 0     2-31    *       *       root    [ "$(date +\%u)" = "7" ] && cv4pve-autosnap @"$SNAP_CREDENTIALS" --vmid="$SNAP_VMID" snap --only-running --label="weekly" --keep="$SNAP_KEEP_WEEKLY" > /dev/null || cv4pve-autosnap @"$SNAP_CREDENTIALS" --vmid="$SNAP_VMID" snap --only-running --label="daily" --keep="$SNAP_KEEP_DAILY" > /dev/null

# monthly
1 0     1       *       *       root    cv4pve-autosnap @"$SNAP_CREDENTIALS" --vmid="$SNAP_VMID" snap --only-running --label="monthly" --keep="$SNAP_KEEP_MONTHLY" > /dev/null

With /etc/cv4pve-autosnap/credentials containing this:

--host=127.0.0.1 --api-token=--host=127.0.0.1 --api-token=snapshot@pam!snapshot=42cfa924-0c23-4b9f-9eba-db62c3984b33 or this:

--host=127.0.0.1 --username=snapshot@pam --password=snappass