| 1637 |
pharsh |
1 |
/*
|
|
|
2 |
* To change this template, choose Tools | Templates
|
|
|
3 |
* and open the template in the editor.
|
|
|
4 |
*/
|
|
|
5 |
package vep;
|
|
|
6 |
|
| 2678 |
pharsh |
7 |
import java.io.*;
|
| 1637 |
pharsh |
8 |
import java.net.ServerSocket;
|
|
|
9 |
import java.net.Socket;
|
|
|
10 |
import java.net.SocketException;
|
|
|
11 |
import java.net.SocketTimeoutException;
|
|
|
12 |
import java.sql.ResultSet;
|
| 1728 |
fdudouet |
13 |
import java.util.ArrayList;
|
| 1717 |
fdudouet |
14 |
import java.util.Arrays;
|
|
|
15 |
import java.util.HashMap;
|
|
|
16 |
import java.util.HashSet;
|
| 1728 |
fdudouet |
17 |
import java.util.LinkedList;
|
|
|
18 |
import java.util.List;
|
| 1717 |
fdudouet |
19 |
import java.util.Map;
|
|
|
20 |
import java.util.Set;
|
| 2678 |
pharsh |
21 |
import javax.xml.parsers.ParserConfigurationException;
|
|
|
22 |
import javax.xml.parsers.SAXParser;
|
|
|
23 |
import javax.xml.parsers.SAXParserFactory;
|
| 1637 |
pharsh |
24 |
import org.apache.log4j.Logger;
|
| 1728 |
fdudouet |
25 |
import org.opennebula.client.Client;
|
|
|
26 |
import org.opennebula.client.OneResponse;
|
|
|
27 |
import org.opennebula.client.host.HostPool;
|
| 2678 |
pharsh |
28 |
import org.xml.sax.Attributes;
|
|
|
29 |
import org.xml.sax.InputSource;
|
|
|
30 |
import org.xml.sax.SAXException;
|
|
|
31 |
import org.xml.sax.helpers.DefaultHandler;
|
| 1637 |
pharsh |
32 |
|
|
|
33 |
/**
|
|
|
34 |
*
|
| 2678 |
pharsh |
35 |
* @author piyush, florian
|
| 1637 |
pharsh |
36 |
*/
|
| 2678 |
pharsh |
37 |
public class CLIServer extends DefaultHandler implements Runnable //CLI Server is a blocking server, handles only one client at a time
|
| 1637 |
pharsh |
38 |
{
|
|
|
39 |
private int port;
|
|
|
40 |
private boolean continueFlag;
|
|
|
41 |
private Thread t;
|
|
|
42 |
private Logger logger;
|
|
|
43 |
private ServerSocket server;
|
|
|
44 |
private Socket client;
|
|
|
45 |
private dbHandler dbhandle;
|
|
|
46 |
private PrintWriter out;
|
|
|
47 |
private BufferedReader in;
|
| 1893 |
pharsh |
48 |
private String vepProperties;
|
| 1637 |
pharsh |
49 |
|
| 2678 |
pharsh |
50 |
private LinkedList<ONEHost> rowList;
|
|
|
51 |
private ONEHost tempHost;
|
|
|
52 |
private String tempVal;
|
|
|
53 |
private ClusterStats runningStat;
|
|
|
54 |
private List<String> nodes;
|
|
|
55 |
|
| 1893 |
pharsh |
56 |
public CLIServer(int sPort, dbHandler dhandle, String vepProp) //make sure CLI server is started only once DB operations are enabled
|
| 1637 |
pharsh |
57 |
{
|
|
|
58 |
port = sPort;
|
|
|
59 |
dbhandle = dhandle;
|
| 1893 |
pharsh |
60 |
vepProperties = vepProp;
|
| 1637 |
pharsh |
61 |
continueFlag = true;
|
|
|
62 |
logger = Logger.getLogger("VEP.CLIServer");
|
|
|
63 |
client = null;
|
|
|
64 |
try
|
|
|
65 |
{
|
|
|
66 |
server = new ServerSocket(port);
|
|
|
67 |
t = new Thread(this);
|
|
|
68 |
}
|
|
|
69 |
catch(IOException ex)
|
|
|
70 |
{
|
|
|
71 |
t = null;
|
|
|
72 |
server = null;
|
|
|
73 |
logger.debug("Error while trying to create CLI server socket, maybe the port is not free: " + ex.getMessage());
|
| 2678 |
pharsh |
74 |
ex.printStackTrace(System.err);
|
| 1637 |
pharsh |
75 |
}
|
|
|
76 |
}
|
|
|
77 |
|
|
|
78 |
public void startCLIserver()
|
|
|
79 |
{
|
|
|
80 |
if(t != null)
|
|
|
81 |
{
|
|
|
82 |
continueFlag = true;
|
|
|
83 |
t.start();
|
|
|
84 |
}
|
|
|
85 |
}
|
|
|
86 |
|
|
|
87 |
public void stopCLIserver()
|
|
|
88 |
{
|
|
|
89 |
continueFlag = false;
|
|
|
90 |
//just send a dummy connect if server is blocking on client incoming request
|
|
|
91 |
try
|
|
|
92 |
{
|
|
|
93 |
if(client != null && client.isConnected()) client.close();
|
|
|
94 |
Socket sock = new Socket("127.0.0.1", port);
|
|
|
95 |
sock.close();
|
|
|
96 |
server.close();
|
|
|
97 |
t.join(1000);
|
|
|
98 |
}
|
|
|
99 |
catch(Exception ex)
|
|
|
100 |
{
|
|
|
101 |
|
|
|
102 |
}
|
|
|
103 |
}
|
|
|
104 |
|
|
|
105 |
public void run()
|
|
|
106 |
{
|
| 2678 |
pharsh |
107 |
logger.debug("CLI Server has started ...");
|
| 1637 |
pharsh |
108 |
while(continueFlag && (server != null))
|
|
|
109 |
{
|
|
|
110 |
try
|
|
|
111 |
{
|
|
|
112 |
client = server.accept();
|
|
|
113 |
client.setSoTimeout(1000*60*2); //2 minutes idle time
|
|
|
114 |
out = new PrintWriter(client.getOutputStream(), true);
|
|
|
115 |
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
|
| 2678 |
pharsh |
116 |
|
| 1637 |
pharsh |
117 |
boolean authPhase = true;
|
|
|
118 |
boolean passPhase = false;
|
|
|
119 |
boolean isAuthenticated = false;
|
|
|
120 |
boolean forceQuit = false;
|
|
|
121 |
String username = "";
|
|
|
122 |
String password = "";
|
|
|
123 |
|
|
|
124 |
String output = "Welcome to Contrail VEP Command Line Interface!\n";
|
|
|
125 |
output += "You must be authenticated before you are granted access to modify the execution of VEP.\n";
|
|
|
126 |
output += "------------------------------------\n";
|
|
|
127 |
output += "Administrator Username: ";
|
|
|
128 |
|
|
|
129 |
out.println(output);
|
|
|
130 |
String userInput = in.readLine();
|
|
|
131 |
|
|
|
132 |
while(!forceQuit && !client.isClosed() && userInput != null && !userInput.equalsIgnoreCase("bye") && !userInput.equalsIgnoreCase("exit"))
|
|
|
133 |
{
|
|
|
134 |
output = "";
|
|
|
135 |
logger.debug("CLI incoming message: " + userInput);
|
|
|
136 |
if(authPhase)
|
|
|
137 |
{
|
|
|
138 |
username = userInput.trim();
|
|
|
139 |
authPhase = false;
|
|
|
140 |
passPhase = true;
|
|
|
141 |
output = "------------------------------------\nAdministrator " + username + "'s password: ";
|
|
|
142 |
}
|
|
|
143 |
else if(passPhase)
|
|
|
144 |
{
|
|
|
145 |
password = userInput.trim();
|
|
|
146 |
passPhase = false;
|
|
|
147 |
isAuthenticated = doAdminAuth(username, password, out, in);
|
|
|
148 |
username = "";
|
|
|
149 |
password = "";
|
|
|
150 |
if(isAuthenticated)
|
|
|
151 |
output = "------------------------------------\n"
|
|
|
152 |
+ "Authentication successful! List of commands:\n"
|
|
|
153 |
+ "\t show configuration\n"
|
|
|
154 |
+ "\t edit configuration\n"
|
|
|
155 |
+ "\t list hosts\n"
|
|
|
156 |
+ "\t edit hosts\n"
|
|
|
157 |
+ "\t add fedadmin\n"
|
|
|
158 |
+ "\t add datacenter\n"
|
|
|
159 |
+ "\t add cluster\n"
|
|
|
160 |
+ "\t add rack\n"
|
|
|
161 |
+ "\t help\n"
|
|
|
162 |
+ "\t exit\n"
|
|
|
163 |
+ "------------------------------------";
|
|
|
164 |
}
|
|
|
165 |
else if(isAuthenticated)
|
|
|
166 |
{
|
|
|
167 |
if(userInput.equalsIgnoreCase("help"))
|
|
|
168 |
output = showHelp();
|
|
|
169 |
else if(userInput.equalsIgnoreCase("show configuration"))
|
|
|
170 |
{
|
|
|
171 |
output = "------------------------------------\n"
|
|
|
172 |
+ readConfiguration()
|
|
|
173 |
+ "------------------------------------";
|
|
|
174 |
}
|
| 1717 |
fdudouet |
175 |
else if(userInput.equalsIgnoreCase("edit configuration"))
|
|
|
176 |
{
|
|
|
177 |
editConfiguration(out, in);
|
|
|
178 |
}
|
|
|
179 |
else if(userInput.equalsIgnoreCase("add datacenter"))
|
|
|
180 |
{
|
|
|
181 |
addDatacenter(out, in);
|
|
|
182 |
}
|
|
|
183 |
else if(userInput.equalsIgnoreCase("add cluster"))
|
|
|
184 |
{
|
|
|
185 |
addCluster(out, in);
|
|
|
186 |
}
|
|
|
187 |
else if(userInput.equalsIgnoreCase("add rack"))
|
|
|
188 |
{
|
|
|
189 |
addRack(out, in);
|
| 1728 |
fdudouet |
190 |
}
|
|
|
191 |
else if(userInput.equalsIgnoreCase("list hosts"))
|
|
|
192 |
{
|
|
|
193 |
listHost(out, in);
|
|
|
194 |
}
|
| 2678 |
pharsh |
195 |
else if(userInput.equalsIgnoreCase("add host"))
|
| 1728 |
fdudouet |
196 |
{
|
| 2678 |
pharsh |
197 |
addHost(out, in);
|
|
|
198 |
}
|
|
|
199 |
else if(userInput.equalsIgnoreCase("add fedadmin"))
|
|
|
200 |
{
|
| 1728 |
fdudouet |
201 |
addFedAdmin(out, in);
|
|
|
202 |
}
|
| 1637 |
pharsh |
203 |
else
|
|
|
204 |
{
|
|
|
205 |
output = "------------------------------------\n"
|
|
|
206 |
+ "\tNot yet implemented! You may type help or exit ...\n"
|
|
|
207 |
+ "------------------------------------";
|
|
|
208 |
}
|
|
|
209 |
}
|
|
|
210 |
else
|
|
|
211 |
{
|
|
|
212 |
output = "You do not have the proper authorization to continue.";
|
|
|
213 |
forceQuit = true;
|
|
|
214 |
}
|
|
|
215 |
out.println(output);
|
|
|
216 |
if(!forceQuit)
|
|
|
217 |
userInput = in.readLine();
|
|
|
218 |
}
|
|
|
219 |
client.close();
|
|
|
220 |
}
|
|
|
221 |
catch(SocketException sockex)
|
|
|
222 |
{
|
|
|
223 |
logger.warn("CLI client read error, closing connection: " + sockex.getMessage());
|
|
|
224 |
try
|
|
|
225 |
{
|
|
|
226 |
if(client != null && client.isConnected())
|
|
|
227 |
{
|
|
|
228 |
out.println("VEP server shutting down. Closing connection now ...");
|
|
|
229 |
client.close();
|
|
|
230 |
}
|
|
|
231 |
}
|
|
|
232 |
catch(Exception ex)
|
|
|
233 |
{
|
|
|
234 |
//ignore this exception
|
|
|
235 |
}
|
|
|
236 |
}
|
|
|
237 |
catch(SocketTimeoutException timeout)
|
|
|
238 |
{
|
|
|
239 |
logger.warn("CLI client timeout, closing connection: " + timeout.getMessage());
|
|
|
240 |
try
|
|
|
241 |
{
|
|
|
242 |
if(client != null && client.isConnected())
|
|
|
243 |
{
|
|
|
244 |
out.println("You have been inactive for more than 2 minutes. For security reasons this connection will be closed now.");
|
|
|
245 |
client.close();
|
|
|
246 |
}
|
|
|
247 |
}
|
|
|
248 |
catch(Exception ex)
|
|
|
249 |
{
|
|
|
250 |
//ignore this exception
|
|
|
251 |
}
|
|
|
252 |
}
|
|
|
253 |
catch(Exception ex)
|
|
|
254 |
{
|
|
|
255 |
logger.warn("CLI server encountered an exception: " + ex.getMessage());
|
| 2678 |
pharsh |
256 |
ex.printStackTrace(System.err);
|
| 1637 |
pharsh |
257 |
}
|
|
|
258 |
}
|
|
|
259 |
logger.debug("CLI Server exitting now ...");
|
|
|
260 |
}
|
|
|
261 |
|
|
|
262 |
private String showHelp()
|
|
|
263 |
{
|
|
|
264 |
String output = "------------------------------------\nList of commands:\n"
|
|
|
265 |
+ "\t show configuration\n"
|
|
|
266 |
+ "\t edit configuration\n"
|
|
|
267 |
+ "\t list hosts\n"
|
|
|
268 |
+ "\t edit hosts\n"
|
|
|
269 |
+ "\t add fedadmin\n"
|
|
|
270 |
+ "\t add datacenter\n"
|
|
|
271 |
+ "\t add cluster\n"
|
|
|
272 |
+ "\t add rack\n"
|
|
|
273 |
+ "\t help\n"
|
|
|
274 |
+ "\t exit\n"
|
|
|
275 |
+ "------------------------------------";
|
|
|
276 |
return output;
|
|
|
277 |
}
|
|
|
278 |
|
|
|
279 |
private String readConfiguration()
|
|
|
280 |
{
|
|
|
281 |
String output = "";
|
|
|
282 |
try
|
|
|
283 |
{
|
| 1893 |
pharsh |
284 |
// BufferedReader fileReader = new BufferedReader(new FileReader("vep.properties"));
|
|
|
285 |
BufferedReader fileReader = new BufferedReader(new FileReader(vepProperties));
|
| 1637 |
pharsh |
286 |
String strLine = "";
|
|
|
287 |
while ((strLine = fileReader.readLine()) != null)
|
|
|
288 |
{
|
|
|
289 |
output += strLine + "\n";
|
|
|
290 |
}
|
|
|
291 |
fileReader.close();
|
|
|
292 |
}
|
|
|
293 |
catch(Exception ex)
|
|
|
294 |
{
|
|
|
295 |
logger.warn("Caught exception in CLI module while retrieving the VEP properties: " + ex.getMessage());
|
| 2678 |
pharsh |
296 |
ex.printStackTrace(System.err);
|
| 1637 |
pharsh |
297 |
}
|
|
|
298 |
return output;
|
|
|
299 |
}
|
|
|
300 |
|
|
|
301 |
private boolean doAdminAuth(String user, String pass, PrintWriter out, BufferedReader in)
|
|
|
302 |
{
|
|
|
303 |
try
|
|
|
304 |
{
|
|
|
305 |
String userInput = "";
|
|
|
306 |
String adminUser = "";
|
|
|
307 |
String adminPass = "";
|
|
|
308 |
ResultSet rs = dbhandle.query("select", "count(*)", "vepadmin", "");
|
|
|
309 |
if(rs.next())
|
|
|
310 |
{
|
|
|
311 |
int count = rs.getInt(1);
|
|
|
312 |
if(count < 1)
|
|
|
313 |
{
|
|
|
314 |
rs.close();
|
|
|
315 |
out.println("It seems no local administrator has been setup! Would you like to setup one now (yes/no)?");
|
|
|
316 |
userInput = in.readLine();
|
|
|
317 |
if(userInput.equalsIgnoreCase("yes"))
|
|
|
318 |
{
|
|
|
319 |
out.println("New administrator username:");
|
|
|
320 |
userInput = in.readLine().trim();
|
|
|
321 |
if(!userInput.contains(" \t!@#$%^&*()+-=~`;:'\",<>?/") && userInput.length() > 0)
|
|
|
322 |
{
|
|
|
323 |
adminUser = userInput;
|
|
|
324 |
out.println("Provide a password for the new administrator [" + adminUser + "]'s account: ");
|
|
|
325 |
userInput = in.readLine().trim();
|
|
|
326 |
adminPass = VEPHelperMethods.makeSHA1Hash(userInput);
|
|
|
327 |
return dbhandle.insert("vepadmin", "('" + adminUser + "', '" + adminPass + "')");
|
|
|
328 |
}
|
|
|
329 |
}
|
|
|
330 |
else
|
|
|
331 |
{
|
|
|
332 |
return false;
|
|
|
333 |
}
|
|
|
334 |
}
|
|
|
335 |
else
|
|
|
336 |
{
|
|
|
337 |
rs.close();
|
|
|
338 |
}
|
|
|
339 |
}
|
|
|
340 |
//now proceed with the argument's validation
|
|
|
341 |
rs = dbhandle.query("select", "*", "vepadmin", "where username='" + user + "'");
|
|
|
342 |
if(rs.next())
|
|
|
343 |
{
|
|
|
344 |
adminPass = VEPHelperMethods.makeSHA1Hash(pass);
|
|
|
345 |
if(rs.getString("password").equalsIgnoreCase(adminPass))
|
|
|
346 |
{
|
|
|
347 |
rs.close();
|
|
|
348 |
logger.trace("Admin Authentication successful.");
|
|
|
349 |
return true;
|
|
|
350 |
}
|
|
|
351 |
else
|
|
|
352 |
{
|
|
|
353 |
rs.close();
|
|
|
354 |
logger.trace("Admin Authentication failed.");
|
|
|
355 |
return false;
|
|
|
356 |
}
|
|
|
357 |
}
|
|
|
358 |
else
|
|
|
359 |
{
|
|
|
360 |
rs.close();
|
|
|
361 |
return false;
|
|
|
362 |
}
|
|
|
363 |
}
|
|
|
364 |
catch(Exception ex)
|
|
|
365 |
{
|
| 2678 |
pharsh |
366 |
logger.warn("Caught exception while performing admin authentication inside the CLI process: " + ex.getMessage());
|
|
|
367 |
ex.printStackTrace(System.err);
|
| 1637 |
pharsh |
368 |
return false;
|
|
|
369 |
}
|
|
|
370 |
}
|
| 1717 |
fdudouet |
371 |
|
| 3040 |
pharsh |
372 |
private void editConfiguration(PrintWriter out, BufferedReader in)
|
|
|
373 |
{
|
|
|
374 |
try
|
|
|
375 |
{
|
| 1717 |
fdudouet |
376 |
String editChoice = "";
|
|
|
377 |
String userInput = "";
|
| 1728 |
fdudouet |
378 |
out.println("\nChoose an option to edit: ");
|
| 1717 |
fdudouet |
379 |
while(!editChoice.equalsIgnoreCase("q")){
|
| 1728 |
fdudouet |
380 |
out.println("\n[d]b configuration, [l]og configuration, [o]pen nebula configuration, [c]luster configuration, [r]est configuration, [q]uit");
|
| 1717 |
fdudouet |
381 |
editChoice = in.readLine();
|
|
|
382 |
if(editChoice.equalsIgnoreCase("d")){
|
| 1893 |
pharsh |
383 |
out.println("\nChoose DB type: [m]ysql, [s]qlite. Current choice is "+VEPHelperMethods.getProperty("vepdb.choice", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
384 |
userInput = in.readLine();
|
|
|
385 |
if (userInput.equalsIgnoreCase("m"))
|
| 1893 |
pharsh |
386 |
VEPHelperMethods.addProperty("vepdb.choice", "mysql", logger, vepProperties);
|
| 1717 |
fdudouet |
387 |
else if (userInput.equalsIgnoreCase("s"))
|
| 1893 |
pharsh |
388 |
VEPHelperMethods.addProperty("vepdb.choice", "sqlite", logger, vepProperties);
|
| 1728 |
fdudouet |
389 |
out.println("\nConfiguration of the chosen database");
|
| 1893 |
pharsh |
390 |
if (VEPHelperMethods.getProperty("vepdb.choice", logger, vepProperties).equals("sqlite")){
|
|
|
391 |
out.println("\nConfigure path to the database: "+VEPHelperMethods.getProperty("sqlite.db", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
392 |
userInput = in.readLine();
|
|
|
393 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
394 |
VEPHelperMethods.addProperty("sqlite.db", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
395 |
}
|
|
|
396 |
}
|
| 1893 |
pharsh |
397 |
else if (VEPHelperMethods.getProperty("vepdb.choice", logger, vepProperties).equals("mysql")){
|
|
|
398 |
out.println("\nConfigure IP of the database: "+VEPHelperMethods.getProperty("mysql.ip", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
399 |
userInput = in.readLine();
|
|
|
400 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
401 |
VEPHelperMethods.addProperty("mysql.ip", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
402 |
}
|
| 1893 |
pharsh |
403 |
out.println("\nConfigure port of the database: "+VEPHelperMethods.getProperty("mysql.port", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
404 |
userInput = in.readLine();
|
|
|
405 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
406 |
VEPHelperMethods.addProperty("mysql.port", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
407 |
}
|
| 1893 |
pharsh |
408 |
out.println("\nConfigure chosen login of the database: "+VEPHelperMethods.getProperty("mysql.user", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
409 |
userInput = in.readLine();
|
|
|
410 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
411 |
VEPHelperMethods.addProperty("mysql.user", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
412 |
}
|
| 1893 |
pharsh |
413 |
out.println("\nConfigure password of the chosen user of the database: "+VEPHelperMethods.getProperty("mysql.pass", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
414 |
userInput = in.readLine();
|
|
|
415 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
416 |
VEPHelperMethods.addProperty("mysql.pass", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
417 |
}
|
|
|
418 |
}
|
| 1728 |
fdudouet |
419 |
out.println("\nDB configured, going back to the first menu");
|
| 1717 |
fdudouet |
420 |
}
|
|
|
421 |
else if(editChoice.equalsIgnoreCase("l")){
|
| 1893 |
pharsh |
422 |
out.println("\nConfigure path to the log file: "+VEPHelperMethods.getProperty("veplog.file", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
423 |
userInput = in.readLine();
|
|
|
424 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
425 |
VEPHelperMethods.addProperty("veplog.file", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
426 |
}
|
| 1893 |
pharsh |
427 |
out.println("\nConfigure max size to the log file: "+VEPHelperMethods.getProperty("veplog.size", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
428 |
userInput = in.readLine();
|
|
|
429 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
430 |
VEPHelperMethods.addProperty("veplog.size", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
431 |
}
|
| 1728 |
fdudouet |
432 |
out.println("\nLog file configured, going back to the first menu");
|
| 1717 |
fdudouet |
433 |
}
|
|
|
434 |
else if(editChoice.equalsIgnoreCase("o")){
|
| 1893 |
pharsh |
435 |
out.println("\nConfigure OpenNebula server's ip: "+VEPHelperMethods.getProperty("one.ip", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
436 |
userInput = in.readLine();
|
|
|
437 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
438 |
VEPHelperMethods.addProperty("one.ip", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
439 |
}
|
| 1893 |
pharsh |
440 |
out.println("\nConfigure OpenNebula server's port: "+VEPHelperMethods.getProperty("one.port", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
441 |
userInput = in.readLine();
|
|
|
442 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
443 |
VEPHelperMethods.addProperty("one.port", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
444 |
}
|
| 1893 |
pharsh |
445 |
out.println("\nConfigure OpenNebula user: "+VEPHelperMethods.getProperty("one.user", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
446 |
userInput = in.readLine();
|
|
|
447 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
448 |
VEPHelperMethods.addProperty("one.user", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
449 |
}
|
| 1893 |
pharsh |
450 |
out.println("\nConfigure OpenNebula chosen user's password: "+VEPHelperMethods.getProperty("one.pass", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
451 |
userInput = in.readLine();
|
|
|
452 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
453 |
VEPHelperMethods.addProperty("one.pass", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
454 |
}
|
| 1728 |
fdudouet |
455 |
out.println("\nOpenNebula configured, going back to the first menu");
|
| 1717 |
fdudouet |
456 |
}
|
|
|
457 |
else if(editChoice.equalsIgnoreCase("c")){
|
| 1893 |
pharsh |
458 |
out.println("\nConfigure OpenNebula cluster id for contrail: "+VEPHelperMethods.getProperty("contrail.cluster", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
459 |
userInput = in.readLine();
|
|
|
460 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
461 |
VEPHelperMethods.addProperty("contrail.cluser", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
462 |
}
|
| 1728 |
fdudouet |
463 |
out.println("\nCluster id configured, going back to the first menu");
|
| 1717 |
fdudouet |
464 |
}
|
|
|
465 |
else if(editChoice.equalsIgnoreCase("r")){
|
| 1893 |
pharsh |
466 |
out.println("\nConfigure REST keystore: "+VEPHelperMethods.getProperty("rest.keystore", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
467 |
userInput = in.readLine();
|
|
|
468 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
469 |
VEPHelperMethods.addProperty("rest.keystore", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
470 |
}
|
| 1893 |
pharsh |
471 |
out.println("\nConfigure REST keystore password: "+VEPHelperMethods.getProperty("rest.keystorepass", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
472 |
userInput = in.readLine();
|
|
|
473 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
474 |
VEPHelperMethods.addProperty("rest.keystorepass", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
475 |
}
|
| 1893 |
pharsh |
476 |
out.println("\nConfigure REST certificate's password: "+VEPHelperMethods.getProperty("rest.keypass", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
477 |
userInput = in.readLine();
|
|
|
478 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
479 |
VEPHelperMethods.addProperty("rest.keypass", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
480 |
}
|
| 1893 |
pharsh |
481 |
out.println("\nConfigure REST HTTP Port: "+VEPHelperMethods.getProperty("rest.restHTTPPort", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
482 |
userInput = in.readLine();
|
|
|
483 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
484 |
VEPHelperMethods.addProperty("rest.restHTTPPort", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
485 |
}
|
| 1893 |
pharsh |
486 |
out.println("\nConfigure REST HTTPS Port: "+VEPHelperMethods.getProperty("rest.restHTTPSPort", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
487 |
userInput = in.readLine();
|
|
|
488 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
489 |
VEPHelperMethods.addProperty("rest.restHTTPSPort", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
490 |
}
|
| 1893 |
pharsh |
491 |
out.println("\nConfigure REST mandatory authentication: "+VEPHelperMethods.getProperty("rest.clientAuthSelected", logger, vepProperties)+".");
|
| 1717 |
fdudouet |
492 |
userInput = in.readLine();
|
|
|
493 |
if(!userInput.equals("")){
|
| 1893 |
pharsh |
494 |
VEPHelperMethods.addProperty("rest.clientAuthSelected", userInput, logger, vepProperties);
|
| 1717 |
fdudouet |
495 |
}
|
| 1728 |
fdudouet |
496 |
out.println("\nREST Server configured, going back to the first menu");
|
| 1717 |
fdudouet |
497 |
}
|
|
|
498 |
else
|
| 1728 |
fdudouet |
499 |
out.println("\nExiting configuration's edit...");
|
| 1717 |
fdudouet |
500 |
}
|
|
|
501 |
logger.info("Configured local properties file");
|
|
|
502 |
}
|
| 2678 |
pharsh |
503 |
catch(Exception ex){
|
|
|
504 |
logger.warn("Caught exception while editing configuration inside the CLI process: " + ex.getMessage());
|
|
|
505 |
ex.printStackTrace(System.err);
|
| 1717 |
fdudouet |
506 |
}
|
|
|
507 |
}
|
|
|
508 |
|
| 3040 |
pharsh |
509 |
private void addDatacenter(PrintWriter out, BufferedReader in)
|
|
|
510 |
{
|
| 1717 |
fdudouet |
511 |
boolean exit = false;
|
|
|
512 |
String userInput = "";
|
|
|
513 |
String[] codes = new String[] { "AFGHANISTAN ,AF", "Ã…LAND ISLANDS ,AX", "ALBANIA ,AL", "ALGERIA ,DZ", "AMERICAN SAMOA ,AS", "ANDORRA ,AD", "ANGOLA ,AO", "ANGUILLA ,AI", "ANTARCTICA ,AQ", "ANTIGUA AND BARBUDA ,AG", "ARGENTINA ,AR", "ARMENIA ,AM", "ARUBA ,AW", "AUSTRALIA ,AU", "AUSTRIA ,AT", "AZERBAIJAN ,AZ ",
|
|
|
514 |
"BAHAMAS ,BS", "BAHRAIN ,BH", "BANGLADESH ,BD", "BARBADOS ,BB", "BELARUS ,BY", "BELGIUM ,BE", "BELIZE ,BZ", "BENIN ,BJ", "BERMUDA ,BM", "BHUTAN ,BT", "BOLIVIA; PLURINATIONAL STATE OF ,BO", "BONAIRE; SINT EUSTATIUS AND SABA ,BQ", "BOSNIA AND HERZEGOVINA ,BA", "BOTSWANA ,BW", "BOUVET ISLAND ,BV", "BRAZIL ,BR", "BRITISH INDIAN OCEAN TERRITORY ,IO", "BRUNEI DARUSSALAM ,BN", "BULGARIA ,BG",
|
|
|
515 |
"BURKINA FASO ,BF", "BURUNDI ,BI ", "CAMBODIA ,KH", "CAMEROON ,CM", "CANADA ,CA", "CAPE VERDE ,CV", "CAYMAN ISLANDS ,KY", "CENTRAL AFRICAN REPUBLIC ,CF","CHAD ,TD", "CHILE ,CL", "CHINA ,CN", "CHRISTMAS ISLAND ,CX", "COCOS (KEELING) ISLANDS ,CC", "COLOMBIA ,CO", "COMOROS ,KM", "CONGO ,CG", "CONGO; THE DEMOCRATIC REPUBLIC OF THE ,CD", "COOK ISLANDS ,CK", "COSTA RICA ,CR", "CÔTE D'IVOIRE ,CI",
|
|
|
516 |
"CROATIA ,HR", "CUBA ,CU", "CURAÇAO ,CW", "CYPRUS ,CY", "CZECH REPUBLIC ,CZ ", "DENMARK ,DK", "DJIBOUTI ,DJ", "DOMINICA ,DM", "DOMINICAN REPUBLIC ,DO ", "ECUADOR ,EC", "EGYPT ,EG", "EL SALVADOR ,SV", "EQUATORIAL GUINEA ,GQ", "ERITREA ,ER", "ESTONIA ,EE", "ETHIOPIA ,ET ", "FALKLAND ISLANDS (MALVINAS) ,FK","FAROE ISLANDS ,FO", "FIJI ,FJ", "FINLAND ,FI", "FRANCE ,FR", "FRENCH GUIANA ,GF",
|
|
|
517 |
"FRENCH POLYNESIA ,PF", "FRENCH SOUTHERN TERRITORIES ,TF ", "GABON ,GA", "GAMBIA ,GM", "GEORGIA ,GE", "GERMANY ,DE", "GHANA ,GH", "GIBRALTAR ,GI", "GREECE ,GR", "GREENLAND ,GL", "GRENADA ,GD", "GUADELOUPE ,GP", "GUAM ,GU", "GUATEMALA ,GT", "GUERNSEY ,GG", "GUINEA ,GN", "GUINEA-BISSAU ,GW", "GUYANA ,GY ", "HAITI ,HT", "HEARD ISLAND AND MCDONALD ISLANDS ,HM", "HOLY SEE (VATICAN CITY STATE) ,VA",
|
|
|
518 |
"HONDURAS ,HN", "HONG KONG ,HK", "HUNGARY ,HU ", "ICELAND ,IS", "INDIA ,IN", "INDONESIA ,ID", "IRAN; ISLAMIC REPUBLIC OF ,IR", "IRAQ ,IQ", "IRELAND ,IE", "ISLE OF MAN ,IM", "ISRAEL ,IL", "ITALY ,IT ", "JAMAICA ,JM", "JAPAN ,JP", "JERSEY ,JE", "JORDAN ,JO ", "KAZAKHSTAN ,KZ", "KENYA ,KE", "KIRIBATI ,KI", "KOREA; DEMOCRATIC PEOPLE'S REPUBLIC OF ,KP", "KOREA; REPUBLIC OF ,KR", "KUWAIT ,KW", "KYRGYZSTAN ,KG ",
|
|
|
519 |
"LAO PEOPLE'S DEMOCRATIC REPUBLIC ,LA", "LATVIA ,LV", "LEBANON ,LB", "LESOTHO ,LS", "LIBERIA ,LR", "LIBYAN ARAB JAMAHIRIYA ,LY", "LIECHTENSTEIN ,LI", "LITHUANIA ,LT", "LUXEMBOURG ,LU ", "MACAO ,MO", "MACEDONIA; THE FORMER YUGOSLAV REPUBLIC OF ,MK", "MADAGASCAR ,MG", "MALAWI ,MW", "MALAYSIA ,MY", "MALDIVES ,MV", "MALI ,ML", "MALTA ,MT", "MARSHALL ISLANDS ,MH", "MARTINIQUE ,MQ", "MAURITANIA ,MR", "MAURITIUS ,MU",
|
|
|
520 |
"MAYOTTE ,YT", "MEXICO ,MX", "MICRONESIA; FEDERATED STATES OF ,FM", "MOLDOVA; REPUBLIC OF ,MD", "MONACO ,MC", "MONGOLIA ,MN", "MONTENEGRO ,ME", "MONTSERRAT ,MS", "MOROCCO ,MA", "MOZAMBIQUE ,MZ", "MYANMAR ,MM ", "NAMIBIA ,NA", "NAURU ,NR", "NEPAL ,NP", "NETHERLANDS ,NL", "NEW CALEDONIA ,NC", "NEW ZEALAND ,NZ", "NICARAGUA ,NI", "NIGER ,NE", "NIGERIA ,NG", "NIUE ,NU", "NORFOLK ISLAND ,NF", "NORTHERN MARIANA ISLANDS ,MP",
|
|
|
521 |
"NORWAY ,NO ", "OMAN ,OM ", "PAKISTAN ,PK", "PALAU ,PW", "PALESTINIAN TERRITORY; OCCUPIED ,PS", "PANAMA ,PA", "PAPUA NEW GUINEA ,PG", "PARAGUAY ,PY", "PERU ,PE", "PHILIPPINES ,PH", "PITCAIRN ,PN", "POLAND ,PL", "PORTUGAL ,PT", "PUERTO RICO ,PR ", "QATAR ,QA ", "RÉUNION ,RE", "ROMANIA ,RO", "RUSSIAN FEDERATION ,RU", "RWANDA ,RW ", "SAINT BARTHÉLEMY ,BL", "SAINT HELENA; ASCENSION AND TRISTAN DA CUNHA ,SH",
|
|
|
522 |
"SAINT KITTS AND NEVIS ,KN", "SAINT LUCIA ,LC", "SAINT MARTIN (FRENCH PART) ,MF", "SAINT PIERRE AND MIQUELON ,PM", "SAINT VINCENT AND THE GRENADINES ,VC", "SAMOA ,WS", "SAN MARINO ,SM", "SAO TOME AND PRINCIPE ,ST", "SAUDI ARABIA ,SA", "SENEGAL ,SN", "SERBIA ,RS", "SEYCHELLES ,SC", "SIERRA LEONE ,SL", "SINGAPORE ,SG", "SINT MAARTEN (DUTCH PART) ,SX", "SLOVAKIA ,SK", "SLOVENIA ,SI", "SOLOMON ISLANDS ,SB",
|
|
|
523 |
"SOMALIA ,SO", "SOUTH AFRICA ,ZA", "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS ,GS", "SPAIN ,ES", "SRI LANKA ,LK", "SUDAN ,SD", "SURINAME ,SR", "SVALBARD AND JAN MAYEN ,SJ ", "SWAZILAND ,SZ", "SWEDEN ,SE", "SWITZERLAND ,CH", "SYRIAN ARAB REPUBLIC ,SY ", "TAIWAN; PROVINCE OF CHINA ,TW", "TAJIKISTAN ,TJ", "TANZANIA; UNITED REPUBLIC OF ,TZ", "THAILAND ,TH", "TIMOR-LESTE ,TL", "TOGO ,TG", "TOKELAU ,TK", "TONGA ,TO",
|
|
|
524 |
"TRINIDAD AND TOBAGO ,TT", "TUNISIA ,TN", "TURKEY ,TR", "TURKMENISTAN ,TM", "TURKS AND CAICOS ISLANDS ,TC", "TUVALU ,TV ", "UGANDA ,UG", "UKRAINE ,UA", "UNITED ARAB EMIRATES ,AE", "UNITED KINGDOM ,GB", "UNITED STATES ,US", "UNITED STATES MINOR OUTLYING ISLANDS ,UM", "URUGUAY ,UY",
|
|
|
525 |
"UZBEKISTAN ,UZ ", "VANUATU ,VU ", "VENEZUELA; BOLIVARIAN REPUBLIC OF ,VE", "VIET NAM ,VN", "VIRGIN ISLANDS; BRITISH ,VG", "VIRGIN ISLANDS; U.S. ,VI ", "WALLIS AND FUTUNA ,WF", "WESTERN SAHARA ,EH ", "YEMEN ,YE ", "ZAMBIA ,ZM", "ZIMBABWE ,ZW " };
|
|
|
526 |
Set<String> locCodes = new HashSet<String>(Arrays.asList(new String[] {"AF", "AX", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG", "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB", "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI", "KH", "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK", "CR", "CI", "HR", "CU", "CW", "CY", "CZ", "DK", "DJ", "DM", "DO", "EC", "EG",
|
|
|
527 |
"SV", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF", "TF", "GA", "GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN", "HK", "HU", "IS", "IN", "ID", "IR", "IQ", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KP", "KR", "KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK", "MG", "MW", "MY", "MV", "ML",
|
|
|
528 |
"MT", "MH", "MQ", "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME", "MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP", "NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA", "RE", "RO", "RU", "RW", "BL", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS", "SC", "SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "ES",
|
|
|
529 |
"LK", "SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM", "TC", "TV", "UG", "UA", "AE", "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN", "VG", "VI", "WF", "EH", "YE", "ZM", "ZW"}));
|
|
|
530 |
|
|
|
531 |
try {
|
|
|
532 |
while (!exit)
|
|
|
533 |
{
|
|
|
534 |
String dname = "";
|
|
|
535 |
String dloc = "";
|
|
|
536 |
String ddesc = "";
|
| 1728 |
fdudouet |
537 |
out.println("\nAdd a new datacenter:");
|
|
|
538 |
out.println("\nEnter a name - enter nothing to exit");
|
| 1717 |
fdudouet |
539 |
userInput = in.readLine();
|
|
|
540 |
if(userInput.equals(""))
|
|
|
541 |
exit = true;
|
|
|
542 |
else
|
|
|
543 |
{
|
| 1728 |
fdudouet |
544 |
out.println("\nAdding a new datacenter called "+userInput);
|
| 1717 |
fdudouet |
545 |
dname = userInput;
|
|
|
546 |
while (dloc.equals("") && !exit)
|
|
|
547 |
{
|
| 1728 |
fdudouet |
548 |
out.println("\nEnter the code of its location (2 letters): Enter c to get a list of codes, otherwise enter the chosen code (2 letters)");
|
| 1717 |
fdudouet |
549 |
userInput = in.readLine();
|
|
|
550 |
if (userInput.equals("")){
|
|
|
551 |
exit = true;
|
| 1728 |
fdudouet |
552 |
out.println("\nExiting... ");
|
| 1717 |
fdudouet |
553 |
}
|
|
|
554 |
else if(userInput.equalsIgnoreCase("c"))
|
|
|
555 |
out.println(Arrays.toString(codes));
|
|
|
556 |
else if(userInput.length() != 2)
|
| 1728 |
fdudouet |
557 |
out.println("\nCode should be 2 letters' length");
|
| 1717 |
fdudouet |
558 |
else if(!locCodes.contains(userInput.toUpperCase()))
|
| 1728 |
fdudouet |
559 |
out.println("\nthis code is not in the authorized list");
|
| 1717 |
fdudouet |
560 |
else
|
|
|
561 |
{
|
| 1728 |
fdudouet |
562 |
out.println("\nChosen code: "+userInput);
|
| 1717 |
fdudouet |
563 |
dloc = userInput;
|
| 1728 |
fdudouet |
564 |
out.println("\nEnter a description on one line (facultative):");
|
| 1717 |
fdudouet |
565 |
ddesc = in.readLine();
|
| 1728 |
fdudouet |
566 |
out.println("\nAdding a new datacenter with these values:\nName: "+dname+"\nLoc: "+dloc+"\nDesc:"+ddesc);
|
| 1717 |
fdudouet |
567 |
userInput = "";
|
|
|
568 |
boolean recheck = true;
|
|
|
569 |
while ((userInput == null)||recheck){
|
| 1728 |
fdudouet |
570 |
out.println("\nConfirm? (y)es/(n)o");
|
| 1717 |
fdudouet |
571 |
userInput = in.readLine();
|
|
|
572 |
if(userInput.equalsIgnoreCase("y") || userInput.equalsIgnoreCase("n"))
|
|
|
573 |
recheck = false;
|
|
|
574 |
}
|
|
|
575 |
if(userInput.equalsIgnoreCase("y")){
|
|
|
576 |
ResultSet rs = dbhandle.query("select", "max(did)", "datacenter", "");
|
|
|
577 |
int did = 0;
|
|
|
578 |
if(rs.next())
|
|
|
579 |
did = rs.getInt(1) + 1;
|
|
|
580 |
logger.debug("New datacenter id to be assigned: " + did);
|
|
|
581 |
boolean status = dbhandle.insert("datacenter", "(" + did + ", '" + dloc.toUpperCase() + "', '" + dname + "', '" + ddesc + "')");
|
|
|
582 |
if(status)
|
|
|
583 |
{
|
| 1728 |
fdudouet |
584 |
out.println("\nDatacenter was added successfully with datacenter ID: " + did + "\n");
|
| 1717 |
fdudouet |
585 |
logger.debug("Datacenter was added successfully with datacenter ID: " + did);
|
|
|
586 |
}
|
|
|
587 |
else
|
|
|
588 |
{
|
|
|
589 |
logger.error("Datacenter " + did + " addition failed. Error during insert operation into datacenter table.");
|
|
|
590 |
exit = true;
|
|
|
591 |
}
|
|
|
592 |
}
|
|
|
593 |
else
|
|
|
594 |
{
|
|
|
595 |
exit = true;
|
| 1728 |
fdudouet |
596 |
out.println("\nExiting...");
|
| 1717 |
fdudouet |
597 |
}
|
|
|
598 |
}
|
|
|
599 |
}
|
|
|
600 |
}
|
|
|
601 |
}
|
|
|
602 |
} catch (Exception ex) {
|
|
|
603 |
logger.error("Caught exception while adding a datacenter inside the CLI process: " + ex.getMessage());
|
|
|
604 |
ex.printStackTrace(System.err);
|
|
|
605 |
}
|
|
|
606 |
}
|
|
|
607 |
|
|
|
608 |
private void addCluster(PrintWriter out, BufferedReader in) {
|
|
|
609 |
boolean exit = false;
|
|
|
610 |
String userInput = "";
|
|
|
611 |
String[] codes = new String[] { "000, no selection", "001, Gigabit Ethernet", "002, Gigabit Ethernet (Level 5 NICs)", "003, 10 Gigabit Ethernet", "004, Infiniband", "005, Infinipath", "006, Myrinet", "007, QsNet (Quadrics)", "008, SCI (Dolphin)" };
|
|
|
612 |
Set<String> nics = new HashSet(Arrays.asList(new String[]{"000","001","002","003","004","005","006","007","008"}));
|
|
|
613 |
Map<String, String> dcenters = new HashMap<String,String>();
|
|
|
614 |
try {
|
|
|
615 |
int count = 0;
|
|
|
616 |
ResultSet rs = dbhandle.query("SELECT", "did, name", "datacenter", "");
|
|
|
617 |
while(rs.next())
|
|
|
618 |
{
|
|
|
619 |
dcenters.put(Integer.toString(rs.getInt("did")), rs.getString("name"));
|
|
|
620 |
count++;
|
|
|
621 |
}
|
|
|
622 |
if(count == 0)
|
|
|
623 |
{
|
|
|
624 |
logger.warn("No datacenter was found.");
|
| 1728 |
fdudouet |
625 |
out.println("\nThere must be at least 1 datacenter to connect this cluster to, please add one.");
|
| 1717 |
fdudouet |
626 |
exit = true;
|
|
|
627 |
}
|
|
|
628 |
while(!exit){
|
|
|
629 |
String cname = "";
|
|
|
630 |
String cnic = "";
|
|
|
631 |
String did = "";
|
|
|
632 |
String cdesc = "";
|
| 1728 |
fdudouet |
633 |
out.println("\nAdd a new cluster:");
|
|
|
634 |
out.println("\nEnter a name - enter nothing to exit");
|
| 1717 |
fdudouet |
635 |
userInput = in.readLine();
|
|
|
636 |
if(userInput.equals(""))
|
|
|
637 |
exit = true;
|
|
|
638 |
else
|
|
|
639 |
{
|
| 1728 |
fdudouet |
640 |
out.println("\nAdding a new cluster called "+userInput);
|
| 1717 |
fdudouet |
641 |
cname = userInput;
|
|
|
642 |
while(cnic.equals("") && !exit){
|
| 1728 |
fdudouet |
643 |
out.println("\nChoose interconnection: Enter c to get a list of codes, otherwise enter the chosen code (3 digits)");
|
| 1717 |
fdudouet |
644 |
userInput = in.readLine();
|
|
|
645 |
if (userInput.equals("")){
|
|
|
646 |
exit = true;
|
| 1728 |
fdudouet |
647 |
out.println("\nExiting... ");
|
| 1717 |
fdudouet |
648 |
}
|
|
|
649 |
else if(userInput.equalsIgnoreCase("c"))
|
|
|
650 |
out.println(Arrays.toString(codes));
|
|
|
651 |
else if(userInput.length() != 3)
|
| 1728 |
fdudouet |
652 |
out.println("\nCode should be 3 digits' length");
|
| 1717 |
fdudouet |
653 |
else if(!nics.contains(userInput.toUpperCase()))
|
| 1728 |
fdudouet |
654 |
out.println("\nthis code is not in the authorized list");
|
| 1717 |
fdudouet |
655 |
else
|
|
|
656 |
{
|
| 1728 |
fdudouet |
657 |
out.println("\nChosen code: "+userInput);
|
| 1717 |
fdudouet |
658 |
cnic = userInput;
|
|
|
659 |
while(did.equals("") && !exit){
|
| 1728 |
fdudouet |
660 |
out.println("\nChoose the datacenter this cluster belongs to: Enter c to get a list of codes, otherwise enter the chosen code (id)");
|
| 1717 |
fdudouet |
661 |
userInput = in.readLine();
|
|
|
662 |
if (userInput.equals("")){
|
|
|
663 |
exit = true;
|
| 1728 |
fdudouet |
664 |
out.println("\nExiting... ");
|
| 1717 |
fdudouet |
665 |
}
|
|
|
666 |
else if(userInput.equalsIgnoreCase("c"))
|
|
|
667 |
{
|
| 1728 |
fdudouet |
668 |
out.println("\nid : name");
|
| 1717 |
fdudouet |
669 |
for (Map.Entry<String, String> e : dcenters.entrySet())
|
|
|
670 |
out.println(e.getKey()+" : "+e.getValue());
|
|
|
671 |
}
|
|
|
672 |
else if(!dcenters.containsKey(userInput))
|
| 1728 |
fdudouet |
673 |
out.println("\nthis code is not in the authorized list");
|
| 1717 |
fdudouet |
674 |
else
|
|
|
675 |
{
|
| 1728 |
fdudouet |
676 |
out.println("\nChosen datacenter: "+userInput+", "+dcenters.get(userInput));
|
| 1717 |
fdudouet |
677 |
did = userInput;
|
| 1728 |
fdudouet |
678 |
out.println("\nEnter a description on one line (facultative):");
|
| 1717 |
fdudouet |
679 |
cdesc = in.readLine();
|
|
|
680 |
|
| 1728 |
fdudouet |
681 |
out.println("\nAdding a new cluster with these values:\r\nName: "+cname+"\r\nInterconnection: "+cnic
|
| 1717 |
fdudouet |
682 |
+"\r\nDatacenter: "+did+"\r\nDesc:"+cdesc);
|
|
|
683 |
userInput = "";
|
|
|
684 |
boolean recheck = true;
|
|
|
685 |
while ((userInput == null)||recheck){
|
| 1728 |
fdudouet |
686 |
out.println("\nConfirm? (y)es/(n)o");
|
| 1717 |
fdudouet |
687 |
userInput = in.readLine();
|
|
|
688 |
if(userInput.equalsIgnoreCase("y") || userInput.equalsIgnoreCase("n"))
|
|
|
689 |
recheck = false;
|
|
|
690 |
}
|
|
|
691 |
if(userInput.equalsIgnoreCase("y")){
|
|
|
692 |
rs = dbhandle.query("select", "max(clid)", "cluster", "");
|
|
|
693 |
int clid = 0;
|
|
|
694 |
if(rs.next())
|
|
|
695 |
clid = rs.getInt(1) + 1;
|
|
|
696 |
logger.debug("New cluster id to be assigned: " + did);
|
|
|
697 |
boolean status = dbhandle.insert("cluster", "(" + clid + ", '" + cnic + "', " + did + ", '" + cdesc + "', '" + cname + "')");
|
|
|
698 |
if(status)
|
|
|
699 |
{
|
| 1728 |
fdudouet |
700 |
out.println("\nCluster was added successfully with cluster ID: " + clid + "\n");
|
| 1717 |
fdudouet |
701 |
logger.debug("Cluster was added successfully with cluster ID: " + clid);
|
|
|
702 |
}
|
|
|
703 |
else
|
|
|
704 |
{
|
|
|
705 |
logger.error("cluster " + clid + " addition failed. Error during insert operation into datacenter table.");
|
|
|
706 |
exit = true;
|
|
|
707 |
}
|
|
|
708 |
}
|
|
|
709 |
else
|
|
|
710 |
{
|
|
|
711 |
exit = true;
|
| 1728 |
fdudouet |
712 |
out.println("\nExiting...");
|
| 1717 |
fdudouet |
713 |
}
|
|
|
714 |
}
|
|
|
715 |
}
|
|
|
716 |
}
|
|
|
717 |
}
|
|
|
718 |
}
|
|
|
719 |
}
|
|
|
720 |
} catch (Exception ex) {
|
|
|
721 |
logger.error("Caught exception while adding a cluster inside the CLI process: " + ex.getMessage());
|
|
|
722 |
ex.printStackTrace(System.err);
|
|
|
723 |
}
|
|
|
724 |
}
|
|
|
725 |
|
|
|
726 |
private void addRack(PrintWriter out, BufferedReader in) {
|
|
|
727 |
boolean exit = false;
|
|
|
728 |
String userInput = "";
|
|
|
729 |
Map<String, String> clusters = new HashMap<String,String>();
|
|
|
730 |
try {
|
|
|
731 |
int count = 0;
|
|
|
732 |
ResultSet rs = dbhandle.query("SELECT", "clid, name", "cluster", "");
|
|
|
733 |
while(rs.next())
|
|
|
734 |
{
|
|
|
735 |
clusters.put(Integer.toString(rs.getInt("clid")), rs.getString("name"));
|
|
|
736 |
count++;
|
|
|
737 |
}
|
|
|
738 |
if(count == 0)
|
|
|
739 |
{
|
|
|
740 |
logger.warn("No cluster was found.");
|
| 1728 |
fdudouet |
741 |
out.println("\nThere must be at least 1 cluster to connect this rack to, please add one.");
|
| 1717 |
fdudouet |
742 |
exit = true;
|
|
|
743 |
}
|
|
|
744 |
while(!exit){
|
|
|
745 |
String rname = "";
|
|
|
746 |
String clid = "";
|
|
|
747 |
String rdesc = "";
|
| 1728 |
fdudouet |
748 |
out.println("\nAdd a new datacenter:");
|
|
|
749 |
out.println("\nEnter a name - enter nothing to exit");
|
| 1717 |
fdudouet |
750 |
userInput = in.readLine();
|
|
|
751 |
if(userInput.equals(""))
|
|
|
752 |
exit = true;
|
|
|
753 |
else
|
|
|
754 |
{
|
| 1728 |
fdudouet |
755 |
out.println("\nAdding a new rack called "+userInput);
|
| 1717 |
fdudouet |
756 |
rname = userInput;
|
|
|
757 |
while(clid.equals("") && !exit){
|
| 1728 |
fdudouet |
758 |
out.println("\nChoose the cluster this rack belongs to: Enter c to get a list of codes, otherwise enter the chosen code (id)");
|
| 1717 |
fdudouet |
759 |
userInput = in.readLine();
|
|
|
760 |
if (userInput.equals("")){
|
|
|
761 |
exit = true;
|
| 1728 |
fdudouet |
762 |
out.println("\nExiting... ");
|
| 1717 |
fdudouet |
763 |
}
|
|
|
764 |
else if(userInput.equalsIgnoreCase("c"))
|
|
|
765 |
{
|
| 1728 |
fdudouet |
766 |
out.println("\nid : name");
|
| 1717 |
fdudouet |
767 |
for (Map.Entry<String, String> e : clusters.entrySet())
|
|
|
768 |
out.println(e.getKey()+" : "+e.getValue());
|
|
|
769 |
}
|
|
|
770 |
else if(!clusters.containsKey(userInput))
|
| 1728 |
fdudouet |
771 |
out.println("\nthis code is not in the authorized list");
|
| 1717 |
fdudouet |
772 |
else
|
|
|
773 |
{
|
| 1728 |
fdudouet |
774 |
out.println("\nChosen cluster: "+userInput+", "+clusters.get(userInput));
|
| 1717 |
fdudouet |
775 |
clid = userInput;
|
| 1728 |
fdudouet |
776 |
out.println("\nEnter a description on one line (facultative):");
|
| 1717 |
fdudouet |
777 |
rdesc = in.readLine();
|
|
|
778 |
|
| 1728 |
fdudouet |
779 |
out.println("\nAdding a new rack with these values:\r\nName: "+rname+"\r\ncluster: "+clid+"\r\nDesc:"+rdesc);
|
| 1717 |
fdudouet |
780 |
userInput = "";
|
|
|
781 |
boolean recheck = true;
|
|
|
782 |
while ((userInput == null)||recheck){
|
| 1728 |
fdudouet |
783 |
out.println("\nConfirm? (y)es/(n)o");
|
| 1717 |
fdudouet |
784 |
userInput = in.readLine();
|
|
|
785 |
if(userInput.equalsIgnoreCase("y") || userInput.equalsIgnoreCase("n"))
|
|
|
786 |
recheck = false;
|
|
|
787 |
}
|
|
|
788 |
if(userInput.equalsIgnoreCase("y")){
|
| 1728 |
fdudouet |
789 |
rs = dbhandle.query("select", "max(rid)", "rack", "");
|
| 1717 |
fdudouet |
790 |
int rid = 0;
|
|
|
791 |
if(rs.next())
|
|
|
792 |
rid = rs.getInt(1) + 1;
|
|
|
793 |
logger.debug("New rack id to be assigned: " + rid);
|
|
|
794 |
boolean status = dbhandle.insert("rack", "(" + rid + ", " + clid + ", '" + rname + "', '" + rdesc + "')");
|
|
|
795 |
if(status)
|
|
|
796 |
{
|
| 1728 |
fdudouet |
797 |
out.println("\nRack was added successfully with rack ID: " + clid + "\n");
|
| 1717 |
fdudouet |
798 |
logger.debug("Rack was added successfully with rack ID: " + clid);
|
|
|
799 |
}
|
|
|
800 |
else
|
|
|
801 |
{
|
|
|
802 |
logger.error("rack " + rid + " addition failed. Error during insert operation into rack table.");
|
|
|
803 |
exit = true;
|
|
|
804 |
}
|
|
|
805 |
}
|
|
|
806 |
else
|
|
|
807 |
{
|
|
|
808 |
exit = true;
|
| 1728 |
fdudouet |
809 |
out.println("\nExiting...");
|
| 1717 |
fdudouet |
810 |
}
|
|
|
811 |
}
|
|
|
812 |
}
|
|
|
813 |
}
|
|
|
814 |
}
|
|
|
815 |
} catch (Exception ex) {
|
|
|
816 |
logger.error("Caught exception while adding a rack inside the CLI process: " + ex.getMessage());
|
|
|
817 |
ex.printStackTrace(System.err);
|
|
|
818 |
}
|
|
|
819 |
}
|
| 1637 |
pharsh |
820 |
|
| 1728 |
fdudouet |
821 |
/**
|
|
|
822 |
* Gets all available nodes from provider
|
|
|
823 |
* @return List of nodes' description
|
|
|
824 |
*/
|
| 2678 |
pharsh |
825 |
private List<String> getNodes(){
|
| 1728 |
fdudouet |
826 |
//TODO : Actually add XML parsing
|
|
|
827 |
//based on PeriodicThread. Why use a direct connection to one instead of the onexmlrpchandler class?
|
|
|
828 |
Client oneClient;
|
| 1893 |
pharsh |
829 |
String oneUser = VEPHelperMethods.getProperty("one.user", logger, vepProperties);
|
|
|
830 |
String onePass = VEPHelperMethods.getProperty("one.pass", logger, vepProperties);
|
|
|
831 |
String oneIP = VEPHelperMethods.getProperty("one.ip", logger, vepProperties);
|
|
|
832 |
String onePort = VEPHelperMethods.getProperty("one.port", logger, vepProperties);
|
| 1728 |
fdudouet |
833 |
if (oneUser!= null && onePass!=null && oneIP!=null && onePort!=null){
|
|
|
834 |
try
|
|
|
835 |
{
|
|
|
836 |
oneClient = new Client(oneUser + ":" + onePass, "http://" + oneIP + ":" + onePort + "/RPC2");
|
|
|
837 |
}
|
|
|
838 |
catch(Exception ex)
|
|
|
839 |
{
|
|
|
840 |
logger.error("Unable to connect to OpenNebula. Check system properties and try again.");
|
|
|
841 |
oneClient = null;
|
|
|
842 |
}
|
|
|
843 |
if(oneClient != null)
|
|
|
844 |
{
|
|
|
845 |
OneResponse val = HostPool.info(oneClient);
|
|
|
846 |
String response = "";
|
|
|
847 |
if(!val.isError())
|
|
|
848 |
{
|
|
|
849 |
response = val.getMessage();
|
|
|
850 |
}
|
|
|
851 |
else
|
|
|
852 |
{
|
|
|
853 |
logger.warn("OpenNebula XML-RPC connection error. Check OpenNebula connection seetings under system properties. Check if oned is running.");
|
|
|
854 |
}
|
|
|
855 |
//parse the XML response and populate the table next
|
|
|
856 |
if(response.length() > 1)
|
|
|
857 |
{
|
|
|
858 |
//parse XML here
|
| 2678 |
pharsh |
859 |
createTable(response, this.nodes);
|
| 1728 |
fdudouet |
860 |
}
|
|
|
861 |
}
|
|
|
862 |
}
|
|
|
863 |
else
|
|
|
864 |
{
|
|
|
865 |
logger.warn("One or more of the needed properties to connect to OpenNebula are missing.");
|
|
|
866 |
}
|
| 2678 |
pharsh |
867 |
return this.nodes;
|
| 1728 |
fdudouet |
868 |
}
|
|
|
869 |
|
|
|
870 |
private void listHost(PrintWriter out, BufferedReader in) {
|
|
|
871 |
boolean exit = false;
|
|
|
872 |
String userInput = "";
|
| 2678 |
pharsh |
873 |
nodes = new ArrayList<String>();
|
| 1728 |
fdudouet |
874 |
try {
|
|
|
875 |
while(!exit){
|
|
|
876 |
out.println("\nListing hosts");
|
| 2678 |
pharsh |
877 |
//TODO: Change text of next line
|
|
|
878 |
out.println("1:List all available nodes registered on provider");
|
| 1728 |
fdudouet |
879 |
out.println("2:List all nodes already in the federation");
|
|
|
880 |
out.println("q:Quit listing");
|
|
|
881 |
userInput = in.readLine();
|
|
|
882 |
if(userInput.equals("1"))
|
|
|
883 |
{
|
| 2678 |
pharsh |
884 |
//TODO: Test getNodes method
|
| 1728 |
fdudouet |
885 |
nodes = getNodes();
|
|
|
886 |
}
|
|
|
887 |
else if(userInput.equals("2"))
|
|
|
888 |
{
|
|
|
889 |
nodes = getFederationNodes();
|
|
|
890 |
}
|
|
|
891 |
else if(userInput.equals("q")){
|
|
|
892 |
out.println("\nExiting...");
|
|
|
893 |
exit = true;
|
|
|
894 |
}
|
|
|
895 |
if (!nodes.isEmpty()){
|
|
|
896 |
out.println("\nListing...");
|
|
|
897 |
out.println("NodeID : Hostname : CPU : Memory");
|
|
|
898 |
for (String node : nodes)
|
|
|
899 |
out.println(node);
|
|
|
900 |
nodes.clear();
|
|
|
901 |
}
|
|
|
902 |
}
|
|
|
903 |
} catch (Exception ex) {
|
|
|
904 |
logger.error("Caught exception while listing hosts inside the CLI process: " + ex.getMessage());
|
|
|
905 |
ex.printStackTrace(System.err);
|
|
|
906 |
}
|
|
|
907 |
}
|
| 2678 |
pharsh |
908 |
|
| 1728 |
fdudouet |
909 |
/**
|
|
|
910 |
* Get Nodes already in federation
|
|
|
911 |
* @return List of nodes' description
|
|
|
912 |
*/
|
| 2678 |
pharsh |
913 |
private List<String> getFederationNodes()
|
|
|
914 |
{
|
|
|
915 |
List<String> nodes1 = new ArrayList<String>();
|
|
|
916 |
try
|
|
|
917 |
{
|
| 1728 |
fdudouet |
918 |
ResultSet rs = dbhandle.query("select", "cid,hostname,cpu,mem", "computenode", "");
|
| 2678 |
pharsh |
919 |
while (rs.next())
|
|
|
920 |
{
|
|
|
921 |
nodes1.add(Integer.toString(rs.getInt("cid"))+" : " + rs.getString("hostname")+" : "+Integer.toString(rs.getInt("cpu"))+" : "+Integer.toString(rs.getInt("mem")));
|
| 1728 |
fdudouet |
922 |
}
|
| 2678 |
pharsh |
923 |
}
|
|
|
924 |
catch (Exception ex)
|
|
|
925 |
{
|
| 1728 |
fdudouet |
926 |
logger.error("Caught exception while getting federation nodes inside the CLI process: " + ex.getMessage());
|
|
|
927 |
ex.printStackTrace(System.err);
|
|
|
928 |
}
|
| 2678 |
pharsh |
929 |
return nodes1;
|
| 1728 |
fdudouet |
930 |
}
|
| 2678 |
pharsh |
931 |
|
|
|
932 |
private void addHost(PrintWriter out, BufferedReader in) {
|
|
|
933 |
boolean exit = false;
|
|
|
934 |
ONExmlrpcHandler oneHandle = null;
|
|
|
935 |
try
|
|
|
936 |
{
|
|
|
937 |
String oneUser = VEPHelperMethods.getProperty("one.user", logger, vepProperties);
|
|
|
938 |
String onePass = VEPHelperMethods.getProperty("one.pass", logger, vepProperties);
|
|
|
939 |
String oneIP = VEPHelperMethods.getProperty("one.ip", logger, vepProperties);
|
|
|
940 |
String onePort = VEPHelperMethods.getProperty("one.port", logger, vepProperties);
|
|
|
941 |
if (oneUser!= null && onePass!=null && oneIP!=null && onePort!=null){
|
|
|
942 |
oneHandle = new ONExmlrpcHandler(oneIP, onePort, oneUser, onePass, "CLIServer:AddHost");
|
|
|
943 |
} else {
|
|
|
944 |
exit = true;
|
|
|
945 |
}
|
|
|
946 |
|
|
|
947 |
while (!exit)
|
|
|
948 |
{
|
|
|
949 |
String userInput = "";
|
|
|
950 |
out.println("\nAdd a host : You will need hostname, information driver, virtualization driver, storage driver");
|
| 1728 |
fdudouet |
951 |
|
| 2678 |
pharsh |
952 |
String hostname = "";
|
|
|
953 |
while(hostname.equals("") && !exit){
|
|
|
954 |
out.println("\nEnter host name, enter 'exit' to exit");
|
|
|
955 |
userInput = in.readLine();
|
|
|
956 |
if(userInput.equals("exit"))
|
|
|
957 |
{
|
|
|
958 |
exit = true;
|
|
|
959 |
out.println("Exiting...");
|
|
|
960 |
}
|
|
|
961 |
else if(!userInput.equals(""))
|
|
|
962 |
{
|
|
|
963 |
hostname = userInput;
|
|
|
964 |
userInput = "";
|
|
|
965 |
String infoD = "";
|
|
|
966 |
while(infoD.equals("") && !exit)
|
|
|
967 |
{
|
|
|
968 |
out.println("\nEnter information driver, enter 'exit' to exit");
|
|
|
969 |
userInput = in.readLine();
|
|
|
970 |
//TODO : provide list, for now it assumes user knows what he's doing
|
|
|
971 |
if(userInput.equals("exit"))
|
|
|
972 |
{
|
|
|
973 |
exit = true;
|
|
|
974 |
out.println("Exiting...");
|
|
|
975 |
}
|
|
|
976 |
else if(!userInput.equals(""))
|
|
|
977 |
{
|
|
|
978 |
infoD = userInput;
|
|
|
979 |
userInput = "";
|
|
|
980 |
String virtD = "";
|
|
|
981 |
while(virtD.equals("") && !exit)
|
|
|
982 |
{
|
|
|
983 |
out.println("\nEnter virtualization driver, enter 'exit' to exit");
|
|
|
984 |
userInput = in.readLine();
|
|
|
985 |
if(userInput.equals("exit"))
|
|
|
986 |
{
|
|
|
987 |
exit = true;
|
|
|
988 |
out.println("Exiting...");
|
|
|
989 |
}
|
|
|
990 |
else if(!userInput.equals(""))
|
|
|
991 |
{
|
|
|
992 |
virtD = userInput;
|
|
|
993 |
userInput = "";
|
|
|
994 |
String storD = "";
|
|
|
995 |
while(storD.equals("") && !exit)
|
|
|
996 |
{
|
|
|
997 |
out.println("\nEnter storage driver, enter 'exit' to exit");
|
|
|
998 |
userInput = in.readLine();
|
|
|
999 |
if(userInput.equals("exit"))
|
|
|
1000 |
{
|
|
|
1001 |
exit = true;
|
|
|
1002 |
out.println("Exiting...");
|
|
|
1003 |
}
|
|
|
1004 |
else if(!userInput.equals(""))
|
|
|
1005 |
{
|
|
|
1006 |
storD = userInput;
|
|
|
1007 |
userInput = "";
|
|
|
1008 |
out.println("\nthis host will be added:");
|
|
|
1009 |
out.println(hostname+" : "+infoD+" : "+virtD+" : "+storD);
|
|
|
1010 |
boolean recheck = true;
|
|
|
1011 |
while ((userInput == null)||recheck)
|
|
|
1012 |
{
|
|
|
1013 |
out.println("\nConfirm? (y)es/(n)o");
|
|
|
1014 |
userInput = in.readLine();
|
|
|
1015 |
if(userInput.equalsIgnoreCase("y") || userInput.equalsIgnoreCase("n"))
|
|
|
1016 |
recheck = false;
|
|
|
1017 |
}
|
|
|
1018 |
if(userInput.equalsIgnoreCase("y"))
|
|
|
1019 |
{
|
|
|
1020 |
boolean status = oneHandle.addHost(hostname, infoD, virtD, storD);
|
|
|
1021 |
if(status)
|
|
|
1022 |
out.println("Host was added successfully");
|
|
|
1023 |
else
|
|
|
1024 |
out.println("Host addition failed, please check the logs for more information");
|
|
|
1025 |
}
|
|
|
1026 |
else
|
|
|
1027 |
out.println("\nCancelling...");
|
|
|
1028 |
}
|
|
|
1029 |
}
|
|
|
1030 |
}
|
|
|
1031 |
}
|
|
|
1032 |
}
|
|
|
1033 |
}
|
|
|
1034 |
}
|
|
|
1035 |
}
|
|
|
1036 |
}
|
|
|
1037 |
} catch(Exception ex) {
|
|
|
1038 |
logger.error("Caught exception while getting federation nodes inside the CLI process: " + ex.getMessage());
|
|
|
1039 |
ex.printStackTrace(System.err);
|
|
|
1040 |
}
|
|
|
1041 |
}
|
|
|
1042 |
|
| 1728 |
fdudouet |
1043 |
/**
|
|
|
1044 |
* Add node to federation
|
|
|
1045 |
* @param out
|
|
|
1046 |
* @param in
|
|
|
1047 |
*/
|
|
|
1048 |
private void addFedAdmin(PrintWriter out, BufferedReader in) {
|
|
|
1049 |
|
| 2678 |
pharsh |
1050 |
ResultSet rs;
|
|
|
1051 |
VEPComputeNode VCNode = new VEPComputeNode();
|
|
|
1052 |
Map<String, String> rackList = new HashMap<String, String>();
|
|
|
1053 |
Map<String, String> vorgList = new HashMap<String, String>();
|
|
|
1054 |
Map<String, String> clMngrMap = new HashMap<String, String>();
|
|
|
1055 |
clMngrMap.put("-1", "No manager selected");
|
|
|
1056 |
clMngrMap.put("1", "OpenNebula");
|
|
|
1057 |
clMngrMap.put("2", "OpenStack");
|
|
|
1058 |
clMngrMap.put("3", "Nimbus");
|
|
|
1059 |
clMngrMap.put("4", "Eucalyptus");
|
|
|
1060 |
|
| 1728 |
fdudouet |
1061 |
boolean exit = false;
|
| 1893 |
pharsh |
1062 |
String oneUser = VEPHelperMethods.getProperty("one.user", logger, vepProperties);
|
|
|
1063 |
String onePass = VEPHelperMethods.getProperty("one.pass", logger, vepProperties);
|
|
|
1064 |
String oneIP = VEPHelperMethods.getProperty("one.ip", logger, vepProperties);
|
|
|
1065 |
String onePort = VEPHelperMethods.getProperty("one.port", logger, vepProperties);
|
| 1728 |
fdudouet |
1066 |
if (oneUser!= null && onePass!=null && oneIP!=null && onePort!=null){
|
|
|
1067 |
try {
|
|
|
1068 |
ONExmlrpcHandler oneHandle = new ONExmlrpcHandler(oneIP, onePort, oneUser, onePass, "CLIServer:AddFedAdmin");
|
|
|
1069 |
//check to see if cluster contrail is present or not
|
| 1893 |
pharsh |
1070 |
String clusterId = VEPHelperMethods.getProperty("contrail.cluster", logger, vepProperties);
|
| 1728 |
fdudouet |
1071 |
int id = -1;
|
|
|
1072 |
if(clusterId == null || clusterId.length() == 0 || Integer.parseInt(clusterId) < 0)
|
|
|
1073 |
{
|
|
|
1074 |
LinkedList<ONECluster> clusterList = oneHandle.getClusterList();
|
|
|
1075 |
boolean found = false;
|
|
|
1076 |
for(int i=0; i< clusterList.size(); i++)
|
|
|
1077 |
{
|
|
|
1078 |
if(clusterList.get(i).name.equalsIgnoreCase("contrail"))
|
|
|
1079 |
{
|
|
|
1080 |
found = true;
|
|
|
1081 |
id = clusterList.get(i).id;
|
|
|
1082 |
break;
|
|
|
1083 |
}
|
|
|
1084 |
}
|
|
|
1085 |
if(!found)
|
|
|
1086 |
{
|
|
|
1087 |
id = oneHandle.addCluster("contrail");
|
|
|
1088 |
if(id == -1)
|
|
|
1089 |
logger.error("Could not create the contrail cluster. Check ONE settings and try again.");
|
|
|
1090 |
else
|
|
|
1091 |
{
|
| 1893 |
pharsh |
1092 |
boolean status = VEPHelperMethods.addProperty("contrail.cluster", Integer.toString(id), logger, vepProperties);
|
| 1728 |
fdudouet |
1093 |
if(status == false)
|
|
|
1094 |
logger.error("Could not insert contrail.cluster property in the settings file.");
|
|
|
1095 |
}
|
|
|
1096 |
}
|
|
|
1097 |
else
|
|
|
1098 |
{
|
| 1893 |
pharsh |
1099 |
boolean status = VEPHelperMethods.addProperty("contrail.cluster", Integer.toString(id), logger, vepProperties);
|
| 1728 |
fdudouet |
1100 |
if(status == false)
|
|
|
1101 |
logger.error("Could not insert contrail.cluster property in the settings file.");
|
|
|
1102 |
}
|
|
|
1103 |
}
|
|
|
1104 |
else
|
|
|
1105 |
{
|
|
|
1106 |
try
|
|
|
1107 |
{
|
|
|
1108 |
id = Integer.parseInt(clusterId);
|
|
|
1109 |
}
|
|
|
1110 |
catch(Exception ex)
|
|
|
1111 |
{
|
|
|
1112 |
logger.error("Format error in value contrail.cluster. Fix error and try again.");
|
| 2678 |
pharsh |
1113 |
exit = true;
|
| 1728 |
fdudouet |
1114 |
return;
|
|
|
1115 |
}
|
|
|
1116 |
}
|
|
|
1117 |
//now test to see if cluster is actually present
|
|
|
1118 |
String response = oneHandle.getClusterInfo(id);
|
|
|
1119 |
//if cluster is present then add this node to contrail cluster
|
|
|
1120 |
if(response != null && response.contains("contrail"))
|
|
|
1121 |
{
|
| 2678 |
pharsh |
1122 |
while (!exit)
|
|
|
1123 |
{
|
|
|
1124 |
String userInput = "";
|
|
|
1125 |
String rackId = "";
|
|
|
1126 |
String vorgId = "";
|
|
|
1127 |
String clManager = "";
|
|
|
1128 |
String hostid = "";
|
|
|
1129 |
String description = "";
|
|
|
1130 |
while(!exit && hostid.equals("")){
|
|
|
1131 |
out.println("Enter a hostid to add to federation, enter exit to exit:");
|
|
|
1132 |
userInput = in.readLine();
|
|
|
1133 |
if (userInput.equalsIgnoreCase("exit")){
|
|
|
1134 |
exit = true;
|
|
|
1135 |
out.println("Exiting...");
|
| 1728 |
fdudouet |
1136 |
}
|
| 2678 |
pharsh |
1137 |
else
|
|
|
1138 |
{
|
|
|
1139 |
//test node existence
|
|
|
1140 |
oneHandle.getHostInfo(Integer.parseInt(userInput), null, VCNode);
|
|
|
1141 |
if(VCNode.hostname == null)
|
|
|
1142 |
out.println("This host id does not exist, please try again");
|
|
|
1143 |
else
|
| 1728 |
fdudouet |
1144 |
{
|
| 2678 |
pharsh |
1145 |
hostid = userInput;
|
|
|
1146 |
//test node existence
|
|
|
1147 |
oneHandle.getHostInfo(Integer.parseInt(hostid), null, VCNode);
|
|
|
1148 |
|
|
|
1149 |
//Enter rack info
|
|
|
1150 |
// Do not update the rack list if already there, it should not be needed
|
|
|
1151 |
if (rackList.isEmpty()){
|
|
|
1152 |
rs = dbhandle.query("SELECT", "rid, name", "rack", "");
|
|
|
1153 |
int count = 0;
|
|
|
1154 |
while(rs.next())
|
|
|
1155 |
{
|
|
|
1156 |
String rid = Integer.toString(rs.getInt("rid"));
|
|
|
1157 |
String name = rs.getString("name");
|
|
|
1158 |
logger.trace("Composing racklist: found rack " + rid + "," + name);
|
|
|
1159 |
rackList.put(rid,name);
|
|
|
1160 |
count++;
|
|
|
1161 |
|
|
|
1162 |
}
|
|
|
1163 |
if(count == 0){
|
|
|
1164 |
//There is no rack in the db, add one first
|
|
|
1165 |
out.println("There is no rack in the database, please register one");
|
|
|
1166 |
exit = true;
|
|
|
1167 |
}
|
|
|
1168 |
}
|
|
|
1169 |
//If rackList contains some elements
|
|
|
1170 |
|
|
|
1171 |
while (!exit && rackId.equals(""))
|
|
|
1172 |
{
|
|
|
1173 |
out.println("\nChoose the rack id of this node : Enter c to get a list of codes, exit to exit, otherwise enter the chosen code (id)");
|
|
|
1174 |
userInput = in.readLine();
|
|
|
1175 |
if (userInput.equalsIgnoreCase("exit")){
|
|
|
1176 |
exit = true;
|
|
|
1177 |
out.println("Exiting...");
|
|
|
1178 |
}
|
|
|
1179 |
else if(userInput.equalsIgnoreCase("c")){
|
|
|
1180 |
//output the rack list
|
|
|
1181 |
out.println("\rid : name");
|
|
|
1182 |
for (Map.Entry<String, String> e : rackList.entrySet())
|
|
|
1183 |
out.println(e.getKey()+" : "+e.getValue());
|
|
|
1184 |
}
|
|
|
1185 |
else
|
|
|
1186 |
{
|
|
|
1187 |
rackId = userInput;
|
|
|
1188 |
out.println("\nChosen rack: "+userInput+", "+rackList.get(userInput));
|
|
|
1189 |
|
|
|
1190 |
// Now to vorg choice
|
|
|
1191 |
// Populate vorgList if empty
|
|
|
1192 |
if (vorgList.isEmpty()){
|
|
|
1193 |
rs = dbhandle.query("select DISTINCT", "vid, name", "vorg", "");
|
|
|
1194 |
int count = 0;
|
|
|
1195 |
while(rs.next())
|
|
|
1196 |
{
|
|
|
1197 |
String vid = Integer.toString(rs.getInt("vid"));
|
|
|
1198 |
String name = rs.getString("name");
|
|
|
1199 |
logger.trace("Composing vorglist: found vorg " + vid + "," + name);
|
|
|
1200 |
vorgList.put(vid,name);
|
|
|
1201 |
count++;
|
|
|
1202 |
}
|
|
|
1203 |
vorgList.put("-1", "No VOrg assigned");
|
|
|
1204 |
}
|
|
|
1205 |
//If vorgList contains some elements
|
|
|
1206 |
while (vorgId.equals("") && !exit)
|
|
|
1207 |
{
|
|
|
1208 |
out.println("\nChoose the vorg id of this node : Enter c to get a list of codes, exit to exit, otherwise enter the chosen code (id)");
|
|
|
1209 |
userInput = in.readLine();
|
|
|
1210 |
if (userInput.equalsIgnoreCase("exit")){
|
|
|
1211 |
exit = true;
|
|
|
1212 |
out.println("Exiting...");
|
|
|
1213 |
}
|
|
|
1214 |
else if(userInput.equalsIgnoreCase("c")){
|
|
|
1215 |
//output the vorg list
|
|
|
1216 |
out.println("\nvid : name");
|
|
|
1217 |
for (Map.Entry<String, String> e : vorgList.entrySet())
|
|
|
1218 |
out.println(e.getKey()+" : "+e.getValue());
|
|
|
1219 |
}
|
|
|
1220 |
else
|
|
|
1221 |
{
|
|
|
1222 |
vorgId = userInput;
|
|
|
1223 |
out.println("\nChosen vorg: "+userInput+", "+vorgList.get(userInput));
|
|
|
1224 |
|
|
|
1225 |
//Now enter Cluster Manager
|
|
|
1226 |
while(!exit && clManager.equals(""))
|
|
|
1227 |
{
|
|
|
1228 |
out.println("\nChoose the cluster manager id of this node : Enter c to get a list of codes, exit to exit, otherwise enter the chosen code (id)");
|
|
|
1229 |
userInput = in.readLine();
|
|
|
1230 |
if (userInput.equalsIgnoreCase("exit")){
|
|
|
1231 |
exit = true;
|
|
|
1232 |
out.println("Exiting...");
|
|
|
1233 |
}
|
|
|
1234 |
else if(userInput.equalsIgnoreCase("c")){
|
|
|
1235 |
//output the cl mngr list
|
|
|
1236 |
out.println("\nclid : name");
|
|
|
1237 |
for (Map.Entry<String, String> e : clMngrMap.entrySet())
|
|
|
1238 |
out.println(e.getKey()+" : "+e.getValue());
|
|
|
1239 |
}
|
|
|
1240 |
else {
|
|
|
1241 |
clManager = clMngrMap.get(userInput);
|
|
|
1242 |
out.println("\nChosen cluster manager: "+userInput+", "+clMngrMap.get(userInput));
|
|
|
1243 |
|
|
|
1244 |
//add description
|
|
|
1245 |
while(!exit && description.equals("")){
|
|
|
1246 |
out.println("Enter a description, exit to exit");
|
|
|
1247 |
userInput = in.readLine();
|
|
|
1248 |
if (userInput.equalsIgnoreCase("exit"))
|
|
|
1249 |
{
|
|
|
1250 |
exit = true;
|
|
|
1251 |
out.println("Exiting...");
|
|
|
1252 |
}
|
|
|
1253 |
else if(!dbHandler.validateSentence(userInput))
|
|
|
1254 |
out.println("Some characters are not allowed, please try again");
|
|
|
1255 |
else
|
|
|
1256 |
{
|
|
|
1257 |
description = userInput;
|
|
|
1258 |
//now do the final checks
|
|
|
1259 |
//add this host to the cluster contrail and store its information in the VEP computenode table
|
|
|
1260 |
boolean recheck = true;
|
|
|
1261 |
while ((userInput == null)||recheck){
|
|
|
1262 |
out.println("\nConfirm? (y)es/(n)o");
|
|
|
1263 |
userInput = in.readLine();
|
|
|
1264 |
if(userInput.equalsIgnoreCase("y") || userInput.equalsIgnoreCase("n"))
|
|
|
1265 |
recheck = false;
|
|
|
1266 |
}
|
|
|
1267 |
if(userInput.equalsIgnoreCase("y")){
|
|
|
1268 |
try
|
|
|
1269 |
{
|
|
|
1270 |
VCNode.rackId = rackId;
|
|
|
1271 |
VCNode.virtualOrgId = vorgId;
|
|
|
1272 |
VCNode.clusterManagerType = clManager;
|
|
|
1273 |
VCNode.description = description;
|
|
|
1274 |
|
|
|
1275 |
//Use insert or update from VEPComputeNode
|
|
|
1276 |
//TODO: Test the next 6 lines and uncomment
|
|
|
1277 |
if(VCNode.checkAction(dbhandle))
|
|
|
1278 |
VCNode.update(dbhandle, logger);
|
|
|
1279 |
else
|
|
|
1280 |
VCNode.insert(dbhandle, logger);
|
|
|
1281 |
//then one handle add host
|
|
|
1282 |
oneHandle.addHostToCluster(id, Integer.parseInt(hostid));
|
|
|
1283 |
}
|
|
|
1284 |
catch(Exception ex)
|
|
|
1285 |
{
|
|
|
1286 |
out.println("Host " + hostid + " could not be added to contrail cluster in OpenNebula.");
|
|
|
1287 |
}
|
|
|
1288 |
}
|
|
|
1289 |
else
|
|
|
1290 |
out.println("Cancelling...");
|
|
|
1291 |
}
|
|
|
1292 |
}
|
|
|
1293 |
}
|
|
|
1294 |
}
|
|
|
1295 |
}
|
|
|
1296 |
}
|
|
|
1297 |
}
|
|
|
1298 |
}
|
| 1728 |
fdudouet |
1299 |
}
|
|
|
1300 |
}
|
|
|
1301 |
}
|
|
|
1302 |
}
|
|
|
1303 |
}
|
| 2678 |
pharsh |
1304 |
} catch (Exception e) {
|
|
|
1305 |
out.println("Caught exception while adding a node to federation inside the CLI process : ");
|
|
|
1306 |
logger.error("Caught exception while adding a node to federation inside the CLI process : ");
|
|
|
1307 |
e.printStackTrace(System.err);
|
|
|
1308 |
exit = true;
|
| 1728 |
fdudouet |
1309 |
}
|
|
|
1310 |
}
|
|
|
1311 |
else
|
|
|
1312 |
{
|
|
|
1313 |
logger.error("One or more of the needed properties to connect to OpenNebula are missing.");
|
|
|
1314 |
out.println("One or more of the needed properties to connect to OpenNebula are missing.");
|
|
|
1315 |
}
|
|
|
1316 |
}
|
| 2678 |
pharsh |
1317 |
|
| 1717 |
fdudouet |
1318 |
|
| 2678 |
pharsh |
1319 |
public void createTable(String input, List<String> nodes)
|
|
|
1320 |
{
|
|
|
1321 |
rowList = new LinkedList<ONEHost>();
|
|
|
1322 |
SAXParserFactory spf = SAXParserFactory.newInstance();
|
|
|
1323 |
try
|
|
|
1324 |
{
|
|
|
1325 |
SAXParser sp = spf.newSAXParser();
|
|
|
1326 |
InputSource is = new InputSource();
|
|
|
1327 |
is.setCharacterStream(new StringReader(input));
|
|
|
1328 |
sp.parse(is, this);
|
|
|
1329 |
}
|
|
|
1330 |
catch(SAXException se)
|
|
|
1331 |
{
|
|
|
1332 |
if(logger.isDebugEnabled())
|
|
|
1333 |
se.printStackTrace(System.err);
|
|
|
1334 |
else
|
|
|
1335 |
logger.warn(se.getMessage());
|
|
|
1336 |
}
|
|
|
1337 |
catch(ParserConfigurationException pce)
|
|
|
1338 |
{
|
|
|
1339 |
if(logger.isDebugEnabled())
|
|
|
1340 |
pce.printStackTrace(System.err);
|
|
|
1341 |
else
|
|
|
1342 |
logger.warn(pce.getMessage());
|
|
|
1343 |
}
|
|
|
1344 |
catch(IOException ie)
|
|
|
1345 |
{
|
|
|
1346 |
if(logger.isDebugEnabled())
|
|
|
1347 |
ie.printStackTrace(System.err);
|
|
|
1348 |
else
|
|
|
1349 |
logger.warn(ie.getMessage());
|
|
|
1350 |
}
|
|
|
1351 |
}
|
|
|
1352 |
|
|
|
1353 |
@Override
|
|
|
1354 |
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
|
|
|
1355 |
{
|
|
|
1356 |
tempVal = "";
|
|
|
1357 |
if(qName.equalsIgnoreCase("HOST"))
|
|
|
1358 |
{
|
|
|
1359 |
tempHost = new ONEHost(); //blank it for new row
|
|
|
1360 |
}
|
|
|
1361 |
}
|
|
|
1362 |
|
|
|
1363 |
@Override
|
|
|
1364 |
public void characters(char[] ch, int start, int length) throws SAXException
|
|
|
1365 |
{
|
|
|
1366 |
tempVal = new String(ch,start,length);
|
|
|
1367 |
}
|
|
|
1368 |
|
|
|
1369 |
@Override
|
|
|
1370 |
public void endElement(String uri, String localName, String qName) throws SAXException
|
|
|
1371 |
{
|
|
|
1372 |
if(qName.equalsIgnoreCase("HOST"))
|
|
|
1373 |
{
|
|
|
1374 |
rowList.add(tempHost);
|
|
|
1375 |
}
|
|
|
1376 |
else if(qName.equalsIgnoreCase("ID"))
|
|
|
1377 |
{
|
|
|
1378 |
tempHost.id = tempVal;
|
|
|
1379 |
}
|
|
|
1380 |
else if(qName.equalsIgnoreCase("NAME"))
|
|
|
1381 |
{
|
|
|
1382 |
tempHost.name = tempVal;
|
|
|
1383 |
}
|
|
|
1384 |
else if(qName.equalsIgnoreCase("STATE"))
|
|
|
1385 |
{
|
|
|
1386 |
tempHost.state = tempVal;
|
|
|
1387 |
}
|
|
|
1388 |
else if(qName.equalsIgnoreCase("IM_MAD"))
|
|
|
1389 |
{
|
|
|
1390 |
tempHost.im_mad = tempVal;
|
|
|
1391 |
}
|
|
|
1392 |
else if(qName.equalsIgnoreCase("VM_MAD"))
|
|
|
1393 |
{
|
|
|
1394 |
tempHost.vm_mad = tempVal;
|
|
|
1395 |
}
|
|
|
1396 |
else if(qName.equalsIgnoreCase("TM_MAD"))
|
|
|
1397 |
{
|
|
|
1398 |
tempHost.tm_mad = tempVal;
|
|
|
1399 |
}
|
|
|
1400 |
else if(qName.equalsIgnoreCase("LAST_MON_TIME"))
|
|
|
1401 |
{
|
|
|
1402 |
tempHost.mon_time = tempVal;
|
|
|
1403 |
}
|
|
|
1404 |
else if(qName.equalsIgnoreCase("CLUSTER"))
|
|
|
1405 |
{
|
|
|
1406 |
tempHost.cluster = tempVal;
|
|
|
1407 |
}
|
|
|
1408 |
else if(qName.equalsIgnoreCase("FREE_MEM"))
|
|
|
1409 |
{
|
|
|
1410 |
tempHost.free_mem = tempVal;
|
|
|
1411 |
}
|
|
|
1412 |
else if(qName.equalsIgnoreCase("USED_MEM"))
|
|
|
1413 |
{
|
|
|
1414 |
tempHost.used_mem = tempVal;
|
|
|
1415 |
}
|
|
|
1416 |
else if(qName.equalsIgnoreCase("FREE_CPU"))
|
|
|
1417 |
{
|
|
|
1418 |
tempHost.free_cpu = tempVal;
|
|
|
1419 |
}
|
|
|
1420 |
else if(qName.equalsIgnoreCase("USED_CPU"))
|
|
|
1421 |
{
|
|
|
1422 |
tempHost.used_cpu = tempVal;
|
|
|
1423 |
}
|
|
|
1424 |
else if(qName.equalsIgnoreCase("CPUSPEED"))
|
|
|
1425 |
{
|
|
|
1426 |
tempHost.cpuspeed = tempVal;
|
|
|
1427 |
}
|
|
|
1428 |
else if(qName.equalsIgnoreCase("MAX_CPU"))
|
|
|
1429 |
{
|
|
|
1430 |
tempHost.max_cpu = tempVal;
|
|
|
1431 |
}
|
|
|
1432 |
else if(qName.equalsIgnoreCase("MAX_MEM"))
|
|
|
1433 |
{
|
|
|
1434 |
tempHost.max_mem = tempVal;
|
|
|
1435 |
}
|
|
|
1436 |
else if(qName.equalsIgnoreCase("HOST_POOL"))
|
|
|
1437 |
{
|
|
|
1438 |
String outVal = "";
|
|
|
1439 |
|
|
|
1440 |
//resetting the running stat
|
|
|
1441 |
|
|
|
1442 |
for(ONEHost temp : rowList)
|
|
|
1443 |
{
|
|
|
1444 |
//here also check if in contrail cluster then update the running stats
|
|
|
1445 |
if(temp.cluster.equalsIgnoreCase("contrail"))
|
|
|
1446 |
{
|
|
|
1447 |
try
|
|
|
1448 |
{
|
|
|
1449 |
runningStat.freeMemory += Double.parseDouble(temp.free_mem);
|
|
|
1450 |
runningStat.usedMemory += Double.parseDouble(temp.used_mem);
|
|
|
1451 |
double cpSpeed = Double.parseDouble(temp.cpuspeed);
|
|
|
1452 |
double maxcpu = Double.parseDouble(temp.free_cpu) + Double.parseDouble(temp.used_cpu);
|
|
|
1453 |
runningStat.freeCPU = (cpSpeed * (maxcpu/100.0)) * (Double.parseDouble(temp.free_cpu)/maxcpu);
|
|
|
1454 |
runningStat.usedCPU = (cpSpeed * (maxcpu/100.0)) * (Double.parseDouble(temp.used_cpu)/maxcpu);
|
|
|
1455 |
// System.out.println("\n" + runningStat.freeMemory + "-" + runningStat.usedMemory + "|" + runningStat.freeCPU + "-" + runningStat.usedCPU + "\n");
|
|
|
1456 |
}
|
|
|
1457 |
catch(Exception ex)
|
|
|
1458 |
{
|
|
|
1459 |
//do nothing, ignore
|
|
|
1460 |
}
|
|
|
1461 |
}
|
|
|
1462 |
outVal = temp.id + " : " + temp.name + " : " + temp.max_cpu + " : " + temp.max_mem;
|
|
|
1463 |
nodes.add(outVal);
|
|
|
1464 |
logger.trace("Found host: " + temp.id + " " + temp.name + " " + temp.state + " " + temp.im_mad + " " + temp.vm_mad + " " + temp.tm_mad + " " + temp.cluster + " " + temp.mon_time);
|
|
|
1465 |
}
|
|
|
1466 |
}
|
|
|
1467 |
}
|
|
|
1468 |
}
|