[pve-devel] [PATCH pve-manager 4/4] api2: network: check vlan permissions for local bridges
Alexandre Derumier
aderumier at odiso.com
Fri May 26 09:27:24 CEST 2023
We need to display the bridge is the user have a permission
on any vlan on the bridge.
to avoid to check permissions on 4096 vlans for each bridge
(could be slow with a lot of bridges),
we first list vlans where acls are defined.
(4000 check took 60ms on 10year xeon server, should be enough
for any network where the total number of vlans is limited)
Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
PVE/API2/Network.pm | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/PVE/API2/Network.pm b/PVE/API2/Network.pm
index ba3b3e0e..39f17d14 100644
--- a/PVE/API2/Network.pm
+++ b/PVE/API2/Network.pm
@@ -240,17 +240,35 @@ __PACKAGE__->register_method({
if (my $tfilter = $param->{type}) {
my $vnets;
+ my $bridges_vlans_acl = {};
#check access for local bridges
my $can_access_vnet = sub {
+ my $bridge = $_[0];
return 1 if $authuser eq 'root at pam';
return 1 if $rpcenv->check_any($authuser, "/sdn/zones/local", ['SDN.Audit', 'SDN.Allocate'], 1);
- return 1 if $rpcenv->check_any($authuser, "/sdn/vnets/$_[0]", ['SDN.Audit', 'SDN.Allocate'], 1);
+ return 1 if $rpcenv->check($authuser, "/sdn/vnets/$bridge", ['SDN.Audit'], 1);
+ my $bridge_vlan = $bridges_vlans_acl->{$bridge};
+ for my $tag (sort keys %$bridge_vlan) {
+ return 1 if $rpcenv->check($authuser, "/sdn/vnets/$bridge.$tag", ['SDN.Audit'], 1);
+ }
};
if ($have_sdn && $param->{type} eq 'any_bridge') {
$vnets = PVE::Network::SDN::get_local_vnets(); # returns already access-filtered
}
+ #find all vlans where we have specific acls
+ if ($tfilter =~ /^any(_local)?_bridge$/) {
+ my $cfg = $rpcenv->{user_cfg};
+ my $vnets_acl_root = $cfg->{acl_root}->{children}->{sdn}->{children}->{vnets};
+ PVE::AccessControl::iterate_acl_tree("/", $vnets_acl_root, sub {
+ my ($path, $node) = @_;
+ if ($path =~ /\/(.*)\.(\d+)$/) {
+ $bridges_vlans_acl->{$1}->{$2} = 1;
+ }
+ });
+ }
+
for my $k (sort keys $ifaces->%*) {
my $type = $ifaces->{$k}->{type};
my $match = $tfilter eq $type || ($tfilter =~ /^any(_local)?_bridge$/ && ($type eq 'bridge' || $type eq 'OVSBridge'));
--
2.30.2
More information about the pve-devel
mailing list