Community discussions

MikroTik App
 
tabraham
newbie
Topic Author
Posts: 27
Joined: Wed Feb 08, 2017 10:18 pm
Location: Germany
Contact:

Nested DO ON-ERROR scripts

Tue May 09, 2023 1:30 am

Hello everyone. I am trying to implement a nested :do {} on-error{} script. The idea is to have a mother do loop to check if the script fails or not and then inside the child do and on-error loop is used to prevent the script action timeout error while signing the certificates.

The problem is if something fails inside the child do loop, it is not caught by its own on-error section but rather it goes directly to the on-error section of the mother. can anyone help me out to solve the issue?

One possible way to solve the issue is to increase the script action timeout so that the certificates gets signed or may be some special command which will ensure that the certificates are signed regardless of the timeout.

I have posted the script for your reproduction. Thanks a lot for your time and help.
{; # BeginOfScript

######################################################################
###Identity: Generate SSH Keys And Certificates Script
###Author: Tahasanul Abraham
###Created: Apr 18 2023
###Last Edited: May 05 2023
###Compatible Versions: ROS 7.x
###Tested on: ROS 7.0 - 7.9
######################################################################

:do {
	:local ServerName ("XXXXXXXX")
	:local CertificateValidityDays (18250)
	:local CertificatePassword ("XXXXXXX")
	:local KeySize (8192)
	
	/ip/ssh/ set allow-none-crypto=no always-allow-password-login=yes strong-crypto=yes forwarding-enabled=remote host-key-size=$KeySize

	:do {
		/ip/ssh/ regenerate-host-key
	} on-error={
		:log error ("** Generate SSH Keys And Certificates Script ** Waiting for $ServerName_SSH key generation")
	}; # EndDo
	
	/ip/ssh/ export-host-key key-file-prefix="$ServerName_SSH"
	
	/certificate/ add name="$ServerName_CA" common-name="$ServerName_CA" days-valid=$CertificateValidityDays key-size=$KeySize key-usage=crl-sign,key-cert-sign
	/certificate/ add name="$ServerName_Server" common-name="$ServerName_Server" days-valid=$CertificateValidityDays key-size=$KeySize key-usage=digital-signature,key-encipherment,tls-server
	/certificate/ add name="$ServerName_Client" common-name="$ServerName_Client" days-valid=$CertificateValidityDays key-size=$KeySize key-usage=tls-client

	:do {	
		/certificate/ sign "$ServerName_CA" name="$ServerName_CA-Certificate"
	} on-error={
		:log error ("** Generate SSH Keys And Certificates Script ** Waiting for $ServerName_CA-Certificate signing")
	}; # EndDo

	:do {	
		/certificate/ sign "$ServerName_Server" name="$ServerName_Server-Certificate" ca="$ServerName_CA-Certificate"
	} on-error={
		:log error ("** Generate SSH Keys And Certificates Script ** Waiting for $ServerName_Server-Certificate signing")
	}; # EndDo

	:do {	
		/certificate/ sign "$ServerName_Client" name="$ServerName_Client-Certificate" ca="$ServerName_CA-Certificate"
	} on-error={
		:log error ("** Generate SSH Keys And Certificates Script ** Waiting for $ServerName_Client-Certificate signing")
	}; # EndDo


	/certificate/ export-certificate "$ServerName_CA-Certificate" export-passphrase=$CertificatePassword file-name="$ServerName_CA-Certificate"
	/certificate/ export-certificate "$ServerName_Client-Certificate" export-passphrase=$CertificatePassword file-name="$ServerName_Client-Certificate"	
	
	:log warning ("** Generate SSH Keys And Certificates Script ** Completed")
} on-error={
	:log error ("** Generate SSH Keys And Certificates Script ** Failed")
}; # EndDo

}; #EndOfScript
Last edited by tabraham on Tue May 09, 2023 11:36 am, edited 1 time in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 3:41 am

In my opinion, using on-horror is a crap way to write scripts.
But obviously it's my personal opinion, on the other hand I can't help it if things aren't done right.


Also, still using 6.2 on 2023, just one version of decades ago, denotes a few things, which I don't even want to write about, they're so obvious...
Created: Apr 18 2023
[…]
Tested on: ROS 6.2

FYI:
Is needed 3 minutes for just the 8k SSH key on "CCR 2116"...
Is needed 25 minutes for just the 8k SSH key on "hEX S"...
I don't even want to imagine the time it takes in an older device with 6.2 just for the 8k SSH key...
 
tabraham
newbie
Topic Author
Posts: 27
Joined: Wed Feb 08, 2017 10:18 pm
Location: Germany
Contact:

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 10:48 am

I am sorry I did not get you properly? Is it you using 6.2 or you are saying I am? I am using 7.9 and CHR on could. The script is supposed to run there.

I also checked the time required for the keys to be generated and they are close to a minute only.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 10:57 am

Is it you using 6.2 or you are saying I am?
YOU wrote that you tested the script from version 6.2...
Don't you read what you post?

I am using 7.9 and CHR on could. The script is supposed to run there.
And where did you write it on first post?

I also checked the time required for the keys to be generated and they are close to a minute only.
One more reason why on-error is not necessary, just write the script well, if the used machines are so powerful...


One more thing... If you write "Compatible Versions: ROS 6.x" it must be true, you shouldn't use syntax that only works on RouterOS v7.x
So how did you test it on v6? "Tested on: ROS 6.2 - 7.9"
The comments alone are full of mistakes, without considering the mess rest... I would never put (my) name on it...
 
tabraham
newbie
Topic Author
Posts: 27
Joined: Wed Feb 08, 2017 10:18 pm
Location: Germany
Contact:

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 11:09 am

YOU wrote that you tested the script from version 6.2...
Don't you read what you post?
I see the script is in development mode still and thus the default header. When you said about wrong scripting, I thought the main content of the script.

One more reason why on-error is not necessary, just write the script well, if the used machines are so powerful...
Yes the machine is powerful but the use of on-error is mainly a failsafe protection since the intention of the script is not to run only in 7.9 but also in older versions from 6.2 and onwards

One more thing... If you write "Compatible Versions: ROS 6.x" it must be true, you shouldn't use syntax that only works on RouterOS v7.x
So how did you test it on v6? "Tested on: ROS 6.2 - 7.9"
So far I have tested the script to be working till 6.8 and there since the machine was not so powerful, the nested on-error issue was found due to more time to generate the key and thus the post.

The comments alone are full of mistakes, without considering the mess rest... I would never put (my) name on it...
Yes I agree that the comments are misleading but the post was to seek help for the main content of the script but not the comment. As a DevOP we both know that it is a common practice to update the comments at then end of everything (during the testing and QA)
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 11:30 am

When you said about wrong scripting, I thought the main content of the script.
You thought correctly, and on that I have nothing more to add...

the intention of the script is not to run only in 7.9 but also in older versions from 6.2 and onwards
Off to a bad start...
Already so it is not compatible with v6...
And I repeat that it is better that I do not comment on the desire to use it on such old versions full of hacks
already known by everyone (except those who use them, apparently) worldwide....
 
tabraham
newbie
Topic Author
Posts: 27
Joined: Wed Feb 08, 2017 10:18 pm
Location: Germany
Contact:

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 11:36 am

Already so it is not compatible with v6...
And I repeat that it is better that I do not comment on the desire to use it on such old versions full of hacks
already known by everyone (except those who use them, apparently) worldwide....
Hahaha true... then I guess I will stick to 7.x only but then also the nested on-error thing stays... what can be done for that? any help would be appriciated
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 11:54 am

here, now let's talk

let me the time to rewrite..........
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 12:15 pm

Do something like this, and fix all the point whre comments are present.

untested example code

# what can go wrong: the input parameter are not sanitized and some value for server name (or export pass) have one or some forbidden characters
:local ScriptName  "thisscript"
:local HostKeySize 8192
:local ServerName  "XXXXXXXX"
:local DaysValid   18250
:local KeySize     8192
:local ExportPass  "XXXXXXX"

/ip ssh
set allow-none-crypto=no always-allow-password-login=yes strong-crypto=yes forwarding-enabled=remote host-key-size=$HostKeySize

# what can go wrong: on slow machines the 2 minutes script timeout
:do { regenerate-host-key } on-error={ :log error ("$ScriptName: regenerate-host-key timeout or other error") }

# what can go wrong: the file already exist. Before export, delete the files that can have the same name...
/file
export-host-key key-file-prefix="$ServerName_SSH"

# what can go wrong: the name is already used. Before add delete the cert or the template with the same name,
# or not create the template because something with same name already exist...
/certificate
add name="$ServerName_CA"     common-name="$ServerName_CA"     days-valid=$DaysValid key-size=$KeySize key-usage=crl-sign,key-cert-sign
add name="$ServerName_Server" common-name="$ServerName_Server" days-valid=$DaysValid key-size=$KeySize key-usage=digital-signature,key-encipherment,tls-server
add name="$ServerName_Client" common-name="$ServerName_Client" days-valid=$DaysValid key-size=$KeySize key-usage=tls-client

# what can go wrong: the destination name is already used. Before sign delete the template or the cert with the same name,
# or not sign the template because cert already exist...
# what can go wrong: must be checked before the sign if the template exist
# what can go wrong: on slow machines the 2 minutes script timeout
:do { sign "$ServerName_CA"     name="$ServerName_CA-Certificate"                                     } on-error={ :log error ("$ScriptName: sign $ServerName_CA timeout or other error") }
:do { sign "$ServerName_Server" name="$ServerName_Server-Certificate" ca="$ServerName_CA-Certificate" } on-error={ :log error ("$ScriptName: sign $ServerName_Server timeout or other error") }
:do { sign "$ServerName_Client" name="$ServerName_Client-Certificate" ca="$ServerName_CA-Certificate" } on-error={ :log error ("$ScriptName: sign $ServerName_Client timeout or other error") }

# what can go wrong: the file already exist. Before export, delete the files that can have the same name...
# what can go wrong: must be checked before the export if the certificate exist
export-certificate "$ServerName_CA-Certificate"     export-passphrase=$ExportPass file-name="$ServerName_CA-Certificate"
export-certificate "$ServerName_Server-Certificate" export-passphrase=$ExportPass file-name="$ServerName_Server-Certificate" 
export-certificate "$ServerName_Client-Certificate" export-passphrase=$ExportPass file-name="$ServerName_Client-Certificate" 
 
tabraham
newbie
Topic Author
Posts: 27
Joined: Wed Feb 08, 2017 10:18 pm
Location: Germany
Contact:

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 1:31 pm

Thanks but i got some questions.
  • What is the default timeout? 2 minutes? As far as I have checked its about 1 minute. Is it possible to change the timeout?
  • Is it possible to have the whole script inside another mother :DO loop?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 3:55 pm

I'm not the MikroTik programmer who made some choices I DO NOT agree with.
The default timeout "seems" to vary, more is loaded the CPU, the slower it goes...
The 3 minute and 25 minute tests are real, I haven't written it just for write something.
Since the RouterBOARD doesn't have the RTC I think they "calculate" the time with approximation starting from a known or estimated date.


>>>Is it possible to have the whole script inside another mother :DO loop?

Actually I do not use main script ":do" or loops at all, but I do not see any reason for not use :do if really is needed.

I prefer to prevent errors, instead of dealing with them when they happen....
Of course it's sometimes impossible to prevent them all, but I'd rather control than be controlled...
 
optio
Long time Member
Long time Member
Posts: 655
Joined: Mon Dec 26, 2022 2:57 pm

Re: Nested DO ON-ERROR scripts

Tue May 09, 2023 8:10 pm

  • Is it possible to have the whole script inside another mother :DO loop?
Usually you need to expect an error to use
:do {} on-error {}
so that you can handle that error which will not break code execution (same as try-catch statement in some programming languages). It is better to write more strict code as rextended mentioned above with conditions to avoid errors in first place if you have code flow that needs to be mandatory, since having just logging in on-error block will not describe which error is actually occurred because there is no some error variable (afaik) in that block which will contain error message (but it would be nice that scripting engine provides that). When you have optional code execution in flow then
:do {} on-error {}
makes sense.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Nested DO ON-ERROR scripts

Wed May 10, 2023 10:39 am

One pratical example of expected error, because RouterOS can not handle the problem, is with :resolve...
I'm forced to use on-horror when I try to resolve one domain, because RouterOS instead to reply with NXDOMAIN cause one error that block the script...
 
User avatar
adrianTNT
Member Candidate
Member Candidate
Posts: 113
Joined: Sun Mar 10, 2019 4:27 am
Location: The Internet
Contact:

Re: Nested DO ON-ERROR scripts

Mon Feb 05, 2024 10:50 pm

I have a similar problem, did I get it right, you cannot have on-error={} inside loops ?
I have this below code where I am trying to resolve name to IP inside a loop, and script breaks if domain name is invalid, if I add on-error it breaks with "expected end of command".

Is the only option to use on-error outside of a loop ?
# define variables
:local list
:local comment
:local newip
:local oldip

# Loop through each entry in the address list.
:foreach i in=[/ip firewall address-list find] do={

    # Get the first five characters of the list name
    #:set list [:pick [/ip firewall address-list get $i list] 0 5]
    :set list [/ip firewall address-list get $i list]

    # If they're 'adr_ip_', then we've got a match - process it
    :if ($list = "adr_ip_list") do={
    
        # Get the comment for this address list item (this is the host name to use)
        :set comment [/ip firewall address-list get $i comment]
        :set oldip [/ip firewall address-list get $i address]
    
        # Resolve it and set the address list entry accordingly.
        : if ($newip != $oldip) do={
            :set newip [:resolve $comment]
            /ip firewall address-list set $i address=$newip
        } 
        # if I enable this here, I get error "expected end of command"  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< HERE <<<<<<<<<<<<
        # on-error={};

        :put $comment;
        :put $newip;
    }
}
 
optio
Long time Member
Long time Member
Posts: 655
Joined: Mon Dec 26, 2022 2:57 pm

Re: Nested DO ON-ERROR scripts

Mon Feb 05, 2024 10:59 pm

Did you put code in :do { } block before on-error={}? I don't see that in your commented code and that is probably causing syntax error.
 
User avatar
adrianTNT
Member Candidate
Member Candidate
Posts: 113
Joined: Sun Mar 10, 2019 4:27 am
Location: The Internet
Contact:

Re: Nested DO ON-ERROR scripts

Mon Feb 05, 2024 11:06 pm

I tried it at the end of my code where it is commented, without comments, that part would be:
        : if ($newip != $oldip) do={
            :set newip [:resolve $comment]
            /ip firewall address-list set $i address=$newip
        } on-error={};
Like this but all that in it's parent loop, should that work ?
I have another topic on this: viewtopic.php?p=1053832#p1053832
 
optio
Long time Member
Long time Member
Posts: 655
Joined: Mon Dec 26, 2022 2:57 pm

Re: Nested DO ON-ERROR scripts

Mon Feb 05, 2024 11:11 pm

No, on-error needs its own block with code where you can expect error:
:if ($newip != $oldip) do={
  :do {
    :set newip [:resolve $comment]
    /ip firewall address-list set $i address=$newip
  } on-error={
# do error handling or log here if needed...
  }
}
 
User avatar
adrianTNT
Member Candidate
Member Candidate
Posts: 113
Joined: Sun Mar 10, 2019 4:27 am
Location: The Internet
Contact:

Re: Nested DO ON-ERROR scripts

Mon Feb 05, 2024 11:57 pm

No, on-error needs its own block with code where you can expect error:
Awesome, that worked 8)
Thank you.

// note to self: if inside an : if (...) do={...}, on-error{} needs it's own separate :do{...} block.

Who is online

Users browsing this forum: No registered users and 16 guests