Changes

Jump to navigation Jump to search
Updated code - feb 2024
Line 171: Line 171:     
#----------------------------------------------------------------------
 
#----------------------------------------------------------------------
# heading    : Configuration
+
# heading    : Network
 
# description : DHCP manager
 
# description : DHCP manager
 
# navigation  : 2000 2500
 
# navigation  : 2000 2500
Line 183: Line 183:  
# name  : dhcpd6,  method : get,  url : /dhcpd6,    ctlact : Dhcpd#do_delete_one_lease
 
# name  : dhcpd6,  method : get,  url : /dhcpd6,    ctlact : Dhcpd#do_delete_one_lease
 
# name  : dhcpd7,  method : get,  url : /dhcpd7,    ctlact : Dhcpd#do_refresh_leases
 
# name  : dhcpd7,  method : get,  url : /dhcpd7,    ctlact : Dhcpd#do_refresh_leases
# name  : dhcpd8,  method : post, url : /dhcpd8,    ctlact : Dhcpd#winpopup
+
# name  : dhcpd8,  method : get, url : /dhcpd8,    ctlact : Dhcpd#do_winpopup
 +
# name  : dhcpd9,  method : get,  url : /dhcpd9,    ctlact : Dhcpd#do_wol
 +
# name  : dhcpd10,  method : post, url : /dhcpd10,  ctlact : Dhcpd#do_update_check
 
#
 
#
 
# routes : end
 
# routes : end
Line 190: Line 192:  
# Documentation: https://wiki.koozali.org/Dhcpmanager
 
# Documentation: https://wiki.koozali.org/Dhcpmanager
 
#
 
#
  −
   
</syntaxhighlight>The Server Manager 2 system extracts these "comments" from the header of the controller file and builds the navigation menu and the routing tables accordingly.
 
</syntaxhighlight>The Server Manager 2 system extracts these "comments" from the header of the controller file and builds the navigation menu and the routing tables accordingly.
   Line 223: Line 223:  
</syntaxhighlight>Necessary library units are identified and Configuration databases opened and the hash to be used to communicate with the template files is initialised.
 
</syntaxhighlight>Necessary library units are identified and Configuration databases opened and the hash to be used to communicate with the template files is initialised.
   −
As can be seen from the routing tables the following routines are specified to be the receipt of control depending on the web page user.
+
As can be seen from the routing tables the following routines are specified to be the receipt of control depending on the web page user. I
 +
 
 +
In simplified terms these are the routines.
 +
 
 +
Updated in Feb 2024 - this code is the current at this time. <syntaxhighlight lang="perl">
 +
my %dhcp_data = ();
   −
In simplified terms these are the routines (as before currently untested):<syntaxhighlight lang="perl">
   
sub main {
 
sub main {
 
     #
 
     #
Line 233: Line 237:  
     my $c = shift;
 
     my $c = shift;
 
     %dhcp_data = ();
 
     %dhcp_data = ();
    #$dhcp_data{"first"} = 'dhcpd_DESCRIPTION';
+
do_display($c);
    do_display( $c, %dhcp_data );
   
}
 
}
   Line 276: Line 279:  
dhcp_data => \%dhcp_data  
 
dhcp_data => \%dhcp_data  
 
);
 
);
 +
#die("here");
 
     $c->render( template => 'dhcpd' );
 
     $c->render( template => 'dhcpd' );
 
}
 
}
Line 286: Line 290:  
     my $title = $c->l("dhcpd_MANAGING_DHCP_CLIENT");
 
     my $title = $c->l("dhcpd_MANAGING_DHCP_CLIENT");
 
     my $modul = '';
 
     my $modul = '';
    my $trt  = "LEASES";
+
    my $trt  = "LEASES";
 +
  $dhcp_data{"check"}  = [[$c->l('dhcpd_ENABLED'),'enabled'],
 +
[$c->l('dhcpd_DISABLED'),'disabled']
 +
                            ];
 
     $dhcp_data{trt} = $trt;
 
     $dhcp_data{trt} = $trt;
 
     $dhcp_data{"first"} = '';
 
     $dhcp_data{"first"} = '';
 
     my @leases = get_leases_in_array($c);
 
     my @leases = get_leases_in_array($c);
    #print dumper @leases;
  −
    #$dhcp_data{"leases"} = \@leases;
   
     $c->stash( title => $title, modul => $modul, dhcp_data => \%dhcp_data, leases=> \@leases );
 
     $c->stash( title => $title, modul => $modul, dhcp_data => \%dhcp_data, leases=> \@leases );
 
     $c->render( template => 'dhcpd' );
 
     $c->render( template => 'dhcpd' );
 
}
 
}
    +
 +
sub do_scan {
 +
#
 +
# call to show scan results
 +
#
 +
my $c = shift;
 +
    my $title = $c->l("dhcpd_SCANNING_NETWORK_TITLE");
 +
    my $modul = '';
 +
    my $trt  = "SCAN";
 +
    $dhcp_data{trt} = $trt;
 +
    $dhcp_data{"first"} = '';
 +
# ..... get scan results into stash for passing to html template
 +
my $dhcp_scanresults = get_scan_results($c);
 +
    $c->stash( title => $title, modul => $modul, "dhcp_data" => \%dhcp_data, "scanresults" => $dhcp_scanresults);
 +
    $c->render( template => 'dhcpd' );
 +
}
 +
 
sub do_update_config {
 
sub do_update_config {
 
#
 
#
Line 314: Line 336:  
}
 
}
 
do_display($c);
 
do_display($c);
     return ;
+
     return;
 +
}
 +
 
 +
sub do_update_check {
 +
#Just update the check parameter
 +
my $c = shift;
 +
    my $dhcpd_check = $c->param ('dhcp_check');
 +
    ###Update SME configuration dbase
 +
    my $dbh_sme = esmith::ConfigDB->open('/home/e-smith/db/configuration');
 +
    ##Initiate get method --> create record object
 +
    my $sme_record  = $dbh_sme->get('dhcpd');
 +
    $sme_record->set_prop('check' , $dhcpd_check);
 +
$dhcp_data{"success"}="dhcpd_SUCCESSFULLY_SAVED_SETTINGS";
 +
    do_display($c);
 +
return;
 
}
 
}
 +
    
</syntaxhighlight>
 
</syntaxhighlight>
Line 459: Line 496:  
     exit;
 
     exit;
 
}
 
}
 +
 +
 
</syntaxhighlight>The routine extracts the input field values through the $c-<param routine and validates them, returning an error message if the validation fails and otherwise writing the results back to the DB.  
 
</syntaxhighlight>The routine extracts the input field values through the $c-<param routine and validates them, returning an error message if the validation fails and otherwise writing the results back to the DB.  
   Line 468: Line 507:     
% content_for 'module' => begin
 
% content_for 'module' => begin
 +
 
<div id="module" class="module dhcpman-panel">
 
<div id="module" class="module dhcpman-panel">
   Line 484: Line 524:  
</p>
 
</p>
   −
%}
+
 
</syntaxhighlight>All Mojolicious commands are indicated by a "%" in the first non space character. If the next character is an equals sign then the result of the expression is output.  Inline commands are inside pseudo-tags "<%" and "%>".
 
</syntaxhighlight>All Mojolicious commands are indicated by a "%" in the first non space character. If the next character is an equals sign then the result of the expression is output.  Inline commands are inside pseudo-tags "<%" and "%>".
   Line 510: Line 550:  
%} elsif ($dhcp_data->{success}) {
 
%} elsif ($dhcp_data->{success}) {
 
<div class='sme-border'>
 
<div class='sme-border'>
      <h2> Operation Status Report</h2><p>
+
      <h2> Operation Status Report - success</h2><p>
 +
<font color=green> 
 
%= $c->l($dhcp_data->{success});
 
%= $c->l($dhcp_data->{success});
 +
</font>
 
</p>
 
</p>
 
</div>
 
</div>
Line 518: Line 560:  
  <div class='sme-error'>
 
  <div class='sme-error'>
 
      <h2> Operation Status Report - error</h2><p>
 
      <h2> Operation Status Report - error</h2><p>
 +
<font color=red> 
 
%= $c->l($dhcp_data->{error});
 
%= $c->l($dhcp_data->{error});
 +
</font>
 
</p>
 
</p>
 
     </div>
 
     </div>
 +
   
 
%}
 
%}
   −
    % if ($dhcp_data->{trt} eq 'LEASES') {
+
% if ($dhcp_data->{trt} eq 'LEASES') {
 
%= include 'partials/_dhcpd_leases'
 
%= include 'partials/_dhcpd_leases'
    %} elsif ($dhcp_data->{trt} eq 'WINPOPUP') {
+
%} elsif ($dhcp_data->{trt} eq 'SCAN') {
    %= include 'partials/_dhcpd_winpopup'
+
%= include 'partials/_dhcpd_scan'
    %} elsif ($dhcp_data->{trt} eq 'SCAN') {
  −
    %= include 'partials/_dhcpd_scan'
   
%}
 
%}
 
</syntaxhighlight>and finally the front panel details is defined:
 
</syntaxhighlight>and finally the front panel details is defined:
Line 534: Line 577:  
%} else {  #PARAMS
 
%} else {  #PARAMS
 
% my $ip_regex = '^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$';
 
% my $ip_regex = '^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$';
<table><tr><td>
+
<table>
%= button_to $c->l('dhcpd_CONNECTED_IP') => '/dhcpd1'
+
<tr>
</td><td>
+
<td>
%= button_to $c->l('dhcpd_SCAN_YOUR_NETWORK') => '/dhcpd3'
+
%= button_to $c->l('dhcpd_CONNECTED_IP') => '/dhcpd1', onclick=>"showSpinnerLeases()", id=>"scanLeases"
</td><td>
+
<button class ="btn btn-primary spinnerButtonOverlay"  type = "submit" id="load" style="display:none">
%= button_to $c->l('dhcpd_GLOBAL_WINPOPUP') => '/dhcpd2'
+
  Scanning  <!--%= $c->l('dhcpd_CONNECTED_IP')-->
<td>
+
  <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
</tr>
+
</button>
</table>    
+
</td><td>
 +
%= button_to $c->l('dhcpd_SCAN_YOUR_NETWORK') => '/dhcpd3', onclick=>"showSpinnerNetwork()", id=>"scanNetwork"
 +
<button class ="btn btn-primary spinnerButtonOverlay"  type = "submit" id="loadingNetwork" style="display:none">
 +
  Scanning  <!--%= $c->l('dhcpd_CONNECTED_IP')-->
 +
  <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
 +
</button>
 +
</td>
 +
</tr>
 +
</table>  
 
<hr />  
 
<hr />  
 
<h2>  
 
<h2>  
Line 649: Line 700:  
%= submit_button "$btn", class => 'action'
 
%= submit_button "$btn", class => 'action'
 
% end
 
% end
%}
     −
</div>
  −
%end
   
</syntaxhighlight>This shows the top few controls for the panel.  Note the use of the table to keep the buttons in a row and also the structure of each parameter row involving the <nowiki><span> tags and the <br></nowiki> to create newlines.  Use of this structure will keep your panel in line with both the default and the AdminLTE themes. You need not do this of course!  
 
</syntaxhighlight>This shows the top few controls for the panel.  Note the use of the table to keep the buttons in a row and also the structure of each parameter row involving the <nowiki><span> tags and the <br></nowiki> to create newlines.  Use of this structure will keep your panel in line with both the default and the AdminLTE themes. You need not do this of course!  
   Line 661: Line 709:  
<div id='dhcpd-leases'>
 
<div id='dhcpd-leases'>
 
<table><tr><td>
 
<table><tr><td>
%= button_to $c->l('dhcpd_REFRESH') => '/dhcpd1'
+
%= button_to $c->l('dhcpd_REFRESH') => '/dhcpd1', onclick=>"showSpinnerLeases()", id=>"scanLeases"
</td><td>
+
<button class ="btn btn-primary spinnerButtonOverlay"  type = "submit" id="load" style="display:true">
%= button_to $c->l('dhcpd_REMOVE_ALL_LEASES') => '/dhcpd4'
+
  Scanning  <!--%= $c->l('dhcpd_CONNECTED_IP')-->
</td>
+
  <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
</tr>
+
</button>
 +
 
 +
</td><td>
 +
%= button_to $c->l('dhcpd_REMOVE_ALL_LEASES') => '/dhcpd4'
 +
</td>
 +
</tr>
 
     </table>     
 
     </table>     
<hr />
+
 
 
% my $btn = l('dhcpd_SAVE/RESTART');
 
% my $btn = l('dhcpd_SAVE/RESTART');
%= form_for '/dhcpd5' => (method => 'POST') => begin
+
%= form_for '/dhcpd10' => (method => 'POST') => begin
 
<span class=label>
 
<span class=label>
 
%=l 'dhcpd_CHECK_CLIENT_STATUS'
 
%=l 'dhcpd_CHECK_CLIENT_STATUS'
Line 679: Line 732:  
   %= $c->l("dhcpd_SAVE_TITLE");
 
   %= $c->l("dhcpd_SAVE_TITLE");
 
<br />
 
<br />
   
%= submit_button "$btn", class => 'action'
 
%= submit_button "$btn", class => 'action'
 
     % end
 
     % end
 
     <br>
 
     <br>
 
+
<table class="sme-border TableSort"><thead>
<table class="sme-border"><tbody>
   
<tr>
 
<tr>
 
<th class='sme-border'>
 
<th class='sme-border'>
Line 708: Line 759:  
</th>
 
</th>
 
</tr>
 
</tr>
 +
</thead>
 +
<tbody>
 
         % foreach my $ip (@$leases) {
 
         % foreach my $ip (@$leases) {
 
         <tr>
 
         <tr>
Line 713: Line 766:  
%= t td => (class => 'sme-border') => $ip->{name}
 
%= t td => (class => 'sme-border') => $ip->{name}
 
<td class='sme-border'>
 
<td class='sme-border'>
<a href="/smanager/dhcpd9??state=wake_up&MAC=<%= $ip->{mac}%>&name=<%= $ip->{name}%>" onclick="Wol_confirm(event,'<%=$c->l('dhcpd_WAKING_A_REMOTE_COMPUTER')%>',this);"><%==l $ip->{wol}%></a>
+
% if ($ip->{wol} =~ /ACTIVE/) {
 +
<center><%==l $ip->{wol}%></center>
 +
%} else {
 +
<a href="/smanager/dhcpd9??state=wake_up&MAC=<%= $ip->{mac}%>&name=<%= $ip->{name}%>" onclick="Wol_confirm(event,'<%=$c->l('dhcpd_WAKING_A_REMOTE_COMPUTER')%>',this);"><center><%==l $ip->{wol}%></center></a>
 +
%}
 
</td>
 
</td>
 
%= t td => (class => 'sme-border') => $ip->{start}
 
%= t td => (class => 'sme-border') => $ip->{start}
Line 719: Line 776:  
%= t td => (class => 'sme-border') => $ip->{mac}
 
%= t td => (class => 'sme-border') => $ip->{mac}
 
<td class = 'sme-border'>
 
<td class = 'sme-border'>
<a href="/smanager/dhcpd6?trt=DEL&ip=<%= $ip->{ip}%>" onclick="Remove_lease_confirm(event,'<%=$c->l('dhcpd_REMOVE_A_DHCP_LEASE_ACTION')%>',this);"><%=l 'dhcpd_REMOVE'%></a>
+
<a href="/smanager/dhcpd6?trt=DEL&ip=<%= $ip->{ip}%>&name=<%= $ip->{name}%>" onclick="Remove_lease_confirm(event,'<%=$c->l('dhcpd_REMOVE_A_DHCP_LEASE_ACTION')%>',this);"><center><%=l 'dhcpd_REMOVE'%></center></a>
<a href="/smanager/dhcpd8?trt=WIN&ip=<%= $ip->{ip}%>" onclick="Winpop_confirm(event,'<%=$c->l('dhcpd_SENDING_A_WINPOPUP')%>',this);"><%=l 'dhcpd_WINPOPUP_ACTION'%></a>
   
</td>
 
</td>
 
</tr>
 
</tr>
Line 729: Line 785:  
   <br />
 
   <br />
 
%= button_to $c->l('dhcpd_CLICK_HERE_TO_MAIN_PANEL') => '/dhcpd'
 
%= button_to $c->l('dhcpd_CLICK_HERE_TO_MAIN_PANEL') => '/dhcpd'
<script>
+
 
//var form = document.getElementById("dhcpd-leases").getElementsByTagName('a');
+
%= javascript begin
//confirm("Form elements:"+form.length);
  −
//for (let i = 0; i<form.length; i++) {
  −
//form[i].onclick = function() {
  −
// return confirm("html:"+i);
  −
//}
  −
//}
  −
//function Wol_confirm(){
  −
// if confirm("Confirm Wake on Lan to be sent to:"+this.href) then window.location.href=''
  −
//}
   
function Wol_confirm(event,msg,current){
 
function Wol_confirm(event,msg,current){
 
const getMAC = /.*MAC\=(.*)\&name.*/;
 
const getMAC = /.*MAC\=(.*)\&name.*/;
Line 764: Line 811:  
const getIP = /.*ip\=(.*)/;
 
const getIP = /.*ip\=(.*)/;
 
var IP = current.href.match(getIP)[1];
 
var IP = current.href.match(getIP)[1];
if (prompt(msg+" IP: "+IP))
+
if (confirm(msg+" IP: "+IP))
 
{ return true;}
 
{ return true;}
 
else {event.preventDefault();return false;}
 
else {event.preventDefault();return false;}
 
}
 
}
 
 
</script>
+
%end
       
</div>
 
</div>
 +
 
</syntaxhighlight>
 
</syntaxhighlight>
 
Note the use of Javascript to present to user with dialogs for confirmation and the WinPopup msg. This was done in the original using extra panels. Although some do not like Javascript, I feel it is here to stay and presents opportunities in terms of interfaces that are best taken advantage of. The main challenge is to work out how to pass the various perl based data to and from the JS routines.  Note I use a hidden field for this in one case. And the html request parameters for the others.  It can be a challenge to get the mixture of double and single quotes correct!
 
Note the use of Javascript to present to user with dialogs for confirmation and the WinPopup msg. This was done in the original using extra panels. Although some do not like Javascript, I feel it is here to stay and presents opportunities in terms of interfaces that are best taken advantage of. The main challenge is to work out how to pass the various perl based data to and from the JS routines.  Note I use a hidden field for this in one case. And the html request parameters for the others.  It can be a challenge to get the mixture of double and single quotes correct!
Line 907: Line 955:  
My current way to do this is to put the following code in the "%post" section of the .spec file:
 
My current way to do this is to put the following code in the "%post" section of the .spec file:
   −
  if [ -f /usr/share/smanager/lib/SrvMngr.pm ]
+
  if (systemctl list-unit-files |grep smanager) then
then
+
    echo "Smanager restart in spec file"  /sbin/e-smith/signal-event smanager-refresh
        /usr/sbin/e-smith/signal-event smanager-refresh
   
  fi
 
  fi
true
      
In the fullness of time it might be better to put this in the smeserver-dhcpmanager-update event.
 
In the fullness of time it might be better to put this in the smeserver-dhcpmanager-update event.
Line 927: Line 973:  
So many of the well known contribs have not been done.   
 
So many of the well known contribs have not been done.   
   −
Ones that have been done (Feb 2022) are:
+
Ones that have been done (Feb 2024) are:
    
* smeserver-ddclient
 
* smeserver-ddclient

Navigation menu