Compare commits

..

116 Commits

Author SHA1 Message Date
Wolfgang Bumiller
ae27b307b8 pve: fix use vs mod grouping
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-08-29 10:31:31 +02:00
Wolfgang Bumiller
dfd8a2e321 bump common to 0.3.4
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-08-09 14:22:00 +02:00
Wolfgang Bumiller
a3e466af88 bump pmg-rs to 0.7.6
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-08-09 14:20:50 +02:00
Wolfgang Bumiller
cdc792005e pve: bump version to 0.8.10
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-08-09 13:46:22 +02:00
Lukas Wagner
ea4d87816b cache: add bindings for SharedCache
This is a simple, cache implementation which can be accessed from
multiple processes. It also supports storing a range of historical
values.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
[wb: also update pmg-rs/Cargo.toml and both d/control files]
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-08-09 13:21:01 +02:00
Fabian Grünbichler
9a91594ee6 update to proxmox-log 0.2
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-08-06 14:13:31 +02:00
Wolfgang Bumiller
885830935c update to sys 0.6 and proxmox-log crate
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-17 12:44:46 +02:00
Wolfgang Bumiller
b3b8b375c2 apt: minor parameter cleanup
We cannot use &[&str] - since this would be a poitner to a `[&str]`
data structure, that's not how perl stores strings.
But we *can* use Vec<&str> - here, the Vec will be allocated, but the
contents will borrow. We don't need to transform this afterwards.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-08 15:33:58 +02:00
Lukas Wagner
6789b14986 pve-rs: common: send apt update notification via proxmox-notify
For PMG we for now only provide an empty stub and warn to syslog -
we need basic notification system integration there first.
On PMG, we still use a pure Perl implementation at the moment,
so this should not be an issue unless we change that.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2024-07-08 15:33:58 +02:00
Dietmar Maurer
89d9debadb perl-rs: add further apt api calls
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2024-07-08 15:33:57 +02:00
Dietmar Maurer
5c994bf942 perl-rs: use api functions from proxmox-apt
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2024-07-08 15:33:32 +02:00
Dietmar Maurer
9eda29d688 perl-rs: use proxmox-apt-api-types
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2024-07-08 15:33:29 +02:00
Wolfgang Bumiller
83427e9204 bump proxmox-tfa to 5.0
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-04 10:48:48 +02:00
Wolfgang Bumiller
61b2f69a45 bump proxmox-time to 2.0
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-06-20 14:11:34 +02:00
Fabian Grünbichler
c873ac57d5 build: adapt Makefile to moved cargo config
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-06-20 12:20:42 +02:00
Lukas Wagner
7e3ea35595 pve-rs: pmg-rs: move deprecated .cargo/config to .cargo/config.toml
Fixes the following new warning that appeared after switching
to rust 1.77:

warning: `proxmox-perl-rs/pve-rs/.cargo/config` is deprecated in
favor of `config.toml`

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2024-06-20 12:19:01 +02:00
Fabian Grünbichler
a34b31054d build: force debug symbols in release build
they then get stripped into their own package anyway, but without this we don't
get debug symbols at all with rustc >= 1.77

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-06-20 10:09:19 +02:00
Wolfgang Bumiller
da068b1a47 pmg: add api-types feature of proxmox-acme
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-06-10 12:47:03 +02:00
Wolfgang Bumiller
cd0e7b8cd2 pve: bump version to 0.8.9
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-06-04 11:01:22 +02:00
Wolfgang Bumiller
0b6800b0bd pve: the notify chagnes now break libpve-notify-perl <<8.0.7
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-06-04 10:42:03 +02:00
Lukas Wagner
dc02255bdc notify: adapt to Option<Vec<T>> to Vec<T> changes in proxmox_notify
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
Tested-by: Max Carrara <m.carrara@proxmox.com>
Reviewed-by: Max Carrara <m.carrara@proxmox.com>
2024-06-04 10:40:53 +02:00
Lukas Wagner
7ac7fa5b00 notify: don't pass config structs by reference
proxmox_notify's api functions have been changed so that they take
ownership of config structs.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
Tested-by: Max Carrara <m.carrara@proxmox.com>
Reviewed-by: Max Carrara <m.carrara@proxmox.com>
2024-06-04 10:40:53 +02:00
Lukas Wagner
627a95bf89 notify: use file based notification templates
Instead of passing literal template strings to the notification
system, we now only pass an identifier. This identifier will be used
load the template files from a product-specific directory.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
Tested-by: Max Carrara <m.carrara@proxmox.com>
Reviewed-by: Max Carrara <m.carrara@proxmox.com>
2024-06-04 10:40:53 +02:00
Wolfgang Bumiller
d0633ac98e pve,pmg: bump proxmox-notify to 0.4
build fixes for pve follow

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-06-04 10:40:53 +02:00
Wolfgang Bumiller
45a1af8ad2 remove old toplevel Makefile
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-06-04 10:40:53 +02:00
Wolfgang Bumiller
6bed9c40bc remove old rustfmt.toml
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-06-04 10:40:53 +02:00
Wolfgang Bumiller
2860777e61 buildsys improvements for generated files
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-06-03 14:00:03 +02:00
Wolfgang Bumiller
4e6598ef85 common: cleanup Proxmox/RS in make clean
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-06-03 13:25:32 +02:00
Wolfgang Bumiller
27a7f2e252 pve: bump version to 0.8.8
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-01-10 14:20:00 +01:00
Wolfgang Bumiller
199be72401 pve,pmg: bump proxmox-notify dependency to 0.3.1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-01-10 14:11:09 +01:00
Wolfgang Bumiller
d6df8340c5 pve, pmg: bump perlmod-bin to 0.3.0-3
fixes a syntax error in the generated pm file

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-01-02 14:20:12 +01:00
Wolfgang Bumiller
427fdb13c0 pve: update testcase PVE.pm with fixed library path
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-18 10:39:30 +01:00
Wolfgang Bumiller
a5330e34d2 pmg: upgrade perlmod-bin dependency to 0.2
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-18 10:22:18 +01:00
Wolfgang Bumiller
c57e1868e7 pve: upgrade perlmod-bin dependency to 0.2
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-18 10:22:09 +01:00
Wolfgang Bumiller
ec95bb1c53 pve: build fix
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-18 10:20:16 +01:00
Wolfgang Bumiller
fb5f1be6dc bump pmg-rs to 0.7.5
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-07 09:58:06 +01:00
Wolfgang Bumiller
237b276028 bump common to 0.3.3
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-07 09:58:06 +01:00
Wolfgang Bumiller
16c41f1a91 pve: load SslProbe in Proxmox/Lib/PVE.pm
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-07 09:56:05 +01:00
Wolfgang Bumiller
86706cc049 pmg: load SslProbe in Proxmox/Lib/PMG.pm
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-07 09:56:05 +01:00
Wolfgang Bumiller
62fc43fea9 common: move probe into a new SslProbe package
Because Proxmox::Lib::Common isn't actually `use`d by most packages.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-07 09:56:05 +01:00
Wolfgang Bumiller
6a31f73fa3 bump common to 0.3.2
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-06 11:23:09 +01:00
Wolfgang Bumiller
9525623c19 bump pmg-rs to 0.7.4
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-06 11:23:09 +01:00
Wolfgang Bumiller
089e555d51 fixate openssl-probe dependency, probe env vars in perl
This fixes an issue with `openssl-probe` calling `setenv` when (issued
via the `native-tls` crate with the ACME client) which crashes perl.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-06 11:21:25 +01:00
Wolfgang Bumiller
b9185327f4 update d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-04 11:58:36 +01:00
Folke Gleumes
ce550d06e2 acme: add eab fields for pmg
Signed-off-by: Folke Gleumes <f.gleumes@proxmox.com>
2023-12-04 11:54:05 +01:00
Wolfgang Bumiller
5ac44c9fbb pmg: bump acme-rs to 0.5
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-12-04 11:54:05 +01:00
Thomas Lamprecht
4c54abcea8 pve: bump version to 0.8.7
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-11-17 13:42:07 +01:00
Thomas Lamprecht
61ab181b01 cargo: depend on notify 0.3
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-11-17 13:38:28 +01:00
Lukas Wagner
036236c278 notify: support 'origin' paramter
This parameter shows the origin of a config entry (builtin,
user-created, modified-builtin)

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-11-17 13:30:57 +01:00
Lukas Wagner
36fbb76145 notify: add 'disable' parameter
This parameter disables a matcher/a target.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-11-17 13:30:57 +01:00
Lukas Wagner
b905cfd03d pve-rs: notify: remove notify_context for PVE
The context has now been moved to `proxmox-notify` due to the fact
that we also need it in `proxmox-mail-forward` now.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-11-17 13:30:57 +01:00
Lukas Wagner
7f8cb0c5c3 notify: add bindings for smtp API calls
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-11-17 13:30:57 +01:00
Lukas Wagner
29602a4b01 notify: adapt to new matcher-based notification routing
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-11-17 13:30:57 +01:00
Fiona Ebner
bfc7f2c518 pve: test: resource scheduling: add another test where memory is secondary to CPU
but this time, without any start load on the node. This test fails
with librust-proxmox-resource-scheduling-dev=0.2.0-1

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-11-06 18:21:06 +01:00
Fiona Ebner
14a3de9826 pve: test: resource scheduling: add test where memory is secondary to CPU
because memory usage differences are small.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2023-11-06 18:21:06 +01:00
Wolfgang Bumiller
a04d26b0d2 expose use_safe_putenv via Proxmox::Lib::PMG
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-10-09 08:47:23 +02:00
Wolfgang Bumiller
c8d4db7836 bump perlmod to 0.13.4 for use_safe_putenv
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-10-06 09:09:15 +02:00
Wolfgang Bumiller
1c2ff27e75 pve: switch openid to use magic
Instead of blessed raw pointers as these can easily lead to double
free corruptions when they're copied in perl.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-10-04 09:09:45 +02:00
Wolfgang Bumiller
e3bc763de4 pmg: switch acme to use magic
Instead of blessed raw pointers as these can easily lead to double
free corruptions when they're copied in perl.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-10-04 09:07:23 +02:00
Wolfgang Bumiller
e9c2ba606d pmg: buildsys: add notify related dependencies
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-10-04 09:07:23 +02:00
Fabian Grünbichler
4c6cc7e241 update to env_logger 0.10
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2023-10-03 10:00:27 +02:00
Lukas Wagner
50f372fe7e notify context: fix 'default_sendmail_from' context method
The name of the configuration option in datacenter.cfg is `email_from`
and not `mail_from`.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-10-02 12:31:11 +02:00
Thomas Lamprecht
8d031134e1 bump version to 0.8.6
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-09-05 16:32:45 +02:00
Wolfgang Bumiller
e52b4ea877 bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-28 11:51:53 +02:00
Wolfgang Bumiller
8ff4471ee6 bump notify dependency
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-28 11:51:28 +02:00
Lukas Wagner
76b63ed6a8 notify: use new HttpError type
Use `proxmox-http-error::HttpError` instead of
`proxmox-notify::api::ApiError`.

Also factoring out the digest decoding into a small helper.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-28 11:50:08 +02:00
Wolfgang Bumiller
2be21ff9fa bump common to 0.3.1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-24 14:14:06 +02:00
Wolfgang Bumiller
47b7ebbc96 common: bump pve-rs dep to 0.8.5 for Proxmox::RS::Notify
Note: this is more of a soft requirement, since as long as the Notify
module isn't loaded we don't need the latest version.
This is important to keep in mind since we do not currently have a
`pmg-rs` notify `Context` implementation and thus cannot depend on a
newer `pmg-rs`. However, as long as pmg code doesn't try to *use* the
Notify module, this won't be a problem.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-24 14:14:06 +02:00
Wolfgang Bumiller
af7ff77ac7 bump pve-rs to 0.8.5
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-24 14:14:06 +02:00
Wolfgang Bumiller
d5ff7165a2 remove leftover PVE::RS::Notify module
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-24 14:01:23 +02:00
Lukas Wagner
703cfbd212 notify: rename PVE::RS::Notify to Proxmox::RS::Notify
Also splitting PVE-specific context into its own file.

Suggested-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 13:58:26 +02:00
Lukas Wagner
69d2eb953d notify: add wrapper for get_referenced_entities
The function returns all other entities referenced by a filter/target.
This is useful for permission checks, where the user must have the
appropriate permissions for all entities.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 11:17:45 +02:00
Lukas Wagner
de59ffe4ec notify: add context for getting http_proxy from datacenter.cfg
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 11:17:43 +02:00
Lukas Wagner
178196e1ae notify: implement context for getting default author/mailfrom
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 11:17:42 +02:00
Lukas Wagner
a5ee03ed0f notify: sendmail: support the mailto-user parameter
This parameter allows to send mails to the email address configured
for users from the product's user database.

`proxmox-notify` now has a `Context` that must be set via
`proxmox_notify::context::set_context` before the crate is used.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 11:17:41 +02:00
Lukas Wagner
79f339d136 notify: add api for notification filters
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 11:17:39 +02:00
Lukas Wagner
6b5dbc3238 notify: add api for gotify endpoints
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 11:17:38 +02:00
Lukas Wagner
a73ba69716 notify: add api for sendmail endpoints
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 11:17:36 +02:00
Lukas Wagner
4b64b63ff7 notify: add api for notification groups
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 11:17:35 +02:00
Lukas Wagner
350cdd6b59 notify: add api for sending notifications/testing endpoints
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 11:17:33 +02:00
Lukas Wagner
b9c4756445 add PVE::RS::Notify module
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-07-24 11:17:31 +02:00
Wolfgang Bumiller
cd8984a954 buildsys: both: check crate vs debian version
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-05 13:50:17 +02:00
Wolfgang Bumiller
225b640f1f bump pmg-rs to 0.7.3
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-05 13:35:43 +02:00
Wolfgang Bumiller
8759447585 bump pve-rs to 0.8.4
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-05 13:30:27 +02:00
Wolfgang Bumiller
e2c950bf4c pmg: bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-05 11:03:08 +02:00
Wolfgang Bumiller
0be7076578 pve: bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-05 11:02:40 +02:00
Wolfgang Bumiller
470849f974 pmg: reset tfa failure count on unlock
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-05 11:01:45 +02:00
Wolfgang Bumiller
5c6a27da1d pve: reset tfa failure count on unlock
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-05 11:01:36 +02:00
Wolfgang Bumiller
06f325fd9d bump proxmox-tfa dependency to 4.0.4
This allows resetting the tfa failure counters on unlock.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-05 10:59:52 +02:00
Wolfgang Bumiller
3df4aecac0 bump pmg-rs to 0.7.2
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-06-27 16:01:55 +02:00
Wolfgang Bumiller
fdcdd326c3 pmg: enable tfa lockout
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-06-27 15:59:39 +02:00
Wolfgang Bumiller
aed1657598 pmg: add tfa_lock_status_query and api_unlock_tfa
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-06-27 15:59:14 +02:00
Wolfgang Bumiller
39a7399c2c pmg: bump proxmox-tfa to 4.0.2
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-06-27 15:56:02 +02:00
Wolfgang Bumiller
7bd8036ff0 bump pve-rs to 0.8.3
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-06-05 12:55:12 +02:00
Wolfgang Bumiller
e1f6379b02 bump proxmox-tfa dep to 4.0.2
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-06-05 12:53:22 +02:00
Wolfgang Bumiller
0d530835cb pve: add tfa_lock_status query sub
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-06-05 09:25:05 +02:00
Lukas Wagner
d0cab6371a log: set default log level to 'info', add product specific logging env var
Logging behaviour can be overridden by the {PMG,PVE}_LOG environment
variable.

This commit also disables styled output and  timestamps in log messages,
since we usually log to the journal anyway. The log output is configured
to match with other log messages in task logs.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
2023-06-05 09:25:05 +02:00
Thomas Lamprecht
15e7531f3c pve: bump version to 0.8.2
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-06-04 18:34:02 +02:00
Wolfgang Bumiller
3037864e4d bump pve-rs to 0.8.1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-05-31 14:18:13 +02:00
Wolfgang Bumiller
590af894ef pve: enable tfa lockout, add api_unlock_tfa method
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-05-31 14:15:42 +02:00
Wolfgang Bumiller
10472bc265 pve-rs: bump proxmox-tfa dep to 4.0.1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-05-31 14:15:42 +02:00
Wolfgang Bumiller
a4610c6a0f bump proxmox-apt,http,openid,subscription,sys crate dependencies
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-05-24 16:05:33 +02:00
Thomas Lamprecht
f7bb45a38b pve: update & wrap-and-sort d/control
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-05-18 13:07:28 +02:00
Thomas Lamprecht
181b19e2ef buildsys: add clean target for common package
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-05-18 12:46:27 +02:00
Thomas Lamprecht
e3d4bb03c9 common: wrap-and-sort & refresh
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-05-18 12:45:44 +02:00
Thomas Lamprecht
a53d4737d3 common: d/changelog: fixup distribution to bookworm
got (correctly) uploaded to bookworm, not bullseye

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-05-18 12:34:43 +02:00
Thomas Lamprecht
6b92c01349 pmg: bump version to 0.7.1
as the cargo one wasn't bumped, d/changelog still listed bullseye as
distribution for the original 0.7.0 upload and d/control was a bit
dusted, so to avoid any confusion just re-bumped with no actual code
change.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-05-18 12:34:43 +02:00
Thomas Lamprecht
0d049201e9 pmg: refresh d/control and note that debcargo.toml isn't canonical source
Also run `wrap-and-sort -tkn`

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-05-18 12:28:58 +02:00
Thomas Lamprecht
f7a9ddfdfd buildsys: cleanup and expand clean target
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-05-18 12:00:17 +02:00
Thomas Lamprecht
c0bc3436ee pmg: d/changelog: fixup distribution to bookworm
this release got uploaded to bookworm only.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-05-18 11:43:49 +02:00
Wolfgang Bumiller
6beb0ffa6b buildsys: add missing deb targets
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-05-17 15:57:02 +02:00
Wolfgang Bumiller
4917bd4ead bump proxmox-rs-perl to 0.3.0, pmg-rs to 0.7.0
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-05-17 15:53:38 +02:00
Wolfgang Bumiller
3255c3b59c buildsys: pmg-rs: dsc and sbuild updates
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-05-17 15:45:59 +02:00
Wolfgang Bumiller
1b499b7611 bump pve-rs to 0.8.0
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-05-17 11:02:12 +02:00
Wolfgang Bumiller
f863004159 buildsys: make pve-rs sbuild compatible
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-05-17 11:02:12 +02:00
Wolfgang Bumiller
34a0068618 undo rust workspace change in preparation for .dsc builds
The library ending up a level above the actual code just
makes .dsc/sbuild building very inconvenient, and pve-rs and
pmg-rs often grow independently from one another.

All we need is the common code available.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-05-17 11:02:00 +02:00
38 changed files with 1497 additions and 428 deletions

View File

@ -1,45 +0,0 @@
CARGO ?= cargo
ifeq ($(BUILD_MODE), release)
CARGO_BUILD_ARGS += --release
else
endif
.PHONY: all
all:
ifeq ($(BUILD_TARGET), pve)
$(MAKE) pve
else ifeq ($(BUILD_TARGET), pmg)
$(MAKE) pmg
else
@echo "Run one of"
@echo " - make pve"
@echo " - make pmg"
endif
build:
rm -rf build
mkdir build
echo system >build/rust-toolchain
cp -a ./Cargo.toml ./build
cp -a ./common ./build
cp -a ./pve-rs ./build
cp -a ./pmg-rs ./build
# Replace the symlinks with copies of the common code in pve/pmg:
cd build; for i in pve pmg; do \
rm ./$$i-rs/common ; \
mkdir ./$$i-rs/common ; \
cp -R ./common/src ./$$i-rs/common/src ; \
done
# So the common packages end up in ./build, rather than ./build/common
mv ./build/common/pkg ./build/common-pkg
# Copy the workspace root into the sources
mkdir build/pve-rs/.workspace
cp -t build/pve-rs/.workspace Cargo.toml
sed -i -e '/\[package\]/a\workspace = ".workspace"' build/pve-rs/Cargo.toml
# Clear the member array and replace it with ".."
sed -i -e '/^members = \[/,/^]$$/d' build/pve-rs/.workspace/Cargo.toml
sed -i -e '/^\[workspace\]/a\members = [ ".." ]' build/pve-rs/.workspace/Cargo.toml
# Copy the cargo config
mkdir build/pve-rs/.cargo
cp -t build/pve-rs/.cargo .cargo/config

View File

@ -20,18 +20,24 @@ PERLMOD_GENPACKAGE := /usr/lib/perlmod/genpackage.pl \
--lib-package=Proxmox::Lib::Common \
--lib-prefix=Proxmox
# Point to any generated pm file (Proxmox/ dir is already present in this package)
Proxmox/RS/CalendarEvent.pm:
$(PERLMOD_GENPACKAGE) \
PERLMOD_PACKAGES := \
Proxmox::RS::APT::Repositories \
Proxmox::RS::CalendarEvent \
Proxmox::RS::Notify \
Proxmox::RS::SharedCache \
Proxmox::RS::Subscription
all: Proxmox/RS/CalendarEvent.pm
PERLMOD_PACKAGE_FILES := $(addsuffix .pm,$(subst ::,/,$(PERLMOD_PACKAGES)))
Proxmox/RS: $(PERLMOD_PACKAGE_FILES)
$(PERLMOD_PACKAGE_FILES) &:
$(PERLMOD_GENPACKAGE) $(PERLMOD_PACKAGES)
all: Proxmox/RS
true
.PHONY: install
install: Proxmox/RS/CalendarEvent.pm
install: Proxmox/RS
install -d -m755 $(DESTDIR)$(PERL_INSTALLVENDORLIB)
find PVE \! -type d -print -exec install -Dm644 '{}' $(DESTDIR)$(PERL_INSTALLVENDORLIB)'/{}' ';'
find Proxmox \! -type d -print -exec install -Dm644 '{}' $(DESTDIR)$(PERL_INSTALLVENDORLIB)'/{}' ';'
@ -67,3 +73,4 @@ upload: $(DEB)
clean:
rm -f *.deb *.dsc *.tar.* *.build *.buildinfo *.changes
rm -rf $(PACKAGE)-[0-9]*/
rm -rf Proxmox/RS

View File

@ -0,0 +1,100 @@
package Proxmox::Lib::SslProbe;
use strict;
use warnings;
=head1 Environment Variable Safety
Perl's handling of environment variables was completely messed up until v5.38.
Using `setenv` such as use din the `openssl-probe` crate would cause it to
crash later on, therefore we provide a perl-version of env var probing instead,
and override the crate with one that doesn't replace the variables if they are
already set correctly.
=cut
BEGIN {
# Copied from openssl-probe
my @cert_dirs = (
"/var/ssl",
"/usr/share/ssl",
"/usr/local/ssl",
"/usr/local/openssl",
"/usr/local/etc/openssl",
"/usr/local/share",
"/usr/lib/ssl",
"/usr/ssl",
"/etc/openssl",
"/etc/pki/ca-trust/extracted/pem",
"/etc/pki/tls",
"/etc/ssl",
"/etc/certs",
"/opt/etc/ssl",
"/data/data/com.termux/files/usr/etc/tls",
"/boot/system/data/ssl",
);
# Copied from openssl-probe
my @cert_file_names = (
"cert.pem",
"certs.pem",
"ca-bundle.pem",
"cacert.pem",
"ca-certificates.crt",
"certs/ca-certificates.crt",
"certs/ca-root-nss.crt",
"certs/ca-bundle.crt",
"CARootCertificates.pem",
"tls-ca-bundle.pem",
);
my $probed_ssl_vars = 0;
# The algorithm here is taken from the `openssl-probe` crate and should
# produce the exact same result in order to ensure the rust code does not
# call `setenv()`.
my sub probe_ssl_vars : prototype() {
return if $probed_ssl_vars;
$probed_ssl_vars = 1;
my $result_file = $ENV{SSL_CERT_FILE};
my $result_file_changed = 0;
my $result_dir = $ENV{SSL_CERT_DIR};
my $result_dir_changed = 0;
for my $certs_dir (@cert_dirs) {
if (!defined($result_file)) {
for my $file (@cert_file_names) {
my $path = "$certs_dir/$file";
if (-e $path) {
$result_file = $path;
$result_file_changed = 1;
last;
}
}
}
if (!defined($result_dir)) {
for my $file (@cert_file_names) {
my $path = "$certs_dir/certs";
if (-d $path) {
$result_dir = $path;
$result_dir_changed = 1;
last;
}
}
}
last if defined($result_file) && defined($result_dir);
}
if ($result_file_changed && defined($result_file)) {
$ENV{SSL_CERT_FILE} = $result_file;
}
if ($result_dir_changed && defined($result_dir)) {
$ENV{SSL_CERT_DIR} = $result_dir;
}
}
probe_ssl_vars();
}
1;

View File

@ -1,3 +1,33 @@
libproxmox-rs-perl (0.3.4) bookworm; urgency=medium
* add bindings for proxmox-shared-cache crate
-- Proxmox Support Team <support@proxmox.com> Fri, 09 Aug 2024 14:21:41 +0200
libproxmox-rs-perl (0.3.3) bookworm; urgency=medium
* move ssl var probing to Proxmox::Lib::SslProbe
-- Proxmox Support Team <support@proxmox.com> Thu, 07 Dec 2023 09:57:33 +0100
libproxmox-rs-perl (0.3.2) bookworm; urgency=medium
* add Proxmox::Lib::Common::probe_ssl_vars() helper
-- Proxmox Support Team <support@proxmox.com> Tue, 05 Dec 2023 10:46:39 +0100
libproxmox-rs-perl (0.3.1) bookworm; urgency=medium
* add Proxmox::RS::Notify module
-- Proxmox Support Team <support@proxmox.com> Mon, 24 Jul 2023 14:02:17 +0200
libproxmox-rs-perl (0.3.0) bookworm; urgency=medium
* rebuild for Debian 12 Bookworm based release series
-- Proxmox Support Team <support@proxmox.com> Wed, 17 May 2023 15:48:41 +0200
libproxmox-rs-perl (0.2.1) bullseye; urgency=medium
* update to proxmox-subscription 0.3 / proxmox-http 0.7

View File

@ -1 +0,0 @@
12

View File

@ -1,11 +1,9 @@
Source: libproxmox-rs-perl
Section: perl
Priority: optional
Build-Depends:
debhelper (>= 12),
perlmod-bin,
Build-Depends: debhelper-compat (= 13), perlmod-bin,
Maintainer: Proxmox Support Team <support@proxmox.com>
Standards-Version: 4.5.1
Standards-Version: 4.6.2
Vcs-Git: git://git.proxmox.com/git/proxmox-perl-rs.git
Vcs-Browser: https://git.proxmox.com/?p=proxmox-perl-rs.git
Homepage: https://www.proxmox.com
@ -15,15 +13,12 @@ Package: libproxmox-rs-perl
Architecture: any
# always bump both versioned Depends and Breaks, otherwise systems with both
# libpmg-rs-perl and libpve-rs-perl might load an outdated lib and break
Depends:
${misc:Depends},
${perl:Depends},
${shlibs:Depends},
libpve-rs-perl (>= 0.7.2) | libpmg-rs-perl (>= 0.6.2),
Breaks:
libpve-rs-perl (<< 0.7.2),
libpmg-rs-perl (<< 0.6.2),
Replaces: libpve-rs-perl (<< 0.6.0)
Description: PVE/PMG common parts which have been ported to Rust - Perl packages
Contains the perl side of modules provided by the libraries of both libpve-rs-perl and
libpmg-rs-perl, loading whichever is available.
Depends: libpve-rs-perl (>= 0.8.10) | libpmg-rs-perl (>= 0.7.6),
${misc:Depends},
${perl:Depends},
${shlibs:Depends},
Breaks: libpmg-rs-perl (<< 0.6.2), libpve-rs-perl (<< 0.7.2),
Replaces: libpve-rs-perl (<< 0.6.0),
Description: PVE/PMG common perl parts for Rust perlmod bindings
Contains the perl side of modules provided by the libraries of both
libpve-rs-perl and libpmg-rs-perl, loading whichever is available.

View File

@ -1,62 +1,18 @@
#[perlmod::package(name = "Proxmox::RS::APT::Repositories")]
pub mod export {
use std::convert::TryInto;
use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
use anyhow::Error;
use proxmox_apt::repositories::{
APTRepositoryFile, APTRepositoryFileError, APTRepositoryHandle, APTRepositoryInfo,
APTStandardRepository,
use proxmox_apt_api_types::{
APTChangeRepositoryOptions, APTGetChangelogOptions, APTRepositoriesResult,
APTRepositoryHandle, APTUpdateInfo, APTUpdateOptions,
};
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
/// Result for the repositories() function
pub struct RepositoriesResult {
/// Successfully parsed files.
pub files: Vec<APTRepositoryFile>,
/// Errors for files that could not be parsed or read.
pub errors: Vec<APTRepositoryFileError>,
/// Common digest for successfully parsed files.
pub digest: String,
/// Additional information/warnings about repositories.
pub infos: Vec<APTRepositoryInfo>,
/// Standard repositories and their configuration status.
pub standard_repos: Vec<APTStandardRepository>,
}
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
/// For changing an existing repository.
pub struct ChangeProperties {
/// Whether the repository should be enabled or not.
pub enabled: Option<bool>,
}
use proxmox_config_digest::ConfigDigest;
/// Get information about configured repositories and standard repositories for `product`.
#[export]
pub fn repositories(product: &str) -> Result<RepositoriesResult, Error> {
let (files, errors, digest) = proxmox_apt::repositories::repositories()?;
let digest = hex::encode(&digest);
let suite = proxmox_apt::repositories::get_current_release_codename()?;
let infos = proxmox_apt::repositories::check_repositories(&files, suite);
let standard_repos =
proxmox_apt::repositories::standard_repositories(&files, product, suite);
Ok(RepositoriesResult {
files,
errors,
digest,
infos,
standard_repos,
})
pub fn repositories(product: &str) -> Result<APTRepositoriesResult, Error> {
proxmox_apt::list_repositories(product)
}
/// Add the repository identified by the `handle` and `product`.
@ -64,65 +20,12 @@ pub mod export {
///
/// The `digest` parameter asserts that the configuration has not been modified.
#[export]
pub fn add_repository(handle: &str, product: &str, digest: Option<&str>) -> Result<(), Error> {
let (mut files, errors, current_digest) = proxmox_apt::repositories::repositories()?;
let handle: APTRepositoryHandle = handle.try_into()?;
let suite = proxmox_apt::repositories::get_current_release_codename()?;
if let Some(digest) = digest {
let expected_digest = hex::decode(digest)?;
if expected_digest != current_digest {
bail!("detected modified configuration - file changed by other user? Try again.");
}
}
// check if it's already configured first
for file in files.iter_mut() {
for repo in file.repositories.iter_mut() {
if repo.is_referenced_repository(handle, product, &suite.to_string()) {
if repo.enabled {
return Ok(());
}
repo.set_enabled(true);
file.write()?;
return Ok(());
}
}
}
let (repo, path) =
proxmox_apt::repositories::get_standard_repository(handle, product, suite);
if let Some(error) = errors.iter().find(|error| error.path == path) {
bail!(
"unable to parse existing file {} - {}",
error.path,
error.error,
);
}
if let Some(file) = files
.iter_mut()
.find(|file| file.path.as_ref() == Some(&path))
{
file.repositories.push(repo);
file.write()?;
} else {
let mut file = match APTRepositoryFile::new(&path)? {
Some(file) => file,
None => bail!("invalid path - {}", path),
};
file.repositories.push(repo);
file.write()?;
}
Ok(())
pub fn add_repository(
handle: APTRepositoryHandle,
product: &str,
digest: Option<ConfigDigest>,
) -> Result<(), Error> {
proxmox_apt::add_repository_handle(product, handle, digest)
}
/// Change the properties of the specified repository.
@ -132,39 +35,55 @@ pub mod export {
pub fn change_repository(
path: &str,
index: usize,
options: ChangeProperties,
digest: Option<&str>,
options: APTChangeRepositoryOptions,
digest: Option<ConfigDigest>,
) -> Result<(), Error> {
let (mut files, errors, current_digest) = proxmox_apt::repositories::repositories()?;
proxmox_apt::change_repository(path, index, &options, digest)
}
if let Some(digest) = digest {
let expected_digest = hex::decode(digest)?;
if expected_digest != current_digest {
bail!("detected modified configuration - file changed by other user? Try again.");
}
}
/// Retrieve the changelog of the specified package.
#[export]
pub fn get_changelog(options: APTGetChangelogOptions) -> Result<String, Error> {
proxmox_apt::get_changelog(&options)
}
if let Some(error) = errors.iter().find(|error| error.path == path) {
bail!("unable to parse file {} - {}", error.path, error.error);
}
/// List available APT updates
///
/// Automatically updates an expired package cache.
#[export]
pub fn list_available_apt_update(apt_state_file: &str) -> Result<Vec<APTUpdateInfo>, Error> {
proxmox_apt::list_available_apt_update(apt_state_file)
}
if let Some(file) = files
.iter_mut()
.find(|file| file.path.as_ref() == Some(&path.to_string()))
{
if let Some(repo) = file.repositories.get_mut(index) {
if let Some(enabled) = options.enabled {
repo.set_enabled(enabled);
}
/// Update the APT database
///
/// You should update the APT proxy configuration before running this.
#[export]
pub fn update_database(apt_state_file: &str, options: APTUpdateOptions) -> Result<(), Error> {
proxmox_apt::update_database(
apt_state_file,
&options,
|updates: &[&APTUpdateInfo]| -> Result<(), Error> {
// fixme: howto send notifgications?
crate::send_updates_available(updates)?;
Ok(())
},
)
}
file.write()?;
} else {
bail!("invalid index - {}", index);
}
} else {
bail!("invalid path - {}", path);
}
Ok(())
/// Get package information for a list of important product packages.
#[export]
pub fn get_package_versions(
product_virtual_package: &str,
api_server_package: &str,
running_api_server_version: &str,
package_list: Vec<&str>,
) -> Result<Vec<APTUpdateInfo>, Error> {
proxmox_apt::get_package_versions(
product_virtual_package,
api_server_package,
running_api_server_version,
&package_list,
)
}
}

View File

@ -1,6 +1,12 @@
use anyhow::Error;
/// Initialize logging. Should only be called once
pub fn init() {
if let Err(e) = env_logger::try_init() {
eprintln!("could not set up env_logger: {e}");
pub fn init(env_var_name: &str, default_log_level: &str) {
if let Err(e) = default_log_level
.parse()
.map_err(Error::from)
.and_then(|default_log_level| proxmox_log::init_logger(env_var_name, default_log_level))
{
eprintln!("could not set up env_logger: {e:?}");
}
}

View File

@ -1,4 +1,6 @@
pub mod apt;
mod calendar_event;
pub mod logger;
pub mod notify;
pub mod shared_cache;
mod subscription;

506
common/src/notify.rs Normal file
View File

@ -0,0 +1,506 @@
#[perlmod::package(name = "Proxmox::RS::Notify")]
mod export {
use std::collections::HashMap;
use std::sync::Mutex;
use anyhow::{bail, Error};
use serde_json::Value as JSONValue;
use perlmod::Value;
use proxmox_http_error::HttpError;
use proxmox_notify::endpoints::gotify::{
DeleteableGotifyProperty, GotifyConfig, GotifyConfigUpdater, GotifyPrivateConfig,
GotifyPrivateConfigUpdater,
};
use proxmox_notify::endpoints::sendmail::{
DeleteableSendmailProperty, SendmailConfig, SendmailConfigUpdater,
};
use proxmox_notify::endpoints::smtp::{
DeleteableSmtpProperty, SmtpConfig, SmtpConfigUpdater, SmtpMode, SmtpPrivateConfig,
SmtpPrivateConfigUpdater,
};
use proxmox_notify::matcher::{
CalendarMatcher, DeleteableMatcherProperty, FieldMatcher, MatchModeOperator, MatcherConfig,
MatcherConfigUpdater, SeverityMatcher,
};
use proxmox_notify::{api, Config, Notification, Severity};
pub struct NotificationConfig {
config: Mutex<Config>,
}
perlmod::declare_magic!(Box<NotificationConfig> : &NotificationConfig as "Proxmox::RS::Notify");
/// Support `dclone` so this can be put into the `ccache` of `PVE::Cluster`.
#[export(name = "STORABLE_freeze", raw_return)]
fn storable_freeze(
#[try_from_ref] this: &NotificationConfig,
cloning: bool,
) -> Result<Value, Error> {
if !cloning {
bail!("freezing Notification config not supported!");
}
let mut cloned = Box::new(NotificationConfig {
config: Mutex::new(this.config.lock().unwrap().clone()),
});
let value = Value::new_pointer::<NotificationConfig>(&mut *cloned);
let _perl = Box::leak(cloned);
Ok(value)
}
/// Instead of `thaw` we implement `attach` for `dclone`.
#[export(name = "STORABLE_attach", raw_return)]
fn storable_attach(
#[raw] class: Value,
cloning: bool,
#[raw] serialized: Value,
) -> Result<Value, Error> {
if !cloning {
bail!("STORABLE_attach called with cloning=false");
}
let data = unsafe { Box::from_raw(serialized.pv_raw::<NotificationConfig>()?) };
Ok(perlmod::instantiate_magic!(&class, MAGIC => data))
}
#[export(raw_return)]
fn parse_config(
#[raw] class: Value,
raw_config: &[u8],
raw_private_config: &[u8],
) -> Result<Value, Error> {
let raw_config = std::str::from_utf8(raw_config)?;
let raw_private_config = std::str::from_utf8(raw_private_config)?;
Ok(perlmod::instantiate_magic!(&class, MAGIC => Box::new(
NotificationConfig {
config: Mutex::new(Config::new(raw_config, raw_private_config)?)
}
)))
}
#[export]
fn write_config(#[try_from_ref] this: &NotificationConfig) -> Result<(String, String), Error> {
Ok(this.config.lock().unwrap().write()?)
}
#[export]
fn digest(#[try_from_ref] this: &NotificationConfig) -> String {
let config = this.config.lock().unwrap();
hex::encode(config.digest())
}
#[export(serialize_error)]
fn send(
#[try_from_ref] this: &NotificationConfig,
severity: Severity,
template_name: String,
template_data: Option<JSONValue>,
fields: Option<HashMap<String, String>>,
) -> Result<(), HttpError> {
let config = this.config.lock().unwrap();
let notification = Notification::from_template(
severity,
template_name,
template_data.unwrap_or_default(),
fields.unwrap_or_default(),
);
api::common::send(&config, &notification)
}
#[export(serialize_error)]
fn test_target(
#[try_from_ref] this: &NotificationConfig,
target: &str,
) -> Result<(), HttpError> {
let config = this.config.lock().unwrap();
api::common::test_target(&config, target)
}
#[export(serialize_error)]
fn get_sendmail_endpoints(
#[try_from_ref] this: &NotificationConfig,
) -> Result<Vec<SendmailConfig>, HttpError> {
let config = this.config.lock().unwrap();
api::sendmail::get_endpoints(&config)
}
#[export(serialize_error)]
fn get_sendmail_endpoint(
#[try_from_ref] this: &NotificationConfig,
id: &str,
) -> Result<SendmailConfig, HttpError> {
let config = this.config.lock().unwrap();
api::sendmail::get_endpoint(&config, id)
}
#[export(serialize_error)]
#[allow(clippy::too_many_arguments)]
fn add_sendmail_endpoint(
#[try_from_ref] this: &NotificationConfig,
name: String,
mailto: Option<Vec<String>>,
mailto_user: Option<Vec<String>>,
from_address: Option<String>,
author: Option<String>,
comment: Option<String>,
disable: Option<bool>,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
api::sendmail::add_endpoint(
&mut config,
SendmailConfig {
name,
mailto: mailto.unwrap_or_default(),
mailto_user: mailto_user.unwrap_or_default(),
from_address,
author,
comment,
disable,
filter: None,
origin: None,
},
)
}
#[export(serialize_error)]
#[allow(clippy::too_many_arguments)]
fn update_sendmail_endpoint(
#[try_from_ref] this: &NotificationConfig,
name: &str,
mailto: Option<Vec<String>>,
mailto_user: Option<Vec<String>>,
from_address: Option<String>,
author: Option<String>,
comment: Option<String>,
disable: Option<bool>,
delete: Option<Vec<DeleteableSendmailProperty>>,
digest: Option<&str>,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
let digest = decode_digest(digest)?;
api::sendmail::update_endpoint(
&mut config,
name,
SendmailConfigUpdater {
mailto,
mailto_user,
from_address,
author,
comment,
disable,
},
delete.as_deref(),
digest.as_deref(),
)
}
#[export(serialize_error)]
fn delete_sendmail_endpoint(
#[try_from_ref] this: &NotificationConfig,
name: &str,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
api::sendmail::delete_endpoint(&mut config, name)
}
#[export(serialize_error)]
fn get_gotify_endpoints(
#[try_from_ref] this: &NotificationConfig,
) -> Result<Vec<GotifyConfig>, HttpError> {
let config = this.config.lock().unwrap();
api::gotify::get_endpoints(&config)
}
#[export(serialize_error)]
fn get_gotify_endpoint(
#[try_from_ref] this: &NotificationConfig,
id: &str,
) -> Result<GotifyConfig, HttpError> {
let config = this.config.lock().unwrap();
api::gotify::get_endpoint(&config, id)
}
#[export(serialize_error)]
fn add_gotify_endpoint(
#[try_from_ref] this: &NotificationConfig,
name: String,
server: String,
token: String,
comment: Option<String>,
disable: Option<bool>,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
api::gotify::add_endpoint(
&mut config,
GotifyConfig {
name: name.clone(),
server,
comment,
disable,
filter: None,
origin: None,
},
GotifyPrivateConfig { name, token },
)
}
#[export(serialize_error)]
#[allow(clippy::too_many_arguments)]
fn update_gotify_endpoint(
#[try_from_ref] this: &NotificationConfig,
name: &str,
server: Option<String>,
token: Option<String>,
comment: Option<String>,
disable: Option<bool>,
delete: Option<Vec<DeleteableGotifyProperty>>,
digest: Option<&str>,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
let digest = decode_digest(digest)?;
api::gotify::update_endpoint(
&mut config,
name,
GotifyConfigUpdater {
server,
comment,
disable,
},
GotifyPrivateConfigUpdater { token },
delete.as_deref(),
digest.as_deref(),
)
}
#[export(serialize_error)]
fn delete_gotify_endpoint(
#[try_from_ref] this: &NotificationConfig,
name: &str,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
api::gotify::delete_gotify_endpoint(&mut config, name)
}
#[export(serialize_error)]
fn get_smtp_endpoints(
#[try_from_ref] this: &NotificationConfig,
) -> Result<Vec<SmtpConfig>, HttpError> {
let config = this.config.lock().unwrap();
api::smtp::get_endpoints(&config)
}
#[export(serialize_error)]
fn get_smtp_endpoint(
#[try_from_ref] this: &NotificationConfig,
id: &str,
) -> Result<SmtpConfig, HttpError> {
let config = this.config.lock().unwrap();
api::smtp::get_endpoint(&config, id)
}
#[export(serialize_error)]
#[allow(clippy::too_many_arguments)]
fn add_smtp_endpoint(
#[try_from_ref] this: &NotificationConfig,
name: String,
server: String,
port: Option<u16>,
mode: Option<SmtpMode>,
username: Option<String>,
password: Option<String>,
mailto: Option<Vec<String>>,
mailto_user: Option<Vec<String>>,
from_address: String,
author: Option<String>,
comment: Option<String>,
disable: Option<bool>,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
api::smtp::add_endpoint(
&mut config,
SmtpConfig {
name: name.clone(),
server,
port,
mode,
username,
mailto: mailto.unwrap_or_default(),
mailto_user: mailto_user.unwrap_or_default(),
from_address,
author,
comment,
disable,
origin: None,
},
SmtpPrivateConfig { name, password },
)
}
#[export(serialize_error)]
#[allow(clippy::too_many_arguments)]
fn update_smtp_endpoint(
#[try_from_ref] this: &NotificationConfig,
name: &str,
server: Option<String>,
port: Option<u16>,
mode: Option<SmtpMode>,
username: Option<String>,
password: Option<String>,
mailto: Option<Vec<String>>,
mailto_user: Option<Vec<String>>,
from_address: Option<String>,
author: Option<String>,
comment: Option<String>,
disable: Option<bool>,
delete: Option<Vec<DeleteableSmtpProperty>>,
digest: Option<&str>,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
let digest = decode_digest(digest)?;
api::smtp::update_endpoint(
&mut config,
name,
SmtpConfigUpdater {
server,
port,
mode,
username,
mailto,
mailto_user,
from_address,
author,
comment,
disable,
},
SmtpPrivateConfigUpdater { password },
delete.as_deref(),
digest.as_deref(),
)
}
#[export(serialize_error)]
fn delete_smtp_endpoint(
#[try_from_ref] this: &NotificationConfig,
name: &str,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
api::smtp::delete_endpoint(&mut config, name)
}
#[export(serialize_error)]
fn get_matchers(
#[try_from_ref] this: &NotificationConfig,
) -> Result<Vec<MatcherConfig>, HttpError> {
let config = this.config.lock().unwrap();
api::matcher::get_matchers(&config)
}
#[export(serialize_error)]
fn get_matcher(
#[try_from_ref] this: &NotificationConfig,
id: &str,
) -> Result<MatcherConfig, HttpError> {
let config = this.config.lock().unwrap();
api::matcher::get_matcher(&config, id)
}
#[export(serialize_error)]
#[allow(clippy::too_many_arguments)]
fn add_matcher(
#[try_from_ref] this: &NotificationConfig,
name: String,
target: Option<Vec<String>>,
match_severity: Option<Vec<SeverityMatcher>>,
match_field: Option<Vec<FieldMatcher>>,
match_calendar: Option<Vec<CalendarMatcher>>,
mode: Option<MatchModeOperator>,
invert_match: Option<bool>,
comment: Option<String>,
disable: Option<bool>,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
api::matcher::add_matcher(
&mut config,
MatcherConfig {
name,
match_severity: match_severity.unwrap_or_default(),
match_field: match_field.unwrap_or_default(),
match_calendar: match_calendar.unwrap_or_default(),
target: target.unwrap_or_default(),
mode,
invert_match,
comment,
disable,
origin: None,
},
)
}
#[export(serialize_error)]
#[allow(clippy::too_many_arguments)]
fn update_matcher(
#[try_from_ref] this: &NotificationConfig,
name: &str,
target: Option<Vec<String>>,
match_severity: Option<Vec<SeverityMatcher>>,
match_field: Option<Vec<FieldMatcher>>,
match_calendar: Option<Vec<CalendarMatcher>>,
mode: Option<MatchModeOperator>,
invert_match: Option<bool>,
comment: Option<String>,
disable: Option<bool>,
delete: Option<Vec<DeleteableMatcherProperty>>,
digest: Option<&str>,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
let digest = decode_digest(digest)?;
api::matcher::update_matcher(
&mut config,
name,
MatcherConfigUpdater {
match_severity,
match_field,
match_calendar,
target,
mode,
invert_match,
comment,
disable,
},
delete.as_deref(),
digest.as_deref(),
)
}
#[export(serialize_error)]
fn delete_matcher(
#[try_from_ref] this: &NotificationConfig,
name: &str,
) -> Result<(), HttpError> {
let mut config = this.config.lock().unwrap();
api::matcher::delete_matcher(&mut config, name)
}
#[export]
fn get_referenced_entities(
#[try_from_ref] this: &NotificationConfig,
name: &str,
) -> Result<Vec<String>, HttpError> {
let config = this.config.lock().unwrap();
api::common::get_referenced_entities(&config, name)
}
fn decode_digest(digest: Option<&str>) -> Result<Option<Vec<u8>>, HttpError> {
digest
.map(hex::decode)
.transpose()
.map_err(|e| api::http_err!(BAD_REQUEST, "invalid digest: {e}"))
}
}

View File

@ -0,0 +1,68 @@
#[perlmod::package(name = "Proxmox::RS::SharedCache")]
mod export {
use std::time::Duration;
use anyhow::Error;
use nix::sys::stat::Mode;
use serde::Deserialize;
use serde_json::Value as JSONValue;
use perlmod::Value;
use proxmox_shared_cache::SharedCache;
use proxmox_sys::fs::CreateOptions;
pub struct CacheWrapper(SharedCache);
perlmod::declare_magic!(Box<CacheWrapper> : &CacheWrapper as "Proxmox::RS::SharedCache");
#[derive(Deserialize)]
struct Params {
path: String,
owner: u32,
group: u32,
entry_mode: u32,
keep_old: u32,
}
#[export(raw_return)]
fn new(#[raw] class: Value, params: Params) -> Result<Value, Error> {
let options = CreateOptions::new()
.owner(params.owner.into())
.group(params.group.into())
.perm(Mode::from_bits_truncate(params.entry_mode));
Ok(perlmod::instantiate_magic!(&class, MAGIC => Box::new(
CacheWrapper (
SharedCache::new(params.path, options, params.keep_old)?
)
)))
}
#[export]
fn set(
#[try_from_ref] this: &CacheWrapper,
value: JSONValue,
lock_timeout: u64,
) -> Result<(), Error> {
this.0.set(&value, Duration::from_secs(lock_timeout))
}
#[export]
fn get(#[try_from_ref] this: &CacheWrapper) -> Result<Option<JSONValue>, Error> {
this.0.get()
}
#[export]
fn get_last(
#[try_from_ref] this: &CacheWrapper,
number_of_old_entries: u32,
) -> Result<Vec<JSONValue>, Error> {
this.0.get_last(number_of_old_entries)
}
#[export]
fn delete(#[try_from_ref] this: &CacheWrapper, lock_timeout: u64) -> Result<(), Error> {
this.0.delete(Duration::from_secs(lock_timeout))
}
}

View File

@ -3,3 +3,6 @@
directory = "/usr/share/cargo/registry"
[source.crates-io]
replace-with = "debian-packages"
[profile.release]
debug = true

View File

@ -1,6 +1,6 @@
[package]
name = "pmg-rs"
version = "0.6.3"
version = "0.7.6"
description = "PMG parts which have been ported to rust"
homepage = "https://www.proxmox.com"
authors = ["Proxmox Support Team <support@proxmox.com>"]
@ -8,34 +8,37 @@ edition = "2021"
license = "AGPL-3"
repository = "https://git.proxmox.com/?p=proxmox.git"
exclude = [
"build",
"debian",
"PMG",
]
exclude = ["build", "debian", "PMG"]
[lib]
crate-type = [ "cdylib" ]
crate-type = ["cdylib"]
[dependencies]
anyhow = "1.0"
env_logger = "0.9"
hex = "0.4"
http = "0.2.7"
libc = "0.2"
log = "0.4.17"
nix = "0.26"
openssl = "0.10.40"
serde = "1.0"
serde_bytes = "0.11"
serde_json = "1.0"
tracing = "0.1.37"
url = "2"
perlmod = { version = "0.13", features = [ "exporter" ] }
perlmod = { version = "0.13.4", features = ["exporter"] }
proxmox-acme-rs = { version = "0.4", features = ["client"] }
proxmox-apt = "0.9.4"
proxmox-http = { version = "0.8", features = ["client-sync", "client-trait"] }
proxmox-subscription = "0.3"
proxmox-sys = "0.4.2"
proxmox-tfa = { version = "4", features = ["api"] }
proxmox-time = "1.1.3"
proxmox-acme = { version = "0.5", features = ["client", "api-types"] }
proxmox-apt = { version = "0.11", features = ["cache"] }
proxmox-apt-api-types = "1.0"
proxmox-config-digest = "0.1"
proxmox-http = { version = "0.9", features = ["client-sync", "client-trait"] }
proxmox-http-error = "0.1.0"
proxmox-log = "0.2"
proxmox-notify = "0.4"
proxmox-shared-cache = "0.1.0"
proxmox-subscription = "0.4"
proxmox-sys = "0.6"
proxmox-tfa = { version = "5", features = ["api"] }
proxmox-time = "2"

4
pmg-rs/Fixup.pm Normal file
View File

@ -0,0 +1,4 @@
# BEGIN Fixup.pm
# This is prepended to the current PMG.pm to force-include the temporary `openssl-probe` fixup.
use Proxmox::Lib::SslProbe;
# END Fixup.pm

View File

@ -22,7 +22,8 @@ PERLMOD_GENPACKAGE := /usr/lib/perlmod/genpackage.pl \
--lib=pmg_rs \
--lib-tag=proxmox \
--lib-package=Proxmox::Lib::PMG \
--lib-prefix=PMG
--lib-prefix=PMG \
--include-file=Fixup.pm
PERLMOD_PACKAGES := \
PMG::RS::APT::Repositories \
@ -31,6 +32,8 @@ PERLMOD_PACKAGES := \
PMG::RS::OpenId \
PMG::RS::TFA
PERLMOD_PACKAGE_FILES := $(addsuffix .pm,$(subst ::,/,$(PERLMOD_PACKAGES)))
ifeq ($(BUILD_MODE), release)
CARGO_BUILD_ARGS += --release
TARGET_DIR=release
@ -41,12 +44,13 @@ endif
all: PMG
cargo build $(CARGO_BUILD_ARGS)
PMG: Proxmox/Lib/PMG.pm
Proxmox/Lib/PMG.pm:
Proxmox: Proxmox/Lib/PMG.pm
PMG: $(PERLMOD_PACKAGE_FILES)
Proxmox/Lib/PMG.pm $(PERLMOD_PACKAGE_FILES) &: Fixup.pm
$(PERLMOD_GENPACKAGE) $(PERLMOD_PACKAGES)
.PHONY: install
install: target/release/libpmg_rs.so Proxmox/Lib/PMG.pm PMG
install: target/release/libpmg_rs.so Proxmox/Lib/PMG.pm $(PERLMOD_PACKAGE_FILES)
install -d -m755 $(DESTDIR)$(PERL_INSTALLVENDORARCH)/auto
install -m644 target/release/libpmg_rs.so $(DESTDIR)$(PERL_INSTALLVENDORARCH)/auto/libpmg_rs.so
install -d -m755 $(DESTDIR)$(PERL_INSTALLVENDORLIB)
@ -56,6 +60,7 @@ install: target/release/libpmg_rs.so Proxmox/Lib/PMG.pm PMG
distclean: clean
clean:
rm -rf PMG Proxmox
cargo clean
rm -f *.deb *.dsc *.tar.* *.build *.buildinfo *.changes Cargo.lock
rm -rf $(PACKAGE)-[0-9]*/
@ -71,11 +76,11 @@ upload: $(DEBS)
git diff --exit-code --stat && git diff --exit-code --stat --staged
tar cf - $(DEBS) | ssh -X repoman@repo.proxmox.com upload --product pmg --dist $(DEB_DISTRIBUTION)
$(BUILDDIR): src debian common/src Cargo.toml Makefile .cargo/config
$(BUILDDIR): src debian common/src Cargo.toml Makefile .cargo/config.toml
rm -rf $(BUILDDIR) $(BUILDDIR).tmp
mkdir $(BUILDDIR).tmp
mkdir $(BUILDDIR).tmp/common
cp -a -t $(BUILDDIR).tmp src debian Cargo.toml Makefile .cargo
cp -a -t $(BUILDDIR).tmp src debian Cargo.toml Makefile .cargo Fixup.pm
cp -a -t $(BUILDDIR).tmp/common common/src
mv $(BUILDDIR).tmp $(BUILDDIR)

View File

@ -1,9 +1,58 @@
libpmg-rs-perl (0.6.3) bullseye; urgency=medium
libpmg-rs-perl (0.7.6) bookworm; urgency=medium
* build with proxmox-apt 0.9.4 to also detect repository with next suite as
configured
* upgrade to current rust crates or perlmod and proxmox-sys/tfa/apt/notify
-- Proxmox Support Team <support@proxmox.com> Fri, 09 Jun 2023 11:36:12 +0200
* add bindings for proxmox-shared-cache crate
* use apt api method implementation from proxmox-apt crate
-- Proxmox Support Team <support@proxmox.com> Fri, 09 Aug 2024 14:19:56 +0200
libpmg-rs-perl (0.7.5) bookworm; urgency=medium
* add EAB binding support to ACME
* make Proxmox::Lib::PMG pull in Proxmox::Lib::SslProbe to work around
an issue where the openssl-probe crate calls setenv() and messes up perl's
view of the environment
-- Proxmox Support Team <support@proxmox.com> Thu, 07 Dec 2023 09:57:43 +0100
libpmg-rs-perl (0.7.4) bookworm; urgency=medium
* update to env logger 0.10
* use declare_magic for ACME
* add Promox::Lib::PMG::use_safe_putenv
-- Proxmox Support Team <support@proxmox.com> Wed, 06 Dec 2023 11:22:56 +0100
libpmg-rs-perl (0.7.3) bookworm; urgency=medium
* reset failure counts when unlocking second factors
-- Proxmox Support Team <support@proxmox.com> Wed, 05 Jul 2023 13:35:23 +0200
libpmg-rs-perl (0.7.2) bookworm; urgency=medium
* set default log level to 'info'
* introduce PMG_LOG environment variable to override log level
* add tfa_lock_status query sub
* add api_unlock_tfa sub
* bump proxmox-tfa to 4.0.2
-- Proxmox Support Team <support@proxmox.com> Tue, 27 Jun 2023 16:01:23 +0200
libpmg-rs-perl (0.7.1) bookworm; urgency=medium
* rebuild for Debian 12 Bookworm based release series
-- Proxmox Support Team <support@proxmox.com> Thu, 18 May 2023 12:01:08 +0200
libpmg-rs-perl (0.6.2) bullseye; urgency=medium

View File

@ -1 +0,0 @@
12

View File

@ -1,45 +1,58 @@
Source: libpmg-rs-perl
Section: perl
Priority: optional
Build-Depends: cargo:native <!nocheck>,
debhelper-compat (= 13),
librust-openssl-probe-dev (= 0.1.5-1~bpo12+pve1),
dh-cargo (>= 25),
librust-anyhow-1+default-dev,
librust-hex-0.4+default-dev,
librust-http-0.2+default-dev (>= 0.2.7-~~),
librust-libc-0.2+default-dev,
librust-log-0.4+default-dev (>= 0.4.17-~~),
librust-nix-0.26+default-dev,
librust-openssl-0.10+default-dev (>= 0.10.40-~~),
librust-perlmod-0.13+default-dev (>= 0.13.4-~~),
librust-perlmod-0.13+exporter-dev (>= 0.13.4-~~),
librust-proxmox-acme-0.5+api-types-dev,
librust-proxmox-acme-0.5+client-dev,
librust-proxmox-acme-0.5+default-dev,
librust-proxmox-apt-0.11+cache-dev,
librust-proxmox-apt-0.11+default-dev,
librust-proxmox-apt-api-types-1+default-dev,
librust-proxmox-config-digest-0.1+default-dev,
librust-proxmox-http-0.9+client-sync-dev,
librust-proxmox-http-0.9+client-trait-dev,
librust-proxmox-http-0.9+default-dev,
librust-proxmox-http-error-0.1+default-dev,
librust-proxmox-log-0.2+default-dev,
librust-proxmox-notify-0.4+default-dev,
librust-proxmox-shared-cache-0.1+default-dev,
librust-proxmox-subscription-0.4+default-dev,
librust-proxmox-sys-0.6+default-dev,
librust-proxmox-tfa-5+api-dev,
librust-proxmox-tfa-5+default-dev,
librust-proxmox-time-2+default-dev,
librust-serde-1+default-dev,
librust-serde-bytes-0.11+default-dev,
librust-serde-json-1+default-dev,
librust-tracing-0.1+default-dev (>= 0.1.37-~~),
librust-url-2+default-dev,
libstd-rust-dev <!nocheck>,
perlmod-bin (>= 0.2.0-3),
rustc:native <!nocheck>,
Maintainer: Proxmox Support Team <support@proxmox.com>
Build-Depends:
debhelper (>= 12),
dh-cargo (>= 24),
perlmod-bin,
cargo:native <!nocheck>,
rustc:native <!nocheck>,
libstd-rust-dev <!nocheck>,
librust-anyhow-1+default-dev,
librust-env-logger-0.9+default-dev,
librust-hex-0.4+default-dev,
librust-http-0.2+default-dev (>= 0.2.7-~~),
librust-libc-0.2+default-dev,
librust-nix-0.26+default-dev,
librust-openssl-0.10+default-dev (>= 0.10.40-~~),
librust-perlmod-0.13+default-dev,
librust-perlmod-0.13+exporter-dev,
librust-proxmox-acme-rs-0.4+client-dev,
librust-proxmox-acme-rs-0.4+default-dev,
librust-proxmox-apt-0.9+default-dev (>= 0.9.4-~~),
librust-proxmox-http-0.8+client-sync-dev,
librust-proxmox-http-0.8+client-trait-dev,
librust-proxmox-http-0.8+default-dev,
librust-proxmox-subscription-0.3+default-dev,
librust-proxmox-sys-0.4+default-dev (>= 0.4.2-~~),
librust-proxmox-tfa-4+api-dev,
librust-proxmox-tfa-4+default-dev,
librust-proxmox-time-1+default-dev (>= 1.1.3-~~),
librust-serde-1+default-dev,
librust-serde-bytes-0.11+default-dev,
librust-serde-json-1+default-dev,
librust-url-2+default-dev,
Standards-Version: 4.3.0
Standards-Version: 4.6.1
Vcs-Git: git://git.proxmox.com/git/proxmox-perl-rs.git
Vcs-Browser: https://git.proxmox.com/?p=proxmox-perl-rs.git
Homepage: https://www.proxmox.com
Package: libpmg-rs-perl
Architecture: any
Depends: ${perl:Depends},
Depends: ${misc:Depends},
${perl:Depends},
${shlibs:Depends},
libproxmox-rs-perl (>= 0.3.3),
Description: Components of Proxmox Mail Gateway which have been ported to Rust.
Contains parts of Proxmox Mail Gateway which have been ported to, or newly
implemented in the Rust programming language.

View File

@ -1,10 +1,31 @@
# WARNING: this is *NOT* use as canonical source for d/control, but rather occasionally used via
# an invocation like:
# make clean
# rm debian/control
# debcargo package --config debian/debcargo.toml --changelog-ready --no-overlay-write-back --directory libpmg-rs-perl-0.7.1 pmg-rs 0.7.1
# mv libpmg-rs-perl-0.7.1/debian/control debian/control
# to semi.manually refresh the control file
#
# NOTE: debcargo thinks this is a source package, but it isn't! Drop provides, the dependencies of
# the binary package on rust source packages, Multi-Arch same, and other things that do not make
# sense for a combined perl + arch-dependent library package.
overlay = "."
crate_src_path = ".."
maintainer = "Proxmox Support Team <support@proxmox.com>"
[source]
section = "perl"
vcs_git = "git://git.proxmox.com/git/proxmox.git"
vcs_browser = "https://git.proxmox.com/?p=proxmox.git"
vcs_git = "git://git.proxmox.com/git/proxmox-perl-rs.git"
vcs_browser = "https://git.proxmox.com/?p=proxmox-perl-rs.git"
build_depends = [
"perlmod-bin",
]
[packages.libpmg-rs-perl]
[packages.bin]
name = "libpmg-rs-perl"
summary = "Components of Proxmox Mail Gateway which have been ported to Rust."
description = """
Contains parts of Proxmox Mail Gateway which have been ported to, or newly
implemented in the Rust programming language.
"""

View File

@ -1,7 +1,25 @@
#!/usr/bin/make -f
include /usr/share/dpkg/pkg-info.mk
include /usr/share/rustc/architecture.mk
#export DH_VERBOSE=1
export BUILD_MODE=release
CARGO=/usr/share/cargo/bin/cargo
export CFLAGS CXXFLAGS CPPFLAGS LDFLAGS
export DEB_HOST_RUST_TYPE DEB_HOST_GNU_TYPE
export CARGO_HOME = $(CURDIR)/debian/cargo_home
export DEB_CARGO_CRATE=pmg-rs_$(DEB_VERSION_UPSTREAM)
export DEB_CARGO_PACKAGE=pmg-rs
%:
dh $@
override_dh_auto_configure:
@perl -ne 'if (/^version\s*=\s*"(\d+(?:\.\d+)+)"/) { my $$v_cargo = $$1; my $$v_deb = "$(DEB_VERSION_UPSTREAM)"; \
die "ERROR: d/changelog <-> Cargo.toml version mismatch: $$v_cargo != $$v_deb\n" if $$v_cargo ne $$v_deb; exit(0); }' Cargo.toml
$(CARGO) prepare-debian $(CURDIR)/debian/cargo_registry --link-from-system
dh_auto_configure

View File

@ -9,8 +9,8 @@ use std::os::unix::fs::OpenOptionsExt;
use anyhow::{format_err, Error};
use serde::{Deserialize, Serialize};
use proxmox_acme_rs::account::AccountData as AcmeAccountData;
use proxmox_acme_rs::{Account, Client};
use proxmox_acme::types::AccountData as AcmeAccountData;
use proxmox_acme::{Account, Client};
/// Our on-disk format inherited from PVE's proxmox-acme code.
#[derive(Deserialize, Serialize)]
@ -79,6 +79,7 @@ impl Inner {
tos_agreed: bool,
contact: Vec<String>,
rsa_bits: Option<u32>,
eab_creds: Option<(String, String)>,
) -> Result<(), Error> {
self.tos = if tos_agreed {
self.client.terms_of_service_url()?.map(str::to_owned)
@ -86,7 +87,9 @@ impl Inner {
None
};
let _account = self.client.new_account(contact, tos_agreed, rsa_bits)?;
let _account = self
.client
.new_account(contact, tos_agreed, rsa_bits, eab_creds)?;
let file = OpenOptions::new()
.write(true)
.create(true)
@ -182,67 +185,45 @@ impl Inner {
#[perlmod::package(name = "PMG::RS::Acme")]
pub mod export {
use std::collections::HashMap;
use std::convert::TryFrom;
use std::sync::Mutex;
use anyhow::Error;
use serde_bytes::{ByteBuf, Bytes};
use perlmod::Value;
use proxmox_acme_rs::directory::Meta;
use proxmox_acme_rs::order::OrderData;
use proxmox_acme_rs::{Authorization, Challenge, Order};
use proxmox_acme::directory::Meta;
use proxmox_acme::order::OrderData;
use proxmox_acme::{Authorization, Challenge, Order};
use super::{AccountData, Inner};
const CLASSNAME: &str = "PMG::RS::Acme";
perlmod::declare_magic!(Box<Acme> : &Acme as "PMG::RS::Acme");
/// An Acme client instance.
pub struct Acme {
inner: Mutex<Inner>,
}
impl<'a> TryFrom<&'a Value> for &'a Acme {
type Error = Error;
fn try_from(value: &'a Value) -> Result<&'a Acme, Error> {
Ok(unsafe { value.from_blessed_box(CLASSNAME)? })
}
}
fn bless(class: Value, mut ptr: Box<Acme>) -> Result<Value, Error> {
let value = Value::new_pointer::<Acme>(&mut *ptr);
let value = Value::new_ref(&value);
let this = value.bless_sv(&class)?;
let _perl = Box::leak(ptr);
Ok(this)
}
/// Create a new ACME client instance given an account path and an API directory URL.
#[export(raw_return)]
pub fn new(#[raw] class: Value, api_directory: String) -> Result<Value, Error> {
bless(
class,
Box::new(Acme {
Ok(perlmod::instantiate_magic!(
&class,
MAGIC => Box::new(Acme {
inner: Mutex::new(Inner::new(api_directory)?),
}),
)
})
))
}
/// Load an existing account.
#[export(raw_return)]
pub fn load(#[raw] class: Value, account_path: String) -> Result<Value, Error> {
bless(
class,
Box::new(Acme {
Ok(perlmod::instantiate_magic!(
&class,
MAGIC => Box::new(Acme {
inner: Mutex::new(Inner::load(account_path)?),
}),
)
}
#[export(name = "DESTROY")]
fn destroy(#[raw] this: Value) {
perlmod::destructor!(this, Acme: CLASSNAME);
})
))
}
/// Create a new account.
@ -260,11 +241,16 @@ pub mod export {
tos_agreed: bool,
contact: Vec<String>,
rsa_bits: Option<u32>,
eab_kid: Option<String>,
eab_hmac_key: Option<String>,
) -> Result<(), Error> {
this.inner
.lock()
.unwrap()
.new_account(account_path, tos_agreed, contact, rsa_bits)
this.inner.lock().unwrap().new_account(
account_path,
tos_agreed,
contact,
rsa_bits,
eab_kid.zip(eab_hmac_key),
)
}
/// Get the directory's meta information.

View File

@ -1,12 +1,16 @@
#[perlmod::package(name = "PMG::RS::APT::Repositories")]
mod export {
use anyhow::Error;
use proxmox_apt_api_types::{
APTChangeRepositoryOptions, APTRepositoriesResult, APTRepositoryHandle,
};
use proxmox_config_digest::ConfigDigest;
use crate::common::apt::repositories::export as common;
/// Get information about configured and standard repositories.
#[export]
pub fn repositories() -> Result<common::RepositoriesResult, Error> {
pub fn repositories() -> Result<APTRepositoriesResult, Error> {
common::repositories("pmg")
}
@ -15,7 +19,10 @@ mod export {
///
/// The `digest` parameter asserts that the configuration has not been modified.
#[export]
pub fn add_repository(handle: &str, digest: Option<&str>) -> Result<(), Error> {
pub fn add_repository(
handle: APTRepositoryHandle,
digest: Option<ConfigDigest>,
) -> Result<(), Error> {
common::add_repository(handle, "pmg", digest)
}
@ -26,8 +33,8 @@ mod export {
pub fn change_repository(
path: &str,
index: usize,
options: common::ChangeProperties,
digest: Option<&str>,
options: APTChangeRepositoryOptions,
digest: Option<ConfigDigest>,
) -> Result<(), Error> {
common::change_repository(path, index, options, digest)
}

View File

@ -5,7 +5,7 @@ pub mod export {
use anyhow::Error;
use serde_bytes::ByteBuf;
use proxmox_acme_rs::util::Csr;
use proxmox_acme::util::Csr;
/// Generates a CSR and its accompanying private key.
///

View File

@ -1,3 +1,7 @@
use anyhow::Error;
use proxmox_apt_api_types::APTUpdateInfo;
#[path = "../common/src/mod.rs"]
pub mod common;
@ -12,6 +16,20 @@ mod export {
#[export]
pub fn init() {
common::logger::init();
common::logger::init("PMG_LOG", "info");
}
/// CLI tools should call this very early. This is a workaround causing environment variable
/// manipulation to leak instead of crash. Required when calling into rust code that causes
/// `setenv` calls, particularly code using the openssl crate.
#[export]
pub fn use_safe_putenv() {
perlmod::ffi::use_safe_putenv(true);
}
}
pub fn send_updates_available(_updates: &[&APTUpdateInfo]) -> Result<(), Error> {
log::warn!("update notifications are not implemented for PMG yet");
Ok(())
}

View File

@ -24,6 +24,7 @@ pub(self) use proxmox_tfa::api::{
#[perlmod::package(name = "PMG::RS::TFA")]
mod export {
use std::collections::HashMap;
use std::convert::TryInto;
use std::sync::Mutex;
@ -436,6 +437,66 @@ mod export {
Err(methods::EntryNotFound) => bail!("no such entry"),
}
}
#[export]
fn api_unlock_tfa(#[raw] raw_this: Value, userid: &str) -> Result<bool, Error> {
let this: &Tfa = (&raw_this).try_into()?;
Ok(methods::unlock_and_reset_tfa(
&mut this.inner.lock().unwrap(),
&UserAccess::new(&raw_this)?,
userid,
)?)
}
#[derive(serde::Serialize)]
#[serde(rename_all = "kebab-case")]
struct TfaLockStatus {
/// Once a user runs into a TOTP limit they get locked out of TOTP until they successfully use
/// a recovery key.
#[serde(skip_serializing_if = "bool_is_false", default)]
totp_locked: bool,
/// If a user hits too many 2nd factor failures, they get completely blocked for a while.
#[serde(skip_serializing_if = "Option::is_none", default)]
#[serde(deserialize_with = "filter_expired_timestamp")]
tfa_locked_until: Option<i64>,
}
impl From<&proxmox_tfa::api::TfaUserData> for TfaLockStatus {
fn from(data: &proxmox_tfa::api::TfaUserData) -> Self {
Self {
totp_locked: data.totp_locked,
tfa_locked_until: data.tfa_locked_until,
}
}
}
fn bool_is_false(b: &bool) -> bool {
!*b
}
#[export]
fn tfa_lock_status(
#[try_from_ref] this: &Tfa,
userid: Option<&str>,
) -> Result<Option<perlmod::Value>, Error> {
let this = this.inner.lock().unwrap();
if let Some(userid) = userid {
if let Some(user) = this.users.get(userid) {
Ok(Some(perlmod::to_value(&TfaLockStatus::from(user))?))
} else {
Ok(None)
}
} else {
Ok(Some(perlmod::to_value(
&HashMap::<String, TfaLockStatus>::from_iter(
this.users
.iter()
.map(|(uid, data)| (uid.clone(), TfaLockStatus::from(data))),
),
)?))
}
}
}
/// Attach the path to errors from [`nix::mkir()`].
@ -589,9 +650,8 @@ impl proxmox_tfa::api::OpenUserChallengeData for UserAccess {
}
}
// TODO: enable once we have UI/API admin stuff to unlock locked accounts
fn enable_lockout(&self) -> bool {
false
true
}
}

View File

@ -3,3 +3,6 @@
directory = "/usr/share/cargo/registry"
[source.crates-io]
replace-with = "debian-packages"
[profile.release]
debug = true

View File

@ -1,6 +1,6 @@
[package]
name = "pve-rs"
version = "0.7.7"
version = "0.8.10"
description = "PVE parts which have been ported to Rust"
homepage = "https://www.proxmox.com"
authors = ["Proxmox Support Team <support@proxmox.com>"]
@ -8,35 +8,40 @@ edition = "2021"
license = "AGPL-3"
repository = "https://git.proxmox.com/?p=proxmox.git"
exclude = [
"debian",
]
exclude = ["debian"]
[lib]
crate-type = [ "cdylib" ]
crate-type = ["cdylib"]
[dependencies]
anyhow = "1.0"
base32 = "0.4"
base64 = "0.13"
env_logger = "0.9"
hex = "0.4"
http = "0.2.7"
libc = "0.2"
log = "0.4.17"
nix = "0.26"
openssl = "0.10.40"
serde = "1.0"
serde_bytes = "0.11"
serde_json = "1.0"
tracing = "0.1.37"
url = "2"
perlmod = { version = "0.13", features = [ "exporter" ] }
perlmod = { version = "0.13", features = ["exporter"] }
proxmox-apt = "0.9.4"
proxmox-http = { version = "0.8", features = ["client-sync", "client-trait"] }
proxmox-openid = "0.9.8"
proxmox-resource-scheduling = "0.2.1"
proxmox-subscription = "0.3"
proxmox-sys = "0.4.2"
proxmox-tfa = { version = "4", features = ["api"] }
proxmox-time = "1.1.3"
proxmox-apt = { version = "0.11", features = ["cache"] }
proxmox-apt-api-types = "1.0"
proxmox-config-digest = "0.1"
proxmox-http = { version = "0.9", features = ["client-sync", "client-trait"] }
proxmox-http-error = "0.1.0"
proxmox-log = "0.2"
proxmox-notify = { version = "0.4", features = ["pve-context"] }
proxmox-openid = "0.10"
proxmox-resource-scheduling = "0.3.0"
proxmox-shared-cache = "0.1.0"
proxmox-subscription = "0.4"
proxmox-sys = "0.6"
proxmox-tfa = { version = "5", features = ["api"] }
proxmox-time = "2"

4
pve-rs/Fixup.pm Normal file
View File

@ -0,0 +1,4 @@
# BEGIN Fixup.pm
# This is prepended to the current PMG.pm to force-include the temporary `openssl-probe` fixup.
use Proxmox::Lib::SslProbe;
# END Fixup.pm

View File

@ -23,7 +23,8 @@ PERLMOD_GENPACKAGE := /usr/lib/perlmod/genpackage.pl \
--lib=pve_rs \
--lib-tag=proxmox \
--lib-package=Proxmox::Lib::PVE \
--lib-prefix=PVE
--lib-prefix=PVE \
--include-file=Fixup.pm
PERLMOD_PACKAGES := \
PVE::RS::APT::Repositories \
@ -31,6 +32,8 @@ PERLMOD_PACKAGES := \
PVE::RS::ResourceScheduling::Static \
PVE::RS::TFA
PERLMOD_PACKAGE_FILES := $(addsuffix .pm,$(subst ::,/,$(PERLMOD_PACKAGES)))
ifeq ($(BUILD_MODE), release)
CARGO_BUILD_ARGS += --release
TARGET_DIR=release
@ -42,18 +45,19 @@ all: PVE
cargo build $(CARGO_BUILD_ARGS)
mkdir -p test/Proxmox/Lib
sed -r -e \
's@^sub libdirs.*$$@sub libdirs { return ("./target/$(TARGET_DIR)", "./../target/$(TARGET_DIR)"); }@' \
's@^sub libfile.*$$@sub libfile { "$(shell pwd)/target/$(TARGET_DIR)/libpve_rs.so"; }@' \
Proxmox/Lib/PVE.pm >test/Proxmox/Lib/PVE.pm
PVE: Proxmox/Lib/PVE.pm
Proxmox/Lib/PVE.pm:
Proxmox: Proxmox/Lib/PVE.pm
PVE: $(PERLMOD_PACKAGE_FILES)
Proxmox/Lib/PVE.pm $(PERLMOD_PACKAGE_FILES) &: Fixup.pm
$(PERLMOD_GENPACKAGE) $(PERLMOD_PACKAGES)
check: all
$(MAKE) -C test test
.PHONY: install
install: target/release/libpve_rs.so Proxmox/Lib/PVE.pm PVE
install: target/release/libpve_rs.so Proxmox/Lib/PVE.pm $(PERLMOD_PACKAGE_FILES)
install -d -m755 $(DESTDIR)$(PERL_INSTALLVENDORARCH)/auto
install -m644 target/release/libpve_rs.so $(DESTDIR)$(PERL_INSTALLVENDORARCH)/auto/libpve_rs.so
install -d -m755 $(DESTDIR)$(PERL_INSTALLVENDORLIB)
@ -62,6 +66,7 @@ install: target/release/libpve_rs.so Proxmox/Lib/PVE.pm PVE
find $(PM_DIR) \! -type d -print -exec install -Dm644 '{}' $(DESTDIR)$(PERL_INSTALLVENDORLIB)'/{}' ';'
clean:
rm -rf PVE Proxmox
cargo clean
rm -f *.deb *.dsc *.tar.* *.build *.buildinfo *.changes Cargo.lock
rm -rf $(PACKAGE)-[0-9]*/
@ -77,11 +82,11 @@ upload: $(DEBS)
git diff --exit-code --stat && git diff --exit-code --stat --staged
tar cf - $(DEBS) | ssh -X repoman@repo.proxmox.com upload --product pve --dist $(DEB_DISTRIBUTION)
$(BUILDDIR): src debian test common/src Cargo.toml Makefile .cargo/config
$(BUILDDIR): src debian test common/src Cargo.toml Makefile .cargo/config.toml
rm -rf $(BUILDDIR) $(BUILDDIR).tmp
mkdir $(BUILDDIR).tmp
mkdir $(BUILDDIR).tmp/common
cp -a -t $(BUILDDIR).tmp src debian test Cargo.toml Makefile .cargo
cp -a -t $(BUILDDIR).tmp src debian test Cargo.toml Makefile .cargo Fixup.pm
cp -a -t $(BUILDDIR).tmp/common common/src
mv $(BUILDDIR).tmp $(BUILDDIR)

View File

@ -1,9 +1,99 @@
libpve-rs-perl (0.7.7) bullseye; urgency=medium
libpve-rs-perl (0.8.10) bookworm; urgency=medium
* build with proxmox-apt 0.9.4 to also detect repository with next suite as
configured
* use apt api implementation from the proxmox-apt crate
-- Proxmox Support Team <support@proxmox.com> Fri, 09 Jun 2023 11:30:59 +0200
* send apt update notification via proxmox-notify
* add bindings for proxmox-shared-cache crate
* update to current proxmox-time/tfa/sys/log crates
-- Proxmox Support Team <support@proxmox.com> Fri, 09 Aug 2024 13:42:38 +0200
libpve-rs-perl (0.8.9) bookworm; urgency=medium
* update to notify 0.4: use file based notification templates
-- Proxmox Support Team <support@proxmox.com> Tue, 04 Jun 2024 11:01:03 +0200
libpve-rs-perl (0.8.8) bookworm; urgency=medium
* notify: include 'hostname' and 'type' metadata fields for forwarded mails
* notify: smtp: forward original message instead of nesting
* notify: smtp: add 'Auto-Submitted' header to email body
* notify: api: allow resetting built-in targets if used by a matcher
-- Proxmox Support Team <support@proxmox.com> Wed, 10 Jan 2024 14:19:47 +0100
libpve-rs-perl (0.8.7) bookworm; urgency=medium
* notify: adapt to new matcher-based notification routing
* notify: add bindings for smtp API calls
* pve-rs: notify: remove notify_context for PVE
* notify: add 'disable' parameter
* notify: support 'origin' paramter
-- Proxmox Support Team <support@proxmox.com> Fri, 17 Nov 2023 13:41:17 +0100
libpve-rs-perl (0.8.6) bookworm; urgency=medium
* re-build with newer proxmox-apt depenceny to make Ceph Reef repo available
-- Proxmox Support Team <support@proxmox.com> Tue, 05 Sep 2023 15:37:44 +0200
libpve-rs-perl (0.8.5) bookworm; urgency=medium
* add PVE::RS::Notify module
-- Proxmox Support Team <support@proxmox.com> Mon, 24 Jul 2023 11:18:56 +0200
libpve-rs-perl (0.8.4) bookworm; urgency=medium
* reset failure counts when unlocking second factors
-- Proxmox Support Team <support@proxmox.com> Wed, 05 Jul 2023 13:30:17 +0200
libpve-rs-perl (0.8.3) bookworm; urgency=medium
* set default log level to 'info'
* introduce PVE_LOG environment variable to override log level
* add tfa_lock_status query sub
* bump proxmox-tfa to 4.0.2
-- Proxmox Support Team <support@proxmox.com> Mon, 05 Jun 2023 12:55:03 +0200
libpve-rs-perl (0.8.2) bookworm; urgency=medium
* update proxmox-apt which updated repositories info for bookworm
-- Proxmox Support Team <support@proxmox.com> Sun, 04 Jun 2023 18:33:42 +0200
libpve-rs-perl (0.8.1) bookworm; urgency=medium
* bump proxmox-apt,http,openid,subscription,sys crates to their bookworm
versions
* bump proxmox-tfa to 4.0.1 to include the unlock API
* enable TFA lockout and provide the `api_unlock_tfa` call
-- Proxmox Support Team <support@proxmox.com> Wed, 31 May 2023 14:17:31 +0200
libpve-rs-perl (0.8.0) bookworm; urgency=medium
* rebuild for Debian 12 Bookworm based release series
-- Proxmox Support Team <support@proxmox.com> Tue, 16 May 2023 14:26:52 +0200
libpve-rs-perl (0.7.6) bullseye; urgency=medium

View File

@ -1,41 +1,49 @@
Source: libpve-rs-perl
Section: perl
Priority: optional
Build-Depends:
debhelper-compat (= 13),
dh-cargo (>= 24),
perlmod-bin,
cargo:native <!nocheck>,
rustc:native <!nocheck>,
libstd-rust-dev <!nocheck>,
librust-anyhow-1+default-dev,
librust-base32-0.4+default-dev,
librust-base64-0.13+default-dev,
librust-env-logger-0.9+default-dev,
librust-hex-0.4+default-dev,
librust-http-0.2+default-dev (>= 0.2.7-~~),
librust-libc-0.2+default-dev,
librust-nix-0.26+default-dev,
librust-openssl-0.10+default-dev (>= 0.10.40-~~),
librust-perlmod-0.13+default-dev,
librust-perlmod-0.13+exporter-dev,
librust-proxmox-apt-0.9+default-dev (>= 0.9.4-~~),
librust-proxmox-http-0.8+client-sync-dev,
librust-proxmox-http-0.8+client-trait-dev,
librust-proxmox-http-0.8+default-dev,
librust-proxmox-openid-0.9+default-dev (>= 0.9.8-~~),
librust-proxmox-resource-scheduling-0.2+default-dev (>= 0.2.1-~~),
librust-proxmox-subscription-0.3+default-dev,
librust-proxmox-sys-0.4+default-dev (>= 0.4.2-~~),
librust-proxmox-tfa-4+api-dev,
librust-proxmox-tfa-4+default-dev,
librust-proxmox-time-1+default-dev (>= 1.1.3-~~),
librust-serde-1+default-dev,
librust-serde-bytes-0.11+default-dev,
librust-serde-json-1+default-dev,
librust-url-2+default-dev,
Build-Depends: cargo:native <!nocheck>,
debhelper-compat (= 13),
dh-cargo (>= 25),
librust-anyhow-1+default-dev,
librust-base32-0.4+default-dev,
librust-base64-0.13+default-dev,
librust-hex-0.4+default-dev,
librust-http-0.2+default-dev (>= 0.2.7-~~),
librust-libc-0.2+default-dev,
librust-log-0.4+default-dev (>= 0.4.17-~~),
librust-nix-0.26+default-dev,
librust-openssl-0.10+default-dev (>= 0.10.40-~~),
librust-perlmod-0.13+default-dev,
librust-perlmod-0.13+exporter-dev,
librust-proxmox-apt-0.11+cache-dev,
librust-proxmox-apt-0.11+default-dev,
librust-proxmox-apt-api-types-1+default-dev,
librust-proxmox-config-digest-0.1+default-dev,
librust-proxmox-http-0.9+client-sync-dev,
librust-proxmox-http-0.9+client-trait-dev,
librust-proxmox-http-0.9+default-dev,
librust-proxmox-http-error-0.1+default-dev,
librust-proxmox-log-0.2+default-dev,
librust-proxmox-notify-0.4+default-dev,
librust-proxmox-notify-0.4+pve-context-dev,
librust-proxmox-openid-0.10+default-dev,
librust-proxmox-resource-scheduling-0.3+default-dev,
librust-proxmox-shared-cache-0.1+default-dev,
librust-proxmox-subscription-0.4+default-dev,
librust-proxmox-sys-0.6+default-dev,
librust-proxmox-tfa-5+api-dev,
librust-proxmox-tfa-5+default-dev,
librust-proxmox-time-2+default-dev,
librust-serde-1+default-dev,
librust-serde-bytes-0.11+default-dev,
librust-serde-json-1+default-dev,
librust-tracing-0.1+default-dev (>= 0.1.37-~~),
librust-url-2+default-dev,
libstd-rust-dev <!nocheck>,
perlmod-bin (>= 0.2.0-3),
rustc:native <!nocheck>,
Maintainer: Proxmox Support Team <support@proxmox.com>
Standards-Version: 4.5.1
Standards-Version: 4.6.1
Vcs-Git: git://git.proxmox.com/git/proxmox-perl-rs.git
Vcs-Browser: https://git.proxmox.com/?p=proxmox-perl-rs.git
Homepage: https://www.proxmox.com
@ -43,14 +51,14 @@ Rules-Requires-Root: no
Package: libpve-rs-perl
Architecture: any
Depends:
${misc:Depends},
${perl:Depends},
${shlibs:Depends},
Breaks:
libpve-access-control (<< 7.1-3),
libpve-common-perl (<< 7.1-4),
pve-manager (<< 7.1-11),
Depends: ${misc:Depends},
${perl:Depends},
${shlibs:Depends},
libproxmox-rs-perl (>= 0.3.3),
Breaks: libpve-access-control (<< 7.1-3),
libpve-common-perl (<< 7.1-4),
libpve-notify-perl (<< 8.0.7),
pve-manager (<< 7.1-11),
Description: PVE parts which have been ported to Rust - Rust source code
This package contains the source for the Rust pve-rs crate, packaged by
debcargo for use with cargo and dh-cargo.

View File

@ -1,7 +1,25 @@
#!/usr/bin/make -f
include /usr/share/dpkg/pkg-info.mk
include /usr/share/rustc/architecture.mk
#export DH_VERBOSE=1
export BUILD_MODE=release
CARGO=/usr/share/cargo/bin/cargo
export CFLAGS CXXFLAGS CPPFLAGS LDFLAGS
export DEB_HOST_RUST_TYPE DEB_HOST_GNU_TYPE
export CARGO_HOME = $(CURDIR)/debian/cargo_home
export DEB_CARGO_CRATE=pve-rs_$(DEB_VERSION_UPSTREAM)
export DEB_CARGO_PACKAGE=pve-rs
%:
dh $@
override_dh_auto_configure:
@perl -ne 'if (/^version\s*=\s*"(\d+(?:\.\d+)+)"/) { my $$v_cargo = $$1; my $$v_deb = "$(DEB_VERSION_UPSTREAM)"; \
die "ERROR: d/changelog <-> Cargo.toml version mismatch: $$v_cargo != $$v_deb\n" if $$v_cargo ne $$v_deb; exit(0); }' Cargo.toml
$(CARGO) prepare-debian $(CURDIR)/debian/cargo_registry --link-from-system
dh_auto_configure

View File

@ -2,12 +2,17 @@
mod export {
use anyhow::Error;
use proxmox_apt_api_types::{
APTChangeRepositoryOptions, APTRepositoriesResult, APTRepositoryHandle,
};
use proxmox_config_digest::ConfigDigest;
use crate::common::apt::repositories::export as common;
/// Get information about configured and standard repositories.
#[export]
pub fn repositories() -> Result<common::RepositoriesResult, Error> {
common::repositories("pve")
pub fn repositories() -> Result<APTRepositoriesResult, Error> {
proxmox_apt::list_repositories("pve")
}
/// Add the repository identified by the `handle`.
@ -15,7 +20,10 @@ mod export {
///
/// The `digest` parameter asserts that the configuration has not been modified.
#[export]
pub fn add_repository(handle: &str, digest: Option<&str>) -> Result<(), Error> {
pub fn add_repository(
handle: APTRepositoryHandle,
digest: Option<ConfigDigest>,
) -> Result<(), Error> {
common::add_repository(handle, "pve", digest)
}
@ -26,8 +34,8 @@ mod export {
pub fn change_repository(
path: &str,
index: usize,
options: common::ChangeProperties,
digest: Option<&str>,
options: APTChangeRepositoryOptions,
digest: Option<ConfigDigest>,
) -> Result<(), Error> {
common::change_repository(path, index, options, digest)
}

View File

@ -1,5 +1,13 @@
//! Rust library for the Proxmox VE code base.
use std::collections::HashMap;
use anyhow::Error;
use serde_json::json;
use proxmox_apt_api_types::APTUpdateInfo;
use proxmox_notify::{Config, Notification, Severity};
#[path = "../common/src/mod.rs"]
pub mod common;
@ -10,10 +18,69 @@ pub mod tfa;
#[perlmod::package(name = "Proxmox::Lib::PVE", lib = "pve_rs")]
mod export {
use proxmox_notify::context::pve::PVE_CONTEXT;
use crate::common;
#[export]
pub fn init() {
common::logger::init();
common::logger::init("PVE_LOG", "info");
proxmox_notify::context::set_context(&PVE_CONTEXT);
}
}
fn send_notification(notification: &Notification) -> Result<(), Error> {
let config = proxmox_sys::fs::file_read_optional_string("/etc/pve/notifications.cfg")?
.unwrap_or_default();
let private_config =
proxmox_sys::fs::file_read_optional_string("/etc/pve/priv/notifications.cfg")?
.unwrap_or_default();
let config = Config::new(&config, &private_config)?;
proxmox_notify::api::common::send(&config, notification)?;
Ok(())
}
pub fn send_updates_available(updates: &[&APTUpdateInfo]) -> Result<(), Error> {
let hostname = proxmox_sys::nodename().to_string();
let metadata = HashMap::from([
("hostname".into(), hostname.clone()),
("type".into(), "package-updates".into()),
]);
// The template uses the `table` handlebars helper, so
// we need to form the approriate data structure first.
let update_table = json!({
"schema": {
"columns": [
{
"label": "Package",
"id": "Package",
},
{
"label": "Old Version",
"id": "OldVersion",
},
{
"label": "New Version",
"id": "Version",
}
],
},
"data": updates,
});
let template_data = json!({
"hostname": hostname,
"updates": update_table,
});
let notification =
Notification::from_template(Severity::Info, "package-updates", template_data, metadata);
send_notification(&notification)?;
Ok(())
}

View File

@ -1,6 +1,5 @@
#[perlmod::package(name = "PVE::RS::OpenId", lib = "pve_rs")]
mod export {
use std::convert::TryFrom;
use std::sync::Mutex;
use anyhow::Error;
@ -9,34 +8,13 @@ mod export {
use proxmox_openid::{OpenIdAuthenticator, OpenIdConfig, PrivateAuthState};
const CLASSNAME: &str = "PVE::RS::OpenId";
perlmod::declare_magic!(Box<OpenId> : &OpenId as "PVE::RS::OpenId");
/// An OpenIdAuthenticator client instance.
pub struct OpenId {
inner: Mutex<OpenIdAuthenticator>,
}
impl<'a> TryFrom<&'a Value> for &'a OpenId {
type Error = Error;
fn try_from(value: &'a Value) -> Result<&'a OpenId, Error> {
Ok(unsafe { value.from_blessed_box(CLASSNAME)? })
}
}
fn bless(class: Value, mut ptr: Box<OpenId>) -> Result<Value, Error> {
let value = Value::new_pointer::<OpenId>(&mut *ptr);
let value = Value::new_ref(&value);
let this = value.bless_sv(&class)?;
let _perl = Box::leak(ptr);
Ok(this)
}
#[export(name = "DESTROY")]
fn destroy(#[raw] this: Value) {
perlmod::destructor!(this, OpenId: CLASSNAME);
}
/// Create a new OpenId client instance
#[export(raw_return)]
pub fn discover(
@ -45,12 +23,12 @@ mod export {
redirect_url: &str,
) -> Result<Value, Error> {
let open_id = OpenIdAuthenticator::discover(&config, redirect_url)?;
bless(
class,
Box::new(OpenId {
Ok(perlmod::instantiate_magic!(
&class,
MAGIC => Box::new(OpenId {
inner: Mutex::new(open_id),
}),
)
})
))
}
#[export]

View File

@ -27,6 +27,7 @@ pub(self) use proxmox_tfa::api::{
#[perlmod::package(name = "PVE::RS::TFA")]
mod export {
use std::collections::HashMap;
use std::convert::TryInto;
use std::sync::Mutex;
@ -484,6 +485,66 @@ mod export {
Err(methods::EntryNotFound) => bail!("no such entry"),
}
}
#[export]
fn api_unlock_tfa(#[raw] raw_this: Value, userid: &str) -> Result<bool, Error> {
let this: &Tfa = (&raw_this).try_into()?;
Ok(methods::unlock_and_reset_tfa(
&mut this.inner.lock().unwrap(),
&UserAccess::new(&raw_this)?,
userid,
)?)
}
#[derive(serde::Serialize)]
#[serde(rename_all = "kebab-case")]
struct TfaLockStatus {
/// Once a user runs into a TOTP limit they get locked out of TOTP until they successfully use
/// a recovery key.
#[serde(skip_serializing_if = "bool_is_false", default)]
totp_locked: bool,
/// If a user hits too many 2nd factor failures, they get completely blocked for a while.
#[serde(skip_serializing_if = "Option::is_none", default)]
#[serde(deserialize_with = "filter_expired_timestamp")]
tfa_locked_until: Option<i64>,
}
impl From<&proxmox_tfa::api::TfaUserData> for TfaLockStatus {
fn from(data: &proxmox_tfa::api::TfaUserData) -> Self {
Self {
totp_locked: data.totp_locked,
tfa_locked_until: data.tfa_locked_until,
}
}
}
fn bool_is_false(b: &bool) -> bool {
!*b
}
#[export]
fn tfa_lock_status(
#[try_from_ref] this: &Tfa,
userid: Option<&str>,
) -> Result<Option<perlmod::Value>, Error> {
let this = this.inner.lock().unwrap();
if let Some(userid) = userid {
if let Some(user) = this.users.get(userid) {
Ok(Some(perlmod::to_value(&TfaLockStatus::from(user))?))
} else {
Ok(None)
}
} else {
Ok(Some(perlmod::to_value(
&HashMap::<String, TfaLockStatus>::from_iter(
this.users
.iter()
.map(|(uid, data)| (uid.clone(), TfaLockStatus::from(data))),
),
)?))
}
}
}
/// Version 1 format of `/etc/pve/priv/tfa.cfg`
@ -993,9 +1054,8 @@ impl proxmox_tfa::api::OpenUserChallengeData for UserAccess {
}
}
/// TODO: Enable this once we can consider most clusters to support the new format.
fn enable_lockout(&self) -> bool {
false
true
}
}

View File

@ -86,8 +86,59 @@ sub test_overcommitted {
is($nodes[3], "A", 'fourth should be A');
}
sub test_balance_small_memory_difference {
my ($with_start_load) = @_;
my $static = PVE::RS::ResourceScheduling::Static->new();
# Memory is different to avoid flaky results with what would otherwise be ties.
$static->add_node("A", 8, 10_000_000_000);
$static->add_node("B", 4, 9_000_000_000);
$static->add_node("C", 4, 8_000_000_000);
if ($with_start_load) {
$static->add_service_usage_to_node("A", { maxcpu => 4, maxmem => 1_000_000_000 });
$static->add_service_usage_to_node("B", { maxcpu => 2, maxmem => 1_000_000_000 });
$static->add_service_usage_to_node("C", { maxcpu => 2, maxmem => 1_000_000_000 });
}
my $service = {
maxcpu => 3,
maxmem => 16_000_000,
};
for (my $i = 0; $i < 20; $i++) {
my $score_list = $static->score_nodes_to_start_service($service);
# imitate HA manager
my $scores = { map { $_->[0] => -$_->[1] } $score_list->@* };
my @nodes = sort {
$scores->{$a} <=> $scores->{$b} || $a cmp $b
} keys $scores->%*;
if ($i % 4 <= 1) {
is($nodes[0], "A", 'first should be A');
is($nodes[1], "B", 'second should be B');
is($nodes[2], "C", 'third should be C');
} elsif ($i % 4 == 2) {
is($nodes[0], "B", 'first should be B');
is($nodes[1], "C", 'second should be C');
is($nodes[2], "A", 'third should be A');
} elsif ($i % 4 == 3) {
is($nodes[0], "C", 'first should be C');
is($nodes[1], "A", 'second should be A');
is($nodes[2], "B", 'third should be B');
} else {
die "internal error, got $i % 4 == " . ($i % 4) . "\n";
}
$static->add_service_usage_to_node($nodes[0], $service);
}
}
test_basic();
test_balance();
test_overcommitted();
test_balance_small_memory_difference(1);
test_balance_small_memory_difference(0);
done_testing();

View File

@ -1 +0,0 @@
edition = "2018"