r4547 getAllVLANOptions(): new helper function
[racktables] / wwwroot / inc / remote.php
CommitLineData
7cb57a03
AA
1<?php
2
3function queryDevice ($object_id, $command)
4{
5 $breed = detectDeviceBreed ($object_id);
6 if (empty ($breed))
7 throw new RTGatewayError ("Can not determine device breed");
8
9 if (! validBreedFunction ($breed, $command))
10 throw new RTGatewayError ("unsupported command '$command' for the breed '$breed'");
11
12 require_once 'deviceconfig.php';
13 global $breedfunc;
14 if (! is_callable ($breedfunc["$breed-$command-main"]))
15 throw new RTGatewayError ("undeclared function '" . $breedfunc["$breed-$command-main"] . "'");
16 $query = translateDeviceCommands ($object_id, array (array ('opcode' => $command)));
17 if ($command == 'xlatepushq')
18 return $query;
19 else
20 {
21 $answer = queryTerminal ($object_id, $query, FALSE);
22 return $breedfunc["$breed-$command-main"] ($answer);
23 }
24}
25
26function translateDeviceCommands ($object_id, $crq, $vlan_names = NULL)
27{
28 require_once 'deviceconfig.php';
29 $breed = detectDeviceBreed ($object_id);
30 if (empty ($breed))
31 throw new RTGatewayError ("Can not determine device breed");
32
33 if (! validBreedFunction ($breed, 'xlatepushq'))
34 throw new RTGatewayError ("unsupported command 'xlatepushq' for the breed '$breed'");
35
36 global $breedfunc;
37 return $breedfunc["$breed-xlatepushq-main"] ($object_id, $crq, $vlan_names);
38}
39
40// This function returns a text output received from the device
41// You can override connection settings by implement a callback named 'terminal_settings'.
42// Errors are thrown as exceptions if not $tolerate_remote_errors, and shown as warnings otherwise.
43function queryTerminal ($object_id, $commands, $tolerate_remote_errors = TRUE)
44{
45 $objectInfo = spotEntity ('object', $object_id);
46 $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
47 if (count ($endpoints) == 0)
48 throw new RTGatewayError ('no management address set');
49 if (count ($endpoints) > 1)
50 throw new RTGatewayError ('cannot pick management address');
51
52 // default telnet prompt specification
53 $prompt = NULL;
54 switch ($breed = detectDeviceBreed ($object_id))
55 {
56 case 'ios12': // non-interactive, half-opened session
57 break;
58 case 'vrp53':
59 case 'vrp55':
60 $prompt = '[>:\]]$';
61 break;
62 case 'nxos4':
63 $prompt = '[>:#] $';
64 break;
65 case 'xos12':
66 $prompt = ': $|\.\d+ # $';
67 break;
68 case 'jun10':
69 $prompt = '^login: $|^Password:$|^\S+@\S+[>#] $';
70 break;
71 case 'fdry5': // FIXME: add telnet prompt regexp here
72 break;
73 }
74
75 // set the default settings before calling user-defined callback
76 $settings = array
77 (
78 'hostname' => $endpoints[0],
79 'protocol' => 'telnet',
80 'port' => NULL,
81 'prompt' => $prompt,
82 'username' => NULL,
83 'password' => NULL,
84 'timeout' => substr ($breed, 0, 3) == 'vrp' ? 15 : 5,
85 'connect_timeout' => 2,
86 'sudo_user' => NULL,
87 'identity_file' => NULL,
88 );
89 if (is_callable ('terminal_settings'))
90 call_user_func ('terminal_settings', $objectInfo, array (&$settings)); // override settings
91
92 $params = array ( $settings['hostname'] );
93 $params_from_settings = array();
94 switch ($settings['protocol'])
95 {
96 case 'telnet':
97 switch ($breed)
98 {
99 case 'ios12':
100 $commands = "terminal length 0\n" . $commands;
101 break;
102 case 'nxos4':
103 $commands = "terminal length 0\nterminal no monitor\n" . $commands;
104 break;
105 case 'xos12':
106 $commands = "disable clipaging\n" . $commands;
107 break;
108 case 'vrp55':
109 $commands = "screen-length 0 temporary\n" . $commands;
110 break;
111 case 'fdry5':
112 $commands = "skip-page-display\n" . $commands;
113 break;
114 case 'jun10':
115 $commands = "'set cli screen-length 0\n" . $commands;
116 break;
117 }
118 // prepend telnet commands by credentials
119 if (isset ($settings['password']))
120 $commands = $settings['password'] . "\n" . $commands;
121 if (isset ($settings['username']))
122 $commands = $settings['username'] . "\n" . $commands;
123 $params_from_settings['port'] = 'port';
124 $params_from_settings['prompt'] = 'prompt';
125 $params_from_settings['connect-timeout'] = 'connect_timeout';
126 $params_from_settings['timeout'] = 'timeout';
127 break;
128 case 'ssh':
129 $params_from_settings['port'] = 'port';
130 $params_from_settings['username'] = 'username';
131 $params_from_settings['i'] = 'identity_file';
132 $params_from_settings['sudo-user'] = 'sudo_user';
133 $params_from_settings['connect-timeout'] = 'connect_timeout';
134 break;
135 default:
c0b84dfb 136 throw RTGatewayError ("Invalid terminal protocol '${settings['protocol']}' specified");
7cb57a03
AA
137 }
138 foreach ($params_from_settings as $param_name => $setting_name)
139 if (isset ($settings[$setting_name]))
140 $params[$param_name] = $settings[$setting_name];
141
142 $ret_code = callScript ($settings['protocol'], $params, $commands, $out, $errors);
143 if ($settings['protocol'] == 'telnet' || ! $tolerate_remote_errors)
144 {
145 if (! empty ($errors))
146 throw new RTGatewayError ("${settings['protocol']} error: $errors");
147 elseif ($ret_code !== 0)
148 throw new RTGatewayError ("${settings['protocol']} error: result code $ret_code");
149 }
150 elseif (! empty ($errors)) // ssh and not tolerate and non-empty $errors
151 foreach (explode ("\n", $errors) as $line)
152 if (strlen ($line))
153 showWarning ("${settings['protocol']} ${settings['hostname']}: $line");
154 return strtr($out, array("\r" => "")); // cut ^M symbols
155}
156
157function callScript ($gwname, $params, $in, &$out, &$errors)
158{
159 global $racktables_gwdir, $local_gwdir;
160 if (isset ($local_gwdir) && file_exists ("$local_gwdir/$gwname"))
161 $dir = $local_gwdir;
162 elseif (isset ($racktables_gwdir) && file_exists ("$racktables_gwdir/$gwname"))
163 $dir = $racktables_gwdir;
164 if (! isset ($dir))
c0b84dfb 165 throw new RTGatewayError ("Could not find the gateway file called '$gwname'");
7cb57a03
AA
166
167 $cmd_line = "./$gwname";
168 foreach ($params as $key => $value)
169 {
170 if (! isset ($value))
171 continue;
172 if (preg_match ('/^\d+$/', $key))
173 $cmd_line .= " " . escapeshellarg ($value);
174 else
175 {
176 if (strlen ($key) == 1)
177 $cmd_line .= " " . escapeshellarg ("-$key") . " " . escapeshellarg ($value);
178 else
179 $cmd_line .= " " . escapeshellarg("--$key=$value");
180 }
181 }
182
183 $pipes = array();
184 $child = proc_open
185 (
186 $cmd_line,
187 array (
188 0 => array ('pipe', 'r'),
189 1 => array ('pipe', 'w'),
190 2 => array ('pipe', 'w'),
191 ),
192 $pipes,
193 $dir
194 );
195 if (! is_resource ($child))
c0b84dfb 196 throw new RTGatewayError ("cant execute $dir/$gwname");
7cb57a03
AA
197 fwrite ($pipes[0], $in);
198 fclose ($pipes[0]);
199 $out = stream_get_contents ($pipes[1]);
200 $errors = stream_get_contents ($pipes[2]);
201 return proc_close ($child);
202}
203
204?>