/******************************************************************************* * =========================================================== * Ankush : Big Data Cluster Management Solution * =========================================================== * * (C) Copyright 2014, by Impetus Technologies * * This is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License (LGPL v3) as * published by the Free Software Foundation; * * This software is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ******************************************************************************/ /** * */ package com.impetus.ankush.common.utils; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import net.neoremind.sshxcute.core.ConnBean; import net.neoremind.sshxcute.core.Result; import net.neoremind.sshxcute.core.SSHExec; import net.neoremind.sshxcute.exception.TaskExecFailException; import net.neoremind.sshxcute.task.CustomTask; import net.neoremind.sshxcute.task.impl.ExecCommand; import com.impetus.ankush2.constant.Constant; import com.impetus.ankush.common.scripting.AnkushTask; import com.impetus.ankush.common.scripting.impl.AppendFileUsingEcho; import com.impetus.ankush.common.scripting.impl.ExecSudoCommand; import com.impetus.ankush2.logger.AnkushLogger; /** * The Class SSHUtils. * * @author mayur */ public class SSHUtils { /** The logger. */ private static AnkushLogger logger = new AnkushLogger(SSHUtils.class); /** The Constant LS_COMMAND. */ private static final String LS_COMMAND = "ls "; /** The Constant LINE_SEPARATOR. */ private static final String LINE_SEPARATOR = "\n"; private static boolean generateRSAKeyFiles(String publicIp, String username, String password, String privateKey) throws TaskExecFailException { CustomTask task = new ExecCommand( "[[ -f ~/.ssh/id_rsa ]] || ssh-keygen -q -t rsa -P '' -f ~/.ssh/id_rsa; "); SSHExec connection = SSHUtils.connectToNode(publicIp, username, password, privateKey); if (connection.exec(task).rc != 0) { return false; } if (connection != null) { connection.disconnect(); } return true; } /** * Connect to node. * * @param node * the node * @param username * the username * @param password * the password * @param privateKey * the private key * @return the sSH exec */ public static SSHExec connectToNode(String node, String username, String password, String privateKey) { try { // create connection bean node = node.trim(); if (node == null || node.isEmpty()) { return null; } if (username == null || username.isEmpty()) { return null; } ConnBean connectionBean = new ConnBean(node, username, password, privateKey); // singleton bug fix SSHExec connection = new SSHExec(connectionBean); // connect to node/machine Boolean isConnected = connection.connect(); if (isConnected) { return connection; } else { return null; } } catch (Exception e) { logger.error(e.getMessage(), e); return null; } } /** * Action. * * @param passwword * the passwword * @param connection * the connection * @param commands * the commands * @return true, if successful * @author hokam chauhan */ public static boolean action(String passwword, SSHExec connection, String... commands) { CustomTask execTask = new ExecSudoCommand(passwword, commands); boolean done = false; try { if (connection != null) { Result rs = connection.exec(execTask); if (rs.rc == 0) { done = true; } } } catch (Exception e) { logger.error(e.getMessage(), e); } return done; } /** * Action. * * @param connection * the connection * @param commands * the commands * @return true, if successful * @author hokam chauhan */ public static boolean action(SSHExec connection, String... commands) { CustomTask execTask = new ExecCommand(commands); boolean done = false; try { if (connection != null) { Result rs = connection.exec(execTask); if (rs.rc == 0) { done = true; } } } catch (Exception e) { logger.error(e.getMessage(), e); } return done; } /** * Get the Content of the File. * * @param filePath * the file path * @param hostname * Ip Address of Host * @param username * User name for the host * @param authInfo * password/sharedkey * @param authUsingPassword * Using password or shared key for connection * @return The Content of the file. * @throws Exception * the exception * @author hokam chauhan */ public static String getFileContents(String filePath, String hostname, String username, String authInfo, boolean authUsingPassword) throws Exception { String output = null; // Making the SSH Connection. SSHConnection connection = new SSHConnection(hostname, username, authInfo, authUsingPassword); if (!connection.isConnected()) { throw new Exception("Unable to connect to node."); } /* Executing the command. */ if (connection.exec("cat " + filePath)) { if (connection.getExitStatus() == 0) { // Getting the output of command. output = connection.getOutput(); } else { String error = connection.getError(); if (error.contains("No such file")) { throw new Exception(filePath + " does not exists"); } else if (error.contains("Permission denied")) { throw new Exception("Invalid permissions on " + filePath); } } } return output; } public static String getFileContents(SSHExec connection, String filePath) throws Exception { String output = null; Result res = connection.exec(new ExecCommand("cat " + filePath)); output = res.sysout; return output; } public static String getFileContents(String filePath, String hostname, String username, String password, String privateKeyFilePath) throws Exception { String output = null; // Making the SSH Connection. SSHConnection connection = new SSHConnection(hostname, username, password, privateKeyFilePath); if (!connection.isConnected()) { throw new Exception("Unable to connect to node."); } /* Executing the command. */ if (connection.exec("cat " + filePath)) { if (connection.getExitStatus() == 0) { // Getting the output of command. output = connection.getOutput(); } else { String error = connection.getError(); if (error.contains("No such file")) { throw new Exception(filePath + " does not exists"); } else if (error.contains("Permission denied")) { throw new Exception("Invalid permissions on " + filePath); } } } return output; } /** * Find out OSName of remote machine. * * @param hostname * the hostname * @param username * the username * @param authInfo * password/sharedkey * @param authUsingPassword * the auth using password * @return the os */ public static String getOS(String hostname, String username, String authInfo, boolean authUsingPassword) { String osName = ""; SSHConnection connection = null; try { /* Making connection to the node. */ connection = new SSHConnection(hostname, username, authInfo, authUsingPassword); // if connected. if (connection.isConnected()) { osName = ""; /* Executing the command. */ if (connection.exec("cat /etc/*-release")) { String output = connection.getOutput().toLowerCase(); if (output != null) { if (output.contains("ubuntu")) { osName = "Ubuntu"; } if (output.contains("centos")) { osName = "CentOS"; } if (output.contains("opensuse")) { osName = "openSUSE"; } if (output.contains("fedora")) { osName = "Fedora"; } if (output.contains("red hat enterprise linux")) { osName = "RHEL"; } } } } } catch (Exception e) { return osName; } return osName; } /** * Get JavaHome path from remote machine. * * @param hostname * the hostname * @param username * the username * @param authInfo * password/sharedkey * @param authUsingPassword * the auth using password * @return the java home */ public static String getJavaHome(String hostname, String username, String authInfo, boolean authUsingPassword) { /* Making connection to the node. */ SSHConnection connection = new SSHConnection(hostname, username, authInfo, authUsingPassword); /* Executing the command. */ if (connection.exec("readlink -f `which jps`")) { String output = connection.getOutput(); if (output != null) { return output.replace("bin/jps", ""); } } return null; } /** * Get JavaHome path from remote machine. * * @param hostname * the hostname * @param username * the username * @param authInfo * password/sharedkey * @param authUsingPassword * the auth using password * @return the java home */ public static String getJavaVersion(String hostname, String username, String authInfo, boolean authUsingPassword) { /* Making connection to the node. */ SSHConnection connection = new SSHConnection(hostname, username, authInfo, authUsingPassword); /* Executing the command. */ if (connection.exec("java -version")) { String output = connection.getOutput(); if (output == null) { output = connection.getError(); } if (output != null) { String strJavaVersion = output.substring(0, output.indexOf("\n")); String javaVersion = strJavaVersion.substring( strJavaVersion.indexOf("\""), strJavaVersion.length() - 1); return javaVersion; } } return null; } public static Map getCommandOutputAndError(String command, String hostname, String username, String authInfo, boolean authUsingPassword) { Map map = new HashMap(); String output = null; boolean status = false; /* Making connection to the node. */ SSHConnection connection = new SSHConnection(hostname, username, authInfo, authUsingPassword); /* Executing the command. */ if (connection.exec(command)) { if (connection.getExitStatus() != 0) { output = connection.getError(); } else { /* Getting the output from connection object. */ output = connection.getOutput(); status = true; } } else { // command is not executed successfully,getting the Error. output = connection.getError(); } /* Returning the output of command. */ map.put(com.impetus.ankush2.constant.Constant.Keys.STATUS, status); map.put(com.impetus.ankush2.constant.Constant.Keys.OUTPUT, output); return map; } /** * Execute the Command and Return the command output. * * @param command * the command * @param hostname * the hostname * @param username * the username * @param authInfo * the auth info * @param authUsingPassword * the auth using password * @return the command output * @throws Exception * the exception * @author Hokam Chauhan */ public static String getCommandOutput(String command, String hostname, String username, String authInfo, boolean authUsingPassword) throws Exception { String output = null; /* Making connection to the node. */ SSHConnection connection = new SSHConnection(hostname, username, authInfo, authUsingPassword); /* Executing the command. */ if (connection.exec(command)) { if (connection.getExitStatus() != 0) { output = connection.getError(); throw new Exception(connection.getError()); } /* Getting the output from connection object. */ output = connection.getOutput(); } /* Returning the output of command. */ return output; } /** * Check command. * * @param hostname * the hostname * @param username * the username * @param password * the password * @param privateKey * the private key * @param command * the command * @return true, if successful */ public static boolean getCommandStatus(SSHExec connection, String command) { CustomTask task = new ExecCommand(command); try { if (connection == null) { return false; } Result result = connection.exec(task); if (result.rc == 0) { return true; } } catch (TaskExecFailException e) { logger.error(e.getMessage(), e); } catch (Exception e) { logger.error(e.getMessage(), e); } return false; } /** * Method to Get the list of path found in remote directory. * * @param hostname * the hostname * @param username * the username * @param authInfo * the auth info * @param authUsingPassword * the auth using password * @param directoryPath * the directory path * @return The list of paths for files and directories. * @throws Exception * the exception */ public static List<String> listDirectory(String hostname, String username, String authInfo, boolean authUsingPassword, String directoryPath) throws Exception { // Create ls command String lsCommand = LS_COMMAND + directoryPath; // Executing command and getting the command output String commandOutput = SSHUtils.getCommandOutput(lsCommand, hostname, username, authInfo, authUsingPassword); // Create list object List<String> paths = new ArrayList<String>(); // if command output not null. if (commandOutput != null) { // Splitting the output by '\n' String[] fileNameList = commandOutput.split(LINE_SEPARATOR); // Iterating over the filename list. paths.addAll(Arrays.asList(fileNameList)); } else { // throwing the exception throw new Exception("Unable to connect to node."); } return paths; } /** * Method to execute list of tasks. If any one fails it return backs the * result of failed task otherwise the last task result. * * @param tasks * @return */ public static Result executeTasks(List<AnkushTask> tasks, SSHExec connection) { Result result = null; try { // iterating over the tasks. for (AnkushTask task : tasks) { // executing command result = connection.exec(task); // if command execution failed break the for loop if (result.rc != 0) { break; } } } catch (Exception e) { logger.error("Could not execute the tasks.", e); } // returning result. return result; } /** * Adds the process info. * */ public static boolean addAgentConfig(SSHExec connection, String className) { try { // line seperator. String lineSeperator = "\n"; // JPS service status monitor class name. className = lineSeperator + className; // add task information in taskable conf. AnkushTask task = new AppendFileUsingEcho(className, Constant.Agent.AGENT_TASKABLE_FILE_PATH); connection.exec(task); return true; } catch (TaskExecFailException e) { logger.error("Error in adding agent informations..", e); } catch (Exception e) { logger.error("Error in adding agent informations..", e); } return false; } }