diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java
index aee4665209f..742226c2bb8 100644
--- a/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java
+++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java
@@ -5,21 +5,13 @@ import org.apache.log4j.Logger;
import java.io.InputStream;
import java.io.OutputStream;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.ls.DOMImplementationLS;
-import org.w3c.dom.ls.LSSerializer;
-import org.w3c.dom.DOMException;
-
import com.cloud.utils.ssh.*;
import com.trilead.ssh2.Session;
import com.trilead.ssh2.Connection;
import com.trilead.ssh2.ChannelCondition;
+import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.BindingType;
+import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.PortProfileType;
+import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.SwitchPortMode;
import com.cloud.utils.exception.CloudRuntimeException;
public class NetconfHelper {
@@ -56,8 +48,8 @@ public class NetconfHelper {
SSHCmdHelper.releaseSshConnection(_connection);
}
- public void queryStatus() {
- // This command is used query the server status.
+ public void queryStatus() throws CloudRuntimeException {
+ // This command is used to query the server status.
String status = ""
+ "" + " "
@@ -66,231 +58,29 @@ public class NetconfHelper {
+ " " + " " + " " + " "
+ "" + SSH_NETCONF_TERMINATOR;
send(status);
- String reply = receive();
- }
-
- private String getAddPortProfile(String portName, int vlanid) {
- try {
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
- DOMImplementation domImpl = docBuilder.getDOMImplementation();
-
- // Root elements.
- Document doc = domImpl.createDocument("urn:ietf:params:xml:ns:netconf:base:1.0",
- "nf:rpc", null);
- doc.getDocumentElement().setAttribute( "message-id", "101" );
- doc.getDocumentElement().setAttributeNS("http://www.cisco.com/nxos:1.0:ppm",
- "addportprofile", "true");
-
- // Edit configuration command.
- Element editConfig = doc.createElement("nf:edit-config");
- Element target = doc.createElement("nf:target");
- Element running = doc.createElement("nf:running");
- target.appendChild(running);
- Element config = doc.createElement("nf:config");
- Element configure = doc.createElementNS("http://www.cisco.com/nxos:1.0:ppm", "nxos:configure");
- Element execConfigure = doc.createElement("nxos:__XML__MODE__exec_configure");
- Element portProfile = doc.createElement("port-profile");
- Element type = doc.createElement("type");
- Element ethernettype = doc.createElement("vethernet");
- Element name = doc.createElement("name");
- Element value = doc.createElement("__XML__PARAM_value");
- value.setAttribute("isKey", "true");
- value.setTextContent(portName);
-
- // Port profile details start here.
- Element portProf = doc.createElement("__XML__MODE__port-prof");
-
- // Command : switchport mode access
- Element switchport1 = doc.createElement("switchport");
- Element mode1 = doc.createElement("mode");
- Element access1 = doc.createElement("access");
- mode1.appendChild(access1);
- switchport1.appendChild(mode1);
-
- // Command : switchport access vlan
- Element switchport2 = doc.createElement("switchport");
- Element access2 = doc.createElement("access");
- Element vlan = doc.createElement("vlan");
- Element vlancreate = doc.createElement("vlan-id-create-delete");
- Element value2 = doc.createElement("__XML__PARAM_value");
- value2.setTextContent(Integer.toString(vlanid));
- vlancreate.appendChild(value2);
- vlan.appendChild(vlancreate);
- access2.appendChild(vlan);
- switchport2.appendChild(access2);
-
- // Command : vmware port-group
- Element vmware = doc.createElement("vmware");
- Element portgroup = doc.createElement("port-group");
- vmware.appendChild(portgroup);
-
- // Command : state enabled.
- Element state = doc.createElement("state");
- Element enabled = doc.createElement("enabled");
- state.appendChild(enabled);
-
- // Command : no shutdown.
- Element no = doc.createElement("no");
- Element shutdown = doc.createElement("shutdown");
- no.appendChild(shutdown);
-
- // Put the port profile details together.
- portProf.appendChild(switchport1);
- portProf.appendChild(switchport2);
- portProf.appendChild(vmware);
- portProf.appendChild(state);
- portProf.appendChild(no);
-
- // Put the xml-rpc together.
- name.appendChild(value);
- name.appendChild(portProf);
- ethernettype.appendChild(name);
- type.appendChild(ethernettype);
- portProfile.appendChild(type);
- execConfigure.appendChild(portProfile);
- configure.appendChild(execConfigure);
- config.appendChild(configure);
- editConfig.appendChild(target);
- editConfig.appendChild(config);
- doc.getDocumentElement().appendChild(editConfig);
-
- return serialize(domImpl, doc);
- } catch (ParserConfigurationException e) {
- s_logger.error("Error while creating add port profile message : " + e.getMessage());
- return null;
- } catch (DOMException e) {
- s_logger.error("Error while creating add port profile message : " + e.getMessage());
- return null;
- }
- }
-
- public void addPortProfile(String name, int vlan) {
- String command = getAddPortProfile(name, vlan) + SSH_NETCONF_TERMINATOR;
- send(command);
-
// parse the rpc reply and the return success or failure.
- String reply = receive().trim();
- if (reply.endsWith(SSH_NETCONF_TERMINATOR)) {
- reply = reply.substring(0, reply.length() - (new String(SSH_NETCONF_TERMINATOR).length()));
- }
- else {
- throw new CloudRuntimeException("Malformed repsonse from vsm for add " +
- "port profile request: " + reply);
- }
-
- VsmResponse response = new VsmResponse(reply);
- if (!response.isResponseOk()) {
- throw new CloudRuntimeException(response.toString());
- }
+ parseReply(receive());
}
- private String getDeletePortProfile(String portName) {
- try {
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
- DOMImplementation domImpl = docBuilder.getDOMImplementation();
-
- // Root elements.
- Document doc = domImpl.createDocument("urn:ietf:params:xml:ns:netconf:base:1.0",
- "nf:rpc", null);
- doc.getDocumentElement().setAttribute( "message-id", "101" );
- doc.getDocumentElement().setAttributeNS("http://www.cisco.com/nxos:1.0:ppm",
- "deleteportprofile", "true");
-
- // Edit configuration command.
- Element editConfig = doc.createElement("nf:edit-config");
-
- // Details of the port profile to delete.
- Element target = doc.createElement("nf:target");
- Element running = doc.createElement("nf:running");
- target.appendChild(running);
-
- Element config = doc.createElement("nf:config");
- Element configure = doc.createElementNS("http://www.cisco.com/nxos:1.0:ppm", "nxos:configure");
- Element execConfigure = doc.createElement("nxos:__XML__MODE__exec_configure");
- Element delete = doc.createElement("no");
- Element portProfile = doc.createElement("port-profile");
- Element name = doc.createElement("name");
- Element value = doc.createElement("__XML__PARAM_value");
- value.setAttribute("isKey", "true");
- value.setTextContent(portName);
-
- // Put the xml-rpc together.
- name.appendChild(value);
- portProfile.appendChild(name);
- delete.appendChild(portProfile);
- execConfigure.appendChild(delete);
- configure.appendChild(execConfigure);
- config.appendChild(configure);
- editConfig.appendChild(target);
- editConfig.appendChild(config);
- doc.getDocumentElement().appendChild(editConfig);
-
- return serialize(domImpl, doc);
- } catch (ParserConfigurationException e) {
- s_logger.error("Error while creating delete message : " + e.getMessage());
- return null;
- } catch (DOMException e) {
- s_logger.error("Error while creating delete message : " + e.getMessage());
- return null;
- }
- }
-
- public void deletePortProfile(String name) {
- String command = getDeletePortProfile(name) + SSH_NETCONF_TERMINATOR;
+ public void addPortProfile(String name, PortProfileType type, BindingType binding,
+ SwitchPortMode mode, int vlanid) throws CloudRuntimeException {
+ String command = VsmCommand.getAddPortProfile(name, type, binding, mode, vlanid);
+ command = command.concat(SSH_NETCONF_TERMINATOR);
send(command);
-
// parse the rpc reply and the return success or failure.
- String reply = receive().trim();
- if (reply.endsWith(SSH_NETCONF_TERMINATOR)) {
- reply = reply.substring(0, reply.length() - (new String(SSH_NETCONF_TERMINATOR).length()));
- }
- else {
- throw new CloudRuntimeException("Malformed repsonse from vsm for delete " +
- "port profile request :" + reply);
- }
-
- VsmResponse response = new VsmResponse(reply);
- if (!response.isResponseOk()) {
- throw new CloudRuntimeException(response.toString());
- }
+ parseReply(receive());
}
- private String getHello() {
- try {
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
- DOMImplementation domImpl = docBuilder.getDOMImplementation();
-
- // Root elements.
- Document doc = domImpl.createDocument("urn:ietf:params:xml:ns:netconf:base:1.0",
- "nc:hello", null);
-
- // Client capacity. We are only supporting basic capacity.
- Element capabilities = doc.createElement("nc:capabilities");
- Element capability = doc.createElement("nc:capability");
- capability.setTextContent("urn:ietf:params:xml:ns:netconf:base:1.0");
-
- capabilities.appendChild(capability);
- doc.getDocumentElement().appendChild(capabilities);
-
- return serialize(domImpl, doc);
- } catch (ParserConfigurationException e) {
- s_logger.error("Error while creating hello message : " + e.getMessage());
- return null;
- }
- }
-
- private String serialize(DOMImplementation domImpl, Document document) {
- DOMImplementationLS ls = (DOMImplementationLS) domImpl;
- LSSerializer lss = ls.createLSSerializer();
- return lss.writeToString(document);
+ public void deletePortProfile(String name) throws CloudRuntimeException {
+ String command = VsmCommand.getDeletePortProfile(name) + SSH_NETCONF_TERMINATOR;
+ send(command);
+ // parse the rpc reply and the return success or failure.
+ parseReply(receive());
}
private void exchangeHello() {
String ack = receive();
- String hello = getHello() + SSH_NETCONF_TERMINATOR;
+ String hello = VsmCommand.getHello() + SSH_NETCONF_TERMINATOR;
send(hello);
}
@@ -312,7 +102,7 @@ public class NetconfHelper {
while (true) {
if (inputStream.available() == 0) {
int conditions = _session.waitForCondition(ChannelCondition.STDOUT_DATA
- | ChannelCondition.STDERR_DATA | ChannelCondition.EOF, 100);
+ | ChannelCondition.STDERR_DATA | ChannelCondition.EOF, 500);
if ((conditions & ChannelCondition.TIMEOUT) != 0) {
break;
@@ -336,4 +126,19 @@ public class NetconfHelper {
return new String(buffer);
}
+
+ private void parseReply(String reply) throws CloudRuntimeException {
+ reply = reply.trim();
+ if (reply.endsWith(SSH_NETCONF_TERMINATOR)) {
+ reply = reply.substring(0, reply.length() - (new String(SSH_NETCONF_TERMINATOR).length()));
+ }
+ else {
+ throw new CloudRuntimeException("Malformed response from vsm" + reply);
+ }
+
+ VsmResponse response = new VsmResponse(reply);
+ if (!response.isResponseOk()) {
+ throw new CloudRuntimeException(response.toString());
+ }
+ }
}
diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java
new file mode 100644
index 00000000000..064762f8528
--- /dev/null
+++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java
@@ -0,0 +1,330 @@
+package com.cloud.utils.cisco.n1kv.vsm;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSSerializer;
+
+public class VsmCommand {
+
+ private static final Logger s_logger = Logger.getLogger(VsmCommand.class);
+ private static final String s_namespace = "urn:ietf:params:xml:ns:netconf:base:1.0";
+ private static final String s_ciscons = "http://www.cisco.com/nxos:1.0:ppm";
+ private static final String s_configuremode = "__XML__MODE__exec_configure";
+ private static final String s_portprofmode = "__XML__MODE_port-prof";
+ private static final String s_paramvalue = "__XML__PARAM_value";
+
+ public enum PortProfileType {
+ none,
+ vethernet,
+ ethernet;
+ }
+
+ public enum BindingType {
+ none,
+ portbindingstatic,
+ portbindingdynamic,
+ portbindingephermal;
+ }
+
+ public enum SwitchPortMode {
+ none,
+ access,
+ trunk,
+ privatevlanhost,
+ privatevlanpromiscuous
+ }
+
+ public static String getAddPortProfile(String name, PortProfileType type,
+ BindingType binding, SwitchPortMode mode, int vlanid) {
+ try {
+ // Create the document and root element.
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ DOMImplementation domImpl = docBuilder.getDOMImplementation();
+ Document doc = createDocument(domImpl);
+
+ // Edit configuration command.
+ Element editConfig = doc.createElement("nf:edit-config");
+ doc.getDocumentElement().appendChild(editConfig);
+
+ // Command to get into exec configure mode.
+ Element target = doc.createElement("nf:target");
+ Element running = doc.createElement("nf:running");
+ target.appendChild(running);
+ editConfig.appendChild(target);
+
+ // Command to create the port profile with the desired configuration.
+ Element config = doc.createElement("nf:config");
+ config.appendChild(configPortProfileDetails(doc, name, type, binding, mode, vlanid));
+ editConfig.appendChild(config);
+
+ return serialize(domImpl, doc);
+ } catch (ParserConfigurationException e) {
+ s_logger.error("Error while creating delete message : " + e.getMessage());
+ return null;
+ } catch (DOMException e) {
+ s_logger.error("Error while creating delete message : " + e.getMessage());
+ return null;
+ }
+ }
+
+ public static String getDeletePortProfile(String portName) {
+ try {
+ // Create the document and root element.
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ DOMImplementation domImpl = docBuilder.getDOMImplementation();
+ Document doc = createDocument(domImpl);
+
+ // Edit configuration command.
+ Element editConfig = doc.createElement("nf:edit-config");
+ doc.getDocumentElement().appendChild(editConfig);
+
+ // Command to get into exec configure mode.
+ Element target = doc.createElement("nf:target");
+ Element running = doc.createElement("nf:running");
+ target.appendChild(running);
+ editConfig.appendChild(target);
+
+ // Command to create the port profile with the desired configuration.
+ Element config = doc.createElement("nf:config");
+ config.appendChild(deletePortProfileDetails(doc, portName));
+ editConfig.appendChild(config);
+
+ return serialize(domImpl, doc);
+ } catch (ParserConfigurationException e) {
+ s_logger.error("Error while creating delete message : " + e.getMessage());
+ return null;
+ } catch (DOMException e) {
+ s_logger.error("Error while creating delete message : " + e.getMessage());
+ return null;
+ }
+ }
+
+ public static String getHello() {
+ try {
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ DOMImplementation domImpl = docBuilder.getDOMImplementation();
+
+ // Root elements.
+ Document doc = domImpl.createDocument(s_namespace, "nc:hello", null);
+
+ // Client capacity. We are only supporting basic capacity.
+ Element capabilities = doc.createElement("nc:capabilities");
+ Element capability = doc.createElement("nc:capability");
+ capability.setTextContent("urn:ietf:params:xml:ns:netconf:base:1.0");
+
+ capabilities.appendChild(capability);
+ doc.getDocumentElement().appendChild(capabilities);
+
+ return serialize(domImpl, doc);
+ } catch (ParserConfigurationException e) {
+ s_logger.error("Error while creating hello message : " + e.getMessage());
+ return null;
+ } catch (DOMException e) {
+ s_logger.error("Error while creating delete message : " + e.getMessage());
+ return null;
+ }
+ }
+
+ private static Element configPortProfileDetails(Document doc, String name, PortProfileType type,
+ BindingType binding, SwitchPortMode mode, int vlanid) {
+
+ // In mode, exec_configure.
+ Element configure = doc.createElementNS(s_ciscons, "nxos:configure");
+ Element modeConfigure = doc.createElement("nxos:" + s_configuremode);
+ configure.appendChild(modeConfigure);
+
+ // Port profile name and type configuration.
+ Element portProfile = doc.createElement("port-profile");
+ modeConfigure.appendChild(portProfile);
+
+ // Port profile type.
+ Element portDetails = doc.createElement("name");
+ switch (type) {
+ case none:
+ portProfile.appendChild(portDetails);
+ break;
+ case ethernet:
+ {
+ Element typetag = doc.createElement("type");
+ Element ethernettype = doc.createElement("ethernet");
+ portProfile.appendChild(typetag);
+ typetag.appendChild(ethernettype);
+ ethernettype.appendChild(portDetails);
+ }
+ break;
+ case vethernet:
+ {
+ Element typetag = doc.createElement("type");
+ Element ethernettype = doc.createElement("vethernet");
+ portProfile.appendChild(typetag);
+ typetag.appendChild(ethernettype);
+ ethernettype.appendChild(portDetails);
+ }
+ break;
+ }
+
+ // Port profile name.
+ Element value = doc.createElement(s_paramvalue);
+ value.setAttribute("isKey", "true");
+ value.setTextContent(name);
+ portDetails.appendChild(value);
+
+ // element for port prof mode.
+ Element portProf = doc.createElement(s_portprofmode);
+ portDetails.appendChild(portProf);
+
+ // Binding type.
+ if (binding != BindingType.none) {
+ portProf.appendChild(getBindingType(doc, binding));
+ }
+
+ if (mode != SwitchPortMode.none) {
+ // Switchport mode.
+ portProf.appendChild(getSwitchPortMode(doc, mode));
+ // Adding vlan details.
+ portProf.appendChild(getVlanDetails(doc, mode, vlanid));
+ }
+
+ // Command "vmware port-group".
+ Element vmware = doc.createElement("vmware");
+ Element portgroup = doc.createElement("port-group");
+ vmware.appendChild(portgroup);
+ portProf.appendChild(vmware);
+
+ // no shutdown.
+ Element no = doc.createElement("no");
+ Element shutdown = doc.createElement("shutdown");
+ no.appendChild(shutdown);
+ portProf.appendChild(no);
+
+ // Enable the port profile.
+ Element state = doc.createElement("state");
+ Element enabled = doc.createElement("enabled");
+ state.appendChild(enabled);
+ portProf.appendChild(state);
+
+ // Persist the configuration across reboots.
+ // modeConfigure.appendChild(persistConfiguration(doc));
+
+ return configure;
+ }
+
+ private static Element deletePortProfileDetails(Document doc, String name) {
+ Element configure = doc.createElementNS(s_ciscons, "nxos:configure");
+ Element modeConfigure = doc.createElement("nxos:" + s_configuremode);
+ configure.appendChild(modeConfigure);
+
+ // Command and name for the port profile to be deleted.
+ Element deletePortProfile = doc.createElement("no");
+ modeConfigure.appendChild(deletePortProfile);
+
+ Element portProfile = doc.createElement("port-profile");
+ deletePortProfile.appendChild(portProfile);
+
+ Element portDetails = doc.createElement("name");
+ portProfile.appendChild(portDetails);
+
+ // Name of the profile to delete.
+ Element value = doc.createElement(s_paramvalue);
+ value.setAttribute("isKey", "true");
+ value.setTextContent(name);
+ portDetails.appendChild(value);
+
+ // Persist the configuration across reboots.
+ // modeConfigure.appendChild(persistConfiguration(doc));
+
+ return configure;
+ }
+
+ private static Element persistConfiguration(Document doc) {
+ Element copy = doc.createElement("copy");
+ Element running = doc.createElement("running-config");
+ Element startup = doc.createElement("startup-config");
+ copy.appendChild(running);
+ running.appendChild(startup);
+ return copy;
+ }
+
+ private static Element getVlanDetails(Document doc, SwitchPortMode mode, int vlanid) {
+ Element switchport = doc.createElement("switchport");
+
+ // Handling is there only for 'access' mode command.
+ if (mode == SwitchPortMode.access) {
+ Element access = doc.createElement("access");
+ switchport.appendChild(access);
+
+ Element vlan = doc.createElement("vlan");
+ access.appendChild(vlan);
+
+ Element vlancreate = doc.createElement("vlan-id-create-delete");
+ vlan.appendChild(vlancreate);
+
+ Element value = doc.createElement(s_paramvalue);
+ value.setTextContent(Integer.toString(vlanid));
+ vlancreate.appendChild(value);
+ }
+
+ return switchport;
+ }
+
+ private static Element getBindingType(Document doc, BindingType binding) {
+ Element portBinding = doc.createElement("port-binding");
+
+ // We only have handling for access or trunk mode. Handling for private-vlan
+ // host/promiscuous command will have to be added.
+ if (binding == BindingType.portbindingstatic) {
+ Element type = doc.createElement("static");
+ portBinding.appendChild(type);
+ } else if (binding == BindingType.portbindingdynamic) {
+ Element type = doc.createElement("dynamic");
+ portBinding.appendChild(type);
+ } else if (binding == BindingType.portbindingephermal) {
+ Element type = doc.createElement("ephemeral");
+ portBinding.appendChild(type);
+ }
+
+ return portBinding;
+ }
+
+ private static Element getSwitchPortMode(Document doc, SwitchPortMode mode) {
+ Element switchport = doc.createElement("switchport");
+ Element accessmode = doc.createElement("mode");
+ switchport.appendChild(accessmode);
+
+ // We only have handling for access or trunk mode. Handling for private-vlan
+ // host/promiscuous command will have to be added.
+ if (mode == SwitchPortMode.access) {
+ Element access = doc.createElement("access");
+ accessmode.appendChild(access);
+ } else if (mode == SwitchPortMode.trunk) {
+ Element trunk = doc.createElement("trunk");
+ accessmode.appendChild(trunk);
+ }
+
+ return switchport;
+ }
+
+ private static Document createDocument(DOMImplementation dom) {
+ Document doc = dom.createDocument(s_namespace, "nf:rpc", null);
+ doc.getDocumentElement().setAttribute( "message-id", "101" );
+ doc.getDocumentElement().setAttributeNS(s_ciscons, "portprofile", "true");
+ return doc;
+ }
+
+ private static String serialize(DOMImplementation domImpl, Document document) {
+ DOMImplementationLS ls = (DOMImplementationLS) domImpl;
+ LSSerializer lss = ls.createLSSerializer();
+ return lss.writeToString(document);
+ }
+}
diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmResponse.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmResponse.java
index 6bc6371fdb4..50db9981e52 100644
--- a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmResponse.java
+++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmResponse.java
@@ -99,19 +99,19 @@ public class VsmResponse {
StringBuffer error = new StringBuffer("");
error.append(" Severity: " + _severity)
- .append(" Error code: " + _tag)
- .append(" Error type: " + _type);
+ .append(", Error code: " + _tag)
+ .append(", Error type: " + _type);
if (_message != null) {
- error.append(" Error Message: " + _message);
+ error.append(", Error Message: " + _message);
}
if (_info != null) {
- error.append(" Error info: " + _info);
+ error.append(", Error info: " + _info);
}
if (_path != null) {
- error.append(" Path: " + _path);
+ error.append(", Path: " + _path);
}
return error.toString();