Tunnel loadbalancing policy: phase2 support
diff --git a/cli/c_actions.py b/cli/c_actions.py
index b2ab1f8..debece3 100755
--- a/cli/c_actions.py
+++ b/cli/c_actions.py
@@ -95,8 +95,9 @@
tunnelset_id=None
tunnelset_dict=[]
+tunnelset_remove_tunnels=[]
def tunnelset_create(data=None):
- global tunnelset_id,tunnelset_dict
+ global tunnelset_id,tunnelset_dict,tunnelset_remove_tunnels
if sdnsh.description: # description debugging
print "tunnelset_create:" , data
if data.has_key('tunnelset-id'):
@@ -105,22 +106,27 @@
print "tunnelset_create: previous data is not cleaned up"
tunnelset_id=None
tunnelset_dict=[]
+ tunnelset_remove_dict=[]
tunnelset_id=data['tunnelset-id']
tunnelset_dict=[]
+ tunnelset_remove_dict=[]
if sdnsh.description: # description debugging
print "tunnelset_create:" , tunnelset_id
def tunnelset_config_exit():
- global tunnelset_id,tunnelset_dict
+ global tunnelset_id,tunnelset_dict,tunnelset_remove_tunnels
if sdnsh.description: # description debugging
print "tunnelset_config_exit entered", tunnelset_dict
- if tunnelset_dict:
+ if (len(tunnelset_dict) > 0) or (len(tunnelset_remove_tunnels)>0):
url_str = ""
entries = tunnelset_dict
url_str = "http://%s/rest/v1/tunnelset/" % (sdnsh.controller)
obj_data = {}
obj_data['tunnelset_id']=tunnelset_id
- obj_data['tunnel_params']=entries
+ if (len(entries) > 0):
+ obj_data['tunnel_params']=entries
+ if (len(tunnelset_remove_tunnels) > 0):
+ obj_data['remove_tunnel_params']=tunnelset_remove_tunnels
result = "fail"
try:
result = sdnsh.store.rest_post_request(url_str,obj_data)
@@ -129,6 +135,7 @@
print sdnsh.rest_error_dict_to_message(errors)
# LOOK! successful stuff should be returned in json too.
tunnelset_dict = []
+ tunnelset_remove_tunnels = []
tunnelset_id = None
curr_tunnel_id = None
if result != "success":
@@ -141,7 +148,7 @@
if sdnsh.description: # description debugging
print "tunnelset_remove:" , data
tunnelset_id=data['tunnelset-id']
- url_str = "http://%s/rest/v1/tunnel/" % (sdnsh.controller)
+ url_str = "http://%s/rest/v1/tunnelset/" % (sdnsh.controller)
obj_data = {}
obj_data['tunnelset_id']=data['tunnelset-id']
result = "fail"
@@ -175,7 +182,7 @@
print "tunnel_create:" , tunnel_id, tunnel_dict
def tunnel_config_exit():
- global tunnel_id,tunnel_dict
+ global tunnel_id,tunnel_dict,tunnelset_dict
if sdnsh.description: # description debugging
print "tunnel_config_exit entered", tunnel_dict
@@ -206,20 +213,24 @@
#Clear the transit information
def tunnel_remove(data=None):
+ global tunnelset_remove_tunnels
if sdnsh.description: # description debugging
print "tunnel_remove:" , data
tunnel_id=data['tunnel-id']
- url_str = "http://%s/rest/v1/tunnel/" % (sdnsh.controller)
- obj_data = {}
- obj_data['tunnel_id']=data['tunnel-id']
- result = "fail"
- try:
- result = sdnsh.store.rest_post_request(url_str,obj_data,'DELETE')
- except Exception, e:
- errors = sdnsh.rest_error_to_dict(e)
- print sdnsh.rest_error_dict_to_message(errors)
- if not result.startswith("SUCCESS"):
- print result
+ if tunnelset_id:
+ tunnelset_remove_tunnels.append(tunnel_id)
+ else:
+ url_str = "http://%s/rest/v1/tunnel/" % (sdnsh.controller)
+ obj_data = {}
+ obj_data['tunnel_id']=data['tunnel-id']
+ result = "fail"
+ try:
+ result = sdnsh.store.rest_post_request(url_str,obj_data,'DELETE')
+ except Exception, e:
+ errors = sdnsh.rest_error_to_dict(e)
+ print sdnsh.rest_error_dict_to_message(errors)
+ if not result.startswith("SUCCESS"):
+ print result
policy_obj_data = {}
@@ -821,6 +832,16 @@
if (mode_name == 'config-tunnel'):
if (current_mode == 'config-tunnelset'):
mode_name = 'config-tunnelset-tunnel'
+ if (mode_name == 'config-policy'):
+ if (data.has_key('policy-type')):
+ if (data['policy-type'] == 'tunnel-flow'):
+ mode_name = 'config-policy-tunnel'
+ if (data['policy-type'] == 'loadbalance'):
+ mode_name = 'config-policy-loadbalance'
+ if (data['policy-type'] == 'avoid'):
+ mode_name = 'config-policy-avoid'
+ if sdnsh.description: # description debugging
+ print "Changing config-policy sub mode to ", mode_name
if sdnsh.description: # description debugging
print "push_mode: ", mode_name, obj_type, data, parent_field, parent_id
@@ -936,7 +957,7 @@
exitCallback = tunnelset_config_exit
if ((mode_name == 'config-tunnel') or (mode_name == 'config-tunnelset-tunnel')):
exitCallback = tunnel_config_exit
- if (mode_name == 'config-policy'):
+ if (mode_name.startswith('config-policy')):
exitCallback = policy_config_exit
sdnsh.push_mode(mode_name, obj_type, key, exitCallback)
diff --git a/cli/command.py b/cli/command.py
index d99ed41..b710e0b 100755
--- a/cli/command.py
+++ b/cli/command.py
@@ -1352,6 +1352,28 @@
matching_commands = self.get_matching_commands(command_word,
self.is_no_command,
command_registry)
+ # There may be multiple results. We need to figure out it there's
+ # an unambiguous match. The heuristic we use is to iterate over
+ # the command words and try to find a single result which has an
+ # exact match on the word while all the others are prefix matches.
+ # If there are multiple results that are exact matches, then we
+ # discard the other results that were prefix matches and continue
+ # with the next command word. If at an iteration all of the
+ # results are prefix matches for the current word, then we check
+ # all of the full tokens that were prefix matched by the command
+ # word. If all of the results have the same full token, then we
+ # continue. If there are multiple full tokens, then that's
+ # indicative of an ambiguous command, so we break out of the loop
+ # and raise an ambiguous command exception.
+ exact_match_commands = []
+ for matching_command in matching_commands:
+ command, prefix_match = matching_command
+ if prefix_match == False:
+ #exact match found
+ exact_match_commands.append(matching_command)
+ if len(exact_match_commands) > 0:
+ matching_commands = exact_match_commands
+
for matching_command in matching_commands:
command, prefix_match = matching_command
self.handle_one_command(command, prefix_match, words)
@@ -1795,7 +1817,7 @@
}
arg_scopes.insert(0, invocation_scope)
if sdnsh.description: # for deubugging, print command name
- print command['self'], completion_proc
+ print "command and completion_proc", command['self'], completion_proc
try:
_result = _call_proc(completion_proc, completion_registry,
arg_scopes, command)
diff --git a/cli/desc/version200/policy.py b/cli/desc/version200/policy.py
index ad99363..733f2e6 100644
--- a/cli/desc/version200/policy.py
+++ b/cli/desc/version200/policy.py
@@ -17,7 +17,7 @@
'mode' : 'config',
'command-type' : 'config-submode',
'obj-type' : 'policy-config',
- 'submode-name' : 'config-policy',
+ 'submode-name' : 'config-policy', #config-policy-tunnel or config-policy-loadbalance or config-policy-avoid
'parent-field' : None,
'doc' : 'policy|policy',
'doc-example' : 'policy|policy-example',
@@ -56,11 +56,10 @@
'field' : 'policy-type',
'optional-for-no' : True,
'type' : 'enum',
- 'values' : ('tunnel-flow','loadbalanced','avoid','deny'),
+ 'values' : ('tunnel-flow','loadbalance','avoid','deny'),
'completion' : 'complete-object-field',
'syntax-help' : 'Enter a policy type',
'doc' : 'policy|policy',
- #'doc-include' : [ 'type-doc' ],
},
),
),
@@ -179,7 +178,7 @@
POLICY_FLOW_ENTRY_COMMAND_DESCRIPTION = {
'name' : 'flow-entry',
- 'mode' : 'config-policy',
+ 'mode' : 'config-policy*',
'command-type' : 'config',
'short-help' : 'Configure flow entry',
'doc' : 'flow-entry|flow-entry',
@@ -241,7 +240,7 @@
}
POLICY_TUNNEL_ID_COMMAND_DESCRIPTION = {
'name' : 'tunnel',
- 'mode' : 'config-policy',
+ 'mode' : 'config-policy-tunnel',
#'obj-type' : 'policy-config',
'command-type' : 'config',
'short-help' : 'Configure tunnel id',
@@ -249,13 +248,13 @@
#'doc-example' : 'policy|policy-tunnel-example',
'parent-field' : 'policy',
'args' : {
+ 'field' : 'tunnel-id',
+ 'completion' : 'tunnel-id-completion',
'action' : (
{
'proc' : 'create-policy',
},
),
- 'completion' : 'tunnel-id-completion',
- 'field' : 'tunnel-id',
'type' : 'identifier',
'syntax-help' : 'Enter tunnel id',
'doc' : 'policy|tunnel-id',
@@ -265,7 +264,7 @@
POLICY_TUNNELSET_ID_COMMAND_DESCRIPTION = {
'name' : 'tunnelset',
- 'mode' : 'config-policy',
+ 'mode' : 'config-policy-loadbalance',
#'obj-type' : 'policy-config',
'command-type' : 'config',
'short-help' : 'Configure tunnelset id',
@@ -273,13 +272,13 @@
#'doc-example' : 'policy|policy-tunnel-example',
'parent-field' : 'policy',
'args' : {
+ 'field' : 'tunnelset-id',
+ 'completion' : 'tunnelset-id-completion',
'action' : (
{
'proc' : 'create-policy',
},
),
- 'completion' : 'tunnelset-id-completion',
- 'field' : 'tunnelset-id',
'type' : 'identifier',
'syntax-help' : 'Enter tunnelset id',
'doc' : 'policy|tunnelset-id',
@@ -289,7 +288,7 @@
POLICY_PRIORITY_COMMAND_DESCRIPTION = {
'name' : 'priority',
- 'mode' : 'config-policy',
+ 'mode' : 'config-policy*',
'command-type' : 'config',
'short-help' : 'Configure policy priority',
'doc' : 'policy|priority',
@@ -331,7 +330,6 @@
)
}
-
def tunnel_id_completion(prefix, completions):
query_url = "http://127.0.0.1:8000/rest/v1/showtunnel"
result = command.sdnsh.store.rest_simple_request(query_url)
@@ -372,4 +370,4 @@
command.add_completion('policy-id-completion', policy_id_completion,
{'kwargs': { 'prefix' : '$text',
'completions' : '$completions',
- }})
\ No newline at end of file
+ }})