Java tutorial
/* * Copyright 1999-2008 University of Chicago * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package org.globus.workspace.client.modes; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.axis.message.addressing.EndpointReferenceType; import org.globus.workspace.client_core.StubConfigurator; import org.globus.workspace.client_core.ParameterProblem; import org.globus.workspace.client_core.ExecutionProblem; import org.globus.workspace.client_core.ExitNow; import org.globus.workspace.client_core.print.PrCodes; import org.globus.workspace.client_core.utils.EPRUtils; import org.globus.workspace.client_core.utils.FileUtils; import org.globus.workspace.client_core.actions.Ctx_RPQuery; import org.globus.workspace.client_core.actions.Ctx_Identities; import org.globus.workspace.common.print.Print; import org.globus.workspace.common.print.PrintOpts; import org.nimbustools.messaging.gt4_0.common.CommonUtil; import org.nimbustools.ctxbroker.generated.gt4_0.types.ContextualizationContext; import org.nimbustools.ctxbroker.generated.gt4_0.types.Node_Type; import org.nimbustools.ctxbroker.generated.gt4_0.types.MatchedRole_Type; import org.nimbustools.ctxbroker.generated.gt4_0.broker.NimbusContextualizationFault; import org.nimbustools.ctxbroker.generated.gt4_0.description.IdentityProvides_Type; import org.globus.workspace.common.client.CommonPrint; import org.globus.workspace.client.AllArguments; import org.globus.workspace.client.modes.aux.CommonLogs; import org.globus.workspace.client_common.CommonStrings; import org.globus.wsrf.encoding.SerializationException; import org.oasis.wsrf.faults.BaseFaultType; import java.text.DateFormat; import java.text.NumberFormat; import java.io.File; import java.io.IOException; import java.util.Calendar; import java.util.StringTokenizer; import java.util.ArrayList; public class ContextMonitor extends Mode { // ------------------------------------------------------------------------- // STATIC VARIABLES // ------------------------------------------------------------------------- private static final Log logger = LogFactory.getLog(ContextMonitor.class.getName()); private static final DateFormat localFormat = DateFormat.getDateTimeInstance(); public static String newline = System.getProperty("line.separator"); public static final long DEFAULT_POLL_MS = 5000; public static final int DEFAULT_POOL_SIZE = 4; // ------------------------------------------------------------------------- // INSTANCE VARIABLES // ------------------------------------------------------------------------- private String nameToPrint; private Ctx_RPQuery rpQuery; private Ctx_Identities identitiesQuery; private EndpointReferenceType epr; private boolean dryrun; private long pollDelayMs; private String sshKnownHostsPath; private String sshKnownHostsDirPath; private boolean adjustSshKnownHosts; private AdjustTask[] adjustTasks; // ------------------------------------------------------------------------- // CONSTRUCTOR // ------------------------------------------------------------------------- public ContextMonitor(Print print, AllArguments arguments, StubConfigurator stubConfigurator) { super(print, arguments, stubConfigurator); } // ------------------------------------------------------------------------- // extends Mode // ------------------------------------------------------------------------- public String name() { return "Monitor-context"; } public void validateOptionsImpl() throws ParameterProblem { this.handlePollDelay(); this.validateEndpoint(); this.setName(); this.validateReportdir(); this.validateAdjustSSHhostsList(); this.validateSSHhostsFile(); this.validateSSHhostsDir(); this.dryrun = this.args.dryrun; CommonLogs.logBoolean(this.dryrun, "dryrun mode", this.pr, logger); } public void runImpl() throws ParameterProblem, ExecutionProblem, ExitNow { this._runImpl(); } // ------------------------------------------------------------------------- // VALIDATION // ------------------------------------------------------------------------- private void handlePollDelay() throws ParameterProblem { if (this.args.pollDelayString == null) { throw new ParameterProblem("poll delay is required"); } try { this.pollDelayMs = Long.parseLong(this.args.pollDelayString); } catch (NumberFormatException e) { throw new ParameterProblem( "Given poll delay is not valid: '" + this.args.pollDelayString + "': " + e.getMessage(), e); } if (this.pollDelayMs < 1) { throw new ParameterProblem("Given poll delay is less than 1ms: " + this.pollDelayMs + "ms"); } } private void validateEndpoint() throws ParameterProblem { this.epr = this.stubConf.getEPR(); if (this.epr == null) { throw new ParameterProblem(name() + " requires EPR"); } final String eprStr; try { eprStr = EPRUtils.eprToString(this.epr); } catch (Exception e) { final String err = CommonUtil.genericExceptionMessageWrapper(e); throw new ParameterProblem(err, e); } if (this.pr.enabled()) { // xml print final String dbg = "\nGiven EPR:\n----------\n" + eprStr + "----------\n"; if (this.pr.useThis()) { this.pr.dbg(dbg); } else if (this.pr.useLogging()) { logger.debug(dbg); } } this.rpQuery = new Ctx_RPQuery(this.epr, this.stubConf, this.pr); this.identitiesQuery = new Ctx_Identities(this.epr, this.stubConf, this.pr); } private void validateReportdir() throws ParameterProblem { if (this.args.reportDir == null) { return; // *** EARLY RETURN *** } final File f = new File(this.args.reportDir); if (!f.exists()) { throw new ParameterProblem( "Given path for reports directory ('" + this.args.reportDir + "') does not exist."); } if (!f.isDirectory()) { throw new ParameterProblem( "Given path for reports directory ('" + this.args.reportDir + "') is not a directory."); } if (!f.canWrite()) { throw new ParameterProblem( "Given path for reports directory ('" + this.args.reportDir + "') is not writable."); } } private void validateAdjustSSHhostsList() throws ParameterProblem { if (this.args.adjustSshHostsList == null) { return; // *** EARLY RETURN *** } this.adjustSshKnownHosts = true; final StringTokenizer st = new StringTokenizer(this.args.adjustSshHostsList, ","); final ArrayList adjustTaskList = new ArrayList(st.countTokens()); while (st.hasMoreTokens()) { final String val = st.nextToken(); final AdjustTask task = taskFromString(val.trim()); if (task != null) { adjustTaskList.add(task); } } this.adjustTasks = (AdjustTask[]) adjustTaskList.toArray(new AdjustTask[adjustTaskList.size()]); this.pr.debugln("Configured " + this.adjustTasks.length + " known_hosts adjust tasks."); for (final AdjustTask task : this.adjustTasks) { if (task.iface == null) { this.pr.debugln("IP '" + task.ipAddress + "', " + "all interfaces"); } else { this.pr.debugln("IP '" + task.ipAddress + "', " + "one interface: '" + task.iface + "'"); } } } private AdjustTask taskFromString(String val) throws ParameterProblem { this.pr.debugln("Examining adjust-task string '" + val + "'"); final StringTokenizer st = new StringTokenizer(val, "::"); if (st.countTokens() == 1) { return new AdjustTask(st.nextToken(), null, null); } else if (st.countTokens() == 2) { return new AdjustTask(st.nextToken(), st.nextToken(), null); } else if (st.countTokens() == 3) { return new AdjustTask(st.nextToken(), st.nextToken(), st.nextToken()); } else { throw new ParameterProblem("known_hosts adjustment string is invalid: '" + val + "'"); } } private static class AdjustTask { final String ipAddress; final String iface; final String printName; private AdjustTask(String ipAddress, String interfaceName, String toPrintName) { this.ipAddress = ipAddress; this.iface = interfaceName; this.printName = toPrintName; } } private void validateSSHhostsFile() throws ParameterProblem { // file not needed if adjust flag is not present if (!this.adjustSshKnownHosts) { return; // *** EARLY RETURN *** } if (this.args.sshHostsPath == null) { return; // *** EARLY RETURN *** } final File f = new File(this.args.sshHostsPath); if (f.exists()) { if (!f.canWrite()) { throw new ParameterProblem( "Given known_hosts path ('" + this.args.sshHostsPath + "') is not writable."); } this.sshKnownHostsPath = f.getAbsolutePath(); return; // *** EARLY RETURN *** } // if it doesn't exist, create it try { if (!f.createNewFile()) { throw new ParameterProblem("Could not create new known_hosts file @ '" + f.getAbsolutePath() + "'"); } } catch (IOException e) { final String err = CommonUtil.genericExceptionMessageWrapper(e); throw new ParameterProblem( "Could not create new known_hosts file @ '" + f.getAbsolutePath() + "': " + err, e); } this.sshKnownHostsPath = f.getAbsolutePath(); if (this.pr.enabled()) { final String msg = "Created known_hosts file @ '" + this.sshKnownHostsPath + "'"; if (this.pr.useThis()) { this.pr.infoln(PrCodes.CTXMONITOR__KNOWNHOSTS_FILE_CREATE, msg); } else if (this.pr.useLogging()) { logger.info(msg); } } } private void validateSSHhostsDir() throws ParameterProblem { // dir files not needed if adjust flag is not present if (!this.adjustSshKnownHosts) { return; // *** EARLY RETURN *** } if (this.args.sshHostsDirPath == null) { return; // *** EARLY RETURN *** } final File f = new File(this.args.sshHostsDirPath); if (f.exists()) { if (!f.canWrite()) { throw new ParameterProblem( "Given known_hosts directory ('" + this.args.sshHostsDirPath + "') is not writable."); } this.sshKnownHostsDirPath = f.getAbsolutePath(); } else { throw new ParameterProblem( "Given known_hosts directory ('" + this.args.sshHostsDirPath + "') does not exist."); } } private void setName() { if (this.args.shortName != null) { this.nameToPrint = this.args.shortName; } else { this.nameToPrint = "\"" + EPRUtils.getContextIdFromEPR(this.epr) + "\""; } if (this.pr.enabled()) { final String dbg = "Name to print: '" + this.nameToPrint + "'"; if (this.pr.useThis()) { this.pr.dbg(dbg); } else if (this.pr.useLogging()) { logger.debug(dbg); } } } // ------------------------------------------------------------------------- // RUN // ------------------------------------------------------------------------- private void _runImpl() throws ParameterProblem, ExecutionProblem, ExitNow { if (this.dryrun) { if (this.pr.enabled()) { final String msg = "Dryrun, done."; if (this.pr.useThis()) { this.pr.infoln(PrCodes.CTXMONITOR__DRYRUN, msg); } else if (this.pr.useLogging()) { logger.info(msg); } } return; // *** EARLY RETURN *** } ContextualizationContext contextRP; try { while (true) { try { contextRP = this.rpQuery.query(); if (this.analyzeResult(contextRP)) { break; } Thread.sleep(this.pollDelayMs); } catch (InterruptedException e) { // ignore } } final String msg = "Querying ended via analyzeResult"; if (this.pr.useThis()) { this.pr.debugln(msg); } else { logger.debug(msg); } } catch (BaseFaultType e) { final String err = CommonStrings.faultStringOrCommonCause(e, "context"); throw new ExecutionProblem(err, e); } if (contextRP.isErrorPresent()) { if (this.pr.enabled()) { final String msg = "Problem with " + this.nameToPrint + " context"; if (this.pr.useThis()) { this.pr.infoln(PrCodes.CTXMONITOR__ONE_ERROR, msg); } else if (this.pr.useLogging()) { logger.info(msg); } } } else if (contextRP.isAllOK()) { if (this.pr.enabled()) { final String msg = this.nameToPrint + ": contextualized"; if (this.pr.useThis()) { this.pr.infoln(PrCodes.CTXMONITOR__ALL_OK, " - " + msg); } else if (this.pr.useLogging()) { logger.info(msg); } } } else { throw new ExecutionProblem("Incorrect analysis of ctx query?"); } // both oneErrorExists and allOK trigger report(s) if path is configured if (this.args.reportDir != null) { try { this.writeSummary(contextRP); } catch (Exception e) { final String err = CommonUtil.genericExceptionMessageWrapper(e); throw new ExecutionProblem("Problem writing ctx summary: " + err, e); } } // in all cases get the full node report Node_Type[] nodes = null; try { this.identitiesQuery.setQueryAll(true); nodes = this.identitiesQuery.identities(); } catch (NimbusContextualizationFault e) { final String err = CommonUtil.genericExceptionMessageWrapper(e); if (this.pr.enabled()) { final String errMsg = "Problem querying ctx nodes: " + err; if (this.pr.useThis()) { this.pr.errln(errMsg); } else if (this.pr.useLogging()) { logger.error(errMsg); } } } // both oneErrorExists and allOK trigger report(s) if path is configured if (nodes != null && this.args.reportDir != null) { try { this.writeReports(nodes); } catch (Exception e) { final String err = CommonUtil.genericExceptionMessageWrapper(e); throw new ExecutionProblem("Problem writing ctx summary: " + err, e); } } if (contextRP.isErrorPresent()) { throw new ExitNow(1); } if (nodes != null && this.adjustSshKnownHosts) { try { adjustKnownHosts(nodes, this.sshKnownHostsPath, this.sshKnownHostsDirPath, this.adjustTasks, this.pr); } catch (Exception e) { final String err = CommonUtil.genericExceptionMessageWrapper(e); throw new ExecutionProblem( "Problem adjusting known_hosts file @ '" + this.sshKnownHostsPath + "': " + err, e); } } } // return: should querying end? private boolean analyzeResult(ContextualizationContext contextRP) { if (contextRP == null) { return false; } boolean ret = false; if (contextRP.isAllOK()) { ret = true; } else if (contextRP.isErrorPresent()) { ret = true; } if (this.pr.enabled()) { if (this.pr.useThis()) { this.pr.debugln(getResultString(contextRP, false)); } else if (this.pr.useLogging()) { logger.debug(getResultString(contextRP, false)); } } return ret; } private static String getResultString(ContextualizationContext contextRP, boolean roles) { final StringBuffer buf = new StringBuffer("\nCtx query response @ "); final String now = localFormat.format(Calendar.getInstance().getTime()); buf.append(now).append("\n"); if (contextRP.isNoMoreInjections()) { buf.append(" - [X] injects done "); } else { buf.append(" - [ ] injects pending "); } if (contextRP.isComplete()) { buf.append("[X] complete "); } else { buf.append("[ ] not complete "); } if (contextRP.isAllOK()) { buf.append("[X] all OK "); } else { buf.append("[ ] no all OK "); } if (contextRP.isErrorPresent()) { buf.append("[X] error present "); } else { buf.append("[ ] no error present "); } if (roles) { buf.append("\n").append(getRolesString(contextRP.getMatchedRole(), " - ", "\n")); } return buf.toString(); } public static String getRolesString(MatchedRole_Type[] roles, String p, String s) { if (roles == null || roles.length == 0) { return p + "No roles" + s; } // first look through to find longest role name and largest total int longestNameChars = 0; int largestTotal = 0; for (MatchedRole_Type role : roles) { if (role.getName().length() > longestNameChars) { longestNameChars = role.getName().length(); } if (role.getNumProvidersInContext() > largestTotal) { largestTotal = role.getNumProvidersInContext(); } } // don't want number format via Java because it will add zeroes.. short numDigits = 0; if (largestTotal >= 10000) { // someday numDigits = 5; } else if (largestTotal >= 1000) { numDigits = 4; } else if (largestTotal >= 100) { numDigits = 3; } else if (largestTotal >= 10) { numDigits = 2; } else { numDigits = 1; } StringBuffer buf = new StringBuffer(); for (int i = 0; i < longestNameChars; i++) { buf.append(" "); } final String maxNameStr = buf.toString(); buf = new StringBuffer(); for (int i = 0; i < numDigits; i++) { buf.append(" "); } final String maxTotalStr = buf.toString(); buf = new StringBuffer(); for (MatchedRole_Type role : roles) { final String printName = justifyRight(role.getName(), maxNameStr); final String printTotal = justifyRight(Integer.toString(role.getNumProvidersInContext()), maxTotalStr); final String printFilled = justifyRight(Integer.toString(role.getNumFilledProviders()), maxTotalStr); buf.append(p).append(printName).append(": ").append(printTotal).append(" total & ").append(printFilled) .append(" filled.").append(s); } return buf.toString(); } private static String justifyRight(String str, String max) { if (str == null || max == null) { return max; } final int len = str.length(); if (len < max.length()) { return max.substring(len) + str; } else { return str; } } // ------------------------------------------------------------------------- // REPORT WRITING // ------------------------------------------------------------------------- protected void writeSummary(ContextualizationContext contextRP) throws SerializationException, IOException { final String fileName; if (contextRP.isAllOK()) { fileName = "CTX-OK.txt"; } else { fileName = "CTX-ERR.txt"; } final File f = new File(this.args.reportDir, fileName); FileUtils.writeStringToFile(getResultString(contextRP, true), f.getAbsolutePath()); if (this.pr.enabled()) { final String msg = "wrote ctx summary to '" + f.getAbsolutePath() + "'"; if (this.pr.useThis()) { this.pr.infoln(PrCodes.CTXMONITOR__REPORT_DIR, " - " + msg); } else if (this.pr.useLogging()) { logger.info(msg); } } } protected void writeReports(Node_Type[] nodes) { final short numDigits; if (nodes.length > 1000) { numDigits = 4; } else if (nodes.length > 100) { numDigits = 3; } else if (nodes.length > 10) { numDigits = 2; } else { numDigits = 1; } final NumberFormat format = NumberFormat.getInstance(); format.setMinimumIntegerDigits(numDigits); this._writeReports(nodes, this.args.reportDir, format); if (this.pr.enabled()) { final String msg = "wrote reports to '" + this.args.reportDir + "'"; if (this.pr.useThis()) { this.pr.infoln(PrCodes.CTXMONITOR__REPORT_DIR, " - " + msg); } else if (this.pr.useLogging()) { logger.info(msg); } } } protected void _writeReports(Node_Type[] nodes, String reportDir, NumberFormat format) { for (int i = 0; i < nodes.length; i++) { final Node_Type node = nodes[i]; final String prefix = this.getStateString(node) + "-vm-"; final String path = prefix + format.format(i + 1) + ".txt"; try { this.writeOneReport(nodes[i], reportDir, path); } catch (Exception e) { // print error and continue if (this.pr.enabled()) { final String msg = CommonUtil.genericExceptionMessageWrapper(e); if (this.pr.useThis()) { this.pr.err(msg); } else if (this.pr.useLogging()) { if (logger.isDebugEnabled()) { logger.error(msg, e); } else { logger.error(msg); } } } } } } protected void writeOneReport(Node_Type node, String dir, String file) throws SerializationException, IOException { final File f = new File(dir, file); FileUtils.writeStringToFile(this.getOneReportText(node), f.getAbsolutePath()); if (this.pr.enabled()) { final String msg = " Wrote '" + file + "'"; if (this.pr.useThis()) { this.pr.infoln(PrCodes.CTXMONITOR__SINGLE_REPORT_NAMES, msg); } else if (this.pr.useLogging()) { logger.info(msg); } } } protected String getStateString(Node_Type node) { if (node == null) { return "UNKNOWN"; } if (!node.isExited()) { return "DID-NOT-EXIT"; } if (node.isOk()) { return "OK"; } final Short errCode = node.getErrorCode(); return "ERROR-" + errCode.toString(); } protected String getOneReportText(Node_Type node) { final StringBuffer buf = new StringBuffer(16384); final String now = localFormat.format(Calendar.getInstance().getTime()); buf.append("## File autogenerated at ").append(now); add2Newlines(buf); buf.append(CommonPrint.textDebugSection("STATUS")); add2Newlines(buf); buf.append(this.getOneStatus(node)); add2Newlines(buf); buf.append(CommonPrint.textDebugSection("IDENTITIES")); add2Newlines(buf); buf.append(this.getIdentities(node.getIdentity())); add2Newlines(buf); if (node.getErrorMessage() != null) { buf.append(CommonPrint.textDebugSection("ERROR TEXT")); add2Newlines(buf); add2Newlines(buf); buf.append(node.getErrorMessage()); add2Newlines(buf); } return buf.toString(); } protected String getOneStatus(Node_Type node) { final StringBuffer buf = new StringBuffer(2048); buf.append("Node exited: ").append(node.isExited()); addNewline(buf); buf.append("Node OK: ").append(node.isOk()); addNewline(buf); final Short err = node.getErrorCode(); if (err != null) { buf.append("Node ERROR: ").append(err.toString()); addNewline(buf); } return buf.toString(); } protected String getIdentities(IdentityProvides_Type[] identity) { if (identity == null || identity.length == 0) { return "No identities"; } final StringBuffer buf = new StringBuffer(2048); for (IdentityProvides_Type id : identity) { addNewline(buf); final String iface = id.get_interface(); buf.append("INTERFACE NAME: "); if (iface != null) { buf.append(iface); } else { buf.append(" (not supplied)"); } addNewline(buf); final String ip = id.getIp(); buf.append("IP ADDRESS: "); if (ip != null) { buf.append(ip); } else { buf.append(" (not supplied)"); } addNewline(buf); final String hostname = id.getHostname(); buf.append("HOSTNAME: "); if (hostname != null) { buf.append(hostname); } else { buf.append(" (not supplied)"); } addNewline(buf); final String sshkey = id.getPubkey(); buf.append("SSH PUBLIC KEY:"); if (sshkey != null) { buf.append("\n").append(sshkey); } else { buf.append(" (not supplied)"); } add2Newlines(buf); } return buf.toString(); } private static void addNewline(StringBuffer buf) { buf.append(newline); } private static void add2Newlines(StringBuffer buf) { buf.append(newline).append(newline); } // ------------------------------------------------------------------------- // KNOWN HOSTS ADJUSTMENT // ------------------------------------------------------------------------- private static void adjustKnownHosts(Node_Type[] nodes, String knownHostsPath, String sshKnownHostsDirPath, AdjustTask[] adjustTasks, Print pr) throws SerializationException, IOException { if (adjustTasks == null || adjustTasks.length == 0) { throw new IllegalArgumentException("no adjust tasks"); } if (nodes == null || nodes.length == 0) { throw new IllegalArgumentException("no nodes"); } if (pr == null) { throw new IllegalArgumentException("pr may not be null"); } if (knownHostsPath != null) { pr.debugln("\nknown_hosts adjust path: '" + knownHostsPath + "'"); for (final AdjustTask task : adjustTasks) { for (final Node_Type node : nodes) { final IdentityProvides_Type[] ids = node.getIdentity(); if (ids != null) { for (final IdentityProvides_Type id : ids) { if (task.ipAddress.equals(id.getIp())) { knownhosts_rem(pr, task, node, knownHostsPath); knownhosts_add(pr, task, node, knownHostsPath); break; } } } } } } if (sshKnownHostsDirPath != null) { pr.debugln("\nknown_hosts directory: '" + sshKnownHostsDirPath + "'"); for (final AdjustTask task : adjustTasks) { for (final Node_Type node : nodes) { final IdentityProvides_Type[] ids = node.getIdentity(); if (ids != null) { for (final IdentityProvides_Type id : ids) { if (task.ipAddress.equals(id.getIp())) { knownhostsdir_add(pr, task, node, sshKnownHostsDirPath); break; } } } } } } } private static void knownhostsdir_add(Print print, AdjustTask task, Node_Type node, String sshKnownHostsDirPath) throws SerializationException, IOException { final IdentityProvides_Type[] ids = node.getIdentity(); for (final IdentityProvides_Type id : ids) { if (id.getPubkey() == null) { print.errln("No SSH key for " + id.getIp()); continue; } // null task.iface means 'get all' if (task.iface == null || task.iface.equals(id.get_interface())) { // adding via repo.add needs the real key apparently, sending // keyStr.getBytes() to HostKey constructor messes everything up final String newEntry = id.getHostname() + "," + id.getIp() + " " + id.getPubkey(); final String sendString = newEntry + "\n"; final File newfile = new File(sshKnownHostsDirPath, id.getHostname()); final String newfilePath = newfile.getAbsolutePath(); FileUtils.writeStringToFile(sendString, newfilePath, false); String printString = "\nWrote SSH key out to: " + newfilePath; if (task.printName != null) { printString += " [[ " + task.printName + " ]]"; } print.infoln(printString); } } } private static void knownhosts_rem(Print print, AdjustTask task, Node_Type node, String knownHostsPath) throws SerializationException, IOException { final String[] lines = FileUtils.readFileAsString(knownHostsPath).split("\n"); boolean somethingChanged = false; final IdentityProvides_Type[] ids = node.getIdentity(); for (final IdentityProvides_Type id : ids) { if (id.getPubkey() == null) { print.errln("No SSH key for " + id.getIp()); continue; } // null task.iface means 'get all' if (task.iface == null || task.iface.equals(id.get_interface())) { int thisOneChanged = 0; for (int j = 0; j < lines.length; j++) { final String line = lines[j]; if (line == null || line.trim().length() == 0) { continue; } if (line.trim().startsWith("#")) { continue; } if (line.indexOf(id.getHostname()) >= 0 || line.indexOf(id.getIp()) >= 0) { lines[j] = "# " + line; somethingChanged = true; thisOneChanged += 1; } } if (thisOneChanged > 0) { String printString = "\nCommented " + thisOneChanged + " entries in known_hosts for " + id.getHostname() + " / " + id.getIp(); if (task.printName != null) { printString += " [[ " + task.printName + " ]]"; } print.debugln(printString); } } } if (somethingChanged) { // no join() ... final StringBuffer buf = new StringBuffer(200 * lines.length); for (String line : lines) { buf.append(line).append("\n"); } FileUtils.writeStringToFile(buf.toString(), knownHostsPath); } } private static void knownhosts_add(Print print, AdjustTask task, Node_Type node, String knownHostsPath) throws SerializationException, IOException { final IdentityProvides_Type[] ids = node.getIdentity(); for (final IdentityProvides_Type id : ids) { if (id.getPubkey() == null) { print.errln("No SSH key for " + id.getIp()); continue; } // null task.iface means 'get all' if (task.iface == null || task.iface.equals(id.get_interface())) { // adding via repo.add needs the real key apparently, sending // keyStr.getBytes() to HostKey constructor messes everything up final String newEntry = id.getHostname() + "," + id.getIp() + " " + id.getPubkey(); final String sendString = "\n# cloud-client added this:\n" + newEntry + "\n"; FileUtils.writeStringToFile(sendString, knownHostsPath, true); String printString = "\nSSH trusts new key for " + id.getHostname(); if (task.printName != null) { printString += " [[ " + task.printName + " ]]"; } print.infoln(printString); } } } public static void main(String[] args) throws Exception { IdentityProvides_Type id = new IdentityProvides_Type(); id.set_interface(null); id.setHostname("xyz"); id.setIp("1.2.3.4"); id.setPubkey("ssh-rsa 132reoi3nfoi3nfoin3f#$@$@#$@#$@#$@#$"); IdentityProvides_Type[] ids = { id }; Node_Type node = new Node_Type(); node.setIdentity(ids); Node_Type[] nodes = { node }; AdjustTask task = new AdjustTask("1.2.3.4", null, "something"); AdjustTask[] tasks = { task }; Print pr = new Print(new PrintOpts(null), System.out, System.err, System.err); adjustKnownHosts(nodes, "/home/tim/known", null, tasks, pr); } }