[pve-devel] [PATCH pve-access-control v2 1/1] permissions: add ACL paths for SDN fabrics
Stefan Hanreich
s.hanreich at proxmox.com
Fri Apr 11 18:51:49 CEST 2025
On 4/11/25 1:12 PM, Stefan Hanreich wrote:
> On 4/7/25 11:27, Fabian Grünbichler wrote:
>>
>>> Stefan Hanreich <s.hanreich at proxmox.com> hat am 07.04.2025 10:51 CEST geschrieben:
>>>
>>>
>>> On 4/7/25 10:12, Thomas Lamprecht wrote:
>>>> Am 07.04.25 um 09:24 schrieb Fabian Grünbichler:
>>>>> On April 4, 2025 7:20 pm, Thomas Lamprecht wrote:
>>>>>> So, without looking at the implementation, fabrics have the IDs unique
>>>>>> per sub-type? Could maybe also share an ID space, less confusion
>>>>>> potential, but naturally also less flexibility – what do you think?
>>>>>
>>>>> they share a section config (and thus ID-space), so I guess we could
>>>
>>> There's one section config file per fabric, so its ID is unique per
>>> protocol. We'd need to load *all* configuration files everytime we
>>> change one configuration file (at least when adding a fabric) so we can
>>> validate unique IDs across all fabric types.
>>
>> mea culpa, must have mixed that up with something else (probably the
>> controllers :-/). would it make sense to merge them given the similarities?
>
> Re-visiting this again, I took some time to write about the problem in
> greater detail and present some options. I'd really like to get the
> ball rolling on this discussion sooner than later, since otherwise
> it's hard to proceed with this patch series. This is a short overview
> for you to get a better idea, but it might make sense to discuss this
> in greater detail in person.
>
> Overview
> ========
>
> We have multiple types of fabrics:
> OpenFabric, OSPF and more in the future.
>
> We have the following hierarchy of models:
> Fabric -> Node -> Interface
>
> Some constraints for the models:
> * There can be more than one fabric of a given type
> * A fabric contains n nodes, a node contains n interfaces.
> * A node can be part of multiple fabrics, but one interface of a node
> can only be a part of one fabric.
> * Each of the three models has its own properties, that vary depending
> on the type of fabric
>
> Some fabric specific constraints can apply as well, for instance:
> * the IP prefixes of fabrics should not overlap
> * the IP of a node should be unique within a fabric
> * an OSPF interface can either have an IP or be unnumbered
> * OSPFv2 supports only v4, OpenFabric supports both
>
> Ideally, we'd like to validate all those constraints when modifying the
> configuration via the API or loading it.
>
>
> The key issues we ran into:
> * The type of a section can only be uniquely identified together with
> the protocol (e.g. ospf_node)
> * A node section can only be uniquely identified together with the id
> of the fabric that it belongs to (a node can occur in multiple
> fabrics)
> * 3 layers is one too much to cram into one section imo, so we have to
> at least split fabrics and nodes into two sections
> * parsing the type/id of a section into multiple fields is a bit
> clunky with the section-config implementation. Ideally we'd like to
> not have to do this separately at every site (rust, perl, frontend),
> but once when reading.
> * ideally, validation of *all* the constraints laid out above
>
>
> Solutions
> =========
>
> #1: Storing everything in one file
> ----------------------------------
>
> # fabrics.cfg
> <type>_(node|fabric): <fabricid>[_<nodeid>]
>
> + fixed amount of files
> + validation is simple
> + API/ACL paths are simple
> + related entities are in the same file
> - composite section types
> - composite section ids
> - complex API definitions
> - file can grow quite large
>
>
> #2: One file per fabric type (current solution)
> -----------------------------------------------
>
> # <type>.cfg
> fabric: <fabricid>
> node: <fabricid>_<nodeid>
>
> + simple section types
> + simple API definitions
> + related entities are in the same file
> - API/ACL paths are more complex
> - composite section ids
> - variable number of files
> - validation requires reading all files
>
>
> #3: One file per level in the hierarchy
> ---------------------------------------
>
> # fabric.cfg
> <type>: <fabricid>
>
> # node.cfg
> <type>: <fabricid>_<nodeid>
>
> + simple section types
> + fixed amount of files
> + API/ACL paths are simple
> - related entities are in different files
> - complex API definitions
> - composite section ids
> - validation requires reading both files
>
>
> #4: One file per fabric
> -----------------------
>
> # <fabricid>.cfg
> fabric: <fabricid>
> node: <nodeid>
>
> + simple types
> + simple ids
> + API/ACL paths are simple
> + related entities are in the same file
> - complex API definitions
> - variable number of files
> - information about type has to be encoded somewhere (directory?)
> - validation requires reading all files
>
>
> Imo, #2 and #3 seem like the contenders. #3 is what we use for zones /
> vnets / subnets, and it is . #2 makes API definitions a lot nicer,
> since we have exactly one schema per API endpoint, which also makes
> the generated API types in Rust a lot nicer. With #3 we currently
> generate two structs where basically every field is an Option<T>. The
> solution for this could be using oneOf across the whole API, but afaik
> that is not implemented in Schema2Rust currently. Alternatively, we
> could pop our own abstraction models on top of the generated types and
> convert from / to them when using the API in PDM, but the real
> solution is implementing oneOf support in Schema2Rust.
Reusing the models directly on the PDM side would of course render the
whole point wrt Schema2Rust moot.
More information about the pve-devel
mailing list