source: trunk/Modules/NetworkConfigRouterOS/Routerboard.php

Last change on this file was 915, checked in by chronos, 3 years ago
  • Fixed: Various PHP 8.0 related fixes.
File size: 7.1 KB
Line 
1<?php
2
3class Routerboard
4{
5 public string $SSHPath = '/usr/bin/ssh';
6 public int $Timeout = 3;
7 public string $HostName;
8 public string $UserName;
9 public string $Password;
10 public string $PrivateKey = '~/.ssh/id_rsa';
11 public int $MaxBurstLineCount = 100;
12 public bool $Debug = false;
13
14 function __construct($HostName = 'localhost', $UserName = 'admin', $Password = '')
15 {
16 $this->HostName = $HostName;
17 $this->UserName = $UserName;
18 $this->Password = $Password;
19 }
20
21 function Execute($Commands): array
22 {
23 $Output = array();
24 if (is_array($Commands))
25 {
26 $I = 0;
27 $Batch = array();
28 while ($I < count($Commands))
29 {
30 if (($I % $this->MaxBurstLineCount) == 0)
31 {
32 if (count($Batch) > 0)
33 $Output = array_merge($Output, $this->ExecuteBatch(implode(';', $Batch)));
34 $Batch = array();
35 }
36 $Batch[] = $Commands[$I];
37 $I++;
38 }
39 if (count($Batch) > 0)
40 $Output = array_merge($Output, $this->ExecuteBatch(implode(';', $Batch)));
41 } else
42 $Output = array_merge($Output, $this->ExecuteBatch($Commands));
43 return $Output;
44 }
45
46 function ExecuteBatch(string $Commands): array
47 {
48 $Commands = trim($Commands);
49 if ($Commands != '')
50 {
51 $Commands = addslashes($Commands);
52 $Commands = str_replace('$', '\$', $Commands);
53 //$Commands = str_replace(' ', '\ ', $Commands);
54 if ($this->PrivateKey != '') $PrivKey = ' -i '.$this->PrivateKey;
55 else $PrivKey = '';
56
57 $Command = $this->SSHPath.' -oBatchMode=no -o ConnectTimeout='.$this->Timeout.' -l '.$this->UserName.
58 $PrivKey.' '.$this->HostName.' "'.$Commands.'"';
59 if ($this->Debug) echo($Command);
60 $Output = array();
61 exec($Command, $Output);
62 } else $Output = array();
63 if ($this->Debug) print_r($Output);
64 return $Output;
65 }
66
67 function ItemGet(array $Path): array
68 {
69 $Result = $this->Execute(implode(' ', $Path).' print');
70 array_pop($Result);
71 $List = array();
72 foreach ($Result as $ResultLine)
73 {
74 $ResultLineParts = explode(' ', trim($ResultLine));
75 if (count($ResultLineParts) > 1)
76 {
77 if ($ResultLineParts[1][0] == '"') $ResultLineParts[1] = substr($ResultLineParts[1], 1, -1); // Remove quotes
78 $List[substr($ResultLineParts[0], 0, -1)] = $ResultLineParts[1];
79 } else $List[substr($ResultLineParts[0], 0, -1)] = '';
80 }
81 return $List;
82 }
83
84 function ListGet(array $Path, array $Properties, array $Conditions = array()): array
85 {
86 $PropertyList = '"';
87 foreach ($Properties as $Index => $Property)
88 {
89 $PropertyList .= $Index.'=".[get $i '.$Property.']." ';
90 }
91 $PropertyList = substr($PropertyList, 0, -3);
92
93 $ConditionList = '';
94 foreach ($Conditions as $Index => $Item)
95 {
96 if ($Item == 'no') $ConditionList .= $Index.'='.$Item.' ';
97 else $ConditionList .= $Index.'="'.$Item.'" ';
98 }
99 $ConditionList = substr($ConditionList, 0, -1);
100
101 $Result = $this->Execute(implode(' ', $Path).' {:foreach i in=[find '.$ConditionList.'] do={:put ('.$PropertyList.')}}');
102 $List = array();
103 foreach ($Result as $ResultLine)
104 {
105 $ResultLineParts = explode(' ', $ResultLine);
106 $ListItem = array();
107 foreach ($ResultLineParts as $ResultLinePart)
108 {
109 $Value = explode('=', $ResultLinePart);
110 if (count($Value) > 1) $ListItem[$Properties[$Value[0]]] = $Value[1];
111 else $ListItem[$Properties[$Value[0]]] = '';
112 }
113 $List[] = $ListItem;
114 }
115 return $List;
116 }
117
118 function ListGetPrint(array $Path, array $Properties, array $Conditions = array()): array
119 {
120 $ConditionList = '';
121 foreach ($Conditions as $Index => $Item)
122 {
123 $ConditionList .= $Index.'="'.$Item.'" ';
124 }
125 $ConditionList = substr($ConditionList, 0, -1);
126 if (trim($ConditionList) != '')
127 $ConditionList = ' where '.$ConditionList;
128
129 $Result = $this->Execute(implode(' ', $Path).' print terse'.$ConditionList);
130 $List = array();
131 foreach ($Result as $ResultLine)
132 {
133 $ResultLineParts = explode(' ', $ResultLine);
134 $ListItem = array();
135 foreach ($ResultLineParts as $ResultLinePart)
136 {
137 $Value = explode('=', $ResultLinePart);
138 if (in_array($Value[0], $Properties))
139 {
140 if (count($Value) > 1)
141 {
142 if ($Value[1][0] == '"') $Value[1] = substr($Value[1], 1, -1);
143 //if (strlen($Value[1]) > 0)
144 $ListItem[$Value[0]] = $Value[1];
145 } else $ListItem[$Value[0]] = '';
146 }
147 }
148 if (count($ListItem) > 0) $List[] = $ListItem;
149 }
150 return $List;
151 }
152
153 function ListEraseAll(array $Path): void
154 {
155 $this->Execute(implode(' ', $Path).' { remove [find] }');
156 }
157
158 function ListUpdate(array $Path, array $Properties, array $Values, array $Condition = array(), bool $UsePrint = false): array
159 {
160 // Get current list from routerboard
161 if ($UsePrint == 0)
162 {
163 $List = $this->ListGet($Path, $Properties, $Condition);
164 // Change boolean values yes/no to true/false
165 foreach ($List as $Index => $ListItem)
166 {
167 foreach ($ListItem as $Index2 => $Item2)
168 {
169 if ($Item2 == 'true') $List[$Index][$Index2] = 'yes';
170 if ($Item2 == 'false') $List[$Index][$Index2] = 'no';
171 }
172 }
173 } else
174 {
175 $List = $this->ListGetPrint($Path, $Properties, $Condition);
176 }
177 $Commands = array();
178
179 // Add empty properties to values
180 foreach ($Values as $Index => $Item)
181 {
182 foreach ($Properties as $Property)
183 {
184 if (!array_key_exists($Property, $Item))
185 $Item[$Property] = '';
186 }
187 $Values[$Index] = $Item;
188 }
189 foreach ($List as $Index => $Item)
190 {
191 foreach ($Properties as $Property)
192 {
193 if (!array_key_exists($Property, $Item))
194 $Item[$Property] = '';
195 }
196 $List[$Index] = $Item;
197 }
198
199 // Sort properties
200 foreach ($Values as $Index => $Item)
201 {
202 ksort($Values[$Index]);
203 }
204 foreach ($List as $Index => $Item)
205 {
206 ksort($List[$Index]);
207 }
208 if ($this->Debug) print_r($List);
209 if ($this->Debug) print_r($Values);
210
211 // Erase all items not existed in $Values
212 foreach ($List as $Index => $ListItem)
213 {
214 if (!in_array($ListItem, $Values))
215 {
216 $Prop = '';
217 foreach ($ListItem as $Index => $Property)
218 {
219 if ($Property != '')
220 {
221 if (($Property == 'yes') or ($Property == 'no')) $Prop .= $Index.'='.$Property.' ';
222 else $Prop .= $Index.'="'.$Property.'" ';
223 }
224 }
225 $Prop = substr($Prop, 0, -1);
226 if (trim($Prop) != '')
227 $Commands[] = implode(' ', $Path).' remove [find '.$Prop.']';
228 }
229 }
230
231 // Add new items
232 foreach ($Values as $ListItem)
233 {
234 if (!in_array($ListItem, $List))
235 {
236 $Prop = '';
237 foreach ($ListItem as $Index => $Property)
238 {
239 if ($Property != '') $Prop .= $Index.'="'.$Property.'" ';
240 }
241 $Prop = substr($Prop, 0, -1);
242 $Commands[] = implode(' ', $Path).' add '.$Prop;
243 }
244 }
245 if ($this->Debug) print_r($Commands);
246 return $this->Execute($Commands);
247 }
248}
Note: See TracBrowser for help on using the repository browser.