diff --git a/core/src/com/cloud/network/resource/CiscoNexusVSM.java b/core/src/com/cloud/network/resource/CiscoNexusVSM.java index 51d4a377f34..ca4409d2dcc 100644 --- a/core/src/com/cloud/network/resource/CiscoNexusVSM.java +++ b/core/src/com/cloud/network/resource/CiscoNexusVSM.java @@ -49,8 +49,6 @@ public class CiscoNexusVSM { private String vsmPassword; private String vsmSubsystem; com.trilead.ssh2.Connection sshConnection; - private String _helloClientCmd = "urn:ietf:params:xml:ns:netconf:base:1.0]]>]]>"; - private String _clientCmd1 = "]]>]]>"; private static final Logger s_logger = Logger.getLogger(CiscoNexusVSM.class); @@ -58,7 +56,6 @@ public class CiscoNexusVSM { CiscoNexusVSMService _vsmService; Long _timeout = new Long(100000); - //base_response apiCallResult; // We need to store the result of the XML-RPC command sent to // the VSM. For now it's a string. We should make this the appropriate XSD object. @@ -88,15 +85,15 @@ public class CiscoNexusVSM { return vsmIpaddr; } - public String getvsmUsername() { + public String getVsmUsername() { return vsmUsername; } - public String getvsmPassword() { + public String getVsmPassword() { return vsmPassword; } - public String getvsmSubsystem() { + public String getVsmSubsystem() { return vsmSubsystem; } @@ -111,5 +108,4 @@ public class CiscoNexusVSM { } return true; } - } \ No newline at end of file diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java new file mode 100644 index 00000000000..11b69707aad --- /dev/null +++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java @@ -0,0 +1,216 @@ +package com.cloud.utils.cisco.n1kv.vsm; + +import org.apache.log4j.Logger; + +import java.io.InputStream; +import java.io.OutputStream; + +import com.cloud.utils.ssh.*; +import com.trilead.ssh2.Session; +import com.trilead.ssh2.Connection; +import com.trilead.ssh2.ChannelCondition; +import com.cloud.utils.exception.CloudRuntimeException; + +public class NetconfHelper { + private static final Logger s_logger = Logger.getLogger(NetconfHelper.class); + + private static final String SSH_NETCONF_TERMINATOR = "]]>]]>"; + + private Connection _connection; + + private Session _session; + + public NetconfHelper (String ip, String username, String password) throws CloudRuntimeException { + _connection = SSHCmdHelper.acquireAuthorizedConnection(ip, username, password); + if (_connection == null) { + throw new CloudRuntimeException("Error opening ssh connection."); + } + + try { + _session = _connection.openSession(); + _session.startSubSystem("xmlagent"); + exchangeHello(); + } catch (final Exception e) { + disconnect(); + s_logger.error("Failed to connect to device SSH server: " + e.getMessage()); + throw new CloudRuntimeException("Failed to connect to SSH server: " + _connection.getHostname()); + } + } + + public void disconnect() { + if (_session != null) { + _session.close(); + } + SSHCmdHelper.releaseSshConnection(_connection); + } + + public void queryStatus() { + // FIXME: Use an xml parser to generate this request. + String status = "" + + "" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + "" + + SSH_NETCONF_TERMINATOR; + send(status); + String reply = receive(); + } + + public boolean addPortProfile(String name, int vlan) { + // FIXME: Use an xml parser to generate this request. + String command = "" + + "" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " <__XML__PARAM_value isKey=\"true\">@name" + + " <__XML__MODE_port-prof>" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " <__XML__PARAM_value>@vlan" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + "" + + SSH_NETCONF_TERMINATOR; + command = command.replace("@name", name); + command = command.replace("@vlan", Integer.toString(vlan)); + send(command); + // parse the rpc reply and the return success or failure. + String reply = receive(); + return true; + } + + public boolean deletePortProfile(String name) { + // FIXME: Use an xml parser to generate this request. + String command = "" + + "" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " <__XML__PARAM_value isKey=\"true\">@name" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + "" + + SSH_NETCONF_TERMINATOR; + command = command.replace("@name", name); + send(command); + // parse the rpc reply and the return success or failure. + String reply = receive(); + return true; + } + + private void exchangeHello() { + String ack = receive(); + String hello = "" + + "" + + " " + + " urn:ietf:params:xml:ns:netconf:base:1.0" + + " " + + "" + + SSH_NETCONF_TERMINATOR; + send(hello); + } + + private void send(String message) { + try { + OutputStream outputStream = _session.getStdin(); + outputStream.write(message.getBytes()); + outputStream.flush(); + } catch(Exception e) { + s_logger.error("Failed to send message: " + e.getMessage()); + throw new CloudRuntimeException("Failed to send message: " + e.getMessage()); + } + } + + private String receive() { + byte[] buffer = new byte[8192]; + InputStream inputStream = _session.getStdout(); + try { + while (true) { + if (inputStream.available() == 0) { + int conditions = _session.waitForCondition(ChannelCondition.STDOUT_DATA | + ChannelCondition.STDERR_DATA | ChannelCondition.EOF, 500); + + if ((conditions & ChannelCondition.TIMEOUT) != 0) { + break; + } + + if ((conditions & ChannelCondition.EOF) != 0) { + if ((conditions & (ChannelCondition.STDOUT_DATA | + ChannelCondition.STDERR_DATA)) == 0) { + break; + } + } + } + + while (inputStream.available() > 0) { + inputStream.read(buffer); + } + } + } catch(Exception e) { + s_logger.error("Failed to receive message: " + e.getMessage()); + throw new CloudRuntimeException("Failed to receives message: " + e.getMessage()); + } + + return new String(buffer); + } +}