all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Thomas Lamprecht <t.lamprecht@proxmox.com>
To: pdm-devel@lists.proxmox.com
Subject: [PATCH 0/8] subscription: add central key pool registry with reissue support
Date: Thu,  7 May 2026 09:17:23 +0200	[thread overview]
Message-ID: <20260507072436.2649563-1-t.lamprecht@proxmox.com> (raw)

Add a Subscription Registry to PDM: a central pool of PVE and PBS
subscription keys that an operator can assign to remote nodes from one
place, with an explicit Apply/Clear lifecycle for staged changes plus a
Reissue Key action for freeing a key bound to a node so it can be
reassigned elsewhere.

Motivation: managing subscriptions across many remotes today means
doing this for each node individually. PDM already has the remote
inventory; with a key pool plus per-remote query data we can show "which
nodes need a subscription" and "which keys are unused" together, and let
an admin batch-assign and tear down from one place.
In the near/mid-term we can also make polling keys from customers more
integrated, but that needs a bit adaption in our shop infa and does not
block the base work here in anyway. Actually, the implementation here
was split out from a more complete work, so most parts of it are already
prepared to adopt this relatively easily.

Design points worth flagging for review:

* Storage layout. subscriptions.cfg holds key entries via the typed
  section-config layer, with `product-type` as the section type so PVE
  and PBS sections live side-by-side.
  The subscriptions.shadow file is reserved for a future shop-bundle
  import flow (signed info blobs) and stays empty for manually-added
  keys. I can drop that part for now too, but figured it might be nice
  and potentially relevant for review to see the direction this probably
  goes now already.

* Endpoints take PRIV_SYS_AUDIT/MODIFY at the macro level for the pool
  itself, with per-remote PRIV_RESOURCE_* enforced inside the handlers
  when a specific remote is touched.  A dedicated subscription privilege
  seemed not like a necessity and also not fit that well into our
  general priv approach in PDM.

* The pending lifecycle goes like: Pool entries with a (remote, node)
  binding whose live state does not match are "pending push"; entries
  with the new pending-reissue flag are "pending removal". Apply Pending
  walks both queues; Clear Pending drops the queue without touching any
  remote (binding-clear for push, flag-only for reissue so the operator
  can retry without re-importing the key).
  The per-remote subscription cache is invalidated after each successful
  apply step so the next panel load reflects the change rather than a
  5-minute-stale snapshot, which is highly confusing UI/UX wise. This
  might warrant a closer look though, might be currently done in a
  rather heavier handed fashion as potentially needed (had no time to
  recheck).

The lib/pdm-api-types/tests/test_import.rs test should provide basic
coverage for section-config roundtrip for both subscription.cfg and the
shadow file (which is why I'd be fine with keeping it, but not _that_
hard feelings), schema acceptance and rejection (for now only accept
PVE/PBS; everything else rejected), ProductType classification, the
SubscriptionLevel display/from-str backward-compat (single-letter and
full-name forms both parse), and pick_best_pve_socket_key edge cases.

Open follow-ups deliberately out of scope here:
* Auto-import existing remote-side keys into the pool on first
  observation (the reissue path already adopts; an explicit import for
  legacy onboarding would be cleaner).
* Make reissue a full reissue, if it goes in like this it should be
  rather called "Clear Key", but that can be handled on applying too, if
  really nothing else comes up (which I doubt)
* A shop-bundle import path (the shadow file plumbing is already in),
  either manual copy+paste or through an api token.
* Some polishing code and ui/ux wise (e.g., a reload button), but wante
  to finally get this out now. And while I saw some UI/UX imperfections
  myself, I'm naturally still happy to hear of other opinions here.
* ...


Thomas Lamprecht (8):
  api: subscription cache: ensure max_age=0 forces a fresh fetch
  api types: subscription level: render full names
  subscription: add key pool data model and config layer
  subscription: add key pool and node status API endpoints
  ui: add subscription registry with key pool and node status
  cli: add subscription key pool management subcommands
  docs: add subscription registry chapter
  subscription: add Reissue Key action with pending-reissue queue

 cli/client/src/subscriptions.rs               |  226 +++-
 docs/index.rst                                |    1 +
 docs/subscription-registry.rst                |   64 +
 lib/pdm-api-types/Cargo.toml                  |    4 +
 lib/pdm-api-types/src/subscription.rs         |  422 +++++-
 lib/pdm-api-types/tests/test_import.rs        |  310 +++++
 lib/pdm-client/src/lib.rs                     |  157 ++-
 lib/pdm-config/src/lib.rs                     |    1 +
 lib/pdm-config/src/subscriptions.rs           |  102 ++
 server/src/api/mod.rs                         |    2 +
 server/src/api/resources.rs                   |   13 +-
 server/src/api/subscriptions/mod.rs           | 1199 +++++++++++++++++
 server/src/context.rs                         |    7 +
 ui/src/configuration/mod.rs                   |    2 +
 ui/src/configuration/subscription_keys.rs     |  458 +++++++
 ui/src/configuration/subscription_registry.rs |  791 +++++++++++
 ui/src/dashboard/subscriptions_list.rs        |   18 +-
 ui/src/main_menu.rs                           |   10 +
 18 files changed, 3751 insertions(+), 36 deletions(-)
 create mode 100644 docs/subscription-registry.rst
 create mode 100644 lib/pdm-api-types/tests/test_import.rs
 create mode 100644 lib/pdm-config/src/subscriptions.rs
 create mode 100644 server/src/api/subscriptions/mod.rs
 create mode 100644 ui/src/configuration/subscription_keys.rs
 create mode 100644 ui/src/configuration/subscription_registry.rs

-- 
2.47.3





             reply	other threads:[~2026-05-07  7:24 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-07  7:17 Thomas Lamprecht [this message]
2026-05-07  7:17 ` [PATCH 1/8] api: subscription cache: ensure max_age=0 forces a fresh fetch Thomas Lamprecht
2026-05-07  7:17 ` [PATCH 2/8] api types: subscription level: render full names Thomas Lamprecht
2026-05-07  7:17 ` [PATCH 3/8] subscription: add key pool data model and config layer Thomas Lamprecht
2026-05-07  7:17 ` [PATCH 4/8] subscription: add key pool and node status API endpoints Thomas Lamprecht
2026-05-07  7:17 ` [PATCH 5/8] ui: add subscription registry with key pool and node status Thomas Lamprecht
2026-05-07  8:15   ` Lukas Wagner
2026-05-07  8:33     ` Thomas Lamprecht
2026-05-07  7:17 ` [PATCH 6/8] cli: add subscription key pool management subcommands Thomas Lamprecht
2026-05-07  7:17 ` [PATCH 7/8] docs: add subscription registry chapter Thomas Lamprecht
2026-05-07  7:17 ` [PATCH 8/8] subscription: add Reissue Key action with pending-reissue queue Thomas Lamprecht
2026-05-07  7:50   ` Lukas Wagner
2026-05-07  8:38 ` superseded: [PATCH 0/8] subscription: add central key pool registry with reissue support Thomas Lamprecht

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260507072436.2649563-1-t.lamprecht@proxmox.com \
    --to=t.lamprecht@proxmox.com \
    --cc=pdm-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal