mirror of
https://github.com/eworm-de/routeros-scripts
synced 2024-05-14 08:04:19 +00:00
8f75c17e0b
old chain: R3 / ISRG Root X1 new chain: E1 / ISRG Root X2 No user interaction or migration is required for existing installations as we install 'E1' and 'ISRG Root X2' for some time already.
257 lines
10 KiB
Text
257 lines
10 KiB
Text
#!rsc by RouterOS
|
|
# RouterOS script: global-functions
|
|
# Copyright (c) 2013-2023 Christian Hesse <mail@eworm.de>
|
|
# Michael Gisbers <michael@gisbers.de>
|
|
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
|
|
#
|
|
# requires RouterOS, version=7.7
|
|
#
|
|
# WARNING: If you find this stripped version of global-functions
|
|
# on your Router something went wrong and migration failed. To
|
|
# recover run this function: $RouterOSScriptsRecover
|
|
|
|
# expected configuration version
|
|
:global ExpectedConfigVersion 95;
|
|
|
|
# global functions
|
|
:global RouterOSScriptsRecover;
|
|
:global ScriptInstallUpdate;
|
|
|
|
# recover from failed migration
|
|
:set RouterOSScriptsRecover do={
|
|
:global ScriptInstallUpdate;
|
|
|
|
:foreach Script in={ "global-config"; "global-functions" } do={
|
|
/system/script/set name=$Script source=([ /tool/fetch check-certificate=yes-without-crl ("https://git.eworm.de/cgit/routeros-scripts/plain/" . $Script . ".rsc") output=user as-value]->"data");
|
|
/system/script/run $Script;
|
|
}
|
|
|
|
$ScriptInstallUpdate;
|
|
}
|
|
|
|
# install new scripts, update existing scripts
|
|
:set ScriptInstallUpdate do={
|
|
:local Scripts [ :toarray $1 ];
|
|
:local NewComment [ :tostr $2 ];
|
|
|
|
:global ExpectedConfigVersion;
|
|
:global Identity;
|
|
:global IDonate;
|
|
:global NoNewsAndChangesNotification;
|
|
:global NotificationsWithSymbols;
|
|
:global ScriptUpdatesBaseUrl;
|
|
:global ScriptUpdatesFetch;
|
|
:global ScriptUpdatesUrlSuffix;
|
|
|
|
:global CertificateAvailable;
|
|
:global EitherOr;
|
|
:global Grep;
|
|
:global IfThenElse;
|
|
:global LogPrintExit2;
|
|
:global ParseKeyValueStore;
|
|
:global RequiredRouterOS;
|
|
:global SendNotification2;
|
|
:global SymbolForNotification;
|
|
:global ValidateSyntax;
|
|
|
|
:if ([ $CertificateAvailable "E1" ] = false) do={
|
|
$LogPrintExit2 warning $0 ("Downloading certificate failed, trying without.") false;
|
|
}
|
|
|
|
:foreach Script in=$Scripts do={
|
|
:if ([ :len [ /system/script/find where name=$Script ] ] = 0) do={
|
|
$LogPrintExit2 info $0 ("Adding new script: " . $Script) false;
|
|
/system/script/add name=$Script owner=$Script source="#!rsc by RouterOS\n" comment=$NewComment;
|
|
}
|
|
}
|
|
|
|
:local ExpectedConfigVersionBefore $ExpectedConfigVersion;
|
|
:local ReloadGlobalFunctions false;
|
|
:local ReloadGlobalConfig false;
|
|
|
|
:foreach Script in=[ /system/script/find where source~"^#!rsc by RouterOS\n" ] do={
|
|
:local ScriptVal [ /system/script/get $Script ];
|
|
:local ScriptFile [ /file/find where name=("script-updates/" . $ScriptVal->"name") ];
|
|
:local SourceNew;
|
|
:if ([ :len $ScriptFile ] > 0) do={
|
|
:set SourceNew [ /file/get $ScriptFile contents ];
|
|
/file/remove $ScriptFile;
|
|
}
|
|
|
|
:foreach Scheduler in=[ /system/scheduler/find where on-event~("\\b" . $ScriptVal->"name" . "\\b") ] do={
|
|
:local SchedulerVal [ /system/scheduler/get $Scheduler ];
|
|
:if ($ScriptVal->"policy" != $SchedulerVal->"policy") do={
|
|
$LogPrintExit2 warning $0 ("Policies differ for script '" . $ScriptVal->"name" . \
|
|
"' and its scheduler '" . $SchedulerVal->"name" . "'!") false;
|
|
}
|
|
}
|
|
|
|
:if ([ :len $SourceNew ] = 0 && $ScriptUpdatesFetch = true) do={
|
|
:local Comment [ $ParseKeyValueStore ($ScriptVal->"comment") ];
|
|
:if (!($Comment->"ignore" = true)) do={
|
|
:do {
|
|
:local BaseUrl $ScriptUpdatesBaseUrl;
|
|
:local UrlSuffix $ScriptUpdatesUrlSuffix;
|
|
:if ([ :typeof ($Comment->"base-url") ] = "str") do={ :set BaseUrl ($Comment->"base-url"); }
|
|
:if ([ :typeof ($Comment->"url-suffix") ] = "str") do={ :set UrlSuffix ($Comment->"url-suffix"); }
|
|
:local Url ($BaseUrl . $ScriptVal->"name" . ".rsc" . $UrlSuffix);
|
|
|
|
$LogPrintExit2 debug $0 ("Fetching script '" . $ScriptVal->"name" . "' from url: " . $Url) false;
|
|
:local Result [ /tool/fetch check-certificate=yes-without-crl $Url output=user as-value ];
|
|
:if ($Result->"status" = "finished") do={
|
|
:set SourceNew ($Result->"data");
|
|
}
|
|
} on-error={
|
|
:if ($ScriptVal->"source" = "#!rsc by RouterOS\n") do={
|
|
$LogPrintExit2 warning $0 ("Failed fetching script '" . $ScriptVal->"name" . \
|
|
"', removing dummy. Typo on installation?") false;
|
|
/system/script/remove $Script;
|
|
} else={
|
|
$LogPrintExit2 warning $0 ("Failed fetching script '" . $ScriptVal->"name" . "'!") false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
:if ([ :len $SourceNew ] > 0) do={
|
|
:if ($SourceNew != $ScriptVal->"source") do={
|
|
:if ([ :pick $SourceNew 0 18 ] = "#!rsc by RouterOS\n") do={
|
|
:local Required ([ $ParseKeyValueStore [ $Grep $SourceNew "# requires RouterOS, " ] ]->"version");
|
|
:if ([ $RequiredRouterOS $0 [ $EitherOr $Required "0.0" ] false ] = true) do={
|
|
:if ([ $ValidateSyntax $SourceNew ] = true) do={
|
|
$LogPrintExit2 info $0 ("Updating script: " . $ScriptVal->"name") false;
|
|
/system/script/set owner=($ScriptVal->"name") source=$SourceNew $Script;
|
|
:if ($ScriptVal->"name" = "global-config") do={
|
|
:set ReloadGlobalConfig true;
|
|
}
|
|
:if ($ScriptVal->"name" = "global-functions" || $ScriptVal->"name" ~ ("^mod/.")) do={
|
|
:set ReloadGlobalFunctions true;
|
|
}
|
|
} else={
|
|
$LogPrintExit2 warning $0 ("Syntax validation for script '" . $ScriptVal->"name" . \
|
|
"' failed! Ignoring!") false;
|
|
}
|
|
} else={
|
|
$LogPrintExit2 warning $0 ("The script '" . $ScriptVal->"name" . "' requires RouterOS " . \
|
|
$Required . ", which is not met by your installation. Ignoring!") false;
|
|
}
|
|
} else={
|
|
$LogPrintExit2 warning $0 ("Looks like new script '" . $ScriptVal->"name" . \
|
|
"' is not valid (missing shebang). Ignoring!") false;
|
|
}
|
|
} else={
|
|
$LogPrintExit2 debug $0 ("Script '" . $ScriptVal->"name" . "' did not change.") false;
|
|
}
|
|
} else={
|
|
$LogPrintExit2 debug $0 ("No update for script '" . $ScriptVal->"name" . "'.") false;
|
|
}
|
|
}
|
|
|
|
:if ($ReloadGlobalFunctions = true) do={
|
|
$LogPrintExit2 info $0 ("Reloading global functions.") false;
|
|
:do {
|
|
/system/script/run global-functions;
|
|
} on-error={
|
|
$LogPrintExit2 error $0 ("Reloading global functions failed!") false;
|
|
}
|
|
}
|
|
|
|
:if ($ReloadGlobalConfig = true) do={
|
|
$LogPrintExit2 info $0 ("Reloading global configuration.") false;
|
|
:do {
|
|
/system/script/run global-config;
|
|
} on-error={
|
|
$LogPrintExit2 error $0 ("Reloading global configuration failed!" . \
|
|
" Syntax error or missing overlay?") false;
|
|
}
|
|
}
|
|
|
|
:if ($ExpectedConfigVersionBefore > $ExpectedConfigVersion) do={
|
|
$LogPrintExit2 warning $0 ("The configuration version decreased from " . \
|
|
$ExpectedConfigVersionBefore . " to " . $ExpectedConfigVersion . \
|
|
". Installed an older version?") false;
|
|
}
|
|
|
|
:if ($ExpectedConfigVersionBefore < $ExpectedConfigVersion) do={
|
|
:global GlobalConfigChanges;
|
|
:global GlobalConfigMigration;
|
|
:local ChangeLogCode;
|
|
|
|
:do {
|
|
:local Url ($ScriptUpdatesBaseUrl . "news-and-changes.rsc" . $ScriptUpdatesUrlSuffix);
|
|
$LogPrintExit2 debug $0 ("Fetching news, changes and migration: " . $Url) false;
|
|
:local Result [ /tool/fetch check-certificate=yes-without-crl $Url output=user as-value ];
|
|
:if ($Result->"status" = "finished") do={
|
|
:set ChangeLogCode ($Result->"data");
|
|
}
|
|
} on-error={
|
|
$LogPrintExit2 warning $0 ("Failed fetching news, changes and migration!") false;
|
|
}
|
|
|
|
:if ([ :len $ChangeLogCode ] > 0) do={
|
|
:if ([ $ValidateSyntax $ChangeLogCode ] = true) do={
|
|
:do {
|
|
[ :parse $ChangeLogCode ];
|
|
} on-error={
|
|
$LogPrintExit2 warning $0 ("The changelog failed to run!") false;
|
|
}
|
|
} else={
|
|
$LogPrintExit2 warning $0 ("The changelog failed syntax validation!") false;
|
|
}
|
|
}
|
|
|
|
:if ([ :len $GlobalConfigMigration ] > 0) do={
|
|
:for I from=($ExpectedConfigVersionBefore + 1) to=$ExpectedConfigVersion do={
|
|
:local Migration ($GlobalConfigMigration->[ :tostr $I ]);
|
|
:if ([ :typeof $Migration ] = "str") do={
|
|
:if ([ $ValidateSyntax $Migration ] = true) do={
|
|
$LogPrintExit2 info $0 ("Applying migration for change " . $I . ": " . $Migration) false;
|
|
:do {
|
|
[ :parse $Migration ];
|
|
} on-error={
|
|
$LogPrintExit2 warning $0 ("Migration code for change " . $I . " failed to run!") false;
|
|
}
|
|
} else={
|
|
$LogPrintExit2 warning $0 ("Migration code for change " . $I . " failed syntax validation!") false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
:local NotificationMessage ("The configuration version on " . $Identity . " increased " . \
|
|
"to " . $ExpectedConfigVersion . ", current configuration may need modification. " . \
|
|
"Please review and update global-config-overlay, then re-run global-config.");
|
|
$LogPrintExit2 info $0 ($NotificationMessage) false;
|
|
|
|
:if ([ :len $GlobalConfigChanges ] > 0) do={
|
|
:set NotificationMessage ($NotificationMessage . "\n\nChanges:");
|
|
:for I from=($ExpectedConfigVersionBefore + 1) to=$ExpectedConfigVersion do={
|
|
:local Change ($GlobalConfigChanges->[ :tostr $I ]);
|
|
:set NotificationMessage ($NotificationMessage . "\n " . \
|
|
[ $IfThenElse ($NotificationsWithSymbols = true) ("\E2\97\8F") "*" ] . " " . $Change);
|
|
$LogPrintExit2 info $0 ("Change " . $I . ": " . $Change) false;
|
|
}
|
|
} else={
|
|
:set NotificationMessage ($NotificationMessage . "\n\nNews and changes are not available.");
|
|
}
|
|
|
|
:if ($NoNewsAndChangesNotification != true) do={
|
|
:local Link;
|
|
:if ($IDonate != true) do={
|
|
:set NotificationMessage ($NotificationMessage . \
|
|
"\n\n==== donation hint ====\n" . \
|
|
"This project is developed in private spare time and usage is " . \
|
|
"free of charge for you. If you like the scripts and think this is " . \
|
|
"of value for you or your business please consider a donation.");
|
|
:set Link "https://git.eworm.de/cgit/routeros-scripts/about/#donate";
|
|
}
|
|
|
|
$SendNotification2 ({ origin=$0; \
|
|
subject=([ $SymbolForNotification "pushpin" ] . "News and configuration changes"); \
|
|
message=$NotificationMessage; link=$Link });
|
|
}
|
|
|
|
:set GlobalConfigChanges;
|
|
:set GlobalConfigMigration;
|
|
}
|
|
}
|