Add list of singleton pamraeters to custom, refine letsencrypt json

This commit is contained in:
Brian Read 2024-11-04 17:08:38 +00:00
parent d5a771f6f3
commit f238fcfa70
27 changed files with 868 additions and 251 deletions

2
.gitignore vendored
View File

@ -3,4 +3,4 @@ lib/
lib64 lib64
pyvenv.cfg pyvenv.cfg
*.new *.new
*.sav

View File

@ -1,5 +1,5 @@
# #
# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-18 19:00:38 # Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-04 16:03:10
# #
# #
# Routines to be edited by the developer to provide validation for parameters # Routines to be edited by the developer to provide validation for parameters
@ -36,8 +36,86 @@ our $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
return $ret; return $ret;
} }
sub validate_CHECKALLDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = 'ok';
return $ret;
}
sub validate_CHECKALLENABLEDDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = 'ok';
return $ret;
}
# Get singleton data for each panel
sub get_data_for_panel_LIST {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1'=>'Data for LIST', #Example
# fields from Inputs in LIST $fields['LIST']
'InternalIP'=>'InternalIP contents',
'ExternalIP'=>'ExternalIP contents',
'InternetIP'=>'InternetIP contents',
'Issuer'=>'Issuer contents',
'Expiry'=>'Expiry contents',
'NotBefore'=>'NotBefore contents',
);
return %ret;
}
sub get_data_for_panel_PARAMS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1'=>'Data for PARAMS', #Example
# fields from Inputs in PARAMS $fields['PARAMS']
);
return %ret;
}
sub get_data_for_panel_CHECKALLDOMAINS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1'=>'Data for CHECKALLDOMAINS', #Example
# fields from Inputs in CHECKALLDOMAINS $fields['CHECKALLDOMAINS']
);
return %ret;
}
sub get_data_for_panel_CHECKALLENABLEDDOMAINS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1'=>'Data for CHECKALLENABLEDDOMAINS', #Example
# fields from Inputs in CHECKALLENABLEDDOMAINS $fields['CHECKALLENABLEDDOMAINS']
);
return %ret;
}
# Get control data for tables(s) # Get control data for table(s)
sub get_DomainList { sub get_DomainList {
# Return an array of hashes of the contents for each row and column for DomainList # Return an array of hashes of the contents for each row and column for DomainList
@ -70,6 +148,22 @@ our $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
return $ret; return $ret;
} }
sub get_selected_CHECKALLDOMAINS {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return $ret;
}
sub get_selected_CHECKALLENABLEDDOMAINS {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return $ret;
}
#after sucessful modify or create or whatever and submit then perfom (if the params validate) #after sucessful modify or create or whatever and submit then perfom (if the params validate)
@ -87,6 +181,20 @@ our $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
return $ret; return $ret;
} }
sub perform_CHECKALLDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = 'ok';
return $ret;
}
sub perform_CHECKALLENABLEDDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = 'ok';
return $ret;
}
sub create_link{ sub create_link{
# WIP # WIP

View File

@ -1,11 +1,11 @@
package SrvMngr::Controller::Letsencrypt; package SrvMngr::Controller::Letsencrypt;
# #
# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-18 19:00:38 # Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-04 16:03:10
# #
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# heading : Miscellaneous # heading : Network
# description : letsencrypt # description : Letsencrypt certificate
# navigation : 2000 400 # navigation : 6000 6600
# #
# name : letsencrypt, method : get, url : /letsencrypt, ctlact : Letsencrypt#main # name : letsencrypt, method : get, url : /letsencrypt, ctlact : Letsencrypt#main
# name : letsencryptu, method : post, url : /letsencryptu, ctlact : Letsencrypt#do_update # name : letsencryptu, method : post, url : /letsencryptu, ctlact : Letsencrypt#do_update
@ -67,7 +67,7 @@ sub main {
$c->app->log->info( $c->log_req ); $c->app->log->info( $c->log_req );
my %lets_data = (); my %lets_data = ();
my $title = $c->l('lets_letsencrypt'); my $title = $c->l('lets_Letsencrypt_certificate');
my $modul = ''; my $modul = '';
$lets_data{'trt'} = 'LIST'; $lets_data{'trt'} = 'LIST';
@ -76,9 +76,19 @@ sub main {
# which DB - this only really works if the initial panel is a PARAMS type panel and not a TABLE # which DB - this only really works if the initial panel is a PARAMS type panel and not a TABLE
my $db = $cdb; #pickup local or global db or Default to config my $db = $cdb; #pickup local or global db or Default to config
#pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = get_data_for_panel_LIST();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
# and table control fields # and table control fields
$c->stash(DomainList=>$c->get_DomainList());
$c->stash(DomainList=>$c->get_DomainList());
$c->stash( $c->stash(
@ -119,7 +129,7 @@ sub do_update {
$c->app->log->info($c->log_req); $c->app->log->info($c->log_req);
my %lets_data = (); my %lets_data = ();
my $title = $c->l('lets_letsencrypt'); my $title = $c->l('lets_Letsencrypt_certificate');
# Accessing all POST parameters # Accessing all POST parameters
my %params = $c->req->params->to_hash; my %params = $c->req->params->to_hash;
@ -151,6 +161,18 @@ sub do_update {
$thispanel = 'PARAMS'; $thispanel = 'PARAMS';
} }
if ($trt eq 'CHECKALLDOMAINS'){
#Validate form parameters for panel CHECKALLDOMAINS
$ret = $c->validate_CHECKALLDOMAINS(\%lets_data);
$thispanel = 'CHECKALLDOMAINS';
}
if ($trt eq 'CHECKALLENABLEDDOMAINS'){
#Validate form parameters for panel CHECKALLENABLEDDOMAINS
$ret = $c->validate_CHECKALLENABLEDDOMAINS(\%lets_data);
$thispanel = 'CHECKALLENABLEDDOMAINS';
}
if ($ret ne "ok") { if ($ret ne "ok") {
# return to the panel with error message # return to the panel with error message
@ -183,9 +205,33 @@ sub do_update {
} }
} }
if ($trt eq 'CHECKALLDOMAINS'){
#do whatever is required ...
$ret = $c->perform_CHECKALLDOMAINS(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->render("letsencrypt");
} else {
$c->stash( success => $c->l('lets_CHECKALLDOMAINS_panel_action_was_successful')); #A bit bland - edit it in the lex file
}
}
if ($trt eq 'CHECKALLENABLEDDOMAINS'){
#do whatever is required ...
$ret = $c->perform_CHECKALLENABLEDDOMAINS(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->render("letsencrypt");
} else {
$c->stash( success => $c->l('lets_CHECKALLENABLEDDOMAINS_panel_action_was_successful')); #A bit bland - edit it in the lex file
}
}
# and call any signal-events needed # and call any signal-events needed
# Setup shared data and call panel # Setup shared data and call panel
$c->stash( $c->stash(
title => $title, title => $title,
@ -196,7 +242,7 @@ sub do_update {
} else { } else {
$lets_data{'trt'} = 'none'; $lets_data{'trt'} = 'none';
} }
$c->render("letsencrypt"); $c->do_display()
} }
} }
@ -216,7 +262,7 @@ sub do_display {
$c->app->log->info($c->log_req); $c->app->log->info($c->log_req);
my %lets_data = (); my %lets_data = ();
my $title = $c->l('lets_letsencrypt'); my $title = $c->l('lets_Letsencrypt_certificate');
# Accessing all parameters # Accessing all parameters
my %params = $c->req->params->to_hash; my %params = $c->req->params->to_hash;
@ -249,6 +295,16 @@ sub do_display {
%selectedrow = $c->get_selected_PARAMS($lets_data{'Selected'},$is_new_record); %selectedrow = $c->get_selected_PARAMS($lets_data{'Selected'},$is_new_record);
} }
if ($trt eq 'CHECKALLDOMAINS'){
#Validate form parameters for panel CHECKALLDOMAINS
%selectedrow = $c->get_selected_CHECKALLDOMAINS($lets_data{'Selected'},$is_new_record);
}
if ($trt eq 'CHECKALLENABLEDDOMAINS'){
#Validate form parameters for panel CHECKALLENABLEDDOMAINS
%selectedrow = $c->get_selected_CHECKALLENABLEDDOMAINS($lets_data{'Selected'},$is_new_record);
}
#Copy in the selected row params to the prefix_data hash to pass to the panel #Copy in the selected row params to the prefix_data hash to pass to the panel
while (my ($key, $value) = each %selectedrow){ while (my ($key, $value) = each %selectedrow){
@ -257,6 +313,58 @@ sub do_display {
# Where to go now # Where to go now
$lets_data{'trt'} = $trt; $lets_data{'trt'} = $trt;
# Set up other shared data according to the panel to go to
if ($trt eq 'LIST'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = get_data_for_panel_LIST();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
}
if ($trt eq 'PARAMS'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = get_data_for_panel_PARAMS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
}
if ($trt eq 'CHECKALLDOMAINS'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = get_data_for_panel_CHECKALLDOMAINS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
}
if ($trt eq 'CHECKALLENABLEDDOMAINS'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = get_data_for_panel_CHECKALLENABLEDDOMAINS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
}
# and table control fields
$c->stash(DomainList=>$c->get_DomainList());
# Data for panel # Data for panel
$c->stash( $c->stash(
title => $title, title => $title,
@ -264,4 +372,4 @@ sub do_display {
); );
$c->render("letsencrypt"); $c->render("letsencrypt");
} }
1; 1;

View File

@ -0,0 +1,34 @@
%#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-04 16:03:10
%#
<div id="Letsencrypt-CHECKALLDOMAINS" class="partial Letsencrypt-CHECKALLDOMAINS">
<script>
window.onload = function() {
SelectInput();
};
</script>
% my $btn = l('lets_APPLY');
%= form_for "Letsencryptd" => (method => 'POST') => begin
% param 'trt' => $lets_data->{trt} unless param 'trt';
%= hidden_field 'trt' => $lets_data->{trt}
%# Inputs etc in here.
<h1 class='head'><%=l('lets_Check_all_domains')%></h1>
<h2 class='subh'><%=l('lets_Loop_through_checking_the_letsencrypt')%></h2>
<span class=label>
%=l('lets_All_domains_check_result')
</span><span class=data>
% param 'AllDomainsCheck' => $lets_data->{AllDomainsCheck} unless param 'AllDomainsCheck';
%= text_area 'AllDomainsCheck', cols=>40, rows=>10, Readonly=>True
</span><br>
<span class='data'>
%= submit_button l('lets_Back'), class => 'action subm2'
</span>
%# Probably finally by a submit.
%end
</div>

View File

@ -0,0 +1,34 @@
%#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-04 16:03:10
%#
<div id="Letsencrypt-CHECKALLENABLEDDOMAINS" class="partial Letsencrypt-CHECKALLENABLEDDOMAINS">
<script>
window.onload = function() {
SelectInput();
};
</script>
% my $btn = l('lets_APPLY');
%= form_for "Letsencryptd" => (method => 'POST') => begin
% param 'trt' => $lets_data->{trt} unless param 'trt';
%= hidden_field 'trt' => $lets_data->{trt}
%# Inputs etc in here.
<h1 class='head'><%=l('lets_Check_all_enabled_domains')%></h1>
<h2 class='subh'><%=l('lets_Loop_through_checking_the_letsencrypt')%></h2>
<span class=label>
%=l('lets_Enabled_domains_check_result')
</span><span class=data>
% param 'EnabledDomainsCheck' => $lets_data->{EnabledDomainsCheck} unless param 'EnabledDomainsCheck';
%= text_area 'EnabledDomainsCheck', cols=>40, rows=>10, Readonly=>True
</span><br>
<span class='data'>
%= submit_button l('lets_Back'), class => 'action subm2'
</span>
%# Probably finally by a submit.
%end
</div>

View File

@ -1,5 +1,5 @@
%# %#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-18 19:00:38 %# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-04 16:03:10
%# %#
<div id="Letsencrypt-LIST" class="partial Letsencrypt-LIST"> <div id="Letsencrypt-LIST" class="partial Letsencrypt-LIST">
<script> <script>
@ -7,9 +7,6 @@
SelectInput(); SelectInput();
}; };
</script> </script>
<h2>
%= l('lets_Hello_LIST');
</h2>
% my $btn = l('lets_APPLY'); % my $btn = l('lets_APPLY');
%= form_for "Letsencryptd" => (method => 'POST') => begin %= form_for "Letsencryptd" => (method => 'POST') => begin
@ -17,9 +14,16 @@
%= hidden_field 'trt' => $lets_data->{trt} %= hidden_field 'trt' => $lets_data->{trt}
%# Inputs etc in here. %# Inputs etc in here.
<h1 class='head'><%=l('lets_List_of_Domains')%></h1> %= link_to l('lets_CONFIG'), 'letsencrypt?page=0&page_stack=&Next=Next&wherenext=CONFIG_PAGE' , class=>'link link2'
<h2 class='subh'><%=l('lets_FORM_DESCRIPTION')%></h2>
%= link_to l('lets_CHECK_ALL_DOMAINS'), 'letsencrypt?page=0&page_stack=&Next=Next&wherenext=CHECK_DOMAINS_PAGE' , class=>'link link3'
%= link_to l('lets_CHECK_ENABLED_DOMAINS'), 'letsencrypt?page=0&page_stack=&Next=Next&wherenext=CHECK_ENABLED_DOMAINS_PAGE' , class=>'link link4'
<h2 class='subh2'><%=l('lets_IPs_for_this_Server')%></h2>
<p><span class=label> <p><span class=label>
%=l('lets_Internal_IP') %=l('lets_Internal_IP')
@ -28,13 +32,45 @@
%= text_field 'InternalIP', size => '50', class => 'textinput InternalIP' , pattern=>'.*' , placeholder=>'InternalIP', Readonly=>'true' %= text_field 'InternalIP', size => '50', class => 'textinput InternalIP' , pattern=>'.*' , placeholder=>'InternalIP', Readonly=>'true'
<br></span></p> <br></span></p>
<p><span class=label>
%=l('lets_External_Interface_IP')
</span><span class=data>
% param 'ExternalIP' => $lets_data->{ExternalIP} unless param 'ExternalIP';
%= text_field 'ExternalIP', size => '50', class => 'textinput ExternalIP' , pattern=>'.*' , placeholder=>'ExternalIP', Readonly=>'true'
<br></span></p>
<p><span class=label> <p><span class=label>
%=l('lets_Internet_IP') %=l('lets_Internet_IP')
</span><span class=data> </span><span class=data>
% param 'ObserverIP' => $lets_data->{ObserverIP} unless param 'ObserverIP'; % param 'InternetIP' => $lets_data->{InternetIP} unless param 'InternetIP';
%= text_field 'ObserverIP', size => '50', class => 'textinput ObserverIP' , pattern=>'.*' , placeholder=>'ObserverIP', Readonly=>'true' %= text_field 'InternetIP', size => '50', class => 'textinput InternetIP' , pattern=>'.*' , placeholder=>'InternetIP', Readonly=>'true'
<br></span></p> <br></span></p>
<h2 class='subh3'><%=l('lets_Current_certificate_details')%></h2>
<p><span class=label>
%=l('lets_Issuer')
</span><span class=data>
% param 'Issuer' => $lets_data->{Issuer} unless param 'Issuer';
%= text_field 'Issuer', size => '50', class => 'textinput Issuer' , pattern=>'.*' , placeholder=>'Issuer', Readonly=>'true'
<br></span></p>
<p><span class=label>
%=l('lets_Expiry')
</span><span class=data>
% param 'Expiry' => $lets_data->{Expiry} unless param 'Expiry';
%= text_field 'Expiry', size => '50', class => 'textinput Expiry' , pattern=>'.*' , placeholder=>'Expiry', Readonly=>'true'
<br></span></p>
<p><span class=label>
%=l('lets_Not_Before')
</span><span class=data>
% param 'NotBefore' => $lets_data->{NotBefore} unless param 'NotBefore';
%= text_field 'NotBefore', size => '50', class => 'textinput NotBefore' , pattern=>'.*' , placeholder=>'NotBefore', Readonly=>'true'
<br></span></p>
<h2 class='subh4'><%=l('lets_List_of_Domains_and_Hosts')%></h2>
<br /><table class="sme-border TableSort sme-table tabl1 "> <br /><table class="sme-border TableSort sme-table tabl1 ">
<thead class='tabl1'> <thead class='tabl1'>
<tr table-head-row> <tr table-head-row>
@ -68,4 +104,4 @@
%# Probably finally by a submit. %# Probably finally by a submit.
%end %end
</div> </div>

View File

@ -1,5 +1,5 @@
%# %#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-18 19:00:38 %# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-04 16:03:10
%# %#
<div id="Letsencrypt-PARAMS" class="partial Letsencrypt-PARAMS"> <div id="Letsencrypt-PARAMS" class="partial Letsencrypt-PARAMS">
<script> <script>
@ -7,9 +7,6 @@
SelectInput(); SelectInput();
}; };
</script> </script>
<h2>
%= l('lets_Hello_PARAMS');
</h2>
% my $btn = l('lets_APPLY'); % my $btn = l('lets_APPLY');
%= form_for "Letsencryptd" => (method => 'POST') => begin %= form_for "Letsencryptd" => (method => 'POST') => begin
@ -28,7 +25,7 @@
<p><span class=label> <p><span class=label>
%=l('lets_SERVICE_STATUS') %=l('lets_SERVICE_STATUS')
</span><span class=data> </span><span class=data>
% my @status_options = [{'Value': 'disabled', 'Text': 'Disabled'}, {'Value': 'enabled', 'Text': 'Enabled'}, {'Value': 'test', 'Text': 'TEST'}]; % my @status_options = [['Disabled' => 'disabled'], ['Enabled' => 'enabled'], ['TEST' => 'test']];
% param 'status' => $lets_data->{status} unless param 'status'; % param 'status' => $lets_data->{status} unless param 'status';
%= select_field 'status' => @status_options, class => 'input' %= select_field 'status' => @status_options, class => 'input'
<br></span> </p> <br></span> </p>
@ -36,7 +33,7 @@
<p><span class=label> <p><span class=label>
%=l('lets_HOOKSCRIPT_STATUS') %=l('lets_HOOKSCRIPT_STATUS')
</span><span class=data> </span><span class=data>
% my @hookScript_options = [{'Value': 'disabled', 'Text': 'Disabled'}, {'Value': 'enabled', 'Text': 'Enabled'}]; % my @hookScript_options = [['Disabled' => 'disabled'], ['Enabled' => 'enabled']];
% param 'hookScript' => $lets_data->{hookScript} unless param 'hookScript'; % param 'hookScript' => $lets_data->{hookScript} unless param 'hookScript';
%= select_field 'hookScript' => @hookScript_options, class => 'input' %= select_field 'hookScript' => @hookScript_options, class => 'input'
<br></span> </p> <br></span> </p>
@ -44,7 +41,7 @@
<p><span class=label> <p><span class=label>
%=l('lets_HOSTOVERRIDE_STATUS') %=l('lets_HOSTOVERRIDE_STATUS')
</span><span class=data> </span><span class=data>
% my @hostOverride_options = [{'Value': 'disabled', 'Text': 'Disabled'}, {'Value': 'yes', 'Text': 'Yes'}]; % my @hostOverride_options = [['Disabled' => 'disabled'], ['Yes' => 'yes']];
% param 'hostOverride' => $lets_data->{hostOverride} unless param 'hostOverride'; % param 'hostOverride' => $lets_data->{hostOverride} unless param 'hostOverride';
%= select_field 'hostOverride' => @hostOverride_options, class => 'input' %= select_field 'hostOverride' => @hostOverride_options, class => 'input'
<br></span> </p> <br></span> </p>
@ -52,7 +49,7 @@
<p><span class=label> <p><span class=label>
%=l('lets_ACCEPT_TERMS_STATUS') %=l('lets_ACCEPT_TERMS_STATUS')
</span><span class=data> </span><span class=data>
% my @ACCEPT_TERMS_options = [{'Value': 'disabled', 'Text': 'Disabled'}, {'Value': 'yes', 'Text': 'Yes'}]; % my @ACCEPT_TERMS_options = [['Disabled' => 'disabled'], ['Yes' => 'yes']];
% param 'ACCEPT_TERMS' => $lets_data->{ACCEPT_TERMS} unless param 'ACCEPT_TERMS'; % param 'ACCEPT_TERMS' => $lets_data->{ACCEPT_TERMS} unless param 'ACCEPT_TERMS';
%= select_field 'ACCEPT_TERMS' => @ACCEPT_TERMS_options, class => 'input' %= select_field 'ACCEPT_TERMS' => @ACCEPT_TERMS_options, class => 'input'
<br></span> </p> <br></span> </p>
@ -60,7 +57,7 @@
<p><span class=label> <p><span class=label>
%=l('lets_API_STATUS') %=l('lets_API_STATUS')
</span><span class=data> </span><span class=data>
% my @API_options = [{'Value': '2', 'Text': '2'}]; % my @API_options = [['2' => '2']];
% param 'API' => $lets_data->{API} unless param 'API'; % param 'API' => $lets_data->{API} unless param 'API';
%= select_field 'API' => @API_options, class => 'input' %= select_field 'API' => @API_options, class => 'input'
<br></span> </p> <br></span> </p>
@ -68,7 +65,7 @@
<p><span class=label> <p><span class=label>
%=l('lets_KEYSIZE_STATUS') %=l('lets_KEYSIZE_STATUS')
</span><span class=data> </span><span class=data>
% my @keysize_options = [{'Value': '2048', 'Text': '2048'}, {'Value': '3072', 'Text': '3072'}, {'Value': '4096', 'Text': '4096'}]; % my @keysize_options = [['2048' => '2048'], ['3072' => '3072'], ['4096' => '4096']];
% param 'keysize' => $lets_data->{keysize} unless param 'keysize'; % param 'keysize' => $lets_data->{keysize} unless param 'keysize';
%= select_field 'keysize' => @keysize_options, class => 'input' %= select_field 'keysize' => @keysize_options, class => 'input'
<br></span> </p> <br></span> </p>
@ -76,18 +73,11 @@
<p><span class=label> <p><span class=label>
%=l('lets_CONFIGUREMODE_STATUS') %=l('lets_CONFIGUREMODE_STATUS')
</span><span class=data> </span><span class=data>
% my @configure_options = [{'Value': 'all', 'Text': 'ALL'}, {'Value': 'domains', 'Text': 'Domains'}, {'Value': 'hosts', 'Text': 'HOSTS'}, {'Value': 'none', 'Text': 'NONE'}]; % my @configure_options = [['ALL' => 'all'], ['Domains' => 'domains'], ['HOSTS' => 'hosts'], ['NONE' => 'none']];
% param 'configure' => $lets_data->{configure} unless param 'configure'; % param 'configure' => $lets_data->{configure} unless param 'configure';
%= select_field 'configure' => @configure_options, class => 'input' %= select_field 'configure' => @configure_options, class => 'input'
<br></span> </p> <br></span> </p>
<p><span class=label>
%=l('lets_EMAIL')
</span><span class=data>
% param 'email' => $lets_data->{email} unless param 'email';
%= text_field 'email', size => '50', class => 'textinput email' , pattern=>'.*' , placeholder=>'email'
<br></span></p>
<span class='data'> <span class='data'>
%= submit_button l('lets_Save'), class => 'action subm9' %= submit_button l('lets_Save'), class => 'action subm9'
</span> </span>

View File

@ -1,18 +1,10 @@
/* /*
Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-18 19:00:38 Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-04 16:03:10
*/ */
.Letsencrypt-panel {} .Letsencrypt-panel {}
.name {} .name {}
.rout {} .rout {}
.head {} .head {}
.subh {} .subh {}
.para1 {} .text1 {}
.sele1 {} .subm2 {}
.sele2 {}
.sele3 {}
.sele4 {}
.sele5 {}
.sele6 {}
.sele7 {}
.text8 {}
.subm9 {}

View File

@ -1,7 +1,7 @@
%# %#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-18 19:00:38 %# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-04 16:03:10
%# %#
% layout 'default', title => "Sme server 2 - letsencrypt", share_dir => './'; % layout 'default', title => "Sme server 2 - Letsencrypt certificate", share_dir => './';
%# css specific to this panel: %# css specific to this panel:
% content_for 'module' => begin % content_for 'module' => begin
%= stylesheet '/css/letsencrypt.css' %= stylesheet '/css/letsencrypt.css'
@ -50,7 +50,15 @@
%= include 'partials/_lets_PARAMS' %= include 'partials/_lets_PARAMS'
%} %}
% if ($lets_data->{trt} eq "CHECKALLDOMAINS") {
%= include 'partials/_lets_CHECKALLDOMAINS'
%}
% if ($lets_data->{trt} eq "CHECKALLENABLEDDOMAINS") {
%= include 'partials/_lets_CHECKALLENABLEDDOMAINS'
%}
</div> </div>
%end %end

View File

@ -1,33 +1,47 @@
# #
# Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-18 19:00:38 # Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-04 16:03:10
# #
'lets_LABEL_LECERT' => 'LABEL LECERT',
'lets_Hello_LIST' => 'Hello LIST',
'lets_Domain_name_/_HOSTNAME' => 'Domain name / HOSTNAME',
'lets_IS_IN_CERT' => 'IS IN CERT',
'lets_Internet_IP' => 'Internet IP',
'lets_HOOKSCRIPT_STATUS' => 'HOOKSCRIPT STATUS',
'lets_Save' => 'Save',
'lets_FORM_DESCRIPTION' => 'FORM DESCRIPTION',
'lets_EMAIL' => 'Email',
'lets_Hello_PARAMS' => 'Hello PARAMS',
'lets_HOSTOVERRIDE_STATUS' => 'HOSTOVERRIDE STATUS',
'lets_Brief_description' => 'Brief description',
'lets_Internal_IP' => 'Internal IP',
'lets_CONFIG_LETSENCRYPT' => 'CONFIG LETSENCRYPT',
'lets_KEYSIZE_STATUS' => 'KEYSIZE STATUS',
'lets_CONFIGUREMODE_STATUS' => 'CONFIGUREMODE STATUS', 'lets_CONFIGUREMODE_STATUS' => 'CONFIGUREMODE STATUS',
'lets_List_of_Domains' => 'List of Domains',
'lets_SERVICE_STATUS' => 'SERVICE STATUS',
'lets_Configuration_for_Letsencrypt' => 'Configuration for Letsencrypt',
'lets_LABEL_POINT' => 'LABEL POINT',
'lets_API_STATUS' => 'API STATUS',
'lets_letsencrypt' => 'Letsencrypt',
'lets_LIST_panel_action_was_successful' => 'LIST panel action was successful', 'lets_LIST_panel_action_was_successful' => 'LIST panel action was successful',
'lets_CHECK' => 'Check', 'lets_IS_IN_CERT' => 'IS IN CERT',
'lets_IPs_for_this_Server' => 'Ips for this Server',
'lets_LABEL_LECERT' => 'LABEL LECERT',
'lets_LABEL_NAMESERVERS' => 'LABEL NAMESERVERS', 'lets_LABEL_NAMESERVERS' => 'LABEL NAMESERVERS',
'lets_Content' => 'Content',
'lets_ACCEPT_TERMS_STATUS' => 'ACCEPT TERMS STATUS', 'lets_ACCEPT_TERMS_STATUS' => 'ACCEPT TERMS STATUS',
'lets_HOOKSCRIPT_STATUS' => 'HOOKSCRIPT STATUS',
'lets_Check_all_enabled_domains' => 'Check all enabled domains',
'lets_Loop_through_checking_the_letsencrypt' => 'Loop through checking the letsencrypt status for each configured domain wihch is enabled',
'lets_LABEL_POINT' => 'LABEL POINT',
'lets_Issuer' => 'Issuer',
'lets_CHECK_ALL_DOMAINS' => 'CHECK ALL DOMAINS',
'lets_Internet_IP' => 'Internet IP',
'lets_CHECK_ENABLED_DOMAINS' => 'CHECK ENABLED DOMAINS',
'lets_API_STATUS' => 'API STATUS',
'lets_Not_Before' => 'Not Before',
'lets_CONFIG_LETSENCRYPT' => 'CONFIG LETSENCRYPT',
'lets_Configuration_for_Letsencrypt' => 'Configuration for Letsencrypt',
'lets_PARAMS_panel_action_was_successful' => 'PARAMS panel action was successful', 'lets_PARAMS_panel_action_was_successful' => 'PARAMS panel action was successful',
'lets_CHECKALLDOMAINS_panel_action_was_successful' => 'CHECKALLDOMAINS panel action was successful',
'lets_Content' => 'Content',
'lets_KEYSIZE_STATUS' => 'KEYSIZE STATUS',
'lets_Back' => 'Back',
'lets_Domain_name_/_HOSTNAME' => 'Domain name / HOSTNAME',
'lets_Check_all_domains' => 'Check all domains',
'lets_Internal_IP' => 'Internal IP',
'lets_Save' => 'Save',
'lets_External_Interface_IP' => 'External Interface IP',
'lets_Expiry' => 'Expiry',
'lets_Brief_description' => 'Brief description',
'lets_Loop_through_checking_the_letsencrypt' => 'Loop through checking the letsencrypt status for each configured domain',
'lets_HOSTOVERRIDE_STATUS' => 'HOSTOVERRIDE STATUS',
'lets_Enabled_domains_check_result' => 'Enabled domains check result',
'lets_Letsencrypt_certificate' => 'Letsencrypt certificate',
'lets_CHECKALLENABLEDDOMAINS_panel_action_was_successful' => 'CHECKALLENABLEDDOMAINS panel action was successful',
'lets_List_of_Domains_and_Hosts' => 'List of Domains and Hosts',
'lets_Manage_letsencrypt-config_settings:' => 'Manage letsencrypt-config settings:', 'lets_Manage_letsencrypt-config_settings:' => 'Manage letsencrypt-config settings:',
'lets_Current_certificate_details' => 'Current certificate details',
'lets_CONFIG' => 'Config',
'lets_SERVICE_STATUS' => 'SERVICE STATUS',
'lets_APPLY' => 'Apply', 'lets_APPLY' => 'Apply',
'lets_CHECK' => 'Check',
'lets_All_domains_check_result' => 'All domains check result',

View File

@ -1,5 +1,5 @@
%# %#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-19 18:55:51 %# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-20 16:12:38
%# %#
<div id="letsencrypt-config-PARAMS" class="partial letsencrypt-config-PARAMS"> <div id="letsencrypt-config-PARAMS" class="partial letsencrypt-config-PARAMS">
<script> <script>

View File

@ -1,5 +1,5 @@
# #
# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-19 18:55:51 # Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-20 16:12:38
# #
# #
# Routines to be edited by the developer to provide validation for parameters # Routines to be edited by the developer to provide validation for parameters

View File

@ -1,5 +1,5 @@
/* /*
Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-19 18:55:51 Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-20 16:12:38
*/ */
.letsencrypt-config-panel {} .letsencrypt-config-panel {}
.name {} .name {}

View File

@ -1,5 +1,5 @@
%# %#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-19 18:55:51 %# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-20 16:12:38
%# %#
% layout 'default', title => "Sme server 2 - letsencrypt-config", share_dir => './'; % layout 'default', title => "Sme server 2 - letsencrypt-config", share_dir => './';
%# css specific to this panel: %# css specific to this panel:

View File

@ -1,6 +1,6 @@
package SrvMngr::Controller::letsencrypt-config; package SrvMngr::Controller::letsencrypt-config;
# #
# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-19 18:55:51 # Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-20 16:12:38
# #
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# heading : Miscellaneous # heading : Miscellaneous

View File

@ -1,20 +1,20 @@
# #
# Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-19 18:55:51 # Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-20 16:12:38
# #
'lets_SERVICE_STATUS' => 'SERVICE STATUS',
'lets_ACCEPT_TERMS_STATUS' => 'ACCEPT TERMS STATUS',
'lets_FORM_TITLE' => 'FORM TITLE', 'lets_FORM_TITLE' => 'FORM TITLE',
'lets_PARAMS_panel_action_was_successful' => 'PARAMS panel action was successful',
'lets_Manage_letsencrypt-config_settings:' => 'Manage letsencrypt-config settings:',
'lets_Hello_PARAMS' => 'Hello PARAMS',
'lets_CONFIG_LE' => 'CONFIG LE',
'lets_Save' => 'Save',
'lets_SERVICE_STATUS' => 'SERVICE STATUS',
'lets_SERVICE_STATUS' => 'SERVICE STATUS',
'lets_API_STATUS' => 'API STATUS',
'lets_APPLY' => 'Apply', 'lets_APPLY' => 'Apply',
'lets_CONFIGUREMODE_STATUS' => 'CONFIGUREMODE STATUS', 'lets_API_STATUS' => 'API STATUS',
'lets_EMAIL' => 'Email', 'lets_EMAIL' => 'Email',
'lets_KEYSIZE_STATUS' => 'KEYSIZE STATUS', 'lets_Hello_PARAMS' => 'Hello PARAMS',
'lets_HOOKSCRIPT_STATUS' => 'HOOKSCRIPT STATUS', 'lets_HOOKSCRIPT_STATUS' => 'HOOKSCRIPT STATUS',
'lets_CONFIGUREMODE_STATUS' => 'CONFIGUREMODE STATUS',
'lets_Save' => 'Save',
'lets_letsencrypt-config' => 'Letsencrypt-config', 'lets_letsencrypt-config' => 'Letsencrypt-config',
'lets_HOSTOVERRIDE_STATUS' => 'HOSTOVERRIDE STATUS', 'lets_HOSTOVERRIDE_STATUS' => 'HOSTOVERRIDE STATUS',
'lets_ACCEPT_TERMS_STATUS' => 'ACCEPT TERMS STATUS', 'lets_KEYSIZE_STATUS' => 'KEYSIZE STATUS',
'lets_Manage_letsencrypt-config_settings:' => 'Manage letsencrypt-config settings:',
'lets_SERVICE_STATUS' => 'SERVICE STATUS',
'lets_CONFIG_LE' => 'CONFIG LE',
'lets_PARAMS_panel_action_was_successful' => 'PARAMS panel action was successful',

View File

@ -75,12 +75,22 @@ sub main {
#Load any DB entries into the <prefix>_data area so as they are preset in the form #Load any DB entries into the <prefix>_data area so as they are preset in the form
# which DB - this only really works if the initial panel is a PARAMS type panel and not a TABLE # which DB - this only really works if the initial panel is a PARAMS type panel and not a TABLE
my $db = $$${controldb | db | 'cdb'}; #pickup local or global db or Default to config my $db = $$${controldb | db | 'cdb'}; #pickup local or global db or Default to config
<tal:block tal:repeat="dbentry dbentries"> <tal:block tal:repeat="dbfield dbfields">
$$${prefix}_data{${dbentry}} = $db->prop('${dbentry}') || ${dbdefault | ""} || ""; $$${prefix}_data{${dbfield}} = $db->prop('${dbfield}') || ${dbdefault | ""} || "";
</tal:block> </tal:block>
#pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = get_data_for_panel_${firstPanel}();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$$${prefix}_data{$key} = $value;
}
# and table control fields # and table control fields
<tal:block tal:repeat="tablecontrol tablecontrols"> $c->stash(${tablecontrol}=>$c->get_${tablecontrol}()); <tal:block tal:repeat="tablecontrol tablecontrols">
$c->stash(${tablecontrol}=>$c->get_${tablecontrol}());
</tal:block> </tal:block>
$c->stash( $c->stash(
@ -169,7 +179,7 @@ sub do_update {
</tal:block> </tal:block>
# and call any signal-events needed # and call any signal-events needed
# Setup shared data and call panel # Setup shared data and call panel
$c->stash( $c->stash(
title => $title, title => $title,
@ -180,7 +190,7 @@ sub do_update {
} else { } else {
$$${prefix}_data{'trt'} = '${NextPanel | "none"}'; $$${prefix}_data{'trt'} = '${NextPanel | "none"}';
} }
$c->render("${lcPackageName}"); $c->do_display()
} }
} }
@ -236,6 +246,25 @@ sub do_display {
# Where to go now # Where to go now
$$${prefix}_data{'trt'} = $trt; $$${prefix}_data{'trt'} = $trt;
# Set up other shared data according to the panel to go to
<tal:block tal:repeat="panel panels">
if ($trt eq '${panel}'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = get_data_for_panel_${panel}();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$$${prefix}_data{$key} = $value;
}
}
</tal:block>
# and table control fields
<tal:block tal:repeat="tablecontrol tablecontrols">
$c->stash(${tablecontrol}=>$c->get_${tablecontrol}());
</tal:block>
# Data for panel # Data for panel
$c->stash( $c->stash(
title => $title, title => $title,
@ -243,4 +272,4 @@ sub do_display {
); );
$c->render("${lcPackageName}"); $c->render("${lcPackageName}");
} }
1; 1;

View File

@ -2,7 +2,7 @@
# Generated by ${version} # Generated by ${version}
# #
# #
# Routines to be edited by the developer to provide validation for parameters # Routines to be edited by the developer to provide content and validation for parameters
# and provison of the control data for table(s) # and provison of the control data for table(s)
# #
use esmith::util; use esmith::util;
@ -29,8 +29,26 @@ our $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
return $ret; return $ret;
} }
</tal:block> </tal:block>
# Get singleton data for each panel
<tal:block tal:repeat="panel panels">
sub get_data_for_panel_${panel} {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1'=>'Data for ${panel}', #Example
# fields from Inputs in ${panel} $fields['${panel}']
<tal:block tal:repeat="field fields[panel]">
'${field}'=>'${field} contents',
</tal:block>
);
return %ret;
}
</tal:block>
# Get control data for tables(s) # Get control data for table(s)
<tal:block tal:repeat="tablecontrol tablecontrols"> <tal:block tal:repeat="tablecontrol tablecontrols">
sub get_${tablecontrol} { sub get_${tablecontrol} {
# Return an array of hashes of the contents for each row and column for ${tablecontrol} # Return an array of hashes of the contents for each row and column for ${tablecontrol}

View File

@ -222,11 +222,16 @@
</Table> </Table>
<Preformatted><![CDATA[ <Preformatted><![CDATA[
<pre class='preformatted pref${type_serial}'> <pre class='preformatted pref${type_serial}'>
${Value}' ${Value}
</pre> </pre>
]]> ]]>
</Preformatted> </Preformatted>
<Link><![CDATA[
%= link_to l('${title}'), '${structure:href}' , class=>'link link${type_serial}'
]]>
</Link>
</root> </root>

View File

@ -49,4 +49,4 @@
</div> </div>
%end %end

View File

@ -7,9 +7,6 @@
SelectInput(); SelectInput();
}; };
</script> </script>
<h2>
%= l('${prefix} Hello ${route}');
</h2>
% my $btn = l('APPLY'); % my $btn = l('APPLY');
%= form_for "${PackageName}d" => (method => 'POST') => begin %= form_for "${PackageName}d" => (method => 'POST') => begin
@ -18,4 +15,4 @@
%# Inputs etc in here. %# Inputs etc in here.
%# Probably finally by a submit. %# Probably finally by a submit.
%end %end
</div> </div>

View File

@ -0,0 +1,61 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SME Server sme11.thereadclan.me.uk</title>
<link rev="made" href="mailto:bugs%40koozali.org">
<meta name="copyright" content="(head.tmpl)Copyright 2003-2004 Mitel Corporation">
<link rel="stylesheet" type="text/css" href="/server-common/css/sme_core.css">
<style type="text/css">
@import url("/server-common/css/sme_main.css");
</style>
</head>
<body>
<div class="sme-error"><h5>
Warning: a reconfigure and reboot is required before proceeding! Failure to do so now
may leave your system in an unknown state!</h5></div><div class="sme-error"><h5>
URGENT NOTICE: As per June 30th 2024, SME Server 10 is obsolete, and potentially INSECURE. NO support will be offered for any issue found with this installed version.
Please migrate IMMEDIATELY to Koozali SME Server 11 or higher version. Failure to upgrade may lead to the compromise of this server.
</br>Please, consult <a href="https://wiki.koozali.org/SME_Server:Download" target="_blank">https://wiki.koozali.org/SME_Server:Download</a> to get last available version.</h5></div>
<h1>FORM_TITLE</h1>
<form method="POST" action="letsencrypt" enctype="application/x-www-form-urlencoded">
<p>FORM_DESCRIPTION</p>
<p>SERVER_IPS</p><
<p>LABEL_INTERNALIP</p>192.168.1.11
<p>LABEL_IP_FROM_OBSERVER</p>IP
<a class="button-like"
href="letsencrypt?page=0&page_stack=&Next=Next&wherenext=CONFIG_PAGE">CONFIG</a>
<a class="button-like"
href="letsencrypt?page=0&page_stack=&Next=Next&wherenext=CHECK_DOMAINS_PAGE">CHECK_ALL_DOMAINS</a>
<a class="button-like"
href="letsencrypt?page=0&page_stack=&Next=Next&wherenext=CHECK_ENABLED_DOMAINS_PAGE">CHECK_ENABLED_DOMAINS</a>
<p>> Issuer: /C=--/ST=----/L=Ottawa/O=XYZ Corporation/OU=Main/CN=sme11.thereadclan.me.uk/emailAddress=admin@thereadclan.me.uk<br> <br> Expiry: 2025-10-03T02:09:03Z<br> <br> Not Before: 2024-10-03T02:09:03Z</p>>
<h2>CURRENT_LIST_OF_DOMAINS</h2>
<table class="sme-border">
<tr bgcolor="#D4D0C8"><th>Domain name / HOSTNAME</th><th>Brief description</th><th>Content</th><th>LABEL_NAMESERVERS</th><th>LABEL_POINT</th><th>LABEL_LECERT</th><th>IS_IN_CERT</th><th>CHECK</th></tr>
<tr><td>thereadclan.me.uk</td><td>Primary domain</td><td>Primary</td><td>localhost</td><td></td><td>disabled</td><td>Y</td><td><a href="letsencrypt?page=0&page_stack=&Next=First&Domain=thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE">CHECK</a></td></tr>
<tr bgcolor="#D4D0C8"><td>--> fred.thereadclan.me.uk</td><td></td><td>Self</td><td>localhost</td><td></td><td>disabled</td><td>Y</td><td><a href="letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20fred.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE">CHECK</a></td></tr>
<tr><td>--> ftp.thereadclan.me.uk</td><td></td><td>Self</td><td>localhost</td><td></td><td>disabled</td><td>Y</td><td><a href="letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20ftp.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE">CHECK</a></td></tr>
<tr bgcolor="#D4D0C8"><td>--> mail.thereadclan.me.uk</td><td></td><td>Self</td><td>localhost</td><td></td><td>disabled</td><td>Y</td><td><a href="letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20mail.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE">CHECK</a></td></tr>
<tr><td>--> proxy.thereadclan.me.uk</td><td></td><td>Self</td><td>localhost</td><td></td><td>disabled</td><td>Y</td><td><a href="letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20proxy.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE">CHECK</a></td></tr>
<tr bgcolor="#D4D0C8"><td>--> sme11.thereadclan.me.uk</td><td></td><td>Self</td><td>localhost</td><td></td><td>disabled</td><td>Y</td><td><a href="letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20sme11.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE">CHECK</a></td></tr>
<tr><td>--> wpad.thereadclan.me.uk</td><td></td><td>Self</td><td>localhost</td><td></td><td>disabled</td><td>Y</td><td><a href="letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20wpad.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE">CHECK</a></td></tr>
<tr bgcolor="#D4D0C8"><td>--> www.thereadclan.me.uk</td><td></td><td>Self</td><td>localhost</td><td></td><td>disabled</td><td>Y</td><td><a href="letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20www.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE">CHECK</a></td></tr>
</table>
</form>
<HR class="sme-copyrightbar">
<FONT class="sme-copyright">
SME Server 11.0.0<BR>Copyright 1999-2006 Mitel Corporation<BR>All rights reserved.
<BR>Copyright (c) 2013 - 2021 Koozali Foundation Inc.<BR>
</FONT>
</BODY>
</HTML>

View File

@ -13,21 +13,61 @@
{ {
'Name': 'List', 'Name': 'List',
'route': 'LIST', 'route': 'LIST',
'Header': 'lets_List of Domains', 'Link2': {
'SubHeader': 'lets_FORM_DESCRIPTION', 'Type': 'Link',
'Subheader': 'SERVER_IPS', 'href': 'letsencrypt?page=0&page_stack=&Next=Next&wherenext=CONFIG_PAGE',
Input1: { 'title': 'CONFIG'
},
'Link3': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=Next&wherenext=CHECK_DOMAINS_PAGE',
'title': 'CHECK_ALL_DOMAINS'
},
'Link4': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=Next&wherenext=CHECK_ENABLED_DOMAINS_PAGE',
'title': 'CHECK_ENABLED_DOMAINS'
},
SubHeader2: 'IPs for this Server',
Input4: {
Name: 'InternalIP', Name: 'InternalIP',
Type: 'ReadonlyText', Type: 'ReadonlyText',
Label: 'Internal IP', Label: 'Internal IP',
Value: 'stash("InternalIP")', Value: 'stash("InternalIP")',
}, },
Input2: { Input5: {
Name: 'ObserverIP', Name: 'ExternalIP',
Type: 'ReadonlyText',
Label: 'External Interface IP',
Value: 'stash("ExternalIP")',
},
Input6: {
Name: 'InternetIP',
Type: 'ReadonlyText', Type: 'ReadonlyText',
Label: 'Internet IP', Label: 'Internet IP',
Value: 'stash("InternetIP")', Value: 'stash("InternetIP")',
}, },
SubHeader3 : 'Current certificate details',
Input1: {
Name: 'Issuer',
Type: 'ReadonlyText',
Label: 'Issuer',
Value: 'stash("Issuer")',
},
Input2: {
Name: 'Expiry',
Type: 'ReadonlyText',
Label: 'Expiry',
Value: 'stash("Expiry")',
},
Input3: {
Name: 'NotBefore',
Type: 'ReadonlyText',
Label: 'Not Before',
Value: 'stash("NotBefore")',
},
SubHeader4: 'List of Domains and Hosts',
'Table1': { 'Table1': {
'Type': 'Table', 'Type': 'Table',
'TableControl': 'DomainList', 'TableControl': 'DomainList',
@ -202,12 +242,11 @@
'SubHeader': 'Loop through checking the letsencrypt status for each configured domain', 'SubHeader': 'Loop through checking the letsencrypt status for each configured domain',
'Input1': { 'Input1': {
'Type': 'Textarea', 'Type': 'Textarea',
'Value': '',
'Name': 'AllDomainsCheck', 'Name': 'AllDomainsCheck',
'Label': 'All domains check result', 'Label': 'All domains check result',
'Rows':20, 'Rows':20,
'Readonly':true 'Readonly':true
} },
'Input2': { 'Input2': {
'Type': 'Submit', 'Type': 'Submit',
'Value': 'Back', 'Value': 'Back',
@ -219,17 +258,15 @@
'SubHeader': 'Loop through checking the letsencrypt status for each configured domain wihch is enabled', 'SubHeader': 'Loop through checking the letsencrypt status for each configured domain wihch is enabled',
'Input1': { 'Input1': {
'Type': 'Textarea', 'Type': 'Textarea',
'Value': '',
'Name': 'EnabledDomainsCheck', 'Name': 'EnabledDomainsCheck',
'Label': 'Enabled domains check result', 'Label': 'Enabled domains check result',
'Rows':20 'Rows':20,
'Readonly':true 'Readonly':true
} },
'Input2': { 'Input2': {
'Type': 'Submit', 'Type': 'Submit',
'Value': 'Back', 'Value': 'Back',
} }
} }
]
]
} }

View File

@ -0,0 +1,109 @@
//
// Generated by sm1-html-2-json5 version:0.5 Chameleon version:4.5.4 On Python:3.12.3 at 2024-10-20 12:51:29
//
{
'PackageName': 'letsencrypt-list-1',
'prefix': '',
'MenuHeading': 'Miscellaneous',
'MenuDescription': 'letsencrypt-list-1',
'MenuNavigation': '2000 400',
'firstPanel': 'PARAMS',
'signalEvent': 'smeserver-letsencrypt-list-1-update',
'html': [
{
'Name': 'params',
'route': 'PARAMS',
'Header': 'FORM_TITLE',
'SubHeader': 'CURRENT_LIST_OF_DOMAINS',
'Link1': {
'Type': 'Link',
'href': 'https://wiki.koozali.org/SME_Server:Download',
'title': 'https://wiki.koozali.org/SME_Server:Download'
},
'Paragraph1': 'FORM_DESCRIPTION',
'Paragraph2': 'SERVER_IPS',
'Paragraph3': 'LABEL_INTERNALIP',
'Paragraph4': 'LABEL_IP_FROM_OBSERVER',
'Link2': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=Next&wherenext=CONFIG_PAGE',
'title': 'CONFIG'
},
'Link3': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=Next&wherenext=CHECK_DOMAINS_PAGE',
'title': 'CHECK_ALL_DOMAINS'
},
'Link4': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=Next&wherenext=CHECK_ENABLED_DOMAINS_PAGE',
'title': 'CHECK_ENABLED_DOMAINS'
},
'Paragraph5': '> Issuer: /C=--/ST=----/L=Ottawa/O=XYZ Corporation/OU=Main/CN=sme11.thereadclan.me.uk/emailAddress=admin@thereadclan.me.ukExpiry: 2025-10-03T02:09:03ZNot Before: 2024-10-03T02:09:03Z',
'Table1': {
'Type': 'Table',
'TableControl': 'Table1',
'TopHeadings': [
'Domain name / HOSTNAME',
'Brief description',
'Content',
'LABEL_NAMESERVERS',
'LABEL_POINT',
'LABEL_LECERT',
'IS_IN_CERT',
'CHECK'
],
'Columns': [
'Table1-Domain name / HOSTNAME',
'Table1-Brief description',
'Table1-Content',
'Table1-LABEL_NAMESERVERS',
'Table1-LABEL_POINT',
'Table1-LABEL_LECERT',
'Table1-IS_IN_CERT',
'Table1-CHECK'
]
},
'Link5': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=First&Domain=thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE',
'title': 'CHECK'
},
'Link6': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20fred.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE',
'title': 'CHECK'
},
'Link7': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20ftp.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE',
'title': 'CHECK'
},
'Link8': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20mail.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE',
'title': 'CHECK'
},
'Link9': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20proxy.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE',
'title': 'CHECK'
},
'Link10': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20sme11.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE',
'title': 'CHECK'
},
'Link11': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20wpad.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE',
'title': 'CHECK'
},
'Link12': {
'Type': 'Link',
'href': 'letsencrypt?page=0&page_stack=&Next=First&Domain=--%3E%20www.thereadclan.me.uk&wherenext=UPDATE_ONE_DOMAIN_PAGE',
'title': 'CHECK'
}
}
]
}

View File

@ -150,136 +150,141 @@ def sanitize_text(text):
def extract_data(html): def extract_data(html):
"""Extract paragraphs, inputs, tables, and pre blocks from HTML and organize them in order.""" """Extract paragraphs, inputs, tables, and pre blocks from HTML and organize them in order."""
soup = BeautifulSoup(html, "lxml") soup = BeautifulSoup(html, "lxml")
records = [] records = []
hidden_input_names = ["page", "page_stack", ".id", "csrf_token"] hidden_input_names = ["page", "page_stack", ".id", "csrf_token"]
header_text = None header_text = None
sub_header_text = None sub_header_text = None
# Counter for tables # Counter for tables
table_counter = 0 table_counter = 0
# Extract elements while preserving order # Extract elements while preserving order
for element in soup.find_all( for element in soup.find_all(
["h1", "h2", "p", "pre", "input", "select", "textarea", "button", "table"] ["h1", "h2", "p", "pre", "input", "select", "textarea", "button", "table","a"]
): ):
if element.name == "h1": if element.name == "h1":
header_text = element.get_text(strip=True) header_text = element.get_text(strip=True)
records.append({"Type": "Header", "Text": header_text}) records.append({"Type": "Header", "Text": header_text})
elif element.name == "h2": elif element.name == "h2":
sub_header_text = element.get_text(strip=True) sub_header_text = element.get_text(strip=True)
records.append({"Type": "SubHeader", "Text": sub_header_text}) records.append({"Type": "SubHeader", "Text": sub_header_text})
elif element.name == "p": elif element.name == "p":
text = element.get_text(strip=True) text = element.get_text(strip=True)
if text: # Ignore empty paragraphs if text: # Ignore empty paragraphs
# Sanitise text freom newlines,tabs and escape quotes. # Sanitise text from newlines,tabs and escape quotes.
sanitised_text = sanitize_text(text) sanitised_text = sanitize_text(text)
if sanitised_text == "": if sanitised_text == "":
continue continue
records.append({"Type": "Paragraph", "Text": sanitised_text}) records.append({"Type": "Paragraph", "Text": sanitised_text})
elif element.name == "pre": elif element.name == "pre":
text = element.get_text(strip=True) text = element.get_text(strip=True)
if text: # Ensure non-empty before adding if text: # Ensure non-empty before adding
records.append({"Type": "Preformatted", "Text": text}) records.append({"Type": "Preformatted", "Text": text})
elif element.name == "input": elif element.name == "a":
if ( title = element.get_text(strip=True)
element.get("type") == "hidden" href = element.get("href")
or element.get("name") in hidden_input_names records.append({"Type": "Link", "href": href, "title": title})
):
continue
input_info = { elif element.name == "input":
"Type": element.get("type", "text").capitalize(), if (
"Name": element.get("name"), element.get("type") == "hidden"
"Value": element.get("value", ""), or element.get("name") in hidden_input_names
} ):
label = element.find_next("label") continue
input_info["Label"] = label.get_text(strip=True) if label else None
records.append(input_info)
elif element.name == "select": input_info = {
options = [ "Type": element.get("type", "text").capitalize(),
{"Value": option.get("value"), "Text": option.get_text(strip=True)} "Name": element.get("name"),
for option in element.find_all("option") "Value": element.get("value", ""),
] }
select_info = { label = element.find_next("label")
"Type": "Select", input_info["Label"] = label.get_text(strip=True) if label else None
"Name": element.get("name"), records.append(input_info)
"Options": options,
"Label": element.find_previous("label").get_text(strip=True)
if element.find_previous("label")
else None,
}
records.append(select_info)
elif element.name == "textarea": elif element.name == "select":
textarea_info = { options = [
"Type": "Textarea", {"Value": option.get("value"), "Text": option.get_text(strip=True)}
"Name": element.get("name"), for option in element.find_all("option")
"Value": element.get_text(strip=True), ]
} select_info = {
label = element.find_previous("label") "Type": "Select",
textarea_info["Label"] = label.get_text(strip=True) if label else None "Name": element.get("name"),
records.append(textarea_info) "Options": options,
"Label": element.find_previous("label").get_text(strip=True)
if element.find_previous("label")
else None,
}
records.append(select_info)
elif element.name == "button":
button_info = {
"Type": "Button",
"Name": element.get("name"),
"Value": element.get_text(strip=True),
"Label": element.find_previous("label").get_text(strip=True)
if label
else None,
}
records.append(button_info)
elif element.name == "table" and "sme-border" in element.get("class", []): elif element.name == "textarea":
# Increment the table counter textarea_info = {
table_counter += 1 "Type": "Textarea",
"Name": element.get("name"),
"Value": element.get_text(strip=True),
}
label = element.find_previous("label")
textarea_info["Label"] = label.get_text(strip=True) if label else None
records.append(textarea_info)
# Prepare the TableControl format elif element.name == "button":
table_control = f"Table{table_counter}" # e.g., "Table1", "Table2" button_info = {
top_headings = [] "Type": "Button",
columns = [] "Name": element.get("name"),
"Value": element.get_text(strip=True),
"Label": element.find_previous("label").get_text(strip=True)
if label
else None,
}
records.append(button_info)
# Extract headings from the first row elif element.name == "table" and "sme-border" in element.get("class", []):
first_row = element.find("tr") # Increment the table counter
if first_row: table_counter += 1
for th in first_row.find_all("th"):
top_headings.append(th.get_text(strip=True))
# Extract only the first data row's cell values for Columns # Prepare the TableControl format
data_rows = element.find_all("tr")[1:] # Skip the heading row table_control = f"Table{table_counter}" # e.g., "Table1", "Table2"
if data_rows: top_headings = []
first_data_row = data_rows[0] # Take the first row of data columns = []
for idx, th in enumerate(first_row.find_all("th")):
td = (
first_data_row.find_all("td")[idx]
if idx < len(first_data_row.find_all("td"))
else None
)
if td:
columns.append(
f"{table_control}-{th.get_text(strip=True)}"
) # Format as desired
records.append( # Extract headings from the first row
{ first_row = element.find("tr")
"Type": "Table", if first_row:
"TableControl": table_control, for th in first_row.find_all("th"):
"TopHeadings": top_headings, top_headings.append(th.get_text(strip=True))
"Columns": columns,
}
)
return records, header_text, sub_header_text # Extract only the first data row's cell values for Columns
data_rows = element.find_all("tr")[1:] # Skip the heading row
if data_rows:
first_data_row = data_rows[0] # Take the first row of data
for idx, th in enumerate(first_row.find_all("th")):
td = (
first_data_row.find_all("td")[idx]
if idx < len(first_data_row.find_all("td"))
else None
)
if td:
columns.append(
f"{table_control}-{th.get_text(strip=True)}"
) # Format as desired
records.append(
{
"Type": "Table",
"TableControl": table_control,
"TopHeadings": top_headings,
"Columns": columns,
}
)
return records, header_text, sub_header_text
def insert_spaces_before_caps(text): def insert_spaces_before_caps(text):
@ -298,6 +303,7 @@ def save_to_json5(data, output_filename, package_name, header, sub_header,strVer
preformatted_count = 1 preformatted_count = 1
input_count = 1 input_count = 1
table_count = 1 table_count = 1
link_count = 1
for record in data: for record in data:
if record["Type"] == "Paragraph": if record["Type"] == "Paragraph":
@ -308,6 +314,14 @@ def save_to_json5(data, output_filename, package_name, header, sub_header,strVer
{f"Preformatted{preformatted_count}": record["Text"]} {f"Preformatted{preformatted_count}": record["Text"]}
) )
preformatted_count += 1 preformatted_count += 1
elif record["Type"] == "Link":
link_structure = {
"Type": record["Type"],
"href": record["href"],
"title": record["title"]
}
structured_html.append({f"Link{link_count}": link_structure})
link_count += 1
elif record["Type"] == "Header" or record["Type"] == "SubHeader": elif record["Type"] == "Header" or record["Type"] == "SubHeader":
continue # Skip headers for input count continue # Skip headers for input count
elif record["Type"] == "Table": elif record["Type"] == "Table":
@ -432,4 +446,4 @@ def main():
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -399,6 +399,35 @@ def convert_lex_to_dict(pairs_string):
formatted_dict = [{"id": key, "text": value} for key, value in data_dict.items()] formatted_dict = [{"id": key, "text": value} for key, value in data_dict.items()]
return formatted_dict return formatted_dict
def extract_input_fields(json_data, value_type):
result = {}
# Pattern to identify and strip the specified value type and surrounding brackets
pattern = re.compile(rf"{value_type}\((.*?)\)")
# Iterate over each panel in the 'html' array
for panel in json_data['html']:
panel_name = panel['route']
# Initialize an empty list for each panel
result[panel_name] = []
# Iterate over each item in the panel
for key, value in panel.items():
if key.startswith('Input') and isinstance(value, dict):
if value.get('Type').lower() in ['readonlytext', 'text']:
input_value = value.get('Value', '')
# Match and extract the value without the value_type and parentheses
match = pattern.search(input_value)
if match:
# Extract the inner content of the matching pattern
clean_value = match.group(1)
# Take out any double quotes
clean_value = clean_value.replace('"','')
# Add the clean value to the list for the current panel
result[panel_name].append(clean_value)
# Note: Empty lists are not removed, so all panels will be present in the result
return result
if __name__ == "__main__": if __name__ == "__main__":
@ -526,16 +555,16 @@ if __name__ == "__main__":
# print(strVersion,tablecontrols,routes) # print(strVersion,tablecontrols,routes)
# Generate controller file # Generate controller file
dbfields = [] #extract_input_fields(json5_dict, 'db') # Params which correspond to Db fields - TBD
try: try:
controller_template = PageTemplateFile( controller_template = PageTemplateFile(
"Templates/controller.pm.tem", CHAMELEON_DEBUG="true" "Templates/controller.pm.tem", CHAMELEON_DEBUG="true"
) )
dbentries = get_db_fields() # Params which correspond to Db fields
try: try:
controller_perl = controller_template.render( controller_perl = controller_template.render(
version=strVersion, version=strVersion,
tablecontrols=tablecontrols, tablecontrols=tablecontrols,
dbentries=dbentries, dbfields=dbfields,
**json5_dict, **json5_dict,
panels=routes, panels=routes,
lcPackageName=json5_dict["PackageName"].lower(), lcPackageName=json5_dict["PackageName"].lower(),
@ -551,9 +580,13 @@ if __name__ == "__main__":
# Generate Custom controller file # Generate Custom controller file
try: try:
custom_controller_template = PageTemplateFile("Templates/custom.pm.tem") custom_controller_template = PageTemplateFile("Templates/custom.pm.tem")
fields = extract_input_fields(json5_dict, 'stash') # Params which correspond to singleton values
#flatfields = flatten_hash_of_lists(fields)
#print(fields)
#quit(0)
try: try:
custom_controller_perl = custom_controller_template.render( custom_controller_perl = custom_controller_template.render(
version=strVersion, panels=routes, tablecontrols=tablecontrols version=strVersion, panels=routes, tablecontrols=tablecontrols, fields=fields, dbfields=dbfields
) )
# We must be careful to not overwrite the custom file if the developer has already written to it - TBD # We must be careful to not overwrite the custom file if the developer has already written to it - TBD
with open(custom_controller_file, "w") as file: with open(custom_controller_file, "w") as file:

View File

@ -1,10 +0,0 @@
import koji
mytag = "mytag"
session = koji.ClientSession("http://koji.koozali.org/kojihub")
try:
repo_info = session.getRepo(mytag, koji.REPO_STATES["READY"], dist=True)
if not repo_info:
print(f"There is no active dist repo for {mytag}")
except koji.GenericError:
print(f"Tag {mytag} doesn't exist")