]> Git [git.vados.ru] :: Repos - Mikrotiks/ros.vados.ru.git/commitdiff
Autocommit in repo: ros.vados.ru, generated by owner: root, in 06:25:02 01.04.2026.
authorvados-dev <192440777+vados-dev@users.noreply.github.com>
Wed, 1 Apr 2026 03:25:03 +0000 (06:25 +0300)
committervados-dev <192440777+vados-dev@users.noreply.github.com>
Wed, 1 Apr 2026 03:25:03 +0000 (06:25 +0300)
html/AM-GlobalFunc.rsc
html/certificate-renew-issued.rsc [new file with mode: 0644]
html/check-health.d/state.rsc [new file with mode: 0644]
html/check-health.d/temperature.rsc [new file with mode: 0644]
html/check-health.d/voltage.rsc [new file with mode: 0644]

index 04aa5dc486b0572bc4371d1e89e84eb77fbcc878..532f81130879896c85f72202821039bcb599b6fb 100644 (file)
@@ -17,9 +17,9 @@
 :global GlobalFuncReady false;
 
 # Git commit id & info, expected configuration version
-:global CommitId "main/211/7cacb2a2";
+:global CommitId "main/212/5784a4ca";
 :global CommitTAG "unknown";
-:global CommitInfo "Autocommit in repo: ros.vados.ru, generated by owner: root, in 06:20:02 01.04.2026.";
+:global CommitInfo "Autocommit in repo: ros.vados.ru, generated by owner: root, in 06:25:02 01.04.2026.";
 
 # The variables are received right here.
 :global GlobalConfVersion 138;
diff --git a/html/certificate-renew-issued.rsc b/html/certificate-renew-issued.rsc
new file mode 100644 (file)
index 0000000..e78669f
--- /dev/null
@@ -0,0 +1,52 @@
+#!rsc by RouterOS
+# RouterOS script: certificate-renew-issued
+# Copyright (c) 2019-2026 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.19
+#
+# renew locally issued certificates
+# https://rsc.eworm.de/doc/certificate-renew-issued.md
+
+:local ExitOK false;
+:onerror Err {
+  :global GlobalConfigReady; :global GlobalFunctionsReady;
+  :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
+      do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
+  :local ScriptName [ :jobname ];
+
+  :global CertIssuedExportPass;
+
+  :global LogPrint;
+  :global MkDir;
+  :global ScriptLock;
+
+  :if ([ $ScriptLock $ScriptName ] = false) do={
+    :set ExitOK true;
+    :error false;
+  }
+
+  :foreach Cert in=[ /certificate/find where issued expires-after<3w ] do={
+    :local CertVal [ /certificate/get $Cert ];
+    /certificate/issued-revoke $Cert;
+    /certificate/set name=($CertVal->"name" . "-revoked-" . [ /system/clock/get date ]) $Cert;
+    /certificate/add name=($CertVal->"name") common-name=($CertVal->"common-name") \
+        key-usage=($CertVal->"key-usage") subject-alt-name=($CertVal->"subject-alt-name");
+    /certificate/sign ($CertVal->"name") ca=($CertVal->"ca");
+    :if ([ :typeof ($CertIssuedExportPass->($CertVal->"common-name")) ] = "str") do={
+      :if ([ $MkDir "cert-issued" ] = true) do={
+        /certificate/export-certificate ($CertVal->"name") type=pkcs12 \
+            file-name=("cert-issued/" . $CertVal->"common-name") \
+            export-passphrase=($CertIssuedExportPass->($CertVal->"common-name"));
+        $LogPrint info $ScriptName ("Issued a new certificate for '" . $CertVal->"common-name" . \
+          "', exported to 'cert-issued/" . $CertVal->"common-name" . ".p12'.");
+      } else={
+        $LogPrint warning $ScriptName ("Failed creating directory, not exporting certificate.");
+      }
+    } else={
+      $LogPrint info $ScriptName ("Issued a new certificate for '" . $CertVal->"common-name" . "'.");
+    }
+  }
+} do={
+  :global ExitError; $ExitError $ExitOK [ :jobname ] $Err;
+}
diff --git a/html/check-health.d/state.rsc b/html/check-health.d/state.rsc
new file mode 100644 (file)
index 0000000..0728b45
--- /dev/null
@@ -0,0 +1,49 @@
+#!rsc by RouterOS
+# RouterOS script: check-health.d/state
+# Copyright (c) 2019-2026 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.19
+#
+# check for RouterOS health state - state plugin
+# https://rsc.eworm.de/doc/check-health.md
+
+:global CheckHealthPlugins;
+
+:set ($CheckHealthPlugins->[ :jobname ]) do={
+  :local FuncName   [ :tostr $0 ];
+  :local ScriptName [ :tostr $1 ];
+
+  :global CheckHealthLast;
+  :global Identity;
+
+  :global LogPrint;
+  :global SendNotification2;
+  :global SymbolForNotification;
+
+  :if ([ :len [ /system/health/find where type="" name~"-state\$"] ] = 0) do={
+    $LogPrint debug $FuncName ("Your device does not provide any state health values.");
+    :return false;
+  }
+
+  :foreach State in=[ /system/health/find where type="" name~"-state\$" ] do={
+    :local Name  [ /system/health/get $State name  ];
+    :local Value [ /system/health/get $State value ];
+
+    :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
+      :if ($CheckHealthLast->$Name = "ok" && \
+           $Value != "ok") do={
+        $SendNotification2 ({ origin=$ScriptName; \
+          subject=([ $SymbolForNotification "cross-mark" ] . "Health warning: " . $Name); \
+          message=("The device '" . $Name . "' on " . $Identity . " failed!") });
+      }
+      :if ($CheckHealthLast->$Name != "ok" && \
+           $Value = "ok") do={
+        $SendNotification2 ({ origin=$ScriptName; \
+          subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \
+          message=("The device '" . $Name . "' on " . $Identity . " recovered!") });
+      }
+    }
+    :set ($CheckHealthLast->$Name) $Value;
+  }
+}
diff --git a/html/check-health.d/temperature.rsc b/html/check-health.d/temperature.rsc
new file mode 100644 (file)
index 0000000..fdce5dc
--- /dev/null
@@ -0,0 +1,75 @@
+#!rsc by RouterOS
+# RouterOS script: check-health.d/temperature
+# Copyright (c) 2019-2026 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.19
+#
+# check for RouterOS health state - temperature plugin
+# https://rsc.eworm.de/doc/check-health.md
+
+:global CheckHealthPlugins;
+
+:set ($CheckHealthPlugins->[ :jobname ]) do={
+  :local FuncName   [ :tostr $0 ];
+  :local ScriptName [ :tostr $1 ];
+
+  :global CheckHealthLast;
+  :global CheckHealthTemperature;
+  :global CheckHealthTemperatureDeviation;
+  :global CheckHealthTemperatureNotified;
+  :global Identity;
+
+  :global LogPrint;
+  :global SendNotification2;
+  :global SymbolForNotification;
+
+  :if ([ :len [ /system/health/find where type="C" ] ] = 0) do={
+    $LogPrint debug $FuncName ("Your device does not provide any voltage health values.");
+    :return false;
+  }
+
+  :local TempToNum do={
+    :global CharacterReplace;
+    :local T [ :toarray [ $CharacterReplace $1 "." "," ] ];
+    :return ($T->0 * 10 + $T->1);
+  }
+
+  :if ([ :typeof $CheckHealthTemperatureNotified ] != "array") do={
+    :set CheckHealthTemperatureNotified ({});
+  }
+
+  :foreach Temperature in=[ /system/health/find where type="C" ] do={
+    :local Name  [ /system/health/get $Temperature name  ];
+    :local Value [ /system/health/get $Temperature value ];
+
+    :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
+      :if ([ :typeof ($CheckHealthTemperature->$Name) ] != "num" ) do={
+        $LogPrint info $FuncName ("No threshold given for " . $Name . ", assuming 50C.");
+        :set ($CheckHealthTemperature->$Name) 50;
+      }
+      :local Validate [ /system/health/get [ find where name=$Name ] value ];
+      :while ($Value != $Validate) do={
+        :set Value $Validate;
+        :set Validate [ /system/health/get [ find where name=$Name ] value ];
+      }
+      :if ($Value > $CheckHealthTemperature->$Name && \
+           $CheckHealthTemperatureNotified->$Name != true) do={
+        $SendNotification2 ({ origin=$ScriptName; \
+          subject=([ $SymbolForNotification "fire" ] . "Health warning: " . $Name); \
+          message=("The " . $Name . " on " . $Identity . " is above threshold: " . \
+            $Value . "\C2\B0" . "C") });
+        :set ($CheckHealthTemperatureNotified->$Name) true;
+      }
+      :if ($Value <= ($CheckHealthTemperature->$Name - $CheckHealthTemperatureDeviation) && \
+           $CheckHealthTemperatureNotified->$Name = true) do={
+        $SendNotification2 ({ origin=$ScriptName; \
+          subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \
+          message=("The " . $Name . " on " . $Identity . " dropped below threshold: " .  \
+            $Value . "\C2\B0" . "C") });
+        :set ($CheckHealthTemperatureNotified->$Name) false;
+      }
+    }
+    :set ($CheckHealthLast->$Name) $Value;
+  }
+}
diff --git a/html/check-health.d/voltage.rsc b/html/check-health.d/voltage.rsc
new file mode 100644 (file)
index 0000000..67febc2
--- /dev/null
@@ -0,0 +1,64 @@
+#!rsc by RouterOS
+# RouterOS script: check-health.d/voltage
+# Copyright (c) 2019-2026 Christian Hesse <mail@eworm.de>
+# https://rsc.eworm.de/COPYING.md
+#
+# requires RouterOS, version=7.19
+#
+# check for RouterOS health state - voltage plugin
+# https://rsc.eworm.de/doc/check-health.md
+
+:global CheckHealthPlugins;
+
+:set ($CheckHealthPlugins->[ :jobname ]) do={
+  :local FuncName   [ :tostr $0 ];
+  :local ScriptName [ :tostr $1 ];
+
+  :global CheckHealthLast;
+  :global CheckHealthVoltageLow;
+  :global CheckHealthVoltagePercent;
+  :global Identity;
+
+  :global FormatLine;
+  :global IfThenElse;
+  :global LogPrint;
+  :global SendNotification2;
+  :global SymbolForNotification;
+
+  :if ([ :len [ /system/health/find where type="V" ] ] = 0) do={
+    $LogPrint debug $FuncName ("Your device does not provide any voltage health values.");
+    :return false;
+  }
+
+  :foreach Voltage in=[ /system/health/find where type="V" ] do={
+    :local Name  [ /system/health/get $Voltage name  ];
+    :local Value [ /system/health/get $Voltage value ];
+
+    :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={
+      :local NumCurr [ $TempToNum $Value ];
+      :local NumLast [ $TempToNum ($CheckHealthLast->$Name) ];
+
+      :if ($NumLast * (100 + $CheckHealthVoltagePercent) < $NumCurr * 100 || \
+           $NumLast * 100 > $NumCurr * (100 + $CheckHealthVoltagePercent)) do={
+        $SendNotification2 ({ origin=$ScriptName; \
+          subject=([ $SymbolForNotification ("high-voltage-sign,chart-" . [ $IfThenElse ($NumLast < \
+            $NumCurr) "in" "de" ] . "creasing") ] . "Health warning: " . $Name); \
+          message=("The " . $Name . " on " . $Identity . " jumped more than " . $CheckHealthVoltagePercent . "%.\n\n" . \
+            [ $FormatLine "old value" ($CheckHealthLast->$Name . " V") 12 ] . "\n" . \
+            [ $FormatLine "new value" ($Value . " V") 12 ]) });
+      } else={ 
+        :if ($NumCurr <= $CheckHealthVoltageLow && $NumLast > $CheckHealthVoltageLow) do={ 
+          $SendNotification2 ({ origin=$ScriptName; \
+            subject=([ $SymbolForNotification "high-voltage-sign,chart-decreasing" ] . "Health warning: Low " . $Name); \ 
+            message=("The " . $Name . " on " . $Identity . " dropped to " . $Value . " V below hard limit.") }); 
+        } 
+        :if ($NumCurr > $CheckHealthVoltageLow && $NumLast <= $CheckHealthVoltageLow) do={ 
+          $SendNotification2 ({ origin=$ScriptName; \
+            subject=([ $SymbolForNotification "high-voltage-sign,chart-increasing" ] . "Health recovery: Low " . $Name); \ 
+            message=("The " . $Name . " on " . $Identity . " recovered to " . $Value . " V above hard limit.") }); 
+        }
+      }
+    }
+    :set ($CheckHealthLast->$Name) $Value;
+  }
+}