[pve-devel] [PATCH v2 pve-guest-common 1/1] helpers : add check_vnet_access

Alexandre Derumier aderumier at odiso.com
Wed Jun 7 14:03:52 CEST 2023


if a tag is defined, test if user have a specific access to the vlan (or propagate from full bridge acl or zone)
if trunks is defined, we check permissions for each vlan of the trunks
if no tag, test if user have access to full bridge.

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 src/PVE/GuestHelpers.pm | 49 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/src/PVE/GuestHelpers.pm b/src/PVE/GuestHelpers.pm
index b4ccbaa..d22be1e 100644
--- a/src/PVE/GuestHelpers.pm
+++ b/src/PVE/GuestHelpers.pm
@@ -10,10 +10,17 @@ use PVE::Storage;
 use POSIX qw(strftime);
 use Scalar::Util qw(weaken);
 
+my $have_sdn;
+eval {
+    require PVE::Network::SDN;
+    $have_sdn = 1;
+};
+
 use base qw(Exporter);
 
 our @EXPORT_OK = qw(
 assert_tag_permissions
+check_vnet_access
 get_allowed_tags
 safe_boolean_ne
 safe_num_ne
@@ -366,4 +373,46 @@ sub get_unique_tags {
     return !$no_join_result ? join(';', $res->@*) : $res;
 }
 
+sub get_tags_from_trunk {
+    my ($trunks) = @_;
+
+    my $res = {};
+    my @trunks_array = split /;/, $trunks;
+    for my $trunk (@trunks_array) {
+	my ($tag, $tag_end) = split /-/, $trunk;
+	if($tag_end && $tag_end > $tag) {
+	    my @tags = ($tag..$tag_end);
+	    $res->{$_} = 1 for @tags;
+	} else {
+	    $res->{$tag} = 1;
+	}
+    }
+    return $res;
+}
+
+sub check_vnet_access {
+    my ($rpcenv, $authuser, $vnet, $tag, $trunks) = @_;
+
+    my $zone = 'localnetwork';
+
+    if ($have_sdn) {
+	my $vnet_cfg = PVE::Network::SDN::Vnets::config();
+	if (defined(my $vnet = PVE::Network::SDN::Vnets::sdn_vnets_config($vnet_cfg, $vnet, 1))) {
+	    $zone = $vnet->{zone};
+	}
+    }
+
+    # if a tag is defined, test if user have a specific access to the vlan (or propagated from full bridge acl)
+    $rpcenv->check($authuser, "/sdn/zones/$zone/$vnet/$tag", ['SDN.Use']) if $tag;
+    # check each vlan access from trunk
+    if ($trunks) {
+	my $tags = get_tags_from_trunk($trunks);
+	for my $tag (sort keys %$tags) {
+	    $rpcenv->check($authuser, "/sdn/zones/$zone/$vnet/$tag", ['SDN.Use']);
+	}
+    }
+    # if no tag, test if user have access to full bridge.
+    $rpcenv->check($authuser, "/sdn/zones/$zone/$vnet", ['SDN.Use']);
+}
+
 1;
-- 
2.30.2





More information about the pve-devel mailing list