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