aboutsummaryrefslogtreecommitdiffstats
path: root/mod
diff options
context:
space:
mode:
Diffstat (limited to 'mod')
-rw-r--r--mod/bridge-port-to.rsc14
-rw-r--r--mod/bridge-port-vlan.rsc14
-rw-r--r--mod/inspectvar.rsc34
-rw-r--r--mod/ipcalc.rsc14
-rw-r--r--mod/notification-email.rsc132
-rw-r--r--mod/notification-gotify.rsc139
-rw-r--r--mod/notification-matrix.rsc63
-rw-r--r--mod/notification-ntfy.rsc49
-rw-r--r--mod/notification-telegram.rsc94
-rw-r--r--mod/scriptrunonce.rsc46
-rw-r--r--mod/ssh-keys-import.rsc39
11 files changed, 456 insertions, 182 deletions
diff --git a/mod/bridge-port-to.rsc b/mod/bridge-port-to.rsc
index 7dae679..93eedce 100644
--- a/mod/bridge-port-to.rsc
+++ b/mod/bridge-port-to.rsc
@@ -1,16 +1,16 @@
#!rsc by RouterOS
# RouterOS script: mod/bridge-port-to
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.14
+# requires RouterOS, version=7.15
#
# reset bridge ports to default bridge
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/bridge-port-to.md
+# https://rsc.eworm.de/doc/mod/bridge-port-to.md
:global BridgePortTo;
-:set BridgePortTo do={
+:set BridgePortTo do={ :onerror Err {
:local BridgePortTo [ :tostr $1 ];
:global IfThenElse;
@@ -65,4 +65,6 @@
$LogPrint info $0 ("Re-enabling interfaces...");
/interface/ethernet/enable $InterfaceReEnable;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
diff --git a/mod/bridge-port-vlan.rsc b/mod/bridge-port-vlan.rsc
index c9f55ae..6deee99 100644
--- a/mod/bridge-port-vlan.rsc
+++ b/mod/bridge-port-vlan.rsc
@@ -1,16 +1,16 @@
#!rsc by RouterOS
# RouterOS script: mod/bridge-port-vlan
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.14
+# requires RouterOS, version=7.15
#
# manage VLANs on bridge ports
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/bridge-port-vlan.md
+# https://rsc.eworm.de/doc/mod/bridge-port-vlan.md
:global BridgePortVlan;
-:global BridgePortVlan do={
+:global BridgePortVlan do={ :onerror Err {
:local ConfigTo [ :tostr $1 ];
:global IfThenElse;
@@ -74,4 +74,6 @@
$LogPrint info $0 ("Re-enabling interfaces...");
/interface/ethernet/enable $InterfaceReEnable;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
diff --git a/mod/inspectvar.rsc b/mod/inspectvar.rsc
index 73205b2..fc1b366 100644
--- a/mod/inspectvar.rsc
+++ b/mod/inspectvar.rsc
@@ -1,28 +1,31 @@
#!rsc by RouterOS
# RouterOS script: mod/inspectvar
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.14
+# requires RouterOS, version=7.15
#
# inspect variables
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/inspectvar.md
+# https://rsc.eworm.de/doc/mod/inspectvar.md
:global InspectVar;
:global InspectVarReturn;
# inspect variable and print on terminal
-:set InspectVar do={
+:set InspectVar do={ :onerror Err {
:global InspectVarReturn;
:put [ :tocrlf [ $InspectVarReturn $1 ] ];
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# inspect variable and return formatted string
:set InspectVarReturn do={
:local Input $1;
:local Level (0 + [ :tonum $2 ]);
+ :global CharacterReplace;
:global IfThenElse;
:global InspectVarReturn;
@@ -31,14 +34,13 @@
:local Value [ :tostr $2 ];
:local Level [ :tonum $3 ];
- :local Indent "";
- :for I from=1 to=$Level step=1 do={
- :set Indent ($Indent . " ");
- }
- :return ($Indent . "-" . $Prefix . "-> " . $Value);
+ :global CharacterMultiply;
+
+ :return ([ $CharacterMultiply " " $Level ] . "-" . $Prefix . "-> " . $Value);
}
:local TypeOf [ :typeof $Input ];
+ :local Len [ :len $Input ];
:local Return [ $IndentReturn "type" $TypeOf $Level ];
:if ($TypeOf = "array") do={
@@ -48,6 +50,16 @@
[ $InspectVarReturn $Value ($Level + 2) ]);
}
} else={
+ :if ($TypeOf = "str") do={
+ :set $Return ($Return . "\n" . \
+ [ $IndentReturn "len" $Len $Level ]);
+ :if ([ :typeof [ :find $Input ("\r") ] ] = "num") do={
+ :set Input [ $CharacterReplace $Input ("\r") "" ];
+ }
+ :if ([ :typeof [ :find $Input ("\n") ] ] = "num") do={
+ :set Input [ $CharacterReplace $Input ("\n") " " ];
+ }
+ }
:if ($TypeOf != "nothing") do={
:set $Return ($Return . "\n" . \
[ $IndentReturn "value" [ $IfThenElse ([ :len $Input ] > 80) \
diff --git a/mod/ipcalc.rsc b/mod/ipcalc.rsc
index 003bdc3..eacff6d 100644
--- a/mod/ipcalc.rsc
+++ b/mod/ipcalc.rsc
@@ -1,18 +1,18 @@
#!rsc by RouterOS
# RouterOS script: mod/ipcalc
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.14
+# requires RouterOS, version=7.15
#
# ip address calculation
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/ipcalc.md
+# https://rsc.eworm.de/doc/mod/ipcalc.md
:global IPCalc;
:global IPCalcReturn;
# print netmask, network, min host, max host and broadcast
-:set IPCalc do={
+:set IPCalc do={ :onerror Err {
:local Input [ :tostr $1 ];
:global FormatLine;
@@ -27,7 +27,9 @@
[ $FormatLine "HostMin" ($Values->"hostmin") ] . "\n" . \
[ $FormatLine "HostMax" ($Values->"hostmax") ] . "\n" . \
[ $FormatLine "Broadcast" ($Values->"broadcast") ]) ];
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# calculate and return netmask, network, min host, max host and broadcast
:set IPCalcReturn do={
diff --git a/mod/notification-email.rsc b/mod/notification-email.rsc
index 3d62ddf..ad9762a 100644
--- a/mod/notification-email.rsc
+++ b/mod/notification-email.rsc
@@ -1,12 +1,13 @@
#!rsc by RouterOS
# RouterOS script: mod/notification-email
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.14
+# requires RouterOS, version=7.15
+# requires device-mode, email, scheduler
#
# send notifications via e-mail
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/notification-email.md
+# https://rsc.eworm.de/doc/mod/notification-email.md
:global EMailGenerateFrom;
:global FlushEmailQueue;
@@ -34,20 +35,39 @@
}
# flush e-mail queue
-:set FlushEmailQueue do={
+:set FlushEmailQueue do={ :onerror Err {
:global EmailQueue;
:global EitherOr;
:global EMailGenerateFrom;
+ :global FileExists;
:global IsDNSResolving;
:global IsTimeSync;
:global LogPrint;
+ :global RmFile;
:local AllDone true;
:local QueueLen [ :len $EmailQueue ];
:local Scheduler [ /system/scheduler/find where name="_FlushEmailQueue" ];
- :if ([ :len $Scheduler ] > 0 && [ /system/scheduler/get $Scheduler interval ] < 1m) do={
+ :if ([ :len $Scheduler ] > 0 && $QueueLen = 0) do={
+ $LogPrint warning $0 ("Flushing E-Mail messages from scheduler, but queue is empty.");
+ /system/scheduler/remove $Scheduler;
+ :return false;
+ }
+
+ :if ($QueueLen = 0) do={
+ :return true;
+ }
+
+ :if ([ :len $Scheduler ] < 0) do={
+ /system/scheduler/add name="_FlushEmailQueue" interval=1m start-time=startup \
+ comment="Doing initial checks..." on-event=(":global FlushEmailQueue; \$FlushEmailQueue;");
+ :set Scheduler [ /system/scheduler/find where name="_FlushEmailQueue" ];
+ }
+
+ :local SchedVal [ /system/scheduler/get $Scheduler ];
+ :if (($SchedVal->"interval") < 1m) do={
/system/scheduler/set interval=1m comment="Doing initial checks..." $Scheduler;
}
@@ -67,53 +87,64 @@
:return false;
}
- :if ([ :len $Scheduler ] > 0 && $QueueLen = 0) do={
- $LogPrint warning $0 ("Flushing E-Mail messages from scheduler, but queue is empty.");
- }
-
- /system/scheduler/set interval=([ $EitherOr $QueueLen 1 ] . "m") comment="Sending..." $Scheduler;
+ /system/scheduler/set interval=($QueueLen . "m") comment="Sending..." $Scheduler;
:foreach Id,Message in=$EmailQueue do={
:if ([ :typeof $Message ] = "array" ) do={
- :local Attach ({});
:while ([ /tool/e-mail/get last-status ] = "in-progress") do={ :delay 1s; }
- :foreach File in=[ :toarray [ $EitherOr ($Message->"attach") "" ] ] do={
- :if ([ :len [ /file/find where name=$File ] ] = 1) do={
- :set Attach ($Attach, $File);
- } else={
- $LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach.");
+ :onerror Err {
+ :local Attach ({});
+ :foreach File in=[ :toarray [ $EitherOr ($Message->"attach") "" ] ] do={
+ :if ([ $FileExists $File ] = true) do={
+ :set Attach ($Attach, $File);
+ } else={
+ $LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach.");
+ }
}
- }
- /tool/e-mail/send from=[ $EMailGenerateFrom ] to=($Message->"to") cc=($Message->"cc") \
- subject=($Message->"subject") body=($Message->"body") file=$Attach;
- :local Wait true;
- :do {
- :delay 1s;
- :local Status [ /tool/e-mail/get last-status ];
- :if ($Status = "succeeded") do={
- :set ($EmailQueue->$Id);
- :set Wait false;
- :if (($Message->"remove-attach") = true) do={
- :foreach File in=$Attach do={
- /file/remove $File;
+ /tool/e-mail/send from=[ $EMailGenerateFrom ] to=($Message->"to") cc=($Message->"cc") \
+ subject=($Message->"subject") body=($Message->"body") file=$Attach;
+ :local Wait true;
+ :do {
+ :delay 1s;
+ :local Status [ /tool/e-mail/get last-status ];
+ :if ($Status = "succeeded") do={
+ :set ($EmailQueue->$Id);
+ :set Wait false;
+ :if (($Message->"remove-attach") = true) do={
+ :foreach File in=$Attach do={
+ $RmFile $File;
+ }
}
}
- }
- :if ($Status = "failed") do={
- :set AllDone false;
- :set Wait false;
- }
- } while=($Wait = true);
+ :if ($Status = "failed") do={
+ :set AllDone false;
+ :set Wait false;
+ }
+ } while=($Wait = true);
+ } do={
+ $LogPrint warning $0 ("Sending queued mail failed: " . $Err);
+ :set AllDone false;
+ }
}
}
:if ($AllDone = true && $QueueLen = [ :len $EmailQueue ]) do={
/system/scheduler/remove $Scheduler;
:set EmailQueue;
- } else={
- /system/scheduler/set interval=1m comment="Waiting for retry..." $Scheduler;
+ :return true;
}
-}
+
+ :if ([ :len [ /system/scheduler/find where name="_FlushEmailQueue" ] ] = 0 && \
+ [ :typeof $EmailQueue ] = "nothing") do={
+ $LogPrint info $0 ("Queue was purged? Exiting.");
+ :return false;
+ }
+
+ /system/scheduler/set interval=(($SchedVal->"run-count") . "m") \
+ comment="Waiting for retry..." $Scheduler;
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# generate filter for log-forward
:set LogForwardFilterLogForwarding do={
@@ -152,6 +183,7 @@
:global IfThenElse;
:global NotificationEMailSignature;
:global NotificationEMailSubject;
+ :global SymbolForNotification;
:local To [ $EitherOr ($EmailGeneralToOverride->($Notification->"origin")) $EmailGeneralTo ];
:local Cc [ $EitherOr ($EmailGeneralCcOverride->($Notification->"origin")) $EmailGeneralCc ];
@@ -164,13 +196,23 @@
:if ([ :typeof $EmailQueue ] = "nothing") do={
:set EmailQueue ({});
}
+ :local Truncated false;
+ :local Body ($Notification->"message");
+ :if ([ :len $Body ] > 62000) do={
+ :set Body ([ :pick $Body 0 62000 ] . "...");
+ :set Truncated true;
+ }
:local Signature [ $EitherOr [ $NotificationEMailSignature ] [ /system/note/get note ] ];
+ :set Body ($Body . "\n" . \
+ [ $IfThenElse ([ :len ($Notification->"link") ] > 0) \
+ ("\n" . [ $SymbolForNotification "link" ] . ($Notification->"link")) ] . \
+ [ $IfThenElse ($Truncated = true) ("\n" . [ $SymbolForNotification "scissors" ] . \
+ "The message was too long and has been truncated!") ] . \
+ [ $IfThenElse ([ :len $Signature ] > 0) ("\n-- \n" . $Signature) "" ]);
:set ($EmailQueue->[ :len $EmailQueue ]) {
to=$To; cc=$Cc;
subject=[ $NotificationEMailSubject ($Notification->"subject") ];
- body=(($Notification->"message") . \
- [ $IfThenElse ([ :len ($Notification->"link") ] > 0) ("\n\n" . ($Notification->"link")) "" ] . \
- [ $IfThenElse ([ :len $Signature ] > 0) ("\n-- \n" . $Signature) "" ]); \
+ body=$Body; \
attach=($Notification->"attach"); remove-attach=($Notification->"remove-attach") };
:if ([ :len [ /system/scheduler/find where name="_FlushEmailQueue" ] ] = 0) do={
/system/scheduler/add name="_FlushEmailQueue" interval=1s start-time=startup \
@@ -224,11 +266,13 @@
}
# send notification via e-mail - expects at least two string arguments
-:set SendEMail do={
+:set SendEMail do={ :onerror Err {
:global SendEMail2;
$SendEMail2 ({ origin=$0; subject=$1; message=$2; link=$3 });
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via e-mail - expects one array argument
:set SendEMail2 do={
diff --git a/mod/notification-gotify.rsc b/mod/notification-gotify.rsc
new file mode 100644
index 0000000..d8eafbe
--- /dev/null
+++ b/mod/notification-gotify.rsc
@@ -0,0 +1,139 @@
+#!rsc by RouterOS
+# RouterOS script: mod/notification-gotify
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# Leonardo David Monteiro <leo@cub3.xyz>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.15
+# requires device-mode, fetch, scheduler
+#
+# send notifications via Gotify (gotify.net)
+# https://rsc.eworm.de/doc/mod/notification-gotify.md
+
+:global FlushGotifyQueue;
+:global NotificationFunctions;
+:global PurgeGotifyQueue;
+:global SendGotify;
+:global SendGotify2;
+
+# flush Gotify queue
+:set FlushGotifyQueue do={ :onerror Err {
+ :global GotifyQueue;
+
+ :global IsFullyConnected;
+ :global LogPrint;
+
+ :if ([ $IsFullyConnected ] = false) do={
+ $LogPrint debug $0 ("System is not fully connected, not flushing.");
+ :return false;
+ }
+
+ :local AllDone true;
+ :local QueueLen [ :len $GotifyQueue ];
+
+ :if ([ :len [ /system/scheduler/find where name="_FlushGotifyQueue" ] ] > 0 && $QueueLen = 0) do={
+ $LogPrint warning $0 ("Flushing Gotify messages from scheduler, but queue is empty.");
+ }
+
+ :foreach Id,Message in=$GotifyQueue do={
+ :if ([ :typeof $Message ] = "array" ) do={
+ :onerror Err {
+ /tool/fetch check-certificate=yes-without-crl output=none http-method=post \
+ http-header-field=($Message->"headers") http-data=[ :serialize to=json ($Message->"message") ] \
+ ($Message->"url") as-value;
+ :set ($GotifyQueue->$Id);
+ } do={
+ $LogPrint debug $0 ("Sending queued Gotify message failed: " . $Err);
+ :set AllDone false;
+ }
+ }
+ }
+
+ :if ($AllDone = true && $QueueLen = [ :len $GotifyQueue ]) do={
+ /system/scheduler/remove [ find where name="_FlushGotifyQueue" ];
+ :set GotifyQueue;
+ }
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
+
+# send notification via Gotify - expects one array argument
+:set ($NotificationFunctions->"gotify") do={
+ :local Notification $1;
+
+ :global Identity;
+ :global IdentityExtra;
+ :global GotifyQueue;
+ :global GotifyServer;
+ :global GotifyServerOverride;
+ :global GotifyToken;
+ :global GotifyTokenOverride;
+
+ :global EitherOr;
+ :global FetchUserAgentStr;
+ :global IfThenElse;
+ :global LogPrint;
+ :global SymbolForNotification;
+
+ :local Server [ $EitherOr ($GotifyServerOverride->($Notification->"origin")) $GotifyServer ];
+ :local Token [ $EitherOr ($GotifyTokenOverride->($Notification->"origin")) $GotifyToken ];
+
+ :if ([ :len $Token ] = 0) do={
+ :return false;
+ }
+
+ :local Url ("https://" . $Server . "/message");
+ :local Headers ({ [ $FetchUserAgentStr ($Notification->"origin") ]; \
+ ("X-Gotify-Key: " . $Token); "Content-Type: application/json" });
+ :local Message ({
+ "title"=("[" . $IdentityExtra . $Identity . "] " . ($Notification->"subject")); \
+ "message"=(($Notification->"message") . "\n" . [ $IfThenElse ([ :len ($Notification->"link") ] > 0) \
+ ("\n" . [ $SymbolForNotification "link" ] . ($Notification->"link")) ]); \
+ "priority"=[ :tonum [ $IfThenElse ($Notification->"silent") 2 5 ] ] });
+
+ :onerror Err {
+ /tool/fetch check-certificate=yes-without-crl output=none http-method=post \
+ http-header-field=$Headers http-data=[ :serialize to=json $Message ] $Url as-value;
+ } do={
+ $LogPrint info $0 ("Failed sending Gotify notification: " . $Err . " - Queuing...");
+
+ :if ([ :typeof $GotifyQueue ] = "nothing") do={
+ :set GotifyQueue ({});
+ }
+ :set ($Message->"message") (($Notification->"message") . "\n" . \
+ [ $SymbolForNotification "alarm-clock" ] . "This message was queued since " . \
+ [ /system/clock/get date ] . " " . [ /system/clock/get time ] . " and may be obsolete.");
+ :set ($GotifyQueue->[ :len $GotifyQueue ]) \
+ { url=$Url; headers=$Headers; message=$Message };
+ :if ([ :len [ /system/scheduler/find where name="_FlushGotifyQueue" ] ] = 0) do={
+ /system/scheduler/add name="_FlushGotifyQueue" interval=1m start-time=startup \
+ on-event=(":global FlushGotifyQueue; \$FlushGotifyQueue;");
+ }
+ }
+}
+
+# purge the Gotify queue
+:set PurgeGotifyQueue do={
+ :global GotifyQueue;
+
+ /system/scheduler/remove [ find where name="_FlushGotifyQueue" ];
+ :set GotifyQueue;
+}
+
+# send notification via Gotify - expects at least two string arguments
+:set SendGotify do={ :onerror Err {
+ :global SendGotify2;
+
+ $SendGotify2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 });
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
+
+# send notification via Gotify - expects one array argument
+:set SendGotify2 do={
+ :local Notification $1;
+
+ :global NotificationFunctions;
+
+ ($NotificationFunctions->"gotify") ("\$NotificationFunctions->\"gotify\"") $Notification;
+}
diff --git a/mod/notification-matrix.rsc b/mod/notification-matrix.rsc
index 3adc1df..e9b42a0 100644
--- a/mod/notification-matrix.rsc
+++ b/mod/notification-matrix.rsc
@@ -1,13 +1,14 @@
#!rsc by RouterOS
# RouterOS script: mod/notification-matrix
-# Copyright (c) 2013-2024 Michael Gisbers <michael@gisbers.de>
+# Copyright (c) 2013-2025 Michael Gisbers <michael@gisbers.de>
# Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.14
+# requires RouterOS, version=7.15
+# requires device-mode, fetch, scheduler
#
# send notifications via Matrix
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/notification-matrix.md
+# https://rsc.eworm.de/doc/mod/notification-matrix.md
:global FlushMatrixQueue;
:global NotificationFunctions;
@@ -18,7 +19,7 @@
:global SetupMatrixJoinRoom;
# flush Matrix queue
-:set FlushMatrixQueue do={
+:set FlushMatrixQueue do={ :onerror Err {
:global MatrixQueue;
:global IsFullyConnected;
@@ -38,7 +39,7 @@
:foreach Id,Message in=$MatrixQueue do={
:if ([ :typeof $Message ] = "array" ) do={
- :do {
+ :onerror Err {
/tool/fetch check-certificate=yes-without-crl output=none \
http-header-field=($Message->"headers") http-method=post \
http-data=[ :serialize to=json { "msgtype"="m.text"; "body"=($Message->"plain");
@@ -46,8 +47,8 @@
("https://" . $Message->"homeserver" . "/_matrix/client/r0/rooms/" . $Message->"room" . \
"/send/m.room.message?access_token=" . $Message->"accesstoken") as-value;
:set ($MatrixQueue->$Id);
- } on-error={
- $LogPrint debug $0 ("Sending queued Matrix message failed.");
+ } do={
+ $LogPrint debug $0 ("Sending queued Matrix message failed: " . $Err);
:set AllDone false;
}
}
@@ -57,7 +58,9 @@
/system/scheduler/remove [ find where name="_FlushMatrixQueue" ];
:set MatrixQueue;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via Matrix - expects one array argument
:set ($NotificationFunctions->"matrix") do={
@@ -126,15 +129,15 @@
[ $PrepareText $Label ] . "</a>");
}
- :do {
+ :onerror Err {
/tool/fetch check-certificate=yes-without-crl output=none \
http-header-field=$Headers http-method=post \
http-data=[ :serialize to=json { "msgtype"="m.text"; "body"=$Plain;
"format"="org.matrix.custom.html"; "formatted_body"=$Formatted } ] \
("https://" . $HomeServer . "/_matrix/client/r0/rooms/" . $Room . \
"/send/m.room.message?access_token=" . $AccessToken) as-value;
- } on-error={
- $LogPrint info $0 ("Failed sending Matrix notification! Queuing...");
+ } do={
+ $LogPrint info $0 ("Failed sending Matrix notification: " . $Err . " - Queuing...");
:if ([ :typeof $MatrixQueue ] = "nothing") do={
:set MatrixQueue ({});
@@ -164,11 +167,13 @@
}
# send notification via Matrix - expects at least two string arguments
-:set SendMatrix do={
+:set SendMatrix do={ :onerror Err {
:global SendMatrix2;
$SendMatrix2 ({ origin=$0; subject=$1; message=$2; link=$3 });
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via Matrix - expects one array argument
:set SendMatrix2 do={
@@ -191,14 +196,14 @@
:global MatrixHomeServer;
:local Domain [ :pick $User ([ :find $User ":" ] + 1) [ :len $User] ];
- :do {
+ :onerror Err {
:local Data ([ /tool/fetch check-certificate=yes-without-crl output=user \
http-header-field=({ [ $FetchUserAgentStr $0 ] }) \
("https://" . $Domain . "/.well-known/matrix/client") as-value ]->"data");
:set MatrixHomeServer ([ :deserialize from=json value=$Data ]->"m.homeserver"->"base_url");
$LogPrint debug $0 ("Home server is: " . $MatrixHomeServer);
- } on-error={
- $LogPrint error $0 ("Failed getting home server!");
+ } do={
+ $LogPrint error $0 ("Failed getting home server: " . $Err);
:return false;
}
@@ -206,27 +211,27 @@
:set MatrixHomeServer [ :pick $MatrixHomeServer 8 [ :len $MatrixHomeServer ] ];
}
- :do {
+ :onerror Err {
:local Data ([ /tool/fetch check-certificate=yes-without-crl output=user \
http-header-field=({ [ $FetchUserAgentStr $0 ] }) http-method=post \
http-data=[ :serialize to=json { "type"="m.login.password"; "user"=$User; "password"=$Pass } ] \
("https://" . $MatrixHomeServer . "/_matrix/client/r0/login") as-value ]->"data");
:set MatrixAccessToken ([ :deserialize from=json value=$Data ]->"access_token");
$LogPrint debug $0 ("Access token is: " . $MatrixAccessToken);
- } on-error={
- $LogPrint error $0 ("Failed logging in (and getting access token)!");
+ } do={
+ $LogPrint error $0 ("Failed logging in (and getting access token): " . $Err);
:return false;
}
- :do {
+ :onerror Err {
/system/script/remove [ find where name="global-config-overlay.d/mod/notification-matrix" ];
/system/script/add name="global-config-overlay.d/mod/notification-matrix" source=( \
"# configuration snippet: mod/notification-matrix\n\n" . \
":global MatrixHomeServer \"" . $MatrixHomeServer . "\";\n" . \
":global MatrixAccessToken \"" . $MatrixAccessToken . "\";\n");
$LogPrint info $0 ("Added configuration snippet. Now create and join a room, please!");
- } on-error={
- $LogPrint error $0 ("Failed adding configuration snippet!");
+ } do={
+ $LogPrint error $0 ("Failed adding configuration snippet: " . $Err);
:return false;
}
}
@@ -243,24 +248,24 @@
:global MatrixHomeServer;
:global MatrixRoom;
- :do {
+ :onerror Err {
/tool/fetch check-certificate=yes-without-crl output=none \
http-header-field=({ [ $FetchUserAgentStr $0 ] }) http-method=post http-data="" \
("https://" . $MatrixHomeServer . "/_matrix/client/r0/rooms/" . [ $UrlEncode $MatrixRoom ] . \
"/join?access_token=" . [ $UrlEncode $MatrixAccessToken ]) as-value;
$LogPrint debug $0 ("Joined the room.");
- } on-error={
- $LogPrint error $0 ("Failed joining the room!");
+ } do={
+ $LogPrint error $0 ("Failed joining the room: " . $Err);
:return false;
}
- :do {
+ :onerror Err {
:local Snippet [ /system/script/find where name="global-config-overlay.d/mod/notification-matrix" ];
/system/script/set $Snippet source=([ get $Snippet source ] . \
":global MatrixRoom \"" . $MatrixRoom . "\";\n");
$LogPrint info $0 ("Appended configuration to configuration snippet. Please review!");
- } on-error={
- $LogPrint error $0 ("Failed appending configuration to snippet!");
+ } do={
+ $LogPrint error $0 ("Failed appending configuration to snippet: " . $Err);
:return false;
}
}
diff --git a/mod/notification-ntfy.rsc b/mod/notification-ntfy.rsc
index b2bb280..7114020 100644
--- a/mod/notification-ntfy.rsc
+++ b/mod/notification-ntfy.rsc
@@ -1,12 +1,13 @@
#!rsc by RouterOS
# RouterOS script: mod/notification-ntfy
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.14
+# requires RouterOS, version=7.15
+# requires device-mode, fetch, scheduler
#
# send notifications via Ntfy (ntfy.sh)
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/notification-ntfy.md
+# https://rsc.eworm.de/doc/mod/notification-ntfy.md
:global FlushNtfyQueue;
:global NotificationFunctions;
@@ -15,9 +16,8 @@
:global SendNtfy2;
# flush ntfy queue
-:set FlushNtfyQueue do={
+:set FlushNtfyQueue do={ :onerror Err {
:global NtfyQueue;
- :global NtfyMessageIDs;
:global IsFullyConnected;
:global LogPrint;
@@ -36,13 +36,13 @@
:foreach Id,Message in=$NtfyQueue do={
:if ([ :typeof $Message ] = "array" ) do={
- :do {
+ :onerror Err {
/tool/fetch check-certificate=yes-without-crl output=none http-method=post \
http-header-field=($Message->"headers") http-data=($Message->"text") \
- ($Message->"url") user=($Message->"user") password=($Message->"pass") as-value;
+ ($Message->"url") as-value;
:set ($NtfyQueue->$Id);
- } on-error={
- $LogPrint debug $0 ("Sending queued Ntfy message failed.");
+ } do={
+ $LogPrint debug $0 ("Sending queued Ntfy message failed: " . $Err);
:set AllDone false;
}
}
@@ -52,7 +52,9 @@
/system/scheduler/remove [ find where name="_FlushNtfyQueue" ];
:set NtfyQueue;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via ntfy - expects one array argument
:set ($NotificationFunctions->"ntfy") do={
@@ -65,6 +67,8 @@
:global NtfyServerOverride;
:global NtfyServerPass;
:global NtfyServerPassOverride;
+ :global NtfyServerToken;
+ :global NtfyServerTokenOverride;
:global NtfyServerUser;
:global NtfyServerUserOverride;
:global NtfyTopic;
@@ -81,6 +85,7 @@
:local Server [ $EitherOr ($NtfyServerOverride->($Notification->"origin")) $NtfyServer ];
:local User [ $EitherOr ($NtfyServerUserOverride->($Notification->"origin")) $NtfyServerUser ];
:local Pass [ $EitherOr ($NtfyServerPassOverride->($Notification->"origin")) $NtfyServerPass ];
+ :local Token [ $EitherOr ($NtfyServerTokenOverride->($Notification->"origin")) $NtfyServerToken ];
:local Topic [ $EitherOr ($NtfyTopicOverride->($Notification->"origin")) $NtfyTopic ];
:if ([ :len $Topic ] = 0) do={
@@ -91,12 +96,18 @@
:local Headers ({ [ $FetchUserAgentStr ($Notification->"origin") ]; \
("Priority: " . [ $IfThenElse ($Notification->"silent") "low" "default" ]); \
("Title: " . "[" . $IdentityExtra . $Identity . "] " . ($Notification->"subject")) });
+ :if ([ :len $User ] > 0 || [ :len $Pass ] > 0) do={
+ :set Headers ($Headers, ("Authorization: Basic " . [ :convert to=base64 ($User . ":" . $Pass) ]));
+ }
+ :if ([ :len $Token ] > 0) do={
+ :set Headers ($Headers, ("Authorization: Bearer " . $Token));
+ }
:local Text (($Notification->"message") . "\n");
:if ([ :len ($Notification->"link") ] > 0) do={
:set Text ($Text . "\n" . [ $SymbolForNotification "link" ] . ($Notification->"link"));
}
- :do {
+ :onerror Err {
:if ($Server = "ntfy.sh") do={
:if ([ $CertificateAvailable "ISRG Root X1" ] = false) do={
$LogPrint warning $0 ("Downloading required certificate failed.");
@@ -104,9 +115,9 @@
}
}
/tool/fetch check-certificate=yes-without-crl output=none http-method=post \
- http-header-field=$Headers http-data=$Text $Url user=$User password=$Pass as-value;
- } on-error={
- $LogPrint info $0 ("Failed sending ntfy notification! Queuing...");
+ http-header-field=$Headers http-data=$Text $Url as-value;
+ } do={
+ $LogPrint info $0 ("Failed sending ntfy notification: " . $Err . " - Queuing...");
:if ([ :typeof $NtfyQueue ] = "nothing") do={
:set NtfyQueue ({});
@@ -115,7 +126,7 @@
"This message was queued since " . [ /system/clock/get date ] . " " . \
[ /system/clock/get time ] . " and may be obsolete.");
:set ($NtfyQueue->[ :len $NtfyQueue ]) \
- { url=$Url; user=$User; pass=$Pass; headers=$Headers; text=$Text };
+ { url=$Url; headers=$Headers; text=$Text };
:if ([ :len [ /system/scheduler/find where name="_FlushNtfyQueue" ] ] = 0) do={
/system/scheduler/add name="_FlushNtfyQueue" interval=1m start-time=startup \
on-event=(":global FlushNtfyQueue; \$FlushNtfyQueue;");
@@ -132,11 +143,13 @@
}
# send notification via ntfy - expects at least two string arguments
-:set SendNtfy do={
+:set SendNtfy do={ :onerror Err {
:global SendNtfy2;
$SendNtfy2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 });
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via ntfy - expects one array argument
:set SendNtfy2 do={
diff --git a/mod/notification-telegram.rsc b/mod/notification-telegram.rsc
index 671bd1c..2eb90e1 100644
--- a/mod/notification-telegram.rsc
+++ b/mod/notification-telegram.rsc
@@ -1,27 +1,28 @@
#!rsc by RouterOS
# RouterOS script: mod/notification-telegram
-# Copyright (c) 2013-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.14
+# requires RouterOS, version=7.15
+# requires device-mode, fetch, scheduler
#
# send notifications via Telegram
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/notification-telegram.md
+# https://rsc.eworm.de/doc/mod/notification-telegram.md
:global FlushTelegramQueue;
+:global GetTelegramChatId;
:global NotificationFunctions;
:global PurgeTelegramQueue;
:global SendTelegram;
:global SendTelegram2;
# flush telegram queue
-:set FlushTelegramQueue do={
+:set FlushTelegramQueue do={ :onerror Err {
:global TelegramQueue;
:global TelegramMessageIDs;
:global IsFullyConnected;
:global LogPrint;
- :global UrlEncode;
:if ([ $IsFullyConnected ] = false) do={
$LogPrint debug $0 ("System is not fully connected, not flushing.");
@@ -37,16 +38,14 @@
:foreach Id,Message in=$TelegramQueue do={
:if ([ :typeof $Message ] = "array" ) do={
- :do {
+ :onerror Err {
:local Data ([ /tool/fetch check-certificate=yes-without-crl output=user http-method=post \
("https://api.telegram.org/bot" . ($Message->"tokenid") . "/sendMessage") \
- http-data=("chat_id=" . ($Message->"chatid") . "&disable_notification=" . ($Message->"silent") . \
- "&reply_to_message_id=" . ($Message->"replyto") . "&disable_web_page_preview=true" . \
- "&parse_mode=MarkdownV2&text=" . [ $UrlEncode ($Message->"text") ]) as-value ]->"data");
+ http-data=($Message->"http-data") as-value ]->"data");
:set ($TelegramQueue->$Id);
:set ($TelegramMessageIDs->[ :tostr ([ :deserialize from=json value=$Data ]->"result"->"message_id") ]) 1;
- } on-error={
- $LogPrint debug $0 ("Sending queued Telegram message failed.");
+ } do={
+ $LogPrint debug $0 ("Sending queued Telegram message failed: " . $Err);
:set AllDone false;
}
}
@@ -56,7 +55,48 @@
/system/scheduler/remove [ find where name="_FlushTelegramQueue" ];
:set TelegramQueue;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
+
+# get the chat id
+:set GetTelegramChatId do={ :onerror Err {
+ :global TelegramTokenId;
+
+ :global CertificateAvailable;
+ :global LogPrint;
+
+ :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" ] = false) do={
+ $LogPrint warning $0 ("Downloading required certificate failed.");
+ :return false;
+ }
+
+ :local Data;
+ :onerror Err {
+ :set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \
+ ("https://api.telegram.org/bot" . $TelegramTokenId . "/getUpdates?offset=0" . \
+ "&allowed_updates=%5B%22message%22%5D") as-value ]->"data");
+ } do={
+ $LogPrint warning $0 ("Fetching data failed: " . $Err);
+ :return false;
+ }
+
+ :local JSON [ :deserialize from=json value=$Data ];
+ :local Count [ :len ($JSON->"result") ];
+
+ :if ($Count = 0) do={
+ $LogPrint info $0 ("No message received.");
+ :return false;
+ }
+
+ :local Message ($JSON->"result"->($Count - 1)->"message");
+ $LogPrint info $0 ("The chat id is: " . ($Message->"chat"->"id"));
+ :if (($Message->"is_topic_message") = true) do={
+ $LogPrint info $0 ("The thread id is: " . ($Message->"message_thread_id"));
+ }
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via telegram - expects one array argument
:set ($NotificationFunctions->"telegram") do={
@@ -68,6 +108,8 @@
:global TelegramChatIdOverride;
:global TelegramMessageIDs;
:global TelegramQueue;
+ :global TelegramThreadId;
+ :global TelegramThreadIdOverride;
:global TelegramTokenId;
:global TelegramTokenIdOverride;
@@ -108,6 +150,9 @@
:local ChatId [ $EitherOr ($Notification->"chatid") \
[ $EitherOr ($TelegramChatIdOverride->($Notification->"origin")) $TelegramChatId ] ];
+ :local ThreadId [ $EitherOr ($Notification->"threadid") \
+ [ $EitherOr ($TelegramThreadIdOverride->($Notification->"origin")) \
+ [ $IfThenElse ([ :len ($TelegramChatIdOverride->($Notification->"origin")) ] = 0) $TelegramThreadId ] ] ];
:local TokenId [ $EitherOr ($TelegramTokenIdOverride->($Notification->"origin")) $TelegramTokenId ];
:if ([ :len $TokenId ] = 0 || [ :len $ChatId ] = 0) do={
@@ -142,19 +187,20 @@
(($LenSum - [ :len $Text ]) * 100 / $LenSum) . "%_!") "plain" "_" ]);
}
- :do {
+ :local HTTPData ("chat_id=" . $ChatId . "&disable_notification=" . ($Notification->"silent") . \
+ "&reply_to_message_id=" . ($Notification->"replyto") . "&message_thread_id=" . $ThreadId . \
+ "&disable_web_page_preview=true&parse_mode=MarkdownV2");
+ :onerror Err {
:if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" ] = false) do={
$LogPrint warning $0 ("Downloading required certificate failed.");
:error false;
}
:local Data ([ /tool/fetch check-certificate=yes-without-crl output=user http-method=post \
("https://api.telegram.org/bot" . $TokenId . "/sendMessage") \
- http-data=("chat_id=" . $ChatId . "&disable_notification=" . ($Notification->"silent") . \
- "&reply_to_message_id=" . ($Notification->"replyto") . "&disable_web_page_preview=true" . \
- "&parse_mode=MarkdownV2&text=" . [ $UrlEncode $Text ]) as-value ]->"data");
+ http-data=($HTTPData . "&text=" . [ $UrlEncode $Text ]) as-value ]->"data");
:set ($TelegramMessageIDs->[ :tostr ([ :deserialize from=json value=$Data ]->"result"->"message_id") ]) 1;
- } on-error={
- $LogPrint info $0 ("Failed sending Telegram notification! Queuing...");
+ } do={
+ $LogPrint info $0 ("Failed sending Telegram notification: " . $Err . " - Queuing...");
:if ([ :typeof $TelegramQueue ] = "nothing") do={
:set TelegramQueue ({});
@@ -162,8 +208,8 @@
:set Text ($Text . "\n" . [ $SymbolForNotification "alarm-clock" ] . \
[ $EscapeMD ("This message was queued since _" . [ /system/clock/get date ] . \
" " . [ /system/clock/get time ] . "_ and may be obsolete.") "plain" "_" ]);
- :set ($TelegramQueue->[ :len $TelegramQueue ]) { chatid=$ChatId; tokenid=$TokenId;
- text=$Text; silent=($Notification->"silent"); replyto=($Notification->"replyto") };
+ :set ($TelegramQueue->[ :len $TelegramQueue ]) { tokenid=$TokenId;
+ http-data=($HTTPData . "&text=" . [ $UrlEncode $Text ]) };
:if ([ :len [ /system/scheduler/find where name="_FlushTelegramQueue" ] ] = 0) do={
/system/scheduler/add name="_FlushTelegramQueue" interval=1m start-time=startup \
on-event=(":global FlushTelegramQueue; \$FlushTelegramQueue;");
@@ -180,11 +226,13 @@
}
# send notification via telegram - expects at least two string arguments
-:set SendTelegram do={
+:set SendTelegram do={ :onerror Err {
:global SendTelegram2;
$SendTelegram2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 });
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# send notification via telegram - expects one array argument
:set SendTelegram2 do={
diff --git a/mod/scriptrunonce.rsc b/mod/scriptrunonce.rsc
index 3d5dce9..1d6aaf1 100644
--- a/mod/scriptrunonce.rsc
+++ b/mod/scriptrunonce.rsc
@@ -1,22 +1,23 @@
#!rsc by RouterOS
# RouterOS script: mod/scriptrunonece
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.14
+# requires RouterOS, version=7.15
#
# download script and run it once
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/scriptrunonce.md
+# https://rsc.eworm.de/doc/mod/scriptrunonce.md
:global ScriptRunOnce;
# fetch and run script(s) once
-:set ScriptRunOnce do={
+:set ScriptRunOnce do={ :onerror Err {
:local Scripts [ :toarray $1 ];
:global ScriptRunOnceBaseUrl;
:global ScriptRunOnceUrlSuffix;
+ :global FetchHuge;
:global LogPrint;
:global ValidateSyntax;
@@ -29,24 +30,27 @@
:set Script ($ScriptRunOnceBaseUrl . $Script . ".rsc" . $ScriptRunOnceUrlSuffix);
}
- :local Source;
- :do {
- :set Source ([ /tool/fetch check-certificate=yes-without-crl $Script output=user as-value ]->"data");
- } on-error={
+ :local Source [ $FetchHuge $0 $Script true ];
+ :if ($Source = false) do={
$LogPrint warning $0 ("Failed fetching script '" . $Script . "'!");
+ :return false;
}
- :if ([ :len $Source ] > 0) do={
- :if ([ $ValidateSyntax $Source ] = true) do={
- :do {
- $LogPrint info $0 ("Running script '" . $Script . "' now.");
- [ :parse $Source ];
- } on-error={
- $LogPrint warning $0 ("The script '" . $Script . "' failed to run!");
- }
- } else={
- $LogPrint warning $0 ("The script '" . $Script . "' failed syntax validation!");
- }
+ :if ([ $ValidateSyntax $Source ] = false) do={
+ $LogPrint warning $0 ("The script '" . $Script . "' failed syntax validation!");
+ :return false;
+ }
+
+ :onerror Err {
+ $LogPrint info $0 ("Running script '" . $Script . "' now.");
+ [ :parse $Source ];
+ } do={
+ $LogPrint warning $0 ("The script '" . $Script . "' failed to run: " . $Err);
+ :return false;
}
+
+ :return true;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
diff --git a/mod/ssh-keys-import.rsc b/mod/ssh-keys-import.rsc
index d6b3b3f..7bdc95d 100644
--- a/mod/ssh-keys-import.rsc
+++ b/mod/ssh-keys-import.rsc
@@ -1,24 +1,25 @@
#!rsc by RouterOS
# RouterOS script: mod/ssh-keys-import
-# Copyright (c) 2020-2024 Christian Hesse <mail@eworm.de>
-# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
+# Copyright (c) 2020-2025 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
#
-# requires RouterOS, version=7.14
+# requires RouterOS, version=7.16
#
# import ssh keys for public key authentication
-# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/ssh-keys-import.md
+# https://rsc.eworm.de/doc/mod/ssh-keys-import.md
:global SSHKeysImport;
:global SSHKeysImportFile;
# import single key passed as string
-:set SSHKeysImport do={
+:set SSHKeysImport do={ :onerror Err {
:local Key [ :tostr $1 ];
:local User [ :tostr $2 ];
:global GetRandom20CharAlNum;
:global LogPrint;
:global MkDir;
+ :global RmDir;
:global WaitForFile;
:if ([ :len $Key ] = 0 || [ :len $User ] = 0) do={
@@ -54,24 +55,27 @@
/file/add name=$FileName contents=($Key . ", md5=" . $FingerPrintMD5);
$WaitForFile $FileName;
- :do {
+ :onerror Err {
/user/ssh-keys/import public-key-file=$FileName user=$User;
$LogPrint info $0 ("Imported ssh public key (" . $KeyVal->2 . ", " . $KeyVal->0 . ", " . \
"MD5:" . $FingerPrintMD5 . ") for user '" . $User . "'.");
- /file/remove "tmpfs/ssh-keys-import";
- } on-error={
- $LogPrint warning $0 ("Failed importing key.");
- /file/remove "tmpfs/ssh-keys-import";
+ $RmDir "tmpfs/ssh-keys-import";
+ } do={
+ $LogPrint warning $0 ("Failed importing key: " . $Err);
+ $RmDir "tmpfs/ssh-keys-import";
:return false;
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }
# import keys from a file
-:set SSHKeysImportFile do={
+:set SSHKeysImportFile do={ :onerror Err {
:local FileName [ :tostr $1 ];
:local User [ :tostr $2 ];
:global EitherOr;
+ :global FileExists;
:global LogPrint;
:global ParseKeyValueStore;
:global SSHKeysImport;
@@ -81,8 +85,7 @@
:return false;
}
- :local File [ /file/find where name=$FileName ];
- :if ([ :len $File ] = 0) do={
+ :if ([ $FileExists $FileName ] = true) do={
$LogPrint warning $0 ("File '" . $FileName . "' does not exist.");
:return false;
}
@@ -91,9 +94,7 @@
:foreach KeyVal in=[ :deserialize $Keys delimiter=" " from=dsv options=dsv.plain ] do={
:local Continue false;
:if ($KeyVal->0 = "ssh-ed25519" || $KeyVal->0 = "ssh-rsa") do={
- :do {
- $SSHKeysImport ($KeyVal->0 . " " . $KeyVal->1 . " " . $KeyVal->2) $User;
- } on-error={
+ :if ([ $SSHKeysImport ($KeyVal->0 . " " . $KeyVal->1 . " " . $KeyVal->2) $User ] = false) do={
$LogPrint warning $0 ("Failed importing key for user '" . $User . "'.");
}
:set Continue true;
@@ -106,4 +107,6 @@
$LogPrint warning $0 ("SSH key of type '" . $KeyVal->0 . "' is not supported.");
}
}
-}
+} do={
+ :global ExitError; $ExitError false $0 $Err;
+} }