Функция сохранения/восстановления глобальных переменных в /ip firewall layer7

Здесь выкладываем скрипты
Правила форума
Уважаемые Пользователи форума, обратите внимание!
Ни при каких обстоятельствах, Администрация форума, не несёт ответственности за какой-либо, прямой или косвенный, ущерб причиненный в результате использования материалов, взятых на этом Сайте или на любом другом сайте, на который имеется гиперссылка с данного Сайта. Возникновение неисправностей, потерю программ или данных в Ваших устройствах, даже если Администрация будет явно поставлена в известность о возможности такого ущерба.
Просим Вас быть предельно осторожными и внимательными, в использовании материалов раздела. Учитывать не только Ваши пожелания, но и границы возможностей вашего оборудования.
Ответить
Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Идея и реализация в скриптах принадлежит Rex ( https://forum.mikrotik.com/viewtopic.php?t=170591)
Я лишь оформил всё это дело в одну универсальную функцию.
Функция может сохранять глобальные переменные (кроме функций) в /ip firewall Layer7, который как нельзя более подходит для этой задачи. Сохраняются имена переменных (в именах записей), типы переменных (в комментариях), значения переменных - в значениях записей. Можно сохранять их с нужной переодичностью, вызывая функцию с параметром save из Планировщика. Восстановление происходит аналогично. При работе все записи Layer7, не относящиеся к данной задаче - НЕ ТРОГАЮТСЯ ! Можно также стирать все глобальные переменные из layer7 (другие записи при этом также НЕ СТИРАЮТСЯ !)
Можно печатать список переменных, хранящихся в layer7 на экран. Ниже код функции (первая версия):

Код: Выделить всё

#
# The function of saving/restoring global environment variables v 01/06/2022
# by Rextended (Rex) and Sertik https://forum.mikrotik.com/viewtopic.php?t=170591
# $1 parameter can take values:
# "save" - saving global variables in /ip firewall layer7
# "recover" - restoring global variables from layer7
# "erase" - cleaning layer7 only ! from global variables
# "print" - printing to the log and terminal of the list of variables located at the time of printing in Layer7
#

:global FuncGlobal do={
:if ([:typeof $0]="lookup") do={
:local count 0
:if (($1="save") or ($1="recover") or ($1="erase") or ($1="print")) do={
:if ($1="save") do={
/system script environment
:foreach item in=[find] do={
    :local vname [get $item name]
    :local vvalue [get $item value]
    /ip firewall layer7
    remove [find where name=$vname]
    :if (([:typeof [:find [:tostr $vvalue] "(eval " -1]] = "nil") and ([:typeof [:find [:tostr $vvalue] "(evl " -1]] = "nil")) do={
        :if ([:find $vvalue "*" -1] = 0) do={:set vvalue "ID$vvalue"}
        add name=$vname regex="$vvalue"
        :set count ($count+1)
          } 
        :delay 10ms
        :execute "/ip firewall layer7 set [find where name=$vname] comment=[:typeof \$$vname]"
}
:log warning ("Function $0 has saved $count variables")
:return $count}

:if ($1="recover") do={
/ip firewall layer7
:foreach item in=[find where comment~"^(array|bool|id|ip|ip-prefix|ip6|ip6-prefix|num|str|time|code|nothing|nil)\$"] do={
    :set count ($count+1)
    :local vname [get $item name]
    :local vvalue [get $item regexp]
    :local vtype [get $item comment]
#    :if ($vvalue = "(function)") do={:set vtype "function" }
    /system script environment
    remove [find where name=$vname]
    :if ($vtype~"^(array|bool|id|ip|ip6|num|str|time)\$") do={
        :if ($vtype = "id") do={
            :set vvalue [:pick $vvalue [:find $vvalue "*" -1] [:len $vvalue]]
            :execute ":global $vname [:to$vtype $vvalue]"}
        :if ($vtype = "bool") do={
           [[:parse ":global $vname [:to$vtype $[/ip firewall layer7 get [find where name=$vname] regexp]]"]]
# :if ($vtype="bool") do={:execute ":global $vname [:tobool $vvalue]"}
        } else={
            :execute ":global $vname [:to$vtype [/ip firewall layer7 get [find where name=$vname] regexp]]"
        }
    } else={
        :if ($vtype~"^(ip-prefix|ip6-prefix|nothing|nil)\$") do={
            :if ($vtype~"^(ip-prefix|ip6-prefix)\$") do={:execute ":global $vname [[:parse \":return $vvalue\"]]"}
            :if ($vtype="nothing") do={:execute ":global $vname [:nothing]"}
            :if ($vtype="nil") do={:execute ":global $vname"}
        } else={
            :log error "Unknow variable type >$vtype<"
            :execute ":global $vname [/ip firewall layer7 get [find where name=$vname] regexp]"
        }
    }
    :delay 10ms;
}
:log warning ("Function $0 restored $count variables")
:return $count}

:if ($1="erase") do={
/ip firewall layer7
:foreach item in=[find where comment~"^(array|bool|id|ip|ip-prefix|ip6|ip6-prefix|num|str|time|code|nothing|nil)\$"] do={remove $item; :set count ($count+1)
}
:log warning ("The repository has been cleared of $count global variables")
:return $count} 

:if ($1="print") do={
/ip firewall layer7
:foreach item in=[find where comment~"^(array|bool|id|ip|ip-prefix|ip6|ip6-prefix|num|str|time|code|nothing|nil)\$"] do={
    :set count ($count+1)
    :local vname [get $item name];
    :local vvalue [get $item regexp];
    :local vtype [get $item comment];
 :put ("$vname "."$vtype "."$vvalue");
 :log info ("$vname "."[ $vtype ] "."$vvalue");
}
:put ("In Layer7 repository has $count global variables")
:log warning ("In Layer7 repository has $count global variables")
:return $count}

} else={
:if ([:typeof $1]="nothing") do={:log error ("The function $0 parameter is not set"); :return ("Error $0")}}        
 :log error ("The function $0 parameter is not valid"); :return ("Error $0");
 }
}

# usage examples:
 
# :log info [$FuncGlobal save]
# :log info [$FuncGlobal recover]
#:log info [$FuncGlobal erase]
# :log info [$FuncGlobal print]

# examples of erroneous usage:

# :log info [$FuncGlobal]
# :log info [$FuncGlobal anovertext]



:global FuncPersist do={

    :local varName $1
    :local varValue $2
    :local varID [/ip firewall layer7-protocol find name="$varName"]

    :if ([:typeof $varValue] = "nothing") do={
        :if ($varID != "") do={
            :set $varValue [/ip firewall layer7-protocol get $varID value-name=regexp]
        }
    } else={
        :if ($varID = "") do={
            /ip firewall layer7-protocol add name="$varName" regexp="$varValue" comment=[:typeof $varName]
        } else={
            /ip firewall layer7-protocol set $varID regexp="$varValue"
        }
    }

    return $varValue

}

# Usage examples: (name = variable name, value = variable value)
# [$FuncPersist name] = Read persistent variable
# [$FuncPersist name value] = Write persistent variable
# :global name [$FuncPersist name] = Read persistent variable and write it to a global variable
# :global name [$FuncPersist name value] = Write data into a global variable and into a persistent variable at the same time

# Notes:
# The function uses layer7-protocols to store persistent data.
# All data read from persistent storage will be strings.
# The function always returns a value.
Последний раз редактировалось Sertik 17 июн 2022, 13:08, всего редактировалось 2 раза.


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Дополнил скрипт второй функцией FuncPersist, взятой с официального форума (там называлась persist)
Эта функция дополняет возможности FuncGlobal, работает не со всеми переменными окружения сразу, а одномоментно с одной глобальной переменной с указанным именем, позволяя сохранять и восстанавливать её из Layer7-хранилища. Подробное описание в тексте скрипта.


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
Ответить