Network driver development HOWTO

Overview

As of Bella 2.1, network substrate drivers have been reorganized from a number of separate projects (one project per device family) into a single simple project that covers all network elements. Node Agent code has been removed, such that new network drivers and handlers no longer require the use of Node Agent and are invoked directly by the Site Authority.

The drivers are located under $ORCA_SRC/handlers/network and are organized into a number of packages:

  • orca.handlers.network.core - contains interfaces and classes common to multiple network element types (routers, DWDM platforms etc)
  • orca.handlers.network.os - implementation of the Polatis optical switch driver
  • orca.handlers.network.dtn - implementation of the Infinera DTN driver
  • orca.handlers.network.router - implementations for routers/switches (currently contains Cisco6509 and Juniper EX3200)
  • orca.handlers.network.tasks - common interfaces and classes for handler tasks that invoke driver actions. Also tasks for DTN and Polatis.
  • orca.handlers.network.tasks.Cisco6509 - handler tasks for Cisco 6509
  • orca.handlers.network.tasks.EX3200 - handler tasks for Juniper EX3200

These packages are spread over multiple directories under $ORCA_SRC/handlers/network/src/main/java and $ORCA_SRC/handlers/network/src/main/resources. The resources/ subtree contains XML and TXT scripts used by different device drivers that encode the commands that need to be sent.

The attached figure shows the UML diagram of the classes and interfaces that implement router drivers (not DTN or OS).

Implementing a new router driver

Interfaces

A basic router driver must either implement the basic IRouterDevice interface (if the device supports basic VLAN operations) or the IMappingRouterDevice (if the device supports VLAN tag remapping):

IRouterDevice:

public interface IRouterDevice extends INetworkDevice {
	
    // create VLAN with QoS
    public void createVLAN(String vlanTag, String qos) throws CommandException;

    // delete VLAN
    public void deleteVLAN(String vlanTag) throws CommandException;
    
    // add trunk ports to a VLAN
    public void addTrunkPortsToVLAN(String vlanTag, String ports) throws CommandException;
    
    // add access ports to a VLAN
    public void addAccessPortsToVLAN(String vlanTag, String ports) throws CommandException;

    // remove trunk ports from a VLAN
    public void removeTrunkPortsFromVLAN(String vlanTag, String ports) throws CommandException;
    
    // remove access ports from a VLAN
    public void removeAccessPortsFromVLAN(String vlanTag, String ports) throws CommandException;
       
}

IMappingRouterDevice:

public interface IMappingRouterDevice extends IRouterDevice {
	
    public void mapVLANs(String sourceTag, String destinationTag, String port) throws CommandException;

    public void unmapVLANs(String sourceTag, String destinationTag, String port) throws CommandException; 

}

The parameters are passed in as strings and their interpretation is left to the driver implementation. For example, the port ranges are passed in to the Cisco devices in IOS CLI syntax as e.g.

gigabitethernet 1/25-27, gigabitethernet 1/12-14

On the other hand, Juniper device takes port ranges as

ge-0/0/[1-5], xe-0/0/1

Tasks

Once the interface is implemented, the next step is to implement a set of tasks (a class per task) corresponding to driver actions. A common way to implement them is to define a device-specific base task that is a child of NetworkBaseTask and subclass further tasks from it (see the orca.handlers.network.tasks.Cisco6509 or orca.handlers.network.tasks.EX3200 as an example).

Juniper EX3200 driver UML

Each task must have at least an

public void execute() throws BuildException;

method and can have any number of methods of the form

public void setXxxYyyZzz(String s);

These methods automatically take properties of name xxx.yyy.zzz and pass their value to these methods. For example method setVlanTag() takes the value of property vlan.tag from handler scripts and passes it to this method as a Java String.

Compiling

You can compile the network drivers project standalone by issuing

mvn install 

in the $ORCA_SRC/handlers/network directory.

NOTE: you still need to run 'mvn install' on the entire trunk at least once prior to doing this.

Meta-information

Once the tasks are implemented, you must create a mapping between Java properties used by Ant handlers and tasks and declare the driver as available. Targets must be created in the test handler to facilitate testing. This is done by editing files:

$ORCA_SRC/handlers/network/src/main/resources/orca/handlers/network/network.properties - driver declaration

$ORCA_SRC/handlers/network/src/main/resources/orca/handlers/network/network.tasks - Java properties to task classname mapping

$ORCA_SRC/handlers/network/test.xml - test handler where targets need to be added for each declared task and properties can be passed in as parameters to tasks

Unit tests

Developers are strongly encouraged to implement unit tests under handlers/network/src/test/java in the package orca.handlers.network. See existing tests for inspiration.

Task tests

Once unit tests work and tasks and associated meta-information is defined, you can test your driver by invoking the test handler. You should update handlers/network/ant/tests.properties file to add necessary property definitions (like vlan tags, device IP addresses or DNS names although they can be passed as command-line parameters to ant as well). You should create a handlers/network/ant/user.tests.properties file where you can re-declare login properties (usernames and passwords). These properties are declared in handlers/network/ant/tests.properties file, however they have empty values. This is done because ant/tests.properties file is under Subversion control and you should avoid checking in live passwords and logins (and other credentials) into subversion. Any properties declared in ant/user.tests.properties take precedence of properties declared in ant/tests.properties, however the ant/user.tests.properties file is NOT and should NEVER be checked into subversion.

  ant -f test.xml -D<property name>=<property value> <target name>

NOTE: by default ant/tests.properties has emulation and test.mode properties set to true which means drivers will not execute actual tasks on real hardware (this depends on the implementation, you should look at the code of Cisco 6509 and EX3200 drivers and the use of IDevice.enableEmulation() and IDevice.isEmulationEnabled() methods).

Additional Notes

Developing another Cisco driver

Developing a driver for another Cisco device (let's call it 'NewCiscoDevice' here, you should come up with a better name) is simple:

  1. Create a new class for the device that extends CiscoRouterDevice and implements IRouterDevice or directly extends Cisco6509Device if it is capable of VLAN translation. Its constructor is trivial:
        public NewCiscoDevice(String deviceAddress, String uid, String password, String adminPassword) {
            super(deviceAddress, uid, password, adminPassword);
            basepath = "/orca/handlers/network/router/cisco/NewCiscoDevice";
        }
    
  2. Create a new directory
       $ORCA_SRC/handlers/network/src/main/resources/orca/handlers/network/router/cisco/NewCiscoDevice
    
  3. Copy the XML scripts from $ORCA_SRC/handlers/network/src/main/resources/orca/handlers/network/router/cisco/6509 to this folder and modify them for the syntax of the new device
  4. Create a new package under $ORCA_SRC/handlers/network/src/main/java called orca.handlers.network.tasks.NewCiscoDevice and copy into it all the tasks from package orca.handlers.network.tasks.Cisco6509. Modify the tasks if necessary
  5. Declare the new driver and update the meta-information as described above.
  6. Test

Attachments