Update Cluster Driver

Change-Id: I8a3a57e19637ff210548e57d41178e6f194cf694
diff --git a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
index a2537a2..03ab601 100644
--- a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
+++ b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
@@ -95,7 +95,7 @@
                                               main.topology,
                                               main.Mininet1.home + "custom/",
                                               direction="to" )
-            stepResult = main.testSetUp.envSetup( True, True )
+            stepResult = main.testSetUp.envSetup()
         except Exception as e:
             main.testSetUp.envSetupException(e)
         main.testSetUp.evnSetupConclusion( stepResult )
@@ -113,7 +113,7 @@
         - Connect to cli
         """
         main.flowCompiler = "Flow Rules"
-        main.initialized = main.testSetUp.ONOSSetUp( main.Mininet1, True )
+        main.initialized = main.testSetUp.ONOSSetUp( main.Mininet1, main.Cluster, True )
         main.intentFunction.report( main )
 
     def CASE8( self, main ):
@@ -133,7 +133,7 @@
             Report errors/warnings/exceptions
         """
         main.log.info( "Error report: \n" )
-        main.ONOSbench.logReport( globalONOSip[ 0 ],
+        main.ONOSbench.logReport( main.Cluster.active( 0 ).ipAddress,
                                   [ "INFO", "FOLLOWER", "WARN", "flow", "ERROR", "Except" ],
                                   "s" )
         #main.ONOSbench.logReport( globalONOSip[ 1 ], [ "INFO" ], "d" )
@@ -215,9 +215,7 @@
         for i in range( 1, ( main.numSwitch + 1 ) ):
             switchList.append( 's' + str( i ) )
 
-        tempONOSip = []
-        for i in range( main.numCtrls ):
-            tempONOSip.append( main.ONOSip[ i ] )
+        tempONOSip = main.Cluster.getIps()
 
         assignResult = main.Mininet1.assignSwController( sw=switchList,
                                                          ip=tempONOSip,
@@ -230,7 +228,7 @@
         for i in range( 1, ( main.numSwitch + 1 ) ):
             response = main.Mininet1.getSwController( "s" + str( i ) )
             print( "Response is " + str( response ) )
-            if re.search( "tcp:" + main.ONOSip[ 0 ], response ):
+            if re.search( "tcp:" + main.Cluster.active( 0 ).ipAddress, response ):
                 assignResult = assignResult and main.TRUE
             else:
                 assignResult = main.FALSE
@@ -359,7 +357,7 @@
         main.step( "Balancing mastership of switches" )
 
         balanceResult = main.FALSE
-        balanceResult = utilities.retry( f=main.CLIs[ 0 ].balanceMasters, retValue=main.FALSE, args=[] )
+        balanceResult = utilities.retry( f=main.Cluster.active( 0 ).CLI.balanceMasters, retValue=main.FALSE, args=[] )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
@@ -382,9 +380,9 @@
 
         cmd = "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator"
 
-        stepResult = main.CLIs[ 0 ].setCfg( component=cmd,
+        stepResult = main.Cluster.active( 0 ).CLI.setCfg( component=cmd,
                                             propName="useFlowObjectives", value="true" )
-        stepResult &= main.CLIs[ 0 ].setCfg( component=cmd,
+        stepResult &= main.Cluster.active( 0 ).CLI.setCfg( component=cmd,
                                              propName="defaultFlowObjectiveCompiler",
                                              value='org.onosproject.net.intent.impl.compiler.LinkCollectionIntentObjectiveCompiler' )
 
@@ -450,7 +448,7 @@
             main.Utils
         except ( NameError, AttributeError ):
             main.Utils = Utils()
-        main.Utils.copyKarafLog()
+        main.Utils.copyKarafLog( "cycle" + str( main.cycle ) )
     def CASE1000( self, main ):
         """
             Add host intents between 2 host:
@@ -480,12 +478,6 @@
         # if you want to use the wrapper function
         assert main, "There is no main"
         try:
-            assert main.RESTs
-        except AssertionError:
-            main.log.error( "There is no main.RESTs, skipping test cases" )
-            main.initialized = main.FALSE
-            main.skipCase()
-        try:
             assert main.Mininet1
         except AssertionError:
             main.log.error( "Mininet handle should be named Mininet1, skipping test cases" )
@@ -500,12 +492,12 @@
             main.skipCase()
 
         # Save leader candidates
-        intentLeadersOld = main.CLIs[ 0 ].leaderCandidates()
+        intentLeadersOld = main.Cluster.active( 0 ).CLI.leaderCandidates()
 
-        main.case( "Host Intents Test - " + str( main.numCtrls ) +
+        main.case( "Host Intents Test - " + str( main.Cluster.numCtrls ) +
                    " NODE(S) - OF " + main.OFProtocol + " - Using " + main.flowCompiler )
         main.caseExplanation = "This test case tests Host intents using " +\
-                                str( main.numCtrls ) + " node(s) cluster;\n" +\
+                                str( main.Cluster.numCtrls ) + " node(s) cluster;\n" +\
                                 "Different type of hosts will be tested in " +\
                                 "each step such as IPV4, Dual stack, VLAN " +\
                                 "etc;\nThe test will use OF " + main.OFProtocol +\
@@ -679,7 +671,7 @@
         # supported by it
 
         main.step( "Confirm that ONOS leadership is unchanged" )
-        intentLeadersNew = main.CLIs[ 0 ].leaderCandidates()
+        intentLeadersNew = main.Cluster.active( 0 ).CLI.leaderCandidates()
         main.intentFunction.checkLeaderChange( intentLeadersOld,
                                                 intentLeadersNew )
 
@@ -716,12 +708,6 @@
             # if you want to use the wrapper function
         assert main, "There is no main"
         try:
-            assert main.RESTs
-        except AssertionError:
-            main.log.error( "There is no main.RESTs, skipping test cases" )
-            main.initialized = main.FALSE
-            main.skipCase()
-        try:
             assert main.Mininet1
         except AssertionError:
             main.log.error( "Mininet handle should be named Mininet1, skipping test cases" )
@@ -735,10 +721,10 @@
             main.initialized = main.FALSE
             main.skipCase()
 
-        main.case( "Point Intents Test - " + str( main.numCtrls ) +
+        main.case( "Point Intents Test - " + str( main.Cluster.numCtrls ) +
                    " NODE(S) - OF " + main.OFProtocol + " - Using " + main.flowCompiler )
         main.caseExplanation = "This test case will test point to point" + \
-                               " intents using " + str( main.numCtrls ) + \
+                               " intents using " + str( main.Cluster.numCtrls ) + \
                                " node(s) cluster;\n" + \
                                "Different type of hosts will be tested in " + \
                                "each step such as IPV4, Dual stack, VLAN etc" + \
@@ -1068,7 +1054,6 @@
         assert main, "There is no main"
 
         try:
-            assert main.CLIs, "There is no main.CLIs, skipping test cases"
             assert main.Mininet1, "Mininet handle should be named Mininet1, skipping test cases"
             assert main.numSwitch, "Place the total number of switch topology in main.numSwitch"
         except AssertionError:
@@ -1076,11 +1061,11 @@
             main.skipCase()
 
         main.testName = "Single to Multi Point Intents"
-        main.case( main.testName + " Test - " + str( main.numCtrls ) +
+        main.case( main.testName + " Test - " + str( main.Cluster.numCtrls ) +
                    " NODE(S) - OF " + main.OFProtocol + " - Using " + main.flowCompiler )
         main.caseExplanation = "This test case will test single point to" + \
                                " multi point intents using " + \
-                               str( main.numCtrls ) + " node(s) cluster;\n" + \
+                               str( main.Cluster.numCtrls ) + " node(s) cluster;\n" + \
                                "Different type of hosts will be tested in " + \
                                "each step such as IPV4, Dual stack, VLAN etc" + \
                                ";\nThe test will use OF " + main.OFProtocol + \
@@ -1118,7 +1103,7 @@
                 sw2="s2",
                 expectedLink=18 )
         else:
-            main.CLIs[ 0 ].removeAllIntents( purge=True )
+            main.Cluster.active( 0 ).CLI.removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1157,7 +1142,7 @@
                 sw2="s2",
                 expectedLink=18 )
         else:
-            main.CLIs[ 0 ].removeAllIntents( purge=True )
+            main.Cluster.active( 0 ).CLI.removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1196,7 +1181,7 @@
                 sw2="s2",
                 expectedLink=18 )
         else:
-            main.CLIs[ 0 ].removeAllIntents( purge=True )
+            main.Cluster.active( 0 ).CLI.removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1236,7 +1221,7 @@
                 sw2="s2",
                 expectedLink=18 )
         else:
-            main.CLIs[ 0 ].removeAllIntents()
+            main.Cluster.active( 0 ).CLI.removeAllIntents()
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1277,7 +1262,7 @@
                 sw2="s2",
                 expectedLink=18 )
         else:
-            main.CLIs[ 0 ].removeAllIntents()
+            main.Cluster.active( 0 ).CLI.removeAllIntents()
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1306,16 +1291,15 @@
              - Remove intents
         """
         assert main, "There is no main"
-        assert main.CLIs, "There is no main.CLIs"
         assert main.Mininet1, "Mininet handle should be named Mininet1"
         assert main.numSwitch, "Placed the total number of switch topology in \
                                 main.numSwitch"
 
         main.case( "Multi To Single Point Intents Test - " +
-                   str( main.numCtrls ) + " NODE(S) - OF " + main.OFProtocol + " - Using " + main.flowCompiler )
+                   str( main.Cluster.numCtrls ) + " NODE(S) - OF " + main.OFProtocol + " - Using " + main.flowCompiler )
         main.caseExplanation = "This test case will test single point to" +\
                                " multi point intents using " +\
-                               str( main.numCtrls ) + " node(s) cluster;\n" +\
+                               str( main.Cluster.numCtrls ) + " node(s) cluster;\n" +\
                                "Different type of hosts will be tested in " +\
                                "each step such as IPV4, Dual stack, VLAN etc" +\
                                ";\nThe test will use OF " + main.OFProtocol +\
@@ -1437,12 +1421,6 @@
         # if you want to use the wrapper function
         assert main, "There is no main"
         try:
-            assert main.RESTs
-        except AssertionError:
-            main.log.error( "There is no main.RESTs, skipping test cases" )
-            main.initialized = main.FALSE
-            main.skipCase()
-        try:
             assert main.Mininet1
         except AssertionError:
             main.log.error( "Mininet handle should be named Mininet1, skipping test cases" )
diff --git a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.topo b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.topo
index 7701bee..33bcf52 100755
--- a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.topo
+++ b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.topo
@@ -1,94 +1,32 @@
 <TOPOLOGY>
     <COMPONENT>
 
-        <ONOSbench>
-            <host>localhost</host>
+        <ONOScell>
+            <host>localhost</host>  # ONOS "bench" machine
             <user>sdn</user>
             <password>rocks</password>
-            <type>OnosDriver</type>
+            <type>OnosClusterDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOSbench>
-
-        <ONOSrest1>
-            <host>OC1</host>
-            <port>8181</port>
-            <user>onos</user>
-            <password>rocks</password>
-            <type>OnosRestDriver</type>
-            <connect_order>2</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOSrest1>
-
-        <ONOSrest2>
-            <host>OC2</host>
-            <port>8181</port>
-            <user>onos</user>
-            <password>rocks</password>
-            <type>OnosRestDriver</type>
-            <connect_order>3</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOSrest2>
-
-        <ONOSrest3>
-            <host>OC3</host>
-            <port>8181</port>
-            <user>onos</user>
-            <password>rocks</password>
-            <type>OnosRestDriver</type>
-            <connect_order>4</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOSrest3>
-
-        <ONOScli1>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>2</connect_order>
-            <COMPONENTS>
+                <cluster_name></cluster_name>  # Used as a prefix for cluster components. Defaults to 'ONOS'
+                <diff_clihost></diff_clihost>  # if it has different host other than localhost for CLI. True or empty. OC# will be used for True.
                 <karaf_username></karaf_username>
                 <karaf_password></karaf_password>
-                <prompt></prompt>
+                <web_user></web_user>
+                <web_pass></web_pass>
+                <rest_port></rest_port>
+                <prompt></prompt>  # TODO: we technically need a few of these, one per component
+                <onos_home></onos_home>  # defines where onos home is
+                <nodes> 3 </nodes>  # number of nodes in the cluster
             </COMPONENTS>
-        </ONOScli1>
-
-        <ONOScli2>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>3</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOScli2>
-
-         <ONOScli3>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>4</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOScli3>
+        </ONOScell>
 
         <Mininet1>
             <host>OCN</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>MininetCliDriver</type>
-            <connect_order>5</connect_order>
+            <connect_order>2</connect_order>
             <COMPONENTS>
                 <home>~/mininet/</home>
                 <prompt></prompt>
@@ -100,7 +38,7 @@
             <user>sdn</user>
             <password>rocks</password>
             <type>ScapyCliDriver</type>
-            <connect_order>6</connect_order>
+            <connect_order>3</connect_order>
             <COMPONENTS>
                 <prompt></prompt>
             </COMPONENTS>
diff --git a/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py b/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
index 0a67658..5f29037 100644
--- a/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
+++ b/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
@@ -101,13 +101,13 @@
         # Adding host intents
         main.log.info( itemName + ": Adding host intents" )
 
-        intent1 = main.RESTs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
-                                                        hostIdTwo=host2.get( "id" ),
-                                                        vlanId=vlanId )
+        intent1 = main.Cluster.active( onosNode ).REST.addHostIntent( hostIdOne=host1.get( "id" ),
+                                                                      hostIdTwo=host2.get( "id" ),
+                                                                      vlanId=vlanId )
 
         # Get all intents ID in the system, time delay right after intents are added
         time.sleep( main.addIntentSleep )
-        intentsId = main.RESTs[ 0 ].getIntentsId()
+        intentsId = main.Cluster.active( 0 ).REST.getIntentsId()
     except( KeyError, TypeError ):
         errorMsg = "There was a problem loading the hosts data."
         if intentsId:
@@ -405,26 +405,26 @@
         ipSrc = senders[ 0 ].get( "ip" )
         ipDst = recipients[ 0 ].get( "ip" )
 
-        intent1 = main.RESTs[ onosNode ].addPointIntent(
-                                            ingressDevice=ingressDevice,
-                                            egressDevice=egressDevice,
-                                            ingressPort=portIngress,
-                                            egressPort=portEgress,
-                                            ethType=ethType,
-                                            ethSrc=srcMac,
-                                            ethDst=dstMac,
-                                            bandwidth=bandwidth,
-                                            lambdaAlloc=lambdaAlloc,
-                                            protected=protected,
-                                            ipProto=ipProto,
-                                            ipSrc=ipSrc,
-                                            ipDst=ipDst,
-                                            tcpSrc=tcpSrc,
-                                            tcpDst=tcpDst,
-                                            vlanId=vlanId )
+        intent1 = main.Cluster.active( onosNode ).REST.addPointIntent(
+                                                            ingressDevice=ingressDevice,
+                                                            egressDevice=egressDevice,
+                                                            ingressPort=portIngress,
+                                                            egressPort=portEgress,
+                                                            ethType=ethType,
+                                                            ethSrc=srcMac,
+                                                            ethDst=dstMac,
+                                                            bandwidth=bandwidth,
+                                                            lambdaAlloc=lambdaAlloc,
+                                                            protected=protected,
+                                                            ipProto=ipProto,
+                                                            ipSrc=ipSrc,
+                                                            ipDst=ipDst,
+                                                            tcpSrc=tcpSrc,
+                                                            tcpDst=tcpDst,
+                                                            vlanId=vlanId )
 
         time.sleep( main.addIntentSleep )
-        intentsId = main.RESTs[ 0 ].getIntentsId()
+        intentsId = main.Cluster.active( 0 ).REST.getIntentsId()
     except( KeyError, TypeError ):
         errorMsg = "There was a problem loading the hosts data."
         if intentsId:
@@ -782,69 +782,70 @@
 
     # Adding bidirectional point  intents
     main.log.info( itemName + ": Adding point intents" )
-    intent1 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
-                                                     egressDevice=deviceId2,
-                                                     ingressPort=port1,
-                                                     egressPort=port2,
-                                                     ethType=ethType,
-                                                     ethSrc=mac1,
-                                                     ethDst=mac2,
-                                                     bandwidth=bandwidth,
-                                                     lambdaAlloc=lambdaAlloc,
-                                                     ipProto=ipProto,
-                                                     ipSrc=ip1,
-                                                     ipDst=ip2,
-                                                     tcpSrc=tcp1,
-                                                     tcpDst="" )
+    ctrl = main.Cluster.active( onosNode )
+    intent1 = ctrl.REST.addPointIntent( ingressDevice=deviceId1,
+                                        egressDevice=deviceId2,
+                                        ingressPort=port1,
+                                        egressPort=port2,
+                                        ethType=ethType,
+                                        ethSrc=mac1,
+                                        ethDst=mac2,
+                                        bandwidth=bandwidth,
+                                        lambdaAlloc=lambdaAlloc,
+                                        ipProto=ipProto,
+                                        ipSrc=ip1,
+                                        ipDst=ip2,
+                                        tcpSrc=tcp1,
+                                        tcpDst="" )
 
-    intent2 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
-                                                     egressDevice=deviceId1,
-                                                     ingressPort=port2,
-                                                     egressPort=port1,
-                                                     ethType=ethType,
-                                                     ethSrc=mac2,
-                                                     ethDst=mac1,
-                                                     bandwidth=bandwidth,
-                                                     lambdaAlloc=lambdaAlloc,
-                                                     ipProto=ipProto,
-                                                     ipSrc=ip2,
-                                                     ipDst=ip1,
-                                                     tcpSrc=tcp2,
-                                                     tcpDst="" )
+    intent2 = ctrl.REST.addPointIntent( ingressDevice=deviceId2,
+                                        egressDevice=deviceId1,
+                                        ingressPort=port2,
+                                        egressPort=port1,
+                                        ethType=ethType,
+                                        ethSrc=mac2,
+                                        ethDst=mac1,
+                                        bandwidth=bandwidth,
+                                        lambdaAlloc=lambdaAlloc,
+                                        ipProto=ipProto,
+                                        ipSrc=ip2,
+                                        ipDst=ip1,
+                                        tcpSrc=tcp2,
+                                        tcpDst="" )
 
-    intent3 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
-                                                     egressDevice=deviceId2,
-                                                     ingressPort=port1,
-                                                     egressPort=port2,
-                                                     ethType=ethType,
-                                                     ethSrc=mac1,
-                                                     ethDst=mac2,
-                                                     bandwidth=bandwidth,
-                                                     lambdaAlloc=lambdaAlloc,
-                                                     ipProto=ipProto,
-                                                     ipSrc=ip1,
-                                                     ipDst=ip2,
-                                                     tcpSrc="",
-                                                     tcpDst=tcp2 )
+    intent3 = ctrl.REST.addPointIntent( ingressDevice=deviceId1,
+                                        egressDevice=deviceId2,
+                                        ingressPort=port1,
+                                        egressPort=port2,
+                                        ethType=ethType,
+                                        ethSrc=mac1,
+                                        ethDst=mac2,
+                                        bandwidth=bandwidth,
+                                        lambdaAlloc=lambdaAlloc,
+                                        ipProto=ipProto,
+                                        ipSrc=ip1,
+                                        ipDst=ip2,
+                                        tcpSrc="",
+                                        tcpDst=tcp2 )
 
-    intent4 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
-                                                     egressDevice=deviceId1,
-                                                     ingressPort=port2,
-                                                     egressPort=port1,
-                                                     ethType=ethType,
-                                                     ethSrc=mac2,
-                                                     ethDst=mac1,
-                                                     bandwidth=bandwidth,
-                                                     lambdaAlloc=lambdaAlloc,
-                                                     ipProto=ipProto,
-                                                     ipSrc=ip2,
-                                                     ipDst=ip1,
-                                                     tcpSrc="",
-                                                     tcpDst=tcp1 )
+    intent4 = ctrl.REST.addPointIntent( ingressDevice=deviceId2,
+                                        egressDevice=deviceId1,
+                                        ingressPort=port2,
+                                        egressPort=port1,
+                                        ethType=ethType,
+                                        ethSrc=mac2,
+                                        ethDst=mac1,
+                                        bandwidth=bandwidth,
+                                        lambdaAlloc=lambdaAlloc,
+                                        ipProto=ipProto,
+                                        ipSrc=ip2,
+                                        ipDst=ip1,
+                                        tcpSrc="",
+                                        tcpDst=tcp1 )
 
     # Get all intents ID in the system, time delay right after intents are added
     time.sleep( main.addIntentSleep )
-    intentsId = main.RESTs[ 0 ].getIntentsId()
+    intentsId = main.Cluster.active( 0 ).REST.getIntentsId()
     # Check intents state
     time.sleep( main.checkIntentSleep )
     intentResult = checkIntentState( main, intentsId )
@@ -1039,26 +1040,26 @@
             ipDst.append( ip )
 
         # Adding point intent
-        intentId = main.RESTs[ onosNode ].addSinglepointToMultipointIntent(
-                                            ingressDevice=ingressDevice,
-                                            egressDeviceList=egressDeviceList,
-                                            portIngress=portIngress,
-                                            portEgressList=portEgressList,
-                                            ethType=ethType,
-                                            ethSrc=srcMac,
-                                            #ethDst=dstMac, #Isn't working because of ONOS itself
-                                            bandwidth=bandwidth,
-                                            lambdaAlloc=lambdaAlloc,
-                                            ipProto=ipProto,
-                                            ipSrc=ipSrc,
-                                            ipDst=ipDst,
-                                            tcpSrc="",
-                                            tcpDst="",
-                                            vlanId=vlanId,
-                                            partial=partial )
+        intentId = main.Cluster.active( onosNode ).REST.addSinglepointToMultipointIntent(
+                                                                ingressDevice=ingressDevice,
+                                                                egressDeviceList=egressDeviceList,
+                                                                portIngress=portIngress,
+                                                                portEgressList=portEgressList,
+                                                                ethType=ethType,
+                                                                ethSrc=srcMac,
+                                                                #ethDst=dstMac, #Isn't working because of ONOS itself
+                                                                bandwidth=bandwidth,
+                                                                lambdaAlloc=lambdaAlloc,
+                                                                ipProto=ipProto,
+                                                                ipSrc=ipSrc,
+                                                                ipDst=ipDst,
+                                                                tcpSrc="",
+                                                                tcpDst="",
+                                                                vlanId=vlanId,
+                                                                partial=partial )
 
         time.sleep( main.addIntentSleep )
-        intentsId = main.RESTs[ 0 ].getIntentsId()
+        intentsId = main.Cluster.active( 0 ).REST.getIntentsId()
     except ( KeyError, TypeError ):
         errorMsg = "There was a problem loading the hosts data."
         if intentId:
@@ -1225,20 +1226,20 @@
                 dstMac = ""
 
         intentsId.append(
-                        main.RESTs[ onosNode ].addMultipointToSinglepointIntent(
-                                            ingressDeviceList=ingressDeviceList,
-                                            egressDevice=egressDevice,
-                                            portIngressList=portIngressList,
-                                            portEgress=portEgress,
-                                            ethType=ethType,
-                                            ethDst=dstMac,
-                                            bandwidth=bandwidth,
-                                            lambdaAlloc=lambdaAlloc,
-                                            ipProto=ipProto,
-                                            ipSrc="",
-                                            ipDst="",
-                                            tcpSrc="",
-                                            tcpDst="" ) )
+                        main.Cluster.active( onosNode ).REST.addMultipointToSinglepointIntent(
+                                                                ingressDeviceList=ingressDeviceList,
+                                                                egressDevice=egressDevice,
+                                                                portIngressList=portIngressList,
+                                                                portEgress=portEgress,
+                                                                ethType=ethType,
+                                                                ethDst=dstMac,
+                                                                bandwidth=bandwidth,
+                                                                lambdaAlloc=lambdaAlloc,
+                                                                ipProto=ipProto,
+                                                                ipSrc="",
+                                                                ipDst="",
+                                                                tcpSrc="",
+                                                                tcpDst="" ) )
 
     pingResult = pingallHosts( main, hostNames )
 
@@ -1333,7 +1334,7 @@
     appCheck = main.TRUE
     getDataResult = main.TRUE
     main.log.info( "Activating reactive forwarding app " )
-    activateResult = main.RESTs[ 0 ].activateApp( "org.onosproject.fwd" )
+    activateResult = main.Cluster.active( 0 ).activateApp( "org.onosproject.fwd" )
     if not activateResult:
         main.log.error( "Something went wrong installing fwd app" )
     time.sleep( main.fwdSleep )
@@ -1343,7 +1344,7 @@
         for i in xrange( len( hostList ) ):
             main.Mininet1.pingallHosts( hostList[ i ] )
 
-    hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
+    hostsJson = json.loads( main.Cluster.active( 0 ).REST.hosts() )
     hosts = main.Mininet1.getHosts().keys()
     # TODO: Make better use of new getHosts function
     for host in hosts:
@@ -1360,7 +1361,7 @@
                 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
 
     main.log.info( "Deactivating reactive forwarding app " )
-    deactivateResult = main.RESTs[ 0 ].deactivateApp( "org.onosproject.fwd" )
+    deactivateResult = main.Cluster.active( 0 ).REST.deactivateApp( "org.onosproject.fwd" )
     if activateResult and deactivateResult and main.hostsData:
         main.log.info( "Successfully used fwd app to discover hosts " )
         getDataResult = main.TRUE
@@ -1374,14 +1375,12 @@
 
 
 def checkTopology( main, expectedLink ):
-    statusResult = main.TRUE
     # Check onos topology
     main.log.info( itemName + ": Checking ONOS topology " )
 
-    for i in range( main.numCtrls ):
-        statusResult = main.RESTs[ i ].checkStatus( main.numSwitch,
-                                                    expectedLink )\
-                       and statusResult
+    statusResult = main.Cluster.command( "checkStatus",
+                                         args=[ main.numSwitch, expectedLink ],
+                                         returnBool=True, specificDriver=3 )
     if not statusResult:
         main.log.error( itemName + ": Topology mismatch" )
     else:
@@ -1399,13 +1398,13 @@
 
     main.log.info( itemName + ": Checking intents state" )
     # First check of intents
-    for i in range( main.numCtrls ):
-        tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
-        results.append( tempResult )
+    stateCheckResults = main.Cluster.command( "checkIntentState",
+                                         kwargs={ "intentsId":intentsId },
+                                         returnBool=True, specificDriver=3 )
 
     expectedState = [ 'INSTALLED', 'INSTALLING' ]
 
-    if all( result == main.TRUE for result in results ):
+    if stateCheckResults:
         main.log.info( itemName + ": Intents are installed correctly" )
     else:
         # Wait for at least 5 second before checking the intents again
@@ -1414,10 +1413,10 @@
         results = []
         # Second check of intents since some of the intents may be in
         # INSTALLING state, they should be in INSTALLED at this time
-        for i in range( main.numCtrls ):
-            tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
-            results.append( tempResult )
-        if all( result == main.TRUE for result in results ):
+        stateCheckResults = main.Cluster.command( "checkIntentState",
+                                         kwargs={ "intentsId":intentsId },
+                                         returnBool=True, specificDriver=3 )
+        if stateCheckResults:
             main.log.info( itemName + ": Intents are installed correctly" )
             intentResult = main.TRUE
         else:
@@ -1430,7 +1429,7 @@
 def checkFlowsState( main ):
 
     main.log.info( itemName + ": Check flows state" )
-    checkFlowsResult = main.RESTs[ 0 ].checkFlowsState()
+    checkFlowsResult = main.Cluster.active( 0 ).REST.checkFlowsState()
     return checkFlowsResult
 
 
@@ -1450,7 +1449,7 @@
     onosSummary = []
     removeIntentResult = main.TRUE
     # Remove intents
-    removeIntentResult = main.RESTs[ 0 ].removeAllIntents()
+    removeIntentResult = main.Cluster.active( 0 ).REST.removeAllIntents()
 
     if removeIntentResult:
         main.log.info( itemName + ": There are no more intents remaining, " +
@@ -1465,16 +1464,17 @@
     """
     flowsCount = []
     main.log.info( itemName + ": Checking flows count in each ONOS node" )
-    for i in range( main.numCtrls ):
-        flowsCount.append( len( json.loads( main.RESTs[ i ].flows() ) ) )
+    for ctrl in main.Cluster.active():
+        flowsCount.append( len( json.loads( ctrl.REST.flows() ) ) )
+
 
     if flowsCount:
         if all( flows == flowsCount[ 0 ] for flows in flowsCount ):
             main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
                            " flows in all ONOS node" )
         else:
-            for i in range( main.numCtrls ):
-                main.log.debug( itemName + ": ONOS node " + str( i + 1 ) +
+            for i in range( main.Cluster.numCtrls ):
+                main.log.debug( itemName + ": " + main.Cluster.active( i ).name +
                                 " has " + str( flowsCount[ i ] ) + " flows" )
     else:
         main.log.error( "Checking flows count failed, check summary command" )
@@ -1519,12 +1519,12 @@
         main.topoRelated
     except ( NameError, AttributeError ):
         main.topoRelated = Topology()
-    hosts = main.topoRelated.getAllHosts( main.numCtrls, False )  # Get host data from each ONOS node
+    hosts = main.topoRelated.getAll( "hosts", False )  # Get host data from each ONOS node
     hostFails = []  # Reset for each failed attempt
 
     #  Check for matching hosts on each node
     scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
-    for controller in range( main.numCtrls ):
+    for controller in range( main.Cluster.numCtrls ):
         controllerStr = str( controller + 1 )  # ONOS node number
         # Compare Hosts
         # Load hosts data for controller node
@@ -1566,7 +1566,7 @@
     """
     import json
     try:
-        hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
+        hostsJson = json.loads( main.Cluster.active( 0 ).REST.hosts() )
         hosts = main.Mininet1.getHosts().keys()
         # TODO: Make better use of new getHosts function
         for host in hosts:
@@ -1721,7 +1721,7 @@
     """
         Report errors/warnings/exceptions
     """
-    main.ONOSbench.logReport( main.ONOSip[ 0 ],
+    main.ONOSbench.logReport( main.Cluster.active( 0 ).ipAddress,
                               [ "INFO",
                                 "FOLLOWER",
                                 "WARN",
@@ -1731,20 +1731,20 @@
                                 "s" )
 
     main.log.info( "ERROR report: \n" )
-    for i in range( main.numCtrls ):
-        main.ONOSbench.logReport( main.ONOSip[ i ],
+    for ctrl in main.Cluster.active():
+        main.ONOSbench.logReport( ctrl.ipAddress,
                                   [ "ERROR" ],
                                   "d" )
 
     main.log.info( "EXCEPTIONS report: \n" )
-    for i in range( main.numCtrls ):
-        main.ONOSbench.logReport( main.ONOSip[ i ],
+    for ctrl in main.Cluster.active():
+        main.ONOSbench.logReport( ctrl.ipAddress,
                                   [ "Except" ],
                                   "d" )
 
     main.log.info( "WARNING report: \n" )
-    for i in range( main.numCtrls ):
-        main.ONOSbench.logReport( main.ONOSip[ i ],
+    for ctrl in main.Cluster.active():
+        main.ONOSbench.logReport( ctrl.ipAddress,
                                   [ "WARN" ],
                                   "d" )
 
@@ -1755,7 +1755,7 @@
     """
     import time
     main.log.info( "Getting current flow durations" )
-    flowsJson1 = main.RESTs[ 0 ].flows()
+    flowsJson1 = main.Cluster.active( 0 ).REST.flows()
     try:
         flowsJson1 = json.loads( flowsJson1 )
     except ValueError:
@@ -1769,7 +1769,7 @@
     main.log.info( "Sleeping for {} seconds".format( main.flowDurationSleep ) )
     time.sleep( main.flowDurationSleep )
     main.log.info( "Getting new flow durations" )
-    flowsJson2 = main.RESTs[ 0 ].flows()
+    flowsJson2 = main.Cluster.active( 0 ).REST.flows()
     try:
         flowsJson2 = json.loads( flowsJson2 )
     except ValueError:
@@ -1789,7 +1789,7 @@
 
 
 def ProtectedIntentCheck( main ):
-    intent = main.RESTs[ 0 ].intents()
+    intent = main.Cluster.active( 0 ).REST.intents()
     main.log.debug( intent )
     main.stop()
     if "Protection" in intent: