Skip to content

Commit 76e1d33

Browse files
Devdeep SinghVijayendra Bhamidipati
authored andcommitted
CS-9919: Support for Nexus Swiches (Cisco Vswitches)
Description: Adding a helper routine for modifying port profile configuration.
1 parent 781f0b4 commit 76e1d33

2 files changed

Lines changed: 184 additions & 17 deletions

File tree

utils/src/com/cloud/utils/cisco/n1kv/vsm/NetconfHelper.java

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
import java.io.InputStream;
66
import java.io.OutputStream;
7+
import java.util.List;
78

9+
import com.cloud.utils.Pair;
810
import com.cloud.utils.ssh.*;
911
import com.trilead.ssh2.Session;
1012
import com.trilead.ssh2.Connection;
@@ -63,19 +65,41 @@ public void queryStatus() throws CloudRuntimeException {
6365
}
6466

6567
public void addPortProfile(String name, PortProfileType type, BindingType binding,
66-
SwitchPortMode mode, int vlanid) throws CloudRuntimeException {
67-
String command = VsmCommand.getAddPortProfile(name, type, binding, mode, vlanid);
68-
command = command.concat(SSH_NETCONF_TERMINATOR);
69-
send(command);
70-
// parse the rpc reply and the return success or failure.
71-
parseReply(receive());
68+
SwitchPortMode mode, int vlanid, int networkRate) throws CloudRuntimeException {
69+
String command = VsmCommand.getAddPortProfile(name, type, binding, mode, vlanid, networkRate);
70+
if (command != null) {
71+
command = command.concat(SSH_NETCONF_TERMINATOR);
72+
send(command);
73+
// parse the rpc reply and the return success or failure.
74+
parseReply(receive());
75+
} else {
76+
throw new CloudRuntimeException("Error generating rpc request for adding port profile.");
77+
}
78+
}
79+
80+
public void updatePortProfile(String name, SwitchPortMode mode,
81+
List<Pair<VsmCommand.OperationType, String>> params) throws CloudRuntimeException {
82+
String command = VsmCommand.getUpdatePortProfile(name, mode, params);
83+
if (command != null) {
84+
command = command.concat(SSH_NETCONF_TERMINATOR);
85+
send(command);
86+
// parse the rpc reply and the return success or failure.
87+
parseReply(receive());
88+
} else {
89+
throw new CloudRuntimeException("Error generating rpc request for updating port profile.");
90+
}
7291
}
7392

7493
public void deletePortProfile(String name) throws CloudRuntimeException {
75-
String command = VsmCommand.getDeletePortProfile(name) + SSH_NETCONF_TERMINATOR;
76-
send(command);
77-
// parse the rpc reply and the return success or failure.
78-
parseReply(receive());
94+
String command = VsmCommand.getDeletePortProfile(name);
95+
if (command != null) {
96+
command = command.concat(SSH_NETCONF_TERMINATOR);
97+
send(command);
98+
// parse the rpc reply and the return success or failure.
99+
parseReply(receive());
100+
} else {
101+
throw new CloudRuntimeException("Error generating rpc request for deleting port profile.");
102+
}
79103
}
80104

81105
private void exchangeHello() {

utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java

Lines changed: 150 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.cloud.utils.cisco.n1kv.vsm;
22

3+
import java.util.List;
34
import javax.xml.parsers.DocumentBuilder;
45
import javax.xml.parsers.DocumentBuilderFactory;
56
import javax.xml.parsers.ParserConfigurationException;
@@ -9,9 +10,12 @@
910
import org.w3c.dom.DOMImplementation;
1011
import org.w3c.dom.Document;
1112
import org.w3c.dom.Element;
13+
import org.w3c.dom.Node;
1214
import org.w3c.dom.ls.DOMImplementationLS;
1315
import org.w3c.dom.ls.LSSerializer;
1416

17+
import com.cloud.utils.Pair;
18+
1519
public class VsmCommand {
1620

1721
private static final Logger s_logger = Logger.getLogger(VsmCommand.class);
@@ -42,8 +46,14 @@ public enum SwitchPortMode {
4246
privatevlanpromiscuous
4347
}
4448

49+
public enum OperationType {
50+
addvlanid,
51+
removevlanid,
52+
setrate
53+
}
54+
4555
public static String getAddPortProfile(String name, PortProfileType type,
46-
BindingType binding, SwitchPortMode mode, int vlanid) {
56+
BindingType binding, SwitchPortMode mode, int vlanid, int networkRate) {
4757
try {
4858
// Create the document and root element.
4959
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
@@ -76,6 +86,40 @@ public static String getAddPortProfile(String name, PortProfileType type,
7686
}
7787
}
7888

89+
public static String getUpdatePortProfile(String name, SwitchPortMode mode,
90+
List<Pair<VsmCommand.OperationType, String>> params) {
91+
try {
92+
// Create the document and root element.
93+
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
94+
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
95+
DOMImplementation domImpl = docBuilder.getDOMImplementation();
96+
Document doc = createDocument(domImpl);
97+
98+
// Edit configuration command.
99+
Element editConfig = doc.createElement("nf:edit-config");
100+
doc.getDocumentElement().appendChild(editConfig);
101+
102+
// Command to get into exec configure mode.
103+
Element target = doc.createElement("nf:target");
104+
Element running = doc.createElement("nf:running");
105+
target.appendChild(running);
106+
editConfig.appendChild(target);
107+
108+
// Command to update the port profile with the desired configuration.
109+
Element config = doc.createElement("nf:config");
110+
config.appendChild(configPortProfileDetails(doc, name, mode, params));
111+
editConfig.appendChild(config);
112+
113+
return serialize(domImpl, doc);
114+
} catch (ParserConfigurationException e) {
115+
s_logger.error("Error while creating update message : " + e.getMessage());
116+
return null;
117+
} catch (DOMException e) {
118+
s_logger.error("Error while creating update message : " + e.getMessage());
119+
return null;
120+
}
121+
}
122+
79123
public static String getDeletePortProfile(String portName) {
80124
try {
81125
// Create the document and root element.
@@ -193,7 +237,7 @@ private static Element configPortProfileDetails(Document doc, String name, PortP
193237
// Switchport mode.
194238
portProf.appendChild(getSwitchPortMode(doc, mode));
195239
// Adding vlan details.
196-
portProf.appendChild(getVlanDetails(doc, mode, vlanid));
240+
portProf.appendChild(getAddVlanDetails(doc, mode, Integer.toString(vlanid)));
197241
}
198242

199243
// Command "vmware port-group".
@@ -220,6 +264,48 @@ private static Element configPortProfileDetails(Document doc, String name, PortP
220264
return configure;
221265
}
222266

267+
private static Element configPortProfileDetails(Document doc, String name, SwitchPortMode mode,
268+
List<Pair<VsmCommand.OperationType, String>> params) {
269+
270+
// In mode, exec_configure.
271+
Element configure = doc.createElementNS(s_ciscons, "nxos:configure");
272+
Element modeConfigure = doc.createElement("nxos:" + s_configuremode);
273+
configure.appendChild(modeConfigure);
274+
275+
// Port profile name and type configuration.
276+
Element portProfile = doc.createElement("port-profile");
277+
modeConfigure.appendChild(portProfile);
278+
279+
// Port profile type.
280+
Element portDetails = doc.createElement("name");
281+
portProfile.appendChild(portDetails);
282+
283+
// Name of the profile to update.
284+
Element value = doc.createElement(s_paramvalue);
285+
value.setAttribute("isKey", "true");
286+
value.setTextContent(name);
287+
portDetails.appendChild(value);
288+
289+
// element for port prof mode.
290+
Element portProfMode = doc.createElement(s_portprofmode);
291+
portDetails.appendChild(portProfMode);
292+
293+
for (Pair<VsmCommand.OperationType, String> item : params) {
294+
if (item.first() == OperationType.addvlanid) {
295+
// Set the access mode configuration or the list
296+
// of allowed vlans on the trunking interface.
297+
portProfMode.appendChild(getAddVlanDetails(doc, mode, item.second()));
298+
} else if (item.first() == OperationType.removevlanid) {
299+
portProfMode.appendChild(getDeleteVlanDetails(doc, mode, item.second()));
300+
}
301+
}
302+
303+
// Persist the configuration across reboots.
304+
// modeConfigure.appendChild(persistConfiguration(doc));
305+
306+
return configure;
307+
}
308+
223309
private static Element deletePortProfileDetails(Document doc, String name) {
224310
Element configure = doc.createElementNS(s_ciscons, "nxos:configure");
225311
Element modeConfigure = doc.createElement("nxos:" + s_configuremode);
@@ -256,26 +342,83 @@ private static Element persistConfiguration(Document doc) {
256342
return copy;
257343
}
258344

259-
private static Element getVlanDetails(Document doc, SwitchPortMode mode, int vlanid) {
345+
private static Element getAddVlanDetails(Document doc, SwitchPortMode mode, String vlanid) {
260346
Element switchport = doc.createElement("switchport");
261347

262-
// Handling is there only for 'access' mode command.
348+
// Details of the vlanid to add.
349+
Element vlancreate = doc.createElement("vlan-id-create-delete");
350+
Element value = doc.createElement(s_paramvalue);
351+
value.setTextContent(vlanid);
352+
vlancreate.appendChild(value);
353+
354+
// Handling is there only for 'access' and 'trunk allowed' mode command.
263355
if (mode == SwitchPortMode.access) {
264356
Element access = doc.createElement("access");
265357
switchport.appendChild(access);
266358

267359
Element vlan = doc.createElement("vlan");
268360
access.appendChild(vlan);
269361

270-
Element vlancreate = doc.createElement("vlan-id-create-delete");
271362
vlan.appendChild(vlancreate);
363+
} else if (mode == SwitchPortMode.trunk) {
364+
Element trunk = doc.createElement("trunk");
365+
switchport.appendChild(trunk);
366+
367+
Element allowed = doc.createElement("allowed");
368+
trunk.appendChild(allowed);
369+
370+
Element vlan = doc.createElement("vlan");
371+
allowed.appendChild(vlan);
372+
373+
Element add = doc.createElement("add");
374+
vlan.appendChild(add);
375+
376+
add.appendChild(vlancreate);
377+
}
272378

379+
return switchport;
380+
}
381+
382+
private static Node getDeleteVlanDetails(Document doc, SwitchPortMode mode, String vlanid) {
383+
Node parentNode = null;
384+
Element switchport = doc.createElement("switchport");
385+
386+
// Handling is there only for 'access' and 'trunk allowed' mode command.
387+
if (mode == SwitchPortMode.access) {
388+
Element no = doc.createElement("no");
389+
no.appendChild(switchport);
390+
parentNode = no;
391+
392+
Element access = doc.createElement("access");
393+
switchport.appendChild(access);
394+
395+
Element vlan = doc.createElement("vlan");
396+
access.appendChild(vlan);
397+
} else if (mode == SwitchPortMode.trunk) {
398+
parentNode = switchport;
399+
400+
Element trunk = doc.createElement("trunk");
401+
switchport.appendChild(trunk);
402+
403+
Element allowed = doc.createElement("allowed");
404+
trunk.appendChild(allowed);
405+
406+
Element vlan = doc.createElement("vlan");
407+
allowed.appendChild(vlan);
408+
409+
Element remove = doc.createElement("remove");
410+
vlan.appendChild(remove);
411+
412+
// Details of the vlanid to add.
413+
Element vlancreate = doc.createElement("vlan-id-create-delete");
273414
Element value = doc.createElement(s_paramvalue);
274-
value.setTextContent(Integer.toString(vlanid));
415+
value.setTextContent(vlanid);
275416
vlancreate.appendChild(value);
417+
418+
remove.appendChild(vlancreate);
276419
}
277420

278-
return switchport;
421+
return parentNode;
279422
}
280423

281424
private static Element getBindingType(Document doc, BindingType binding) {

0 commit comments

Comments
 (0)