From ad2839e5626f4682547f4f1ae8336a4ea8d180db Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Mon, 17 Jul 2023 11:51:55 +0200 Subject: [PATCH 01/58] wip: turn network into routes and new virtual networks --- lib/Ravada.pm | 48 ++++++++++++ lib/Ravada/Domain.pm | 2 +- lib/Ravada/Front.pm | 4 +- lib/Ravada/{Network.pm => Route.pm} | 6 +- lib/Ravada/VM.pm | 73 +++++++++++++++++- lib/Ravada/VM/KVM.pm | 75 ++++++++++++++++++- lib/Ravada/VM/Void.pm | 20 ++++- lib/Ravada/WebSocket.pm | 14 ++++ public/js/admin.js | 28 +++++-- script/rvd_front | 10 +-- t/70_networks.t | 14 ++-- t/kvm/p10_password.t | 12 +-- t/lib/Test/Ravada.pm | 29 +++++++ t/mojo/30_settings.t | 10 +-- t/vm/v10_volatile.t | 2 +- templates/bootstrap/navigation.html.ep | 2 +- ..._networks.html.ep => admin_routes.html.ep} | 10 +-- ...{network_new.html.ep => route_new.html.ep} | 0 18 files changed, 313 insertions(+), 46 deletions(-) rename lib/Ravada/{Network.pm => Route.pm} (96%) rename templates/main/{admin_networks.html.ep => admin_routes.html.ep} (83%) rename templates/main/{network_new.html.ep => route_new.html.ep} (100%) diff --git a/lib/Ravada.pm b/lib/Ravada.pm index 46f1affc6..eec3e0ac5 100644 --- a/lib/Ravada.pm +++ b/lib/Ravada.pm @@ -1635,6 +1635,10 @@ sub _add_indexes_generic($self) { ,"UNIQUE (name)" ] + ,virtual_networks => [ + "unique(id_vm,internal_id)" + ,"index(date_changed)" + ] ); my $if_not_exists = ''; $if_not_exists = ' IF NOT EXISTS ' if $CONNECTOR->dbh->{Driver}{Name} =~ /sqlite|mariadb/i; @@ -1806,6 +1810,7 @@ sub _add_grants($self) { $self->_add_grant('view_all',0,"The user can start and access the screen of any virtual machine"); $self->_add_grant('create_disk',0,'can create disk volumes'); $self->_add_grant('quota_disk',0,'disk space limit',1); + $self->_add_grant('create_networks',0,'can create virtual networks',1); } sub _add_grant($self, $grant, $allowed, $description, $is_int = 0, $default_admin=1) { @@ -1883,6 +1888,7 @@ sub _enable_grants($self) { ,'start_limit', 'start_many' ,'view_all' ,'create_disk', 'quota_disk' + ,'create_networks' ); my $sth = $CONNECTOR->dbh->prepare("SELECT id,name FROM grant_types"); @@ -2356,6 +2362,23 @@ sub _sql_create_tables($self) { } ] + , + [virtual_networks => { + id => 'integer PRIMARY KEY AUTO_INCREMENT', + ,id_vm => 'integer NOT NULL references `vms` (`id`) ON DELETE CASCADE', + ,name => 'varchar(200)' + ,id_owner => 'integer NOT NULL references `users` (`id`) ON DELETE CASCADE', + ,is_active => 'integer not null' + ,internal_id => 'char(80) not null' + ,autostart => 'integer not null' + ,bridge => 'char(80)' + ,'ip_address' => 'char(20)' + ,'ip_netmask' => 'char(20)' + ,'dhcp_start' => 'integer' + ,'dhcp_end' => 'integer' + ,date_changed => 'timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' + } + ] ); for my $new_table (@tables ) { @@ -5660,6 +5683,7 @@ sub _refresh_active_vms ($self) { next; } $active_vm{$vm->id} = 1; + $vm->list_virtual_networks(); } return \%active_vm; } @@ -6148,6 +6172,9 @@ sub _req_method { ,remove_files => \&_cmd_remove_files ,update_iso_urls => \&_cmd_update_iso_urls + ,create_network => \&_cmd_create_network + ,remove_network => \&_cmd_remove_network + ); return $methods{$cmd}; } @@ -6565,6 +6592,27 @@ sub _cmd_remove_files($self, $request) { $vm->remove_file(@file); } +sub _cmd_create_network($self, $request) { + my $user=Ravada::Auth::SQL->search_by_id($request->args('id_owner')); + die "Error: ".$user->name." not authorized\n" + unless $user->can_create_networks; + + my $id = $request->args('id_vm'); + my $vm = Ravada::VM->open($id); + $vm->create_network($request->args('data'),$request->args('uid')); +} + +sub _cmd_remove_network($self, $request) { + my $user=Ravada::Auth::SQL->search_by_id($request->args('id_owner')); + die "Error: ".$user->name." not authorized\n" + unless $user->can_create_networks; + + my $id = $request->args('id_vm'); + my $vm = Ravada::VM->open($id); + $vm->remove_network($id,$request->args('uid')); +} + + sub _cmd_active_storage_pool($self, $request) { my $user = Ravada::Auth::SQL->search_by_id($request->args('uid')); die "Error: ".$user->name." not authorized to manage storage pools" diff --git a/lib/Ravada/Domain.pm b/lib/Ravada/Domain.pm index d2b8e98ba..4a86c1f5d 100644 --- a/lib/Ravada/Domain.pm +++ b/lib/Ravada/Domain.pm @@ -342,7 +342,7 @@ sub _around_start($orig, $self, @arg) { if ( Ravada::setting(undef,"/backend/display_password") ) { # We'll see if we set it from the network, defaults to 0 meanwhile my $set_password = 0; - my $network = Ravada::Network->new(address => $remote_ip); + my $network = Ravada::Route->new(address => $remote_ip); $set_password = 1 if $network->requires_password(); $arg{set_password} = $set_password; } diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index 470a2f60c..2f7a5d022 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -20,7 +20,7 @@ use Ravada; use Ravada::Auth::LDAP; use Ravada::Front::Domain; use Ravada::Front::Domain::KVM; -use Ravada::Network; +use Ravada::Route; use feature qw(signatures); no warnings "experimental::signatures"; @@ -1200,7 +1200,7 @@ sub list_bases_anonymous { my $self = shift; my $ip = shift or confess "Missing remote IP"; - my $net = Ravada::Network->new(address => $ip); + my $net = Ravada::Route->new(address => $ip); my $sth = $CONNECTOR->dbh->prepare( "SELECT id, name, id_base, is_public, file_screenshot " diff --git a/lib/Ravada/Network.pm b/lib/Ravada/Route.pm similarity index 96% rename from lib/Ravada/Network.pm rename to lib/Ravada/Route.pm index 129eec17f..10d4e14c0 100644 --- a/lib/Ravada/Network.pm +++ b/lib/Ravada/Route.pm @@ -1,11 +1,11 @@ -package Ravada::Network; +package Ravada::Route; use strict; use warnings; =head1 NAME -Ravada::Network - Networks management library for Ravada +Ravada::Route - Routes management library for Ravada =cut @@ -31,7 +31,7 @@ our $CONNECTOR; =head1 Description - my $net = Ravada::Network->new(address => '127.0.0.1/32'); + my $net = Ravada::Route->new(address => '127.0.0.1/32'); if ( $net->allowed( $domain->id ) ) { =cut diff --git a/lib/Ravada/VM.pm b/lib/Ravada/VM.pm index 82c2b52a2..b10657b49 100644 --- a/lib/Ravada/VM.pm +++ b/lib/Ravada/VM.pm @@ -128,6 +128,13 @@ has 'netssh' => ( , lazy => 1 , clearer => 'clear_netssh' ); + +has 'has_networking' => ( + isa => 'Bool' + , is => 'ro' + , default => 0 +); + ############################################################ # # Method Modifiers definition @@ -148,6 +155,10 @@ after 'disconnect' => \&_post_disconnect; around '_list_used_volumes' => \&_around_list_used_volumes; +around 'create_network' => \&_around_create_network; +around 'remove_network' => \&_around_remove_network; +around 'list_virtual_networks' => \&_around_list_networks; + ############################################################# # # method modifiers @@ -590,7 +601,7 @@ sub _add_instance_db($self, $id_domain) { sub _define_spice_password($self, $remote_ip) { my $spice_password = Ravada::Utils::random_name(4); if ($remote_ip) { - my $network = Ravada::Network->new(address => $remote_ip); + my $network = Ravada::Route->new(address => $remote_ip); $spice_password = undef if !$network->requires_password; } return $spice_password; @@ -1416,6 +1427,66 @@ sub _around_ping($orig, $self, $option=undef, $cache=1) { return $ping; } +sub _insert_network($self, $net) { + $net->{id_owner} = Ravada::Utils::user_daemon->id + if !exists $net->{id_owner}; + + my $sql = "INSERT INTO virtual_networks (" + .join(",",sort keys %$net).")" + ." VALUES(".join(",",map { '?' } keys %$net).")"; + my $sth = $self->_dbh->prepare($sql); + $sth->execute(map { $net->{$_} } sort keys %$net); +} + +sub _update_network($self, $net) { + my $sth = $self->_dbh->prepare("SELECT * FROM virtual_networks " + ." WHERE id_vm=? AND internal_id=?" + ); + $sth->execute($self->id,$net->{internal_id}); + my $db_net = $sth->fetchrow_hashref(); + if (!$db_net) { + return $self->_insert_network($net); + } + delete $db_net->{date_changed}; + delete $db_net->{id}; +} + +sub _around_create_network($orig, $self,$data, $id_owner) { + my $owner = Ravada::Auth::SQL->search_by_id($id_owner) or confess "Unknown user id: $id_owner"; + die "Error: Access denied: ".$owner->name." can not create networks" + unless $owner->can_create_networks(); + + $data->{is_active}=1 if !exists $data->{is_active}; + $data->{autostart}=1 if !exists $data->{autostart}; + my $ip = $data->{ip_address}; + $ip =~ s/(.*)\..*/$1/; + $data->{dhcp_start}="$ip.2" if !exists $data->{dhcp_start}; + $data->{dhcp_end}="$ip.254" if !exists $data->{dhcp_end}; + $self->$orig($data); + $data->{id_owner} = $id_owner; + $self->_insert_network($data); +} + +sub _around_remove_network($orig, $self, $user, $id_net) { + die "Error: Access denied: ".$user->name." can not remove networks" + unless $user->can_create_networks(); + + my ($net) = grep { $_->{id} == $id_net } $self->list_networks(); + + die "Error: network id $id_net not found" if !$net; + + $self->$orig($net->{name}); +} + + +sub _around_list_networks($orig, $self) { + my @list = $orig->($self); + for my $net ( @list ) { + $self->_update_network($net); + } + return @list; +} + =head2 is_active Returns if the domain is active. The active state is cached for some seconds. diff --git a/lib/Ravada/VM/KVM.pm b/lib/Ravada/VM/KVM.pm index 6fd216f9b..b21613402 100644 --- a/lib/Ravada/VM/KVM.pm +++ b/lib/Ravada/VM/KVM.pm @@ -54,6 +54,12 @@ has type => ( ,default => 'KVM' ); +has has_networking => ( + isa => 'Bool' + , is => 'ro' + , default => 1 +); + #########################################################################3 # @@ -2660,13 +2666,13 @@ sub _xml_add_graphics_streaming { $listen->setAttribute(mode => 'filter'); } -=head2 list_networks +=head2 list_routes Returns a list of networks known to this VM. Each element is a Ravada::NetInterface object =cut -sub list_networks { +sub list_routes { my $self = shift; $self->connect() if !$self->vm; @@ -2915,4 +2921,69 @@ sub get_library_version($self) { return $self->vm->get_library_version(); } +sub list_virtual_networks($self) { + my @networks; + for my $net ($self->vm->list_all_networks()) { + my $doc = XML::LibXML->load_xml(string => $net->get_xml_description); + my ($ip_doc) = $doc->findnodes("/network/ip"); + my $ip = $ip_doc->getAttribute('address'); + my $netmask = $ip_doc->getAttribute('netmask'); + my $data= { + is_active => $net->is_active() + ,autostart => $net->get_autostart() + ,bridge => $net->get_bridge_name() + ,id_vm => $self->id + ,name => $net->get_name + ,ip_address => $ip + ,ip_netmask => $netmask + ,internal_id => ''.$net->get_uuid_string + }; + my ($dhcp_range) = $ip_doc->findnodes("dhcp/range"); + my ($start,$end); + if ($dhcp_range) { + ($start) = $dhcp_range->getAttribute('start') =~ /.*\.(\d+)/; + ($end) = $dhcp_range->getAttribute('end')=~ /.*\.(\d+)/; + $data->{dhcp_start} = $start if defined $start; + $data->{dhcp_end} = $end if defined $end; + } + push @networks,($data); + } + return @networks; +} + +sub create_network($self, $data) { + + my $xml = XML::LibXML->load_xml(string => + "$data->{name}" + ); + my ($xml_net) = $xml->findnodes("/network"); + + my $forward = $xml_net->addNewChild(undef,'forward'); + $forward->setAttribute('mode' => 'nat'); + + my $ip = $xml_net->addNewChild(undef,'ip'); + $ip->setAttribute('address' => $data->{ip_address}); + $ip->setAttribute('netmask' => $data->{ip_netmask}); + + if ($data->{dhcp_start} || $data->{dhcp_end}) { + my $dhcp = $ip->addNewChild(undef, 'dhcp'); + my $range = $dhcp->addNewChild(undef,'range'); + $range->setAttribute('start' => $data->{dhcp_start}); + $range->setAttribute('end' => $data->{dhcp_end}); + } + + $self->vm->define_network($xml->toString()); + + my $new_network=$self->vm->get_network_by_name($data->{name}); + my $xml2=XML::LibXML->load_xml(string =>$new_network->get_xml_description()); + my ($uuid) = $xml2->findnodes("/network/uuid/text()"); + $data->{internal_id} = $uuid; +} + +sub remove_network($self, $name) { +} + + + + 1; diff --git a/lib/Ravada/VM/Void.pm b/lib/Ravada/VM/Void.pm index 08f6b6c01..067a729bf 100644 --- a/lib/Ravada/VM/Void.pm +++ b/lib/Ravada/VM/Void.pm @@ -336,10 +336,28 @@ sub search_domain { return; } -sub list_networks { +sub list_routes { return Ravada::NetInterface::Void->new(); } +sub list_virtual_networks { + return (); +} + +sub create_network($self, $data) { + my $file_out = $self->dir_img."/networks/".$data->{name}."yml"; + die "Error: network $data->{name} already created" + if $self->file_exists($file_out); + open my $out,">",$file_out or die "$! $file_out"; + close $out; +} + +sub remove_network($self, $name) { + my $file_out = $self->dir_img."/networks/$name.yml"; + unlink $file_out or die "$! $file_out" if $self->file_exists($file_out); +} + + sub search_volume($self, $pattern) { return $self->_search_volume_remote($pattern) if !$self->is_local; diff --git a/lib/Ravada/WebSocket.pm b/lib/Ravada/WebSocket.pm index 6bed72470..6c3ffa86f 100644 --- a/lib/Ravada/WebSocket.pm +++ b/lib/Ravada/WebSocket.pm @@ -49,6 +49,7 @@ my %SUB = ( ,list_next_bookings_today => \&_list_next_bookings_today ,log_active_domains => \&_log_active_domains + ,list_networks => \&_list_networks ); our %TABLE_CHANNEL = ( @@ -60,6 +61,7 @@ our %TABLE_CHANNEL = ( ,list_requests => 'requests' ,machine_info => 'domains' ,log_active_domains => 'log_active_domains' + ,list_networks => 'virtual_networks' ); my $A_WHILE; @@ -381,6 +383,18 @@ sub _log_active_domains($rvd, $args) { return Ravada::Front::Log::list_active_recent($unit,$time); } +sub _list_networks($rvd, $args) { + my @networks; + my $sth = $rvd->_dbh->prepare( + "SELECT * FROM virtual_networks ORDER BY name " + ); + $sth->execute(); + while (my $row = $sth->fetchrow_hashref) { + push @networks,($row); + } + return \@networks; +} + sub _its_been_a_while_channel($channel) { if (!$A_WHILE{$channel} || time -$A_WHILE{$channel} > 5) { $A_WHILE{$channel} = time; diff --git a/public/js/admin.js b/public/js/admin.js index 62d6a6a72..d357e0a93 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -7,6 +7,7 @@ ravadaApp.directive("solShowMachine", swMach) .controller("usersPage", usersPageC) .controller("messagesPage", messagesPageC) .controller("manage_nodes",manage_nodes) + .controller("manage_routes",manage_routes) .controller("manage_networks",manage_networks) .controller("settings_node",settings_node) .controller("settings_storage",settings_storage) @@ -863,17 +864,17 @@ ravadaApp.directive("solShowMachine", swMach) $interval($scope.list_nodes,30 * 1000); }; - function manage_networks($scope, $http, $interval, $timeout) { - list_networks= function() { - $http.get('/list_networks.json').then(function(response) { + function manage_routes($scope, $http, $interval, $timeout) { + list_routes = function() { + $http.get('/list_routes.json').then(function(response) { for (var i=0; i sub($c) { }; -get '/list_networks.json' => sub { +get '/list_routes.json' => sub { my $c = shift; - $c->render(json => [ Ravada::Network->list_networks ]); + $c->render(json => [ Ravada::Route->list_networks ]); }; get '/network/info/#id' => sub($c) { @@ -492,9 +492,9 @@ sub _add_admin_libs($c) { push @{$c->stash->{css}}, '/css/admin.css'; } -any '/network/new' => sub($c) { +any '/route/new' => sub($c) { _add_admin_libs($c); - return $c->render(template => "/main/network_new"); + return $c->render(template => "/main/route_new"); }; post '/v1/network/set' => sub($c) { diff --git a/t/70_networks.t b/t/70_networks.t index 194068b79..a32492c51 100644 --- a/t/70_networks.t +++ b/t/70_networks.t @@ -10,7 +10,7 @@ no warnings "experimental::signatures"; use feature qw(signatures); use_ok('Ravada'); -use_ok('Ravada::Network'); +use_ok('Ravada::Route'); use lib 't/lib'; use Test::Ravada; @@ -28,7 +28,7 @@ sub test_allow_all { my $domain = shift; my $ip = '192.168.1.2/32'; - my $net = Ravada::Network->new(address => $ip); + my $net = Ravada::Route->new(address => $ip); ok(!$net->allowed($domain->id),"Expecting not allowed from unknown network"); #check list bases, default allowed @@ -53,7 +53,7 @@ sub test_allow_all { ok(!$net->allowed_anonymous($domain->id),"Expecting denied anonymous from known network"); ok($net->allowed($domain->id),"Expecting allowed from known network"); - my $net2 = Ravada::Network->new(address => '192.168.1.22/32'); + my $net2 = Ravada::Route->new(address => '192.168.1.22/32'); ok($net2->allowed($domain->id),"Expecting allowed from known network"); ok(!$net2->allowed_anonymous($domain->id),"Expecting denied anonymous from known network"); { # test list bases anonymous @@ -68,7 +68,7 @@ sub test_allow_domain { my $domain = shift; my $ip = '10.1.1.1/32'; - my $net = Ravada::Network->new(address => $ip); + my $net = Ravada::Route->new(address => $ip); ok(!$net->allowed($domain->id),"Expecting not allowed from unknown network"); { # test list bases anonymous @@ -197,7 +197,7 @@ sub test_deny_all { my $ip = '10.0.0.2/32'; - my $net = Ravada::Network->new(address => $ip); + my $net = Ravada::Route->new(address => $ip); ok(!$net->allowed($domain->id),"Expecting not allowed from unknown network"); { # test list bases anonymous @@ -318,11 +318,11 @@ $domain->is_public(1); test_conflict_allowed(); -my $net = Ravada::Network->new(address => '127.0.0.1/32'); +my $net = Ravada::Route->new(address => '127.0.0.1/32'); ok($net->allowed($domain->id)); deny_everything_any(); -my $net2 = Ravada::Network->new(address => '10.0.0.0/32'); +my $net2 = Ravada::Route->new(address => '10.0.0.0/32'); ok(!$net2->allowed($domain->id), "Address unknown should not be allowed to anything"); test_allow_all($domain); diff --git a/t/kvm/p10_password.t b/t/kvm/p10_password.t index 4b397bac6..000354614 100644 --- a/t/kvm/p10_password.t +++ b/t/kvm/p10_password.t @@ -16,13 +16,15 @@ init(); my @VMS = vm_names(); my $USER = create_user("foo","bar", 1); +use_ok('Ravada::Route'); + ####################################################### sub test_domain_no_password { my $vm_name = shift; my $vm = rvd_back->search_vm($vm_name); - my $net = Ravada::Network->new(address => '127.0.0.1/32'); + my $net = Ravada::Route->new(address => '127.0.0.1/32'); ok(!$net->requires_password); my $domain_name = new_domain_name(); @@ -43,7 +45,7 @@ sub test_domain_no_password { } is($domain->is_active,0) or return; - my $net2 = Ravada::Network->new(address => '10.0.0.1/32'); + my $net2 = Ravada::Route->new(address => '10.0.0.1/32'); ok(!$net2->requires_password,"Expecting net requires password "); $domain->start(user => $USER, remote_ip => '10.0.0.1'); @@ -69,7 +71,7 @@ sub test_domain_password2 { my $vm_name = shift; my $vm = rvd_back->search_vm($vm_name); - my $net = Ravada::Network->new(address => '127.0.0.1/32'); + my $net = Ravada::Route->new(address => '127.0.0.1/32'); ok(!$net->requires_password) or return; my $domain_name = new_domain_name(); @@ -90,7 +92,7 @@ sub test_domain_password2 { } is($domain->is_active,0) or return; - my $net2 = Ravada::Network->new(address => '10.0.0.1/32'); + my $net2 = Ravada::Route->new(address => '10.0.0.1/32'); ok($net2->requires_password,"Expecting net requires password ") or return; @@ -117,7 +119,7 @@ sub test_domain_password2 { sub test_domain_password1($vm_name, $requires_password=1) { my $vm = rvd_back->search_vm($vm_name); - my $net2 = Ravada::Network->new(address => '10.0.0.1/32'); + my $net2 = Ravada::Route->new(address => '10.0.0.1/32'); ok($net2->requires_password,"Expecting net requires password ") or return; diff --git a/t/lib/Test/Ravada.pm b/t/lib/Test/Ravada.pm index b0be1e64d..bdb78dc76 100644 --- a/t/lib/Test/Ravada.pm +++ b/t/lib/Test/Ravada.pm @@ -1423,6 +1423,30 @@ sub _qemu_storage_pool { return $pool_name; } +sub remove_qemu_networks($vm=undef) { + return if !$VM_VALID{'KVM'} || $>; + if (!defined $vm) { + eval { $vm = rvd_back->search_vm('KVM') }; + if ($@ && $@ !~ /Missing qemu-img/) { + warn $@; + } + if ( !$vm ) { + $VM_VALID{'KVM'} = 0; + return; + } + } + + my $base = base_domain_name(); + $vm->connect(); + for my $network ( $vm->vm->list_all_networks) { + my $name = $network->get_name; + next if $name !~ /^$base/; + $network->destroy() if $network->is_active; + $network->undefine(); + } + +} + sub remove_qemu_pools($vm=undef) { return if !$VM_VALID{'KVM'} || $>; return if defined $vm && $vm->type eq 'Void'; @@ -1488,6 +1512,10 @@ sub remove_old_pools { remove_qemu_pools(); } +sub remove_old_networks { + remove_qemu_networks(); +} + sub _remove_old_entries($table) { my $sth = connector()->dbh->prepare("DELETE FROM $table" ." WHERE name like ? " @@ -1522,6 +1550,7 @@ sub clean($ldap=undef) { remove_old_domains(); remove_old_disks(); remove_old_pools(); + remove_old_networks(); _remove_old_entries('vms'); _remove_old_entries('networks'); _remove_old_groups_ldap(); diff --git a/t/mojo/30_settings.t b/t/mojo/30_settings.t index 244d9f3df..006bd40db 100644 --- a/t/mojo/30_settings.t +++ b/t/mojo/30_settings.t @@ -146,7 +146,7 @@ sub test_exists_network($id_network, $field, $name) { } sub _remove_network($address) { - my @list_networks = Ravada::Network::list_networks(); + my @list_networks = Ravada::Route::list_networks(); my ($found) = grep { $_->{address} eq $address} @list_networks; return if !$found; @@ -170,7 +170,7 @@ sub test_networks($vm_name) { exit if !$t->success; - my @list_networks = Ravada::Network::list_networks(); + my @list_networks = Ravada::Route::list_networks(); my ($found) = grep { $_->{name} eq $name } @list_networks; ok($found,"Expecting $name in list vms ".Dumper(\@list_networks)) or return; my $id_network = $found->{id}; @@ -183,7 +183,7 @@ sub test_networks($vm_name) { ); is($t->tx->res->code(),200) or die $t->tx->res->body; - @list_networks = Ravada::Network::list_networks(); + @list_networks = Ravada::Route::list_networks(); ($found) = grep { $_->{id} == $id_network } @list_networks; is($found->{name}, $name2) or die Dumper($found); @@ -194,7 +194,7 @@ sub test_networks($vm_name) { } ); - @list_networks = Ravada::Network::list_networks(); + @list_networks = Ravada::Route::list_networks(); ($found) = grep { $_->{id} == $id_network } @list_networks; is($found->{name}, $new_name) or die Dumper(\@list_networks); @@ -207,7 +207,7 @@ sub test_networks($vm_name) { $t->get_ok("/v1/network/remove/".$found->{id}); is($t->tx->res->code(),200) or die $t->tx->res->body; - ok(! grep { $_->{id} == $found->{id} } Ravada::Network::list_networks()); + ok(! grep { $_->{id} == $found->{id} } Ravada::Route::list_networks()); } diff --git a/t/vm/v10_volatile.t b/t/vm/v10_volatile.t index a41de96c1..a3efdc752 100644 --- a/t/vm/v10_volatile.t +++ b/t/vm/v10_volatile.t @@ -13,7 +13,7 @@ no warnings "experimental::signatures"; use feature qw(signatures); use_ok('Ravada'); -use_ok('Ravada::Network'); +use_ok('Ravada::Route'); use lib 't/lib'; use Test::Ravada; diff --git a/templates/bootstrap/navigation.html.ep b/templates/bootstrap/navigation.html.ep index dbf6ceeef..15c2efc2d 100644 --- a/templates/bootstrap/navigation.html.ep +++ b/templates/bootstrap/navigation.html.ep @@ -41,7 +41,7 @@ navbar-dark bg-dark fixed-top navbar-expand-lg navbar-inverse"> % } % if ($_user->is_admin) {  <%=l 'Nodes' %> -  <%=l 'Networks' %> +  <%=l 'Routes' %>  <%=l 'Storage' %> % }  <%=l 'Messages' %> diff --git a/templates/main/admin_networks.html.ep b/templates/main/admin_routes.html.ep similarity index 83% rename from templates/main/admin_networks.html.ep rename to templates/main/admin_routes.html.ep index 28fcb576d..9b8fbfbd5 100644 --- a/templates/main/admin_networks.html.ep +++ b/templates/main/admin_routes.html.ep @@ -4,14 +4,14 @@
%= include 'bootstrap/navigation' -
+
-

<%=l 'Networks' %>

+

<%=l 'Routes' %>

- <%=l 'New Network' %> + class="btn btn-success" href="/route/new"> + <%=l 'New Route' %>

@@ -22,7 +22,7 @@ <%=l 'requires password' %>
-
diff --git a/templates/main/network_new.html.ep b/templates/main/route_new.html.ep similarity index 100% rename from templates/main/network_new.html.ep rename to templates/main/route_new.html.ep From 9b0deb57dcf8fa9cb18902a6dc8b4ac83e7d7fcd Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Mon, 17 Jul 2023 16:55:23 +0200 Subject: [PATCH 02/58] wip: rename network to route --- public/js/admin.js | 54 +++++++++---------- script/rvd_front | 14 +++-- templates/main/admin_routes.html.ep | 2 +- templates/main/network_remove.html.ep | 8 --- ...achines.html.ep => route_machines.html.ep} | 6 +-- templates/main/route_new.html.ep | 6 +-- ..._options.html.ep => route_options.html.ep} | 28 +++++----- templates/main/route_remove.html.ep | 8 +++ templates/main/settings_generic_tabs.html.ep | 2 +- 9 files changed, 66 insertions(+), 62 deletions(-) delete mode 100644 templates/main/network_remove.html.ep rename templates/main/{network_machines.html.ep => route_machines.html.ep} (91%) rename templates/main/{network_options.html.ep => route_options.html.ep} (72%) create mode 100644 templates/main/route_remove.html.ep diff --git a/public/js/admin.js b/public/js/admin.js index d357e0a93..122b23f7e 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -11,7 +11,7 @@ ravadaApp.directive("solShowMachine", swMach) .controller("manage_networks",manage_networks) .controller("settings_node",settings_node) .controller("settings_storage",settings_storage) - .controller("settings_network",settings_network) + .controller("settings_route",settings_route) .controller("new_node", newNodeCtrl) .controller("new_storage", new_storage) .controller("settings_global", settings_global_ctrl) @@ -877,7 +877,7 @@ ravadaApp.directive("solShowMachine", swMach) var value = $scope.routes[id][field]; var args = { 'id': id }; args[field] = value; - $http.post('/v1/network/set' + $http.post('/v2/route/set' , JSON.stringify( args )) .then(function(response) { }); @@ -1136,11 +1136,11 @@ ravadaApp.directive("solShowMachine", swMach) }; - function settings_network($scope, $http, $timeout) { + function settings_route($scope, $http, $timeout) { var url_ws; $scope.init = function(id_network) { if (typeof id_network == 'undefined') { - $scope.network = { + $scope.route= { 'name': '' ,'all_domains': 1 }; @@ -1150,30 +1150,30 @@ ravadaApp.directive("solShowMachine", swMach) } } $scope.check_no_domains = function() { - if ( $scope.network.no_domains == 1 ){ - $scope.network.all_domains = 0; + if ( $scope.route.no_domains == 1 ){ + $scope.route.all_domains = 0; } }; $scope.check_all_domains = function() { - if ( $scope.network.all_domains == 1 ){ - $scope.network.no_domains = 0; + if ( $scope.route.all_domains == 1 ){ + $scope.route.no_domains = 0; } }; $scope.update_network= function(field) { - var data = $scope.network; + var data = $scope.route; if (typeof field != 'undefined') { var data = {}; - data[field] = $scope.network[field]; + data[field] = $scope.route[field]; } $scope.saved = false; $scope.error = ''; - $http.post('/v1/network/set/' + $http.post('/v2/route/set/' , JSON.stringify(data)) // , JSON.stringify({ value: $scope.network[field]})) .then(function(response) { if (response.data.ok == 1){ $scope.saved = true; - if (!$scope.network.id) { + if (!$scope.route.id) { $scope.new_saved = true; } } @@ -1185,19 +1185,19 @@ ravadaApp.directive("solShowMachine", swMach) $scope.load_network = function(id_network) { $scope.error = ''; $scope.saved = false; - $http.get('/network/info/'+id_network+'.json').then(function(response) { - $scope.network = response.data; + $http.get('/route/info/'+id_network).then(function(response) { + $scope.route = response.data; $scope.formNetwork.$setPristine(); - $scope.network._old_name = $scope.network.name; + $scope.route._old_name = $scope.route.name; }); }; $scope.list_domains_network = function(id_network) { - $http.get('/network/list_domains/'+id_network).then(function(response) { + $http.get('/route/list_domains/'+id_network).then(function(response) { $scope.machines = response.data; }); }; $scope.set_network_domain= function(id_domain, field, allowed) { - $http.get("/network/set/"+$scope.network.id+ "/" + field+ "/" +id_domain+"/" + $http.get("/route/set/"+$scope.route.id+ "/" + field+ "/" +id_domain+"/" +allowed) .then(function(response) { }); @@ -1208,26 +1208,26 @@ ravadaApp.directive("solShowMachine", swMach) }); }; - $scope.remove_network = function(id_network) { - if ($scope.network.name == 'default') { - $scope.error = $scope.network.name + " network can't be removed"; + $scope.remove_route = function(id_network) { + if ($scope.route.name == 'default') { + $scope.error = $scope.route.name + " network can't be removed"; return; } - $http.get('/v1/network/remove/'+id_network).then(function(response) { - $scope.message = "Network "+$scope.network.name+" removed"; - $scope.network ={}; + console.log(id_network); + $http.get('/v2/route/remove/'+id_network).then(function(response) { + window.location.assign('/admin/routes'); }); }; $scope.check_duplicate = function(field) { var args = {}; - if (typeof ($scope.network['id']) != 'undefined') { - args['id'] = $scope.network['id']; + if (typeof ($scope.route['id']) != 'undefined') { + args['id'] = $scope.route['id']; } - args[field] = $scope.network[field]; + args[field] = $scope.route[field]; $http.post("/v1/exists/networks",JSON.stringify(args)) .then(function(response) { - $scope.network["_duplicated_"+field]=response.data.id; + $scope.route["_duplicated_"+field]=response.data.id; }); }; $scope.new_saved = false; diff --git a/script/rvd_front b/script/rvd_front index 387ed3e5a..27435afce 100644 --- a/script/rvd_front +++ b/script/rvd_front @@ -470,20 +470,21 @@ get '/list_routes.json' => sub { $c->render(json => [ Ravada::Route->list_networks ]); }; -get '/network/info/#id' => sub($c) { +get '/route/info/#id' => sub($c) { my $sth = $RAVADA->_dbh->prepare("SELECT * from networks WHERE id=?"); $sth->execute($c->stash('id')); my $row = $sth->fetchrow_hashref; return $c->render(json => $row); }; -get '/v1/network/remove/#id' => sub($c) { +get '/v2/route/remove/#id' => sub($c) { my $sth = $RAVADA->_dbh->prepare("DELETE from networks WHERE id=?"); $sth->execute($c->stash('id')); + $USER->send_message("Network ".$c->stash('id')." removed"); return $c->render(json => { ok => 1 }); }; -get '/network/list_domains/#id' => sub($c) { +get '/route/list_domains/#id' => sub($c) { return $c->render( json => $RAVADA->list_bases_network($c->stash('id'))); }; @@ -497,14 +498,14 @@ any '/route/new' => sub($c) { return $c->render(template => "/main/route_new"); }; -post '/v1/network/set' => sub($c) { +post '/v2/route/set' => sub($c) { return access_denied($c) if !$USER->is_admin; my $arg = decode_json($c->req->body); return _update_fields($c, "networks", $arg); }; -get '/network/set/#id/#field/#id_domain/#value' => sub ($c) { +get '/v2/route/set/#id/#field/#id_domain/#value' => sub ($c) { my $id_network = $c->stash('id'); my $field = $c->stash('field'); my $id_domain = $c->stash('id_domain'); @@ -570,12 +571,15 @@ post '/v1/exists/:item' => sub($c) { $query .= " AND id <> $id " if defined $id; + my $sth = $RAVADA->_dbh->prepare("SELECT id FROM $table WHERE $query "); $sth->execute(map { $arg->{$_} } @fields ); my $row = $sth->fetchrow_hashref; $row->{id} = undef if !exists $row->{id}; + warn Dumper([$query, \@fields, $arg, $row]); + return $c->render(json => $row ); }; diff --git a/templates/main/admin_routes.html.ep b/templates/main/admin_routes.html.ep index 9b8fbfbd5..afed4cbe9 100644 --- a/templates/main/admin_routes.html.ep +++ b/templates/main/admin_routes.html.ep @@ -26,7 +26,7 @@ class="row" >
{{network.address}}