CLI support for Segment Routing Tunnel config
diff --git a/cli/cli/c_actions.py b/cli/cli/c_actions.py
index a9ebf0a..01dbc50 100755
--- a/cli/cli/c_actions.py
+++ b/cli/cli/c_actions.py
@@ -76,7 +76,34 @@
         if error_type:
             raise error.CommandRestError(result, message)
 
-  
+tunnel_id=None
+tunnel_dict={}
+def tunnel_create(data=None):
+    global tunnel_id,tunnel_dict
+    if sdnsh.description:   # description debugging
+        print "tunnel_create:" , data
+    if not tunnel_dict:
+        tunnel_id=data['tunnel-id']
+        tunnel_dict[tunnel_id]=[]
+    if sdnsh.description:   # description debugging
+        print "tunnel_create:" , tunnel_id, tunnel_dict
+    if data.has_key('node-value'):    
+        tunnel_dict[tunnel_id].append(data['node-value'])
+
+def tunnel_config_exit():
+    global tunnel_id,tunnel_dict
+    if sdnsh.description:   # description debugging
+        print "tunnel_config_exit entered", tunnel_dict
+    if tunnel_dict:
+        url_str = ""
+        entries = tunnel_dict[tunnel_id]
+        for entry in entries:
+            url_str = url_str + "/node/" + entry
+        print url_str
+    else:
+        print "empty command"
+            
+      
 def write_fields(obj_type, obj_id, data):
     """
     Typical action to update fields of a row in the model
@@ -715,7 +742,10 @@
     
     if sdnsh.description:   # description debugging
         print "push_mode: ", mode_name, obj_type, pk_name, key
-    sdnsh.push_mode(mode_name, obj_type, key)
+    exitCallback = None
+    if (mode_name == 'config-tunnel'):
+        exitCallback = tunnel_config_exit
+    sdnsh.push_mode(mode_name, obj_type, key, exitCallback)
 
     
 def pop_mode_stack():
@@ -3547,6 +3577,10 @@
     sdnsh = bs
     mi = modi
 
+    command.add_action('create-tunnel',
+                       tunnel_create,
+                       {'kwargs': {'data' : '$data',}})
+    
     command.add_action('write-fields', write_fields,
                        {'kwargs': {'obj_type': '$current-mode-obj-type',
                                    'obj_id': '$current-mode-obj-id',
diff --git a/cli/cli/climodelinfo.py b/cli/cli/climodelinfo.py
index 13e5cb6..1f53a25 100755
--- a/cli/cli/climodelinfo.py
+++ b/cli/cli/climodelinfo.py
@@ -112,6 +112,10 @@
 
     # LOOK! Refactor - Should we merge this with model_info_list?
     if (onos == 1):
+        # do nothing
+        additional_model_info_dict = {}
+    elif (onos==2):
+    #if (onos == 1):
         additional_model_info_dict = {
         'switches' : {
             # switches are now directly fetched via rest api.
diff --git a/cli/cli/command.py b/cli/cli/command.py
index be236ce..6428f04 100755
--- a/cli/cli/command.py
+++ b/cli/cli/command.py
@@ -3864,6 +3864,10 @@
         'no-action': 'delete-objects',
     })
 
+    add_command_type('create-tunnel', {
+        'action': 'create-tunnel'
+    })
+    
     add_command_type('display-table', {
         'action': 'display-table'
     })
diff --git a/cli/cli/desc/version200/controller_node.py b/cli/cli/desc/version200/controller_node.py
index 43135b2..4c71c5b 100755
--- a/cli/cli/desc/version200/controller_node.py
+++ b/cli/cli/desc/version200/controller_node.py
@@ -16,7 +16,7 @@
 
 import command
 import fmtcnv
-#"""
+"""
 CONTROLLER_NODE_FORMAT = {
     'controller-node' : {
         'field-orderings' : {
@@ -170,7 +170,6 @@
          }
     ),
 }
-#"""
 CONTROLLER_NODE_INTERFACE_FORMAT = {
     'controller-interface' : {
         'field-orderings': {
@@ -312,7 +311,6 @@
                                    'prefix'      : '$text',
                       }})
 
-
 CONTROLLER_NODE_SHOW_ID_COMMAND_DESCRIPTION = {
     'name'         : 'show',
     'obj-type'     : 'controller-node',
@@ -1077,4 +1075,4 @@
         },
     )
 }
-#"""
+"""
diff --git a/cli/cli/desc/version200/core.py b/cli/cli/desc/version200/core.py
index 3c799f7..bb48a7c 100755
--- a/cli/cli/desc/version200/core.py
+++ b/cli/cli/desc/version200/core.py
@@ -17,6 +17,7 @@
 import command
 import run_config
 
+"""
 SHOW_RUNNING_CONFIG_COMMAND_DESCRIPTION = {
     'name'         : 'show',
     'mode'         : 'login',
@@ -186,7 +187,7 @@
 
     )
 }
-"""
+
 SHOW_FIREWALL_COMMAND_DESCRIPTION = {
     'name'         : 'show',
     'obj-type'     : 'firewall-rule',
@@ -720,7 +721,7 @@
         'optional'        : 'true',
     },
 }
-
+"""
 DEBUG_CLI_COMMAND_DESCRIPTION = {
     'name'                : 'debug',
     'mode'                : ['login', 'enable', 'config*'],
@@ -829,7 +830,7 @@
     }
 }
 
-"""
+
 HA_CONFIG_CLI_COMMAND_DESCRIPTION = {
     'name'                : 'ha',
     'short-help'          : 'Configure high availability',
@@ -1246,7 +1247,7 @@
         },
     ),
 }
-"""
+#"""
 #
 # FORMATS 
 #
@@ -1308,7 +1309,6 @@
     },
 }
 
-"""
 LINK_FORMAT = {
     'link' : {
         'field-orderings' : {
@@ -1328,7 +1328,6 @@
         },
 }
 
-"""
 CONFIG_FORMAT = {
     'config' : {
         'field-orderings' : {
@@ -1702,7 +1701,7 @@
                           'actions', 'dataLayerSource', 'dataLayerDestination',
                           'flow-brief',
                         ],
-            'scoped'  : [
+           'scoped'  : [
                           'Idx', 'cookie', 
                           'byteCount', 'packetCount',
                           'actions', 'dataLayerSource', 'dataLayerDestination',
diff --git a/cli/cli/desc/version200/flow_entry.py b/cli/cli/desc/version200/flow_entry.py
index dfe9449..13213ab 100755
--- a/cli/cli/desc/version200/flow_entry.py
+++ b/cli/cli/desc/version200/flow_entry.py
@@ -16,6 +16,7 @@
 
 import fmtcnv
 
+"""
 FLOW_ENTRY_SUBMODE_COMMAND_DESCRIPTION = {
     'name'            : 'flow-entry',
     'mode'            : 'config-switch*',
@@ -444,7 +445,6 @@
         )
     },
 }
-
 #
 # FORMATS
 #
@@ -489,4 +489,5 @@
             },
         },
 }
+"""
 
diff --git a/cli/cli/desc/version200/switch.py b/cli/cli/desc/version200/switch.py
index 082b7d1..47a56a5 100755
--- a/cli/cli/desc/version200/switch.py
+++ b/cli/cli/desc/version200/switch.py
@@ -13,6 +13,102 @@
 # implied. See the License for the specific language governing
 # permissions and limitations under the License.
 #
+import command
+import json
+
+TUNNEL_SUBMODE_COMMAND_DESCRIPTION = {
+    'name'          : 'tunnel',
+    'short-help'    : 'Enter tunnel submode, configure tunnel details',
+    'mode'          : 'config*',
+    'command-type'  : 'config-submode',
+    'obj-type'      : 'tunnel-config',
+    'parent-field'  : None,
+    'submode-name'  : 'config-tunnel',
+    'doc'           : 'tunnel|tunnel',
+    'doc-example'   : 'tunnel|tunnel-example',
+    'args' : (
+        {
+            'field'        : 'tunnel-id',
+            'type'         : 'identifier',
+            'completion'   : 'complete-object-field',
+            'syntax-help'  : 'Enter a tunnel name',
+            'doc'          : 'tunnel|tunnel',
+            'doc-include'  : [ 'type-doc' ],
+            'action'       : (
+                                {
+                                    'proc' : 'create-tunnel',
+                                },
+                                {
+                                    'proc' : 'push-mode-stack',
+                                },
+                              ),
+        }
+    )
+}
+
+def tunnel_node_completion(prefix, completions):
+    print "tunnel_node_completion:",prefix,completions
+    query_url = "http://127.0.0.1:8000/rest/v1/switches"
+    #print query_url
+    result = command.sdnsh.store.rest_simple_request(query_url)
+    entries = json.loads(result)
+    for entry in entries:
+        if entry['dpid'].startswith(prefix):
+            completions[entry['dpid']+' '] = entry['dpid']
+    return
+
+command.add_completion('tunnel-node-completion', tunnel_node_completion,
+                       {'kwargs': { 'prefix'       : '$text',
+                                    'completions'  : '$completions',
+                                    }})
+
+# obj_type flow-entry field hard-timeout
+TUNNEL_NODE_ENTRY_COMMAND_DESCRIPTION = {
+    'name'                : 'node',
+    'mode'                : 'config-tunnel',
+    'short-help'          : 'Set node for this tunnel',
+    'doc'                 : 'tunnel|node',
+    'doc-example'         : 'tunnel|node',
+    'command-type'        : 'config',
+    'args'                : (
+         {
+             'field'      : 'node-value',
+             'completion'   : 'tunnel-node-completion',
+             'type'         : 'dpid',
+             'other'        : 'switches|dpid',
+#             'data-handler' : 'alias-to-value',
+             'help-name'    : 'switch dpid or switch alias',
+             'action'       : (
+                                {
+                                    'proc' : 'create-tunnel',
+                                },
+                              ),
+         }
+    )
+}
+
+TUNNEL_ADJACENCY_ENTRY_COMMAND_DESCRIPTION = {
+    'name'                : 'adjacency',
+    'mode'                : 'config-tunnel',
+    'short-help'          : 'Set adjacency for this tunnel',
+    'doc'                 : 'tunnel|path',
+    'doc-example'         : 'tunnel|path',
+    'command-type'        : 'config',
+    'args'                : (
+         {
+             'field'      : 'adjacency-value',
+             'type'       : 'string',
+             'help-name'  : 'switch port',
+             'action'       : (
+                                {
+                                    'proc' : 'create-tunnel',
+                                },
+                              ),
+         }
+    )
+}
+
+"""
 SWITCH_SUBMODE_COMMAND_DESCRIPTION = {
     'name'          : 'switch',
     'short-help'    : 'Enter switch submode, configure switch details',
@@ -37,6 +133,7 @@
         }
     )
 }
+"""
 #
 # ------------------------------------------------------------------------------
 # show switch
@@ -517,7 +614,7 @@
         }
     )
 }
-
+"""
 SWITCH_SUBMODE_SHOW_INTERFACE_COMMAND_DESCRIPTION = {
     'name'         : 'show',
     'mode'         : 'config-switch*',
@@ -675,7 +772,7 @@
         },
    )
 }
-"""
+
 #
 # ------------------------------------------------------------------------------
 # SWITCH_TUNNEL_SHOW_COMMAND_DESCRIPTION
@@ -811,7 +908,6 @@
         },
     ),
 }
-"""
 #
 # ------------------------------------------------------------------------------
 # SWITCH_CORE_SWITCH_TERMINATION_COMMAND_DESCRIPTION
@@ -839,7 +935,6 @@
         }
     )
 }
-"""
 #
 # ------------------------------------------------------------------------------
 # SWITCH_TUNNEL_TERMINATION_COMMAND_DESCRIPTION
@@ -865,7 +960,6 @@
         }
     )
 }
-"""
 #
 # ------------------------------------------------------------------------------
 # SWITCH_ALIAS_COMMAND_DESCRIPTION
@@ -974,6 +1068,7 @@
         }
     )
 }
+"""
 #
 # FORMATS
 #
@@ -1046,7 +1141,7 @@
             }
         },
 }
-
+"""
 SWITCH_CONFIG_FORMAT = {
     'switch-config' : {
         'field-orderings' : {
@@ -1164,7 +1259,7 @@
             },
         },
 }
-"""
+
 TUNNEL_DETAILS_FORMAT = {
     'tunnel-details' : {
         'field-orderings' : {
diff --git a/cli/cli/desc/version200/tenant.py b/cli/cli/desc/version200/tenant.py
index 1608953..fa79ed3 100755
--- a/cli/cli/desc/version200/tenant.py
+++ b/cli/cli/desc/version200/tenant.py
@@ -18,7 +18,7 @@
 #
 
 import command
-'''
+"""
 def tenant_origin_external(data):
     """
     Return origin-name when the tenant wasn't created by the cli,
@@ -102,8 +102,6 @@
 command.add_completion('complete-tenant-preprocess', complete_tenant_preprocess,
                            {'kwargs': {'data': '$data',
                                        }})
-'''
-"""
 #
 # ----------------------------------------------------------------------
 # tenant submode commands
@@ -542,4 +540,4 @@
            }
         },
 }
-"""
\ No newline at end of file
+"""
diff --git a/cli/sdncon/controller/models.py b/cli/sdncon/controller/models.py
index 1181f32..ca62e1c 100755
--- a/cli/sdncon/controller/models.py
+++ b/cli/sdncon/controller/models.py
@@ -64,6 +64,62 @@
     """
     return int(time.time()*1000000)
 
+class TunnelPathSeqId(models.Model):
+
+    pathid_seq = models.IntegerField(
+        primary_key=True,
+        verbose_name = 'Path Id Seq',
+        help_text='ID of this Tunnel Path Entry')
+
+    def __unicode__ (self):
+        return self.pathid_seq
+
+    class Rest:
+        NAME = 'tunnel-pathid-seq'
+        FIELD_INFO = (
+        )
+            
+class Tunnel(models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+
+    #
+    # Unique name of the Tunnel
+    #
+    tunnel_id = models.CharField(
+        primary_key  = True,
+        verbose_name = 'Tunnel Id',
+        help_text    = 'A unique Id for a Tunnel',
+        validators   = [ TenantNameValidator() ],
+        max_length   = id_max_length)
+    
+    path_seq = models.CharField(
+        verbose_name = 'Path Sequence',
+        help_text    = 'List of path identifiers: nodes or adjacencies',
+        blank        = True,
+        null         = True,
+        max_length   = 500)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.tunnel_id
+    
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('tunnel_id')
+
+    def delete(self):
+        super(Tunnel, self).delete()
+    class Rest:
+        NAME = 'tunnel-config'
+        FIELD_INFO = (
+            {'name': 'tunnel_id',    'rest_name': 'tunnel-id'},
+            {'name': 'path_seq',     'rest_name': 'path-seq'},
+            )
+
 #
 # ------------------------------------------------------------
 
@@ -113,8 +169,8 @@
             {'name': 'static_flow_pusher_feature', 'rest_name': 'static-flow-pusher-feature'},
             {'name': 'performance_monitor_feature','rest_name': 'performance-monitor-feature'},
             )
-'''
 
+"""
 #
 # ------------------------------------------------------------
 
@@ -237,10 +293,8 @@
             {'name': 'core_priority',      'rest_name': 'core-priority'},
         )
 
-'''
 #
 # ------------------------------------------------------------
-
 class Controller(models.Model):
     #
     # fields ----------------------------------------
@@ -409,7 +463,6 @@
 
     class Rest:
         NAME = 'controller-alias'
-'''
 #
 # ------------------------------------------------------------
 
@@ -611,7 +664,6 @@
         NAME = 'controller-domain-name-server'
         FIELD_INFO = (
             )
-'''
 
 #
 # ------------------------------------------------------------
@@ -735,7 +787,6 @@
             {'name': 'serial_num',        'rest_name': 'serial-num'},
             {'name': 'tunneling_supported', 'rest_name': 'tunnel-supported'},
             )
-
 #
 # ------------------------------------------------------------
 # SwitchConfig
@@ -787,7 +838,6 @@
             {'name': 'core_switch',       'rest_name': 'core-switch'},
             )
 
-
 #
 # ------------------------------------------------------------
 
@@ -1027,7 +1077,6 @@
         FIELD_INFO = (
             {'name': 'switch_interface', 'rest_name': 'switch-interface'},
         )
-
 #
 # ------------------------------------------------------------
 
@@ -1208,7 +1257,6 @@
             {'name': 'actions',         'rest_name': 'actions'},
             )
 
-
 #
 # ------------------------------------------------------------
 
@@ -1290,6 +1338,7 @@
             )
             
 """
+"""
 #
 # ------------------------------------------------------------
 # An address-space separation
@@ -1497,7 +1546,6 @@
             {'name': 'vlans',           'rest_name': 'vlans'},
             {'name': 'tag',             'rest_name': 'tag'},
             )
-"""
 #
 # ------------------------------------------------------------
 
@@ -1646,7 +1694,6 @@
     class Rest:
         NAME = 'host-alias'
 
-"""
 class VlanConfig(models.Model):
     #
     # fields ----------------------------------------    
@@ -2853,7 +2900,6 @@
                       {'name': 'dst_vns',                  'rest_name': 'dst-vns'},
                       {'name': 'gateway_pool',             'rest_name': 'gateway-pool'},
             )
-"""
 #
 # ------------------------------------------------------------
 
@@ -2967,7 +3013,6 @@
 
 #
 # ------------------------------------------------------------
-"""
 class TechSupportConf(models.Model):
 
     #
@@ -3227,4 +3272,4 @@
 #
 #    class Rest:
 #        NAME = 'user'
-"""
\ No newline at end of file
+"""
diff --git a/cli/sdncon/rest/views.py b/cli/sdncon/rest/views.py
index 78f88d2..f8d15a2 100755
--- a/cli/sdncon/rest/views.py
+++ b/cli/sdncon/rest/views.py
@@ -19,9 +19,9 @@
 from django.http import HttpResponse
 from django.utils import simplejson
 from functools import wraps
-from sdncon.controller.models import Controller
+#from sdncon.controller.models import Controller
 #from sdncon.controller.models import ControllerAlias, ControllerDomainNameServer, ControllerInterface, FirewallRule
-from sdncon.controller.models import Switch, Port, PortAlias, Link
+#from sdncon.controller.models import Switch, Port, PortAlias, Link
 from sdncon.rest.models import UserData
 from sdncon.controller.notification import begin_batch_notification, end_batch_notification
 from django.views.decorators.csrf import csrf_exempt
diff --git a/cli/sdncon/statdropd/models.py b/cli/sdncon/statdropd/models.py
index d4e183b..0e93490 100755
--- a/cli/sdncon/statdropd/models.py
+++ b/cli/sdncon/statdropd/models.py
@@ -15,7 +15,7 @@
 #
 
 from django.db import models
-
+"""
 # Create your models here.
 class StatdropdConfig(models.Model):
     
@@ -76,3 +76,4 @@
         FIELD_INFO = (
             {'name': 'last_drop_point', 'rest_name': 'last-drop-point'},
         )
+"""
\ No newline at end of file
diff --git a/cli/sdncon/stats/models.py b/cli/sdncon/stats/models.py
index 7b5c2b6..a493475 100755
--- a/cli/sdncon/stats/models.py
+++ b/cli/sdncon/stats/models.py
@@ -15,7 +15,7 @@
 #
 
 from django.db import models
-
+"""
 class StatdConfig(models.Model):
     stat_type = models.CharField(
         primary_key=True,
@@ -37,3 +37,4 @@
             {'name': 'sampling_period', 'rest_name': 'sampling-period'},
             {'name': 'reporting_period', 'rest_name': 'reporting-period'},
             )
+"""
\ No newline at end of file
diff --git a/cli/sdncon/syncd/models.py b/cli/sdncon/syncd/models.py
index 1ead681..c83461c 100755
--- a/cli/sdncon/syncd/models.py
+++ b/cli/sdncon/syncd/models.py
@@ -15,7 +15,7 @@
 #
 
 from django.db import models
-
+"""
 class SyncdConfig(models.Model):
     
     # id is set to the local cluster id.
@@ -117,3 +117,4 @@
             {'name': 'data_start_time', 'rest_name': 'data-start-time'},
             {'name': 'last_sync_time', 'rest_name': 'last-sync-time'},
         )
+"""
\ No newline at end of file