/* * Copyright 2014 by SCSK Corporation. * * This file is part of PrimeCloud Controller(TM). * * PrimeCloud Controller(TM) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * PrimeCloud Controller(TM) 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PrimeCloud Controller(TM). If not, see <http://www.gnu.org/licenses/>. */ package jp.primecloud.auto.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import jp.primecloud.auto.exception.AutoException; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpException; /** * <p> * SSHでコマンドを実行するためのユーティリティClassです。 * </p> * */ public class JSchUtils { private JSchUtils() { } /** * TODO: メソッドコメントを記述 * * @param username * @param password * @param host * @return */ public static Session createSession(String username, String password, String host) { return createSession(username, password, host, 22); } /** * TODO: メソッドコメントを記述 * * @param username * @param password * @param host * @param port * @return */ public static Session createSession(String username, String password, String host, int port) { try { JSch jsch = new JSch(); Session session = jsch.getSession(username, host, port); session.setConfig("StrictHostKeyChecking", "no"); session.setPassword(password); session.connect(); return session; } catch (JSchException e) { throw new AutoException("ECOMMON-000302", username, host, port); } } /** * TODO: メソッドコメントを記述 * * @param username * @param privateKey * @param host * @return */ public static Session createSessionByPrivateKey(String username, String privateKey, String host) { return createSessionByPrivateKey(username, privateKey, null, host, 22); } /** * TODO: メソッドコメントを記述 * * @param username * @param privateKey * @param passphrase * @param host * @return */ public static Session createSessionByPrivateKey(String username, String privateKey, String passphrase, String host) { return createSessionByPrivateKey(username, privateKey, passphrase, host, 22); } /** * TODO: メソッドコメントを記述 * * @param username * @param privateKey * @param host * @param port * @return */ public static Session createSessionByPrivateKey(String username, String privateKey, String host, int port) { return createSessionByPrivateKey(username, privateKey, null, host, port); } /** * TODO: メソッドコメントを記述 * * @param username * @param privateKey * @param passphrase * @param host * @param port * @return */ public static Session createSessionByPrivateKey(String username, String privateKey, String passphrase, String host, int port) { Charset charset = Charset.forName("UTF-8"); byte[] privateKeyBytes = privateKey.getBytes(charset); byte[] passphraseBytes = null; if (passphrase != null) { passphraseBytes = passphrase.getBytes(charset); } try { JSch jsch = new JSch(); jsch.addIdentity("name", privateKeyBytes, null, passphraseBytes); Session session = jsch.getSession(username, host, port); session.setConfig("StrictHostKeyChecking", "no"); session.connect(); return session; } catch (JSchException e) { throw new AutoException("ECOMMON-000302", username, host, port); } } /** * TODO: メソッドコメントを記述 * * @param session * @param command * @return */ public static JSchResult executeCommand(Session session, String command) { return executeCommand(session, command, null); } /** * TODO: メソッドコメントを記述 * * @param session * @param command * @param encoding * @return */ public static JSchResult executeCommand(Session session, String command, String encoding) { return executeCommand(session, command, encoding, 10000); } /** * TODO: メソッドコメントを記述 * * @param session * @param command * @param timeout * @return */ public static JSchResult executeCommand(Session session, String command, long timeout) { return executeCommand(session, command, null, timeout); } /** * TODO: メソッドコメントを記述 * * @param session * @param command * @param encoding * @param timeout * @return */ public static JSchResult executeCommand(Session session, String command, String encoding, long timeout) { return executeCommand(session, command, encoding, timeout, false); } /** * TODO: メソッドコメントを記述 * * @param session * @param command * @param encoding * @param timeout * @param pty * @return */ public static JSchResult executeCommand(Session session, String command, String encoding, long timeout, boolean pty) { ChannelExec channel = null; try { channel = (ChannelExec) session.openChannel("exec"); channel.setCommand(command); channel.setPty(pty); // 出力Streamの設定 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); channel.setOutputStream(outStream); ByteArrayOutputStream errStream = new ByteArrayOutputStream(); channel.setErrStream(errStream); ByteArrayOutputStream extOutStream = new ByteArrayOutputStream(); channel.setExtOutputStream(extOutStream); // コマンド実行 channel.connect(); // コマンドが終了するまで待機 long startTime = System.currentTimeMillis(); while (!channel.isClosed()) { try { if (System.currentTimeMillis() - startTime > timeout) { // タイムアウト発生時 throw new AutoException("ECOMMON-000301", command); } Thread.sleep(1000); } catch (InterruptedException ignore) { } } // 実行結果の取得 JSchResult result = new JSchResult(); result.setExitStatus(channel.getExitStatus()); if (encoding == null) { result.setOut(outStream.toString()); result.setErr(errStream.toString()); result.setExtOut(extOutStream.toString()); } else { result.setOut(outStream.toString(encoding)); result.setErr(errStream.toString(encoding)); result.setExtOut(extOutStream.toString(encoding)); } return result; } catch (JSchException e) { throw new AutoException("ECOMMON-000303", e, command); } catch (IOException e) { throw new RuntimeException(e); } finally { if (channel != null) { channel.disconnect(); } } } /** * TODO: メソッドコメントを記述 * * @param session * @param input * @param targetFile */ public static void sftpPut(Session session, InputStream input, String targetFile) { ChannelSftp channel = null; try { channel = (ChannelSftp) session.openChannel("sftp"); channel.connect(); // Putを実行 channel.put(input, targetFile, ChannelSftp.OVERWRITE); channel.quit(); } catch (JSchException e) { throw new AutoException("ECOMMON-000304", e); } catch (SftpException e) { throw new AutoException("ECOMMON-000304", e); } finally { if (channel != null) { channel.disconnect(); } } } public static class JSchResult { private String out; private String err; private String extOut; private int exitStatus; /** * outを取得します。 * * @return out */ public String getOut() { return out; } /** * outを設定します。 * * @param out out */ public void setOut(String out) { this.out = out; } /** * errを取得します。 * * @return err */ public String getErr() { return err; } /** * errを設定します。 * * @param err err */ public void setErr(String err) { this.err = err; } /** * extOutを取得します。 * * @return extOut */ public String getExtOut() { return extOut; } /** * extOutを設定します。 * * @param extOut extOut */ public void setExtOut(String extOut) { this.extOut = extOut; } /** * exitStatusを取得します。 * * @return exitStatus */ public int getExitStatus() { return exitStatus; } /** * exitStatusを設定します。 * * @param exitStatus exitStatus */ public void setExitStatus(int exitStatus) { this.exitStatus = exitStatus; } } }