aboutsummaryrefslogtreecommitdiffstats
path: root/script-updates
blob: 95af07dc91fdee1cce7d666c27b80f4b6215d7a2 (about) (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!rsc
# RouterOS script: script-updates
# Copyright (c) 2013-2020 Christian Hesse <mail@eworm.de>
#
# update installed scripts from file or url

:global ExpectedConfigVersion;
:global GlobalConfigVersion;
:global Identity;
:global IDonate;
:global SentConfigChangesNotification;
:global ScriptUpdatesFetch;
:global ScriptUpdatesBaseUrl;
:global ScriptUpdatesUrlSuffix;
:global ScriptUpdatesIgnore;
:global ScriptUpdatesConfigChangesIgnore;

:global SendNotification;

:foreach Script in=[ / system script find ] do={
  :local Ignore 0;
  :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 content ];
    / 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={
      :log warning ("Policies differ for script " . $ScriptVal->"name" . \
        " and its scheduler " . $SchedulerVal->"name" . "!");
    }
  }

  :if ([ :len $SourceNew ] = 0 && $ScriptUpdatesFetch = true) do={
    :foreach IgnoreLoop in=$ScriptUpdatesIgnore do={
      :if ($IgnoreLoop = $ScriptVal->"name") do={ :set Ignore 1; }
    }

    :if ($Ignore = 0) do={
      :log debug ("Fetching script from url: " . $ScriptVal->"name");
      :do {
        :local Result [ / tool fetch check-certificate=yes-without-crl \
            ($ScriptUpdatesBaseUrl . $ScriptVal->"name" . $ScriptUpdatesUrlSuffix) \
            output=user as-value ];
        :if ($Result->"status" = "finished") do={
          :set SourceNew ($Result->"data");
        }
      } on-error={
        :log info ("Failed fetching " . $ScriptVal->"name");
      }
    }
  }

  :if ([ :len $SourceNew ] > 0) do={
    :if ([ :pick $SourceNew 0 5 ] = "#!rsc") do={
      :if ($SourceNew != $ScriptVal->"source") do={
        :local DontRequirePermissions \
            ($SourceNew~"\n# requires: dont-require-permissions=yes\n");
        :log info ("Updating script: " . $ScriptVal->"name");
        / system script set owner=($ScriptVal->"name") source=$SourceNew \
            dont-require-permissions=$DontRequirePermissions $Script;
        :if ($ScriptVal->"name" = "global-config" && \
             [ / system script print count-only where name="global-config-overlay" ] > 0) do={
          / system script { run global-config; run global-config-overlay; }
        }
        :if ($ScriptVal->"name" = "global-functions") do={
          / system script run global-functions;
        }
      } else={
        :log debug ("Script " .  $ScriptVal->"name" . " did not change.");
      }
    } else={
      :log warning ("Looks like new script " . $ScriptVal->"name" . " is not valid. Ignoring!");
    }
  } else={
    :log debug ("No update for script " . $ScriptVal->"name" . ".");
  }
}

:if ($ScriptUpdatesConfigChangesIgnore!=true && \
     $SentConfigChangesNotification!=$ExpectedConfigVersion && \
     $GlobalConfigVersion < $ExpectedConfigVersion) do={
  :global GlobalConfigChanges;
  :local ChangeLogCode;
  :local ConfigScript "global-config";
  :if ([ /system script print count-only where name="global-config-overlay" ] > 0) do={
    :set ConfigScript "global-config-overlay";
  }
  :local NotificationMessage ("Current configuration on " . $Identity . \
      " is out of date. Please update " . $ConfigScript . ", then increase " . \
      "variable GlobalConfigVersion (currently " . $GlobalConfigVersion . \
      ") to " . $ExpectedConfigVersion . " and re-run " . $ConfigScript . ".");

  :log debug ("Fetching changelog.");
  :do {
    :local Result [ / tool fetch check-certificate=yes-without-crl \
        ($ScriptUpdatesBaseUrl . "global-config.changes" . $ScriptUpdatesUrlSuffix) \
        output=user as-value ];
    :if ($Result->"status" = "finished") do={
      :set ChangeLogCode ($Result->"data");
    }
    :set NotificationMessage ($NotificationMessage . "\n\nChanges:");
    [ :parse $ChangeLogCode ];
    :for I from=($GlobalConfigVersion + 1) to=$ExpectedConfigVersion do={
      :set NotificationMessage ($NotificationMessage . \
          "\n * " . $GlobalConfigChanges->[ :tostr $I ]);
    }
    :set GlobalConfigChanges;
  } on-error={
    :log info ("Failed fetching changes!");
    :set NotificationMessage ($NotificationMessage . \
        "\n\nChanges are not available.");
  }

  :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:\n" . \
      "https://git.eworm.de/cgit/routeros-scripts/about/#donate");
  }

  $SendNotification "Configuration warning!" $NotificationMessage;
  :set SentConfigChangesNotification $ExpectedConfigVersion;
}