#!/usr/bin/python
#
# Copyright (c) 2010,2011,2012,2013 Big Switch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
#      http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.
#

#  sdnsh - The Controller Shell
# --------------------------------------------------------------------------------
#
# LOOK! TODO --
#
# create tokens for modify actions in StaticFlowEntryPusher and here
#
# extend completion to show help text
#
# need to verify we can talk to the controller
#
# flow-entry naming - unique across all switches?
#
# joins on show commands (port names, ids, etc.)
#
# accept enums in addition to numbers - "ether-type arp" or "ether-type ip"
#
# cli commands not mapping to database model (this is an -undo-)
#
# simple options/singletons in the CLI ("logging level 5" "twitter username blah")
#
# csv, left/right justification in columns, sorts
#
# completion with multi command lines
#
# disallow 'switch' field and name as options flow-entry ('key' fields in general)
#
# delayed commit semantics (depends on 1?)
#
# delete config files?
#
# --------------------------------------------------------------------------------
#
# Notes:
#
#  support functions for a command, consider, for example, 'vns-definition'
#
#   For a new command, for example 'vns-definition', there will be a variety
#   of different support functions to manage different required functionaly.
#   do_vns_definition() describes what to do to execute the actual command.
#   cp_vns_definition() describes how to perform command completion for the same.
#   do_show_vns_definition() would describe how to show the vns-definitions
#     (this procedure doesn't exist, but is implemented by 'show vns' via
#     do_show_vns), while
#   cp_show_vns_definition() would describe how to complete the show command for
#   this particular command.  Other functions may also be needed, for example
#   specialized changes to the 'no' command for the same command.
#
#  command completion
#
#   currently in many cases, there's a specialized completion handler
#   it would make sense to manage 'no' completion by overloading the
#   same completion handler.
#
#
#  error processing:
#
#   Keep in mond that al errors ought to use a similar prefix so that
#   all the error conditions acan be identifyed by the automated test
#   procedures.  these prefixes are regular expressions in bigtest/cli.py
#   The prefixed currently recognized as errors are 'Error: Not Found",
#   'Error running command ', 'Syntax error:', and 'Syntax: ' the last
#   of which is used to display both usage for some commands, and 
#   various specific syntax errors
#
#  alias management:
#
#   Aliases are managed by having a separate table/model for each
#   of the aliases, for example the host table has an associated alias
#   table called 'host-alias'.  These alias models are nothing more
#   than an id, which is the alias name and a foreign key for the other
#   table, in the 'host-alias' model, the associated foreign key would 
#   point to the host.
#   
#   Alias tables or models are not directly configured as alias tables,
#   the cli can find these tables by noticing the only fields within
#   the model is a foreign key for another table.   The cli builds the
#   alias_obj_type_xref dictionary during initialization, and later uses
#   that association to manage aliases.   Knowing which of the tables
#   are alias tables also allows the cli to exclude these tables from
#   modification in typical config mode.
#
#   Alias are created when within the submode for a particular obj_type,
#   for example, the host-alias table is available within the host
#   config submode, and it appears as the 'host-alias' table there.
#   However no further submode for the host-alias is managed; it is
#   treated as if it were a field in the submode config object.
#   So if 'host-alias xxx' were entered while in host config submode,
#   the cli converts the request into a host-alias table entry.
#
#   Feature management.  The cli is intended to manage the availability
#   of specific feature groups.  This isn't meant to prevent a user from
#   getting at specific sku features (ie: licensing), but instead meant
#   to allow a user to disable specific sub-groups of commands to 
#   prevent unintended enabling of features.  For example,
#   to prevent a 'static-flow' cli configured controller from enabling
#   vns features likely resulting in a misconfigured environment.
#
#  changes:
#
#   -- new source field for obj_types in models, obj_types which are
#      written based on discovered details are typically not editable.
#      don't allow a config submode entry. and don't
#      advertise such an entry is possible
#
#   -- integrated alias support, no special cases through the use
#      of a separated alias tables.  this allows more integrated
#      cli support for tables specifically constructed to manage
#      alias names for other fields.   Currently code in the cli
#      prevents multiple alias for a single foreign key, but this
#      behavior can be relaxed (perhaps it ought to be configurable?)
#
#   -- perform alias substitution for 'no' commands obj_type's
#
#   -- support for primary key/id changes within a row.
#      if an update occurs which modifies the primary key of a row,
#      the cli now identifies whether any foreign keys point at
#      the existing entry, and updates the foreign key to reference
#      the updated primary key.
#
#   -- support for cascaded delete.
#      when a row is deleted, if there are foreign keys associated
#      with the row, the cli will remove them.  the climodelinfo
#      configures which obj_types are included in the cascade deletes.
#
#   -- vns interface creation.
#      vns interfaces are required to have a vns-interface-rule associated.
#      sdnplatform writes both the interface name and the rule, but the cli needed
#      to have code added to determine and validate the associated rule.
#      The validation attempts to ensure the correct rule is associated with
#      the use of the interface name (id).
#

import subprocess
import os, atexit, stat
import sys, traceback                   # traceback.print_exc()
from optparse import OptionParser
from types import StringType
import collections
import datetime
import json
import re
import time
import urllib2
import httplib                          # provides error processing for isinstance
import socket
import select
import fcntl
import posixpath
import random
import copy
import utif
import fmtcnv
import run_config
import imp
import locale

from pkg_resources import resource_filename
from modi import Modi
from midw import *
from vnsw import *
from prettyprint import PrettyPrinter
from storeclient import StoreClient
from climodelinfo import CliModelInfo
from vendor import VendorDB
import error
import command
import rest_to_model
import tech_support
import url_cache
import doc
import sdndb

#
# --------------------------------------------------------------------------------
# 

class ParamException(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

class TooManyVNSException(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

TIMESTAMP_HELP = \
    ('Enter an integer timestamp in milliseconds since the epoch or formatted\n' +
     'as one of the following options in your local timezone:\n'
     '"YYYY-MM-DD HH:MM:SS"      YYYY-MM-DDTHH:MM:SS\n' + 
     '"YYYY-MM-DD HH:MM:SS+TTT"  YYYY-MM-DDTHH:MM:SS+TTT\n' +
     'YYYY-MM-DD                 MM-DD\n' + 
     'HH:MM                      now')


# This is a bit of a hack. The completion and validation functions for time zones
# are static methods, but they need to access the SDNSh object to get at the
# controller field to be able to do a REST call to load the list of time zone
# strings. So we set up a global for the single SDNSh instance we have. An
# alternative would have been to have a global variable for the list of time
# zone strings that's initialized when the CLI is initialized, but it seems
# nicer to only load it on demand, especially since setting the time zone
# will be a pretty infrequently invoked command.
cli = None

#
# Constants for packet tracing
#
SESSIONID = 'sessionId'
FT_VNS = 'vns'
FT_PORT = 'port'
FT_PORT_DPID = 'dpid'
FT_PORT_PORT = 'port'
FT_OUTPUT = 'output'
FT_DIRECTION = 'direction'
FT_PERIOD = 'period'
FT_TIMEOUT = "FilterTimeout"
FT_PERIOD_DEFAULT = 300

onos=1
#
# --------------------------------------------------------------------------------
# 
class NotFound(Exception):
    def __init__(self, obj_type, name):
        self.obj_type = obj_type
        self.name = name
    def __str__(self):
        return "Not Found: %s %s" % (self.obj_type, self.name)


# LOOK!: The next two functions are copied from the sdncon code.
# Should ideally figure out a way to share the code for utility
# functions like this.

def dotted_decimal_to_int(ip):
    """
    Converts a dotted decimal IP address string to a 32 bit integer
    """
    bytes = ip.split('.')
    ip_int = 0
    for b in bytes:
        ip_int = (ip_int << 8) + int(b)
    return ip_int
    

def same_subnet(ip1, ip2, netmask):
    """
    Checks whether the two ip addresses are on the same subnet as
    determined by the netmask argument. All of the arguments are
    dotted decimal IP address strings.
    """
    ip1_int = dotted_decimal_to_int(ip1)
    ip2_int = dotted_decimal_to_int(ip2)
    netmask_int = dotted_decimal_to_int(netmask)
    return (ip1_int & netmask_int) == (ip2_int & netmask_int)

#
# --------------------------------------------------------------------------------
# 

class SDNSh():

    debug = False               # general cli debugging
    debug_backtrace = False     # backtrace on failures
    description = False         # help debug command descriptions
    display_rest = False        # display rest call details
    display_reply_rest = False  # display rest call replies details

    command_dict = {}
    mode_stack = []
    reserved_words = ['unknown', 'all']

    known_controllers = ["127.0.0.1:8000"]
    controller = None
    # LOOK! manage this separately until we can cetainly
    #       talk to eth0 addr instead of 127.0.0.1
    controller_for_prompt = "127.0.0.1:8000"
    cluster = "default"
    
    known_sdn_platforms = ["127.0.0.1:8080"]
    sdn_controller_paltform = None

    run = True

    # Are we running in batch mode, i.e. "cat commands | cli"
    batch = False

    # used for parsing as an arg
    local_name_pattern = "config://([A-Za-z0-9_:@\-\.\/]+$)"

    # name of boot/startup-config
    boot_config_filename = '/opt/sdnplatform/run/boot-config'
    saved_configs_dirname = '/opt/sdnplatform/run/saved-configs/'
    feature_allow_experimental = '/opt/sdnplatform/feature/experimental'

    # contained objects
    pp = None
    store = None
    model_handler = None

    # cached metadata
    stats_metadata = None
    stats_type_metadata = None
    stats_restapi_map = {'controller-node': 'controller'}

    stats_optional_params = {
        'start-time': {'type': 'string',
                       'syntax_help': TIMESTAMP_HELP},
        'end-time': {'type': 'string',
                     'syntax_help': TIMESTAMP_HELP},
        'duration': {'type': 'string',
                     'syntax_help': 
                     "Enter an integer followed by a time unit\n" +
                     "[integer]weeks  [integer]days  [integer]hours\n" +
                     "[integer]mins   [integer]secs  [integer]ms"},
        'sample-interval': {'type': 'int',
                            'syntax_help': 'Enter an integer number of milliseconds'},
        'sample-count': {'type': 'int',
                         'syntax_help': 'Enter an integer target sample count'},
        'sample-window': {'type': 'string',
                          'syntax_help': 'Enter an integer number of milliseconds for sampling window'},
        'data-format': {'type': 'enum', 'values': ['value', 'rate']},
        'display': {'type': 'enum', 'values': ['latest-value', 'graph', 'table']},
        #'limit': {'type': 'int'}
        }

    netvirt_feature_enabled_cached = False
    warning_suppress = False            #

    #
    # --------------------------------------------------------------------------------
    # warning
    #  When a config is getting replayed, warnings are suporessed.  Other situations
    #  may also require supression of warnings.
    #
    def warning(self, message):
        if not self.warning_suppress:
            print "Warning: %s" % message
    
    #
    # --------------------------------------------------------------------------------
    # supress_warnings(self)
    #
    def suppress_warnings(self):
        self.warning_suppress = True

    #
    # --------------------------------------------------------------------------------
    # enable_warnings(self)
    #
    def enable_warnings(self):
        self.warning_suppress = False


    config_replay = False               # only true while replaying config files
    #
    # --------------------------------------------------------------------------------
    # config_replay_start
    #  Behavior is different during config replay.  Warnings are
    #  suppressed, and other error conditions may be relaxed, for example
    #  the switch submode interface command requires that the interface exist,
    #  and the interface names are discovered by sdnplatform, which means that during
    #  config replay for statup, an unknown-named-interface may need to be accepted
    #  since that interface may appear once the switch connected to sdnplatform, and
    #  sdnplatform writes the ports for this switch.
    #
    def config_replay_start(self):
        self.suppress_warnings()
        self.config_replay = True
    
    #
    # --------------------------------------------------------------------------------
    # config_replay_done
    #
    def config_replay_done(self):
        self.enable_warnings()
        self.config_replay = False

    #
    # --------------------------------------------------------------------------------
    # config_replay_active
    #  Returns true when a configuration is getting replayed
    #
    def config_replay_active(self):
        return self.config_replay

    #
    # --------------------------------------------------------------------------------
    # note
    #  When a config is getting replayed, warnings/notes are suporessed.  Other situations
    #  may also require supression of warnings.
    #
    def note(self, message):
        if not self.warning_suppress:
            print "Note: %s" % message

    #
    # --------------------------------------------------------------------------------
    # debug_msg
    #  Debugging message cover.  Only enabled for display once 'debug cli' is performed.
    #
    def debug_msg(self, message):
        if self.debug:
            print "debug_msg: %s" % message
            
    #
    # --------------------------------------------------------------------------------
    # error_msg
    #  Error message cover, to ensure consistent error messages
    #
    @staticmethod
    def error_msg(message):
        return "Error: %s" % message

    #
    # --------------------------------------------------------------------------------
    # syntax_msg
    #  Syntax error message cover, to ensure consistent error messages
    #
    @staticmethod
    def syntax_msg(message):
        return "Syntax: %s" % message 

    #
    # --------------------------------------------------------------------------------
    # completion_error_msg
    #  Error message cover during completion, to ensure consistent error messages
    #
    def completion_error_msg(self, message):
        self.print_completion_help("Error: %s" % message)

    #
    # --------------------------------------------------------------------------------
    # completion_syntax_msg
    #  Syntax error message cover during completion, to ensure consistent error messages
    #
    def completion_syntax_msg(self, message):
        self.print_completion_help("Syntax: %s" % message)

    #
    # --------------------------------------------------------------------------------
    # init_history_file
    #
    def init_history_file(self):
        history_file = os.path.join(os.environ["HOME"], ".sdnsh_history")
        # create the initial history file group-writable,
        # so that the tacacs users can write to it
        if os.path.exists(history_file):
            st = os.stat(history_file)
            if not (st[stat.ST_MODE] & stat.S_IWGRP):
                buf = open(history_file).read()
                os.rename(history_file, history_file + "~")
                mask = os.umask(007)
                fno = os.open(history_file, os.O_WRONLY | os.O_CREAT, 0660)
                os.umask(mask)
                os.write(fno, buf)
                os.close(fno)
        else:
            mask = os.umask(007)
            fno = os.open(history_file, os.O_WRONLY | os.O_CREAT, 0660)
            os.umask(mask)
            os.close(fno)
        try:
            readline.read_history_file(history_file)
        except IOError:
            pass
        atexit.register(readline.write_history_file, history_file)
    
    #
    # --------------------------------------------------------------------------------
    # init_command_dict
    #
    def init_command_dict(self):

        #
        # command_submode_dict saves a little information about
        # submode commands.  The index is 'mode', and the resulting
        # list contains strings, each of which is a submode command
        # available in that mode.
        self.command_submode_dict = {}

        #
        # associate command names with features, so that when
        # help is provided, command names which have associated
        # features are validated to determine whether the feature
        # is enabled or not.
        self.command_name_feature = {}

        #
        # command_nested_dict is indexed by mode, and contains
        # command configured with a trailing '*', for example
        # 'mode' : 'config-*', intended to mean "all nested
        # submodes after config-'.  This can't be computed until
        # all submodes are known, which means all the command
        # describption must be configured., for these to make sense.
        self.command_nested_dict = {}

        #
        # config mode commands
        #
        #self.command_dict['config'] = [ "boot" ]

        #
        # commands which start at 'login'
        #
        if onos == 0:
            self.command_nested_dict['login'] = [ 'show', 'logout', 'exit',
                                              'history', 'help', 'echo',
                                              'date', 'trace', 'traceroute',
                                              'ping', 'test', 'version',
                                              'connect', 'watch', 'no' ]
        else:
            self.command_nested_dict['login'] = [ 'show', 'logout', 'exit',
                                              'history', 'help', 'echo',
                                              'date', 'trace',
                                              'ping', 'test', 'version',
                                              'connect', 'watch', 'no' ]

        self.command_nested_dict['enable'] = [ 'clear', 'end' ]

        #self.command_dict['config-internal'] = ['lint', 'permute']

    #
    # --------------------------------------------------------------------------------
    # make_unit_formatter
    #
    @staticmethod
    def make_unit_formatter(units):
        return lambda x, y: '%s %s' % (x, units)

    #
    # --------------------------------------------------------------------------------
    # init_stats_metadata
    #
    def init_stats_metadata(self):
        # Initialize the stats metadata by pulling it from the rest api
        json_data = self.rest_simple_request_to_dict('http://%s/rest/v1/stats/metadata/%s/' % \
                                                     (self.controller, self.cluster))
        metadata = {}
        fields = {}
        for item in json_data:
            # XXX Requesting this stat causes a long delay in reading; bug in sdncon
            # once this is fixed we can add back in; also add to field_orderings below
            #if json_data[item]['name'] == 'OFActiveFlow':
            #    continue

            if json_data[item]['target_type'] in metadata:
                metadata[json_data[item]['target_type']].append(json_data[item])
            else:
                metadata[json_data[item]['target_type']] = [json_data[item]]
                fields[json_data[item]['target_type']] = {}

            formatter = self.make_unit_formatter(json_data[item]['units'])
            fields[json_data[item]['target_type']][json_data[item]['name']] = \
                {'verbose-name': json_data[item]['verbose_name'],
                 'units': json_data[item]['units'],
                 'formatter': formatter}

        self.stats_metadata = json_data
        self.stats_type_metadata = metadata

        self.pp.add_format('STATS-CONTROLLER',
                           'cli.init_stats_metadata()', # origina
                           {'stats-controller' : {
                'field-orderings' : {'default': 
                                     ['cpu-user', 'cpu-nice', 'cpu-system', 
                                      'cpu-idle'
                                      'mem-free', 'mem-used', 'swap-used',
                                      'disk-root', 'disk-log', 'disk-boot',
                                      'sdnplatform-cpu', 'database-cpu', 
                                      'apache-cpu', 'cli-cpu', 'statd-cpu']},
                'fields' : fields['controller']
                }})

        self.pp.add_format('STATS-SWITCH',
                           'cli.init_stats_metadata()', # origina
                           { 'stats-switch' : {
                'field-orderings' : {'default': 
                                     ['OFPacketIn', 'OFFlowMod', 'OFActiveFlow']},
                'fields' : fields['switch']
                }})
                           
        for obj_type in fields:
            for field in fields[obj_type]:
                for data_format in ['rate', 'value']:
                    units = fields[obj_type][field]['units']
                    if data_format == 'rate':
                        units += '/s'
                    self.pp.add_format('STATS-%s-%s-%s' % (obj_type,field,data_format), 
                                       'cli.init_stats_metadata()',
                            { 'stats-%s-%s-%s' % (obj_type,field,data_format) : { \
                            'field-orderings' : {'default': ['value', 'timestamp']},
                            'fields' : {'timestamp': {'verbose-name': 'Timestamp',
                                                      'formatter': 
                                                      lambda x,y: time.ctime(x/1000)},
                                        'value': {'units': units,
                                                  'verbose-name': 
                                                  '%s (%s)' % 
                                                  (fields[obj_type][field]['verbose-name'],
                                                   units)}}
                            }})

    #
    # --------------------------------------------------------------------------------
    #
    def command_packages_path(self):
        command_descriptions = 'desc'
        desc_path = resource_filename(__name__, command_descriptions)
        if desc_path:
            # print "desc_path %s" % desc_path
            return desc_path
        desc_path = os.path.join(os.path.dirname(__file__), command_descriptions)
        if os.path.exists(desc_path):
            return desc_path
        return None


    #
    # --------------------------------------------------------------------------------
    #
    def command_packages_exists(self, version):
        desc_path = self.command_packages_path()
        if desc_path == None:
            return None
        version_path = os.path.join(desc_path, version)
        if os.path.exists(version_path):
            return version_path
        return None


    #
    # --------------------------------------------------------------------------------
    #
    def add_command_packages(self, version):
        """
        Add all command and output format components

        """
        desc_path = self.command_packages_path()
        if desc_path == None:
            print 'No Command Descriptions subdirectory'
            return

        for path_version in [x for x in os.listdir(desc_path) if x.startswith(version)]:
            print path_version
            result_tuple = imp.find_module(path_version, [desc_path])
            imp.load_module(version, result_tuple[0], result_tuple[1], result_tuple[2])
            new_path = result_tuple[1]
            cmds_imported = []
            for cmds in os.listdir(new_path):
                (prefix, suffix) = os.path.splitext(cmds)
                if (suffix == '.py' or suffix == '.pyc') and prefix not in cmds_imported and prefix != '__init__':
                    cmds_imported.append(prefix)
                    result_tuple = imp.find_module(prefix, [new_path])
                    module = imp.load_module(prefix, result_tuple[0], result_tuple[1], result_tuple[2])
                    command.add_commands_from_module(version, module, self.dump_syntax)
                    self.pp.add_formats_from_module(version, module)
            # print cmds_imported

    #
    # --------------------------------------------------------------------------------
    #
    def choices_text_builder(self, matches, max_len = None, col_width = None):
        """
        @param max_len integer, describes max width of any entry in matches
        @param col_width integer, colun width
        """
        # Sort the choices alphabetically, but if the token ends
        # in a number, sort that number numerically.
        try:
            entries = sorted(matches, utif.completion_trailing_integer_cmp)
        except Exception, e:
            traceback.print_exc()

        if col_width == None:
            # request to look it up
            (col_width, line_length) = self.pp.get_terminal_size()
            col_width = min(120, col_width)

        if max_len == None:
            # request to compute the max length
            max_len = len(max(matches, key=len))

        count = len(matches)
        max_len += 1 # space after each choice
        if max_len > col_width:
            # one per line?
            pass
        else:
            per_line = col_width / max_len
            lines = (count + (per_line - 1)) / per_line
            if lines == 1:
                return ''.join(['%-*s' % (max_len, m) for m in entries])
            else:
                # fill the columns, which means skipping around the entries
                result = []
                for l in range(lines):
                    result.append(['%-*s' % (max_len, entries[i])
                                   for i in range(l, count, lines)])
                lines = [''.join(x) for x in result]
                return '\n'.join(lines)


    #
    # --------------------------------------------------------------------------------
    #
    def matches_hook(self, subs, matches, max_len):

        # one shot disabler, used to disable printing of completion
        # help for two-column help display (for '?' character). 
        # completion printing here can only display the possible selections,
        # for two-column mode, the reason why each keyword was added
        # needs to be displayed, which is no longer available here.
        if self.completion_print == False:
            self.completion_print = True
            return
        
        choices_text = self.choices_text_builder(matches, max_len)
        self.print_completion_help(choices_text)

    #
    # --------------------------------------------------------------------------------
    #
    def pre_input_hook(self):
        """
        """
        pass

    
    #
    # --------------------------------------------------------------------------------
    # 
    def desc_version_to_path_elem(self, version):
        """
        Version numbers like 1.0 need to be converted to the path
        element associated with the number, like version100
        """
        try:
            version_number = float(version)
            version = 'version%s' % int(version_number * 100)
        except:
            pass

        # temporary, use until version100 exists.
        if version == 'version100' and not self.command_packages_exists(version):
            version = 'version200'

        return version
        

    #
    # --------------------------------------------------------------------------------
    # init
    #
    def init(self):
        global mi
        
        self.completion_print = True
        self.vendordb = VendorDB()
        self.vendordb.init()

        parser = OptionParser()
        parser.add_option("-c", "--controller", dest="controller",
                          help="set default controller to CONTROLLER", 
                          metavar="CONTROLLER", default=self.sdn_controller_paltform)
        parser.add_option("-S", "--syntax", dest='dump_syntax',
                          help="display syntax of loaded commands",
                          action='store_true', default=False)
        parser.add_option("-i", "--init", dest='init',
                          help="do not perform initialization checks",
                          action='store_true', default=False)
        parser.add_option("-d", "--debug", dest='debug',
                          help='enable debug for cli (debug cli)',
                          action='store_true', default=False)
        parser.add_option("-v", "--version", dest='desc_version',
                          help='select command versions (description group)',
                          default=None)
        parser.add_option('-m', "--mode", dest='starting_mode',
                          help='once the cli starts, nest into this mode')
        parser.add_option('-q', "--quiet", dest='quiet',
                          help='suppress warning messages',
                          action='store_true', default=False)
        (self.options, self.args) = parser.parse_args()
        if self.controller is None:
            self.controller = "127.0.0.1:8000"
        self.sdn_controller_paltform = self.options.controller
        if not self.sdn_controller_paltform:
            self.sdn_controller_paltform = "127.0.0.1:8080"
        self.dump_syntax = self.options.dump_syntax
        if not self.dump_syntax:
            self.dump_syntax = False
        self.debug = self.options.debug

        # command option, then env, then default
        self.desc_version = self.options.desc_version
        if self.desc_version == None:
            self.desc_version = os.getenv('CLI_COMMAND_VERSION')
        if self.desc_version == None:
            self.desc_version = '2.0'   # 'version200'

        if self.desc_version:
            self.desc_version = self.desc_version_to_path_elem(self.desc_version)

        self.length = 0 # screen length.

        self.set_controller_for_prompt()

        if not sys.stdin.isatty():
            self.batch = True

        self.store = StoreClient()
        self.store.set_controller(self.controller)
        self.store.set_sdn_controller_platform_rest_if(self.sdn_controller_paltform)

        mi = Modi(self, CliModelInfo())
        self.mi = mi
        self.init_command_dict()

        self.completion_reset()
        self.completion_skip = False
        self.completion_cache = True
        readline.set_completer(self.completer)
        readline.set_completer_delims("\t ")
        # readline.set_pre_input_hook(self.pre_input_hook)
        readline.set_completion_display_matches_hook(self.matches_hook)
        if not self.batch:
            self.init_history_file()
        self.push_mode("login")

        # starting mode, 
        starting_mode = self.options.starting_mode
        if starting_mode == None:
            starting_mode = os.getenv('CLI_STARTING_MODE')

        if starting_mode:
            if starting_mode == 'login':
                pass
            elif starting_mode == 'enable':
                self.push_mode("enable")
            elif starting_mode == 'config':
                self.push_mode("enable")
                self.push_mode("config")
            else:
                print 'Only login, enable or config allowed as starting modes'

        # process quiet option
        quiet = self.options.quiet
        if quiet == None:
            quiet = os.getenv('CLI_SUPPRESS_WARNING')

        if quiet:
            self.supress_warnings()

        #
        self.pp = PrettyPrinter(self)

        #
        # pattern matches
        #
        self.IP_ADDR_RE = re.compile(r'^(\d{1,3}\.){3}\d{1,3}$')
        self.CIDR_RE = re.compile(r'^((\d{1,3}\.){3}\d{1,3})/(\d{1,2}?)$')
        self.MAC_RE = re.compile(r'^(([A-Fa-f\d]){2}:?){5}[A-Fa-f\d]{2}$')
        self.DPID_RE = re.compile(r'^(([A-Fa-f\d]){2}:?){7}[A-Fa-f\d]{2}$')
        self.ACL_RE = re.compile(r'^\d+$')  # just the leading digits
        self.DIGITS_RE = re.compile(r'^\d+$')
        self.HEX_RE = re.compile(r'^0x[0-9a-fA-F]+$')

        # Initialize any middleware layers
        init_midware(self, mi)
        init_vnsw(self, mi)
        rest_to_model.rest_to_model_init(self, mi)
        run_config.init_running_config(self, mi)

        # Initialize all doc tags, use a subdirectory based on
        # the locale.   This may be incorect if there's nothing
        # in the configured locale for the returned locale value.
        lc = locale.getdefaultlocale()
        if lc == None or lc[0] == None:
            print 'Locale not configured ', lc
            lc = ('en_US', 'UTF8')
        doc_dir = resource_filename(__name__, 'documentation/%s' % lc[0])
        if doc_dir is None:
            doc_dir = os.path.join(os.path.dirname(__file__), 'documentation', lc[0])
        # print "doc_dir %s" % doc_dir
        doc.add_doc_tags(doc_dir)

        # Initialize the command module, than add command packages
        command.init_command(self, mi)
        self.add_command_packages(self.desc_version)

        # save for possible later use
        #print self.pp.format_table(self.pp.format_details())
        
        #
        if self.debug:
            for (n,v) in self.command_submode_dict.items():
                print "SUBMODE %s %s" % (n,v)
            for (n,v) in self.command_dict.items():
                print "MODE %s %s" % (n,v)


        self.time_zone_list = None
        command.add_completion('time-zone-completion', SDNSh.time_zone_completion)
        command.add_validation('time-zone-validation', SDNSh.time_zone_validation)
        command.add_action('set-clock', SDNSh.set_clock_action, {'kwargs': {'data': '$data'}})
        command.add_action('begin-default-gateway-check', SDNSh.begin_default_gateway_check_action)
        command.add_action('end-default-gateway-check', SDNSh.end_default_gateway_check_action)
    
        command.add_command_type('config-with-default-gateway-check', {
            'action': ('begin-default-gateway-check', 'write-fields', 'end-default-gateway-check'),
            'no-action': ('begin-default-gateway-check', 'reset-fields', 'end-default-gateway-check')
        })

        #
        if self.feature_enabled('experimental'):
            print '***Warning: experimental features enabled***'
            if self.debug:
                self.sdndb = sdndb.SDNDB(self, self, self.pp)
                print '--BEGIN--'
                self.sdndb.display('core/switch', style='table')
                self.sdndb.display('core/controller', style='table')
                self.sdndb.display('core/controller', style='list')
                print '--LINK--', self.pp.table_info['link']['field-orderings']
                self.sdndb.display('topology/link')
                self.sdndb.display('topology/switch-cluster')
                self.sdndb.display('topology/switch-cluster', style='list')
                self.sdndb.display('topology/enabled-port')

    #
    # --------------------------------------------------------------------------------
    # check_rest_result
    @staticmethod
    def check_rest_result(result, message=None):
        if isinstance(result, collections.Mapping):
            error_type = result.get('error_type')
            if error_type:
                raise error.CommandRestError(result, message)

    #
    # --------------------------------------------------------------------------------
    # get_table_from_store
    #  Caches the last result to try to cut down on the number of times large tables
    #  are loaded from the REST API
    #
    def get_table_from_store(self, obj_type, key = None, val = None, match = None):
        return self.store.get_table_from_store(obj_type, key, val, match)

    #
    # --------------------------------------------------------------------------------
    # get_object_from_store
    #   cover for call to get a specific object from a table, only a convenience.
    #
    def get_object_from_store(self, obj_type, obj_name):
        return self.store.get_object_from_store(obj_type, obj_name)

    #
    # --------------------------------------------------------------------------------
    # rest_query_objects
    #   cover for call to query objects from the database, only a convenience.
    #
    def rest_query_objects(self, obj_type, query_params=None):
        return self.store.rest_query_objects(obj_type, query_params)

    #
    # --------------------------------------------------------------------------------
    # rest_create_object
    #  REST API call to create an object, if this is the last table which
    #  was fetched, then discard that table.
    #
    def rest_create_object(self, obj_type, ident):
        return self.store.rest_create_object(obj_type, ident)

    #
    # --------------------------------------------------------------------------------
    # rest_delete_objects
    #
    def rest_delete_objects(self, obj_type, delete_params):
        return self.store.rest_delete_objects(obj_type, delete_params)

    #
    # --------------------------------------------------------------------------------
    # rest_delete_object
    #
    def rest_delete_object(self, obj_type, name):
        if type(name) == dict:
            return self.store.rest_delete_object(obj_type, name)

        return self.store.rest_delete_object(obj_type, mi.pk(obj_type), name)

    #
    # --------------------------------------------------------------------------------
    # rest_update_object
    #
    def rest_update_object(self, obj_type, name, obj_key_val, obj_key_data):
        return self.store.rest_update_object(obj_type, name, obj_key_val, obj_key_data)

    #
    # --------------------------------------------------------------------------------
    # rest_simple_resquest_to_dict
    #  Issue a store_simple_request and covert the result into a dict using json.load
    #  Performs no exception handling
    #
    def rest_simple_request_to_dict(self, url):
        return json.loads(self.store.rest_simple_request(url))

    #
    # --------------------------------------------------------------------------------
    # rest_post_request
    #  Forward a low-level REST request to the store
    #
    def rest_post_request(self, url, obj, verb='PUT'):
        return self.store.rest_post_request(url, obj, verb)
    
    #  
    # --------------------------------------------------------------------------------
    # create_object
    #  Helper function to help identify call sites which create objects
    #  Errors result in printing an error message, then returning True
    #
    def create_object(self, obj_type, field_dict):
        try:
            self.rest_create_object(obj_type, field_dict)
            return False
        except Exception, e:
            errors = self.rest_error_to_dict(e, obj_type)
           
        if errors != None:
            print self.rest_error_dict_to_message(errors)
            return True
        
    #  
    # --------------------------------------------------------------------------------
    # create_row
    #  Helper function to help identify call sites which create new rows
    #
    #  Return a pair of bool's, the first is an error indication, while the second
    #  is True when the row needed to be created.
    #
    #
    def create_row(self, obj_type, name, row_dict = None):
        # create the row with a dictionary which includes all the
        # populated values for the foreign keys
        # the row is created.
        if row_dict == None:
            updated_dict = {}
        else:
            updated_dict = row_dict

        #
        # Only set the primary key for obj_keys which aren't managed
        # by the CassandraSetting/COMPOUND_KEY_FIELDS (this is currently
        # a slightly different predicate than is_compound_key)
        #
        key = mi.pk(obj_type)
        type_info = mi.obj_type_info_dict[obj_type]['fields'][key]['type']
        if type_info != 'compound-key':
            updated_dict[mi.pk(obj_type)] = name
        updated_dict = self.associate_foreign_keys_with_dict(obj_type, updated_dict)

        if self.create_object(obj_type, updated_dict):
            return [True, False]
        return [False, True]

    #
    # --------------------------------------------------------------------------------
    # find_or_create_row
    #  Return a pair of bool's, the first is an error indication, while the second
    #  is True when the row needed to be created.
    #
    #  When a new row is created, if the obj_type has a private_key, an attempt
    #  is made to identify all the private keys, and populate values for each
    #  of them.
    #
    def find_or_create_row(self, obj_type, name, row_dict = None):
        if row_dict == None:
            row_dict = {}
        try:
            result = self.get_object_from_store(obj_type, name)
            if result[mi.pk(obj_type)] == name:
                return [False, False]
        except Exception:
            pass

        return self.create_row(obj_type, name, row_dict)

    #
    # --------------------------------------------------------------------------------
    # associate_foreign_keys_with_dict
    #  Passed an obj_type, and a dictionary, returns a dictionary with updated
    #  key:value pairs for all the known private keys.
    #  
    #
    def associate_foreign_keys_with_dict(self, obj_type, create_dict):
        #
        # Private key names are 'well known', so the names are used here to
        # idenify how the field ought to be populated.
        #
        for foreign_key_id in mi.obj_type_foreign_keys(obj_type):
            if foreign_key_id in create_dict:
                # already set in the dictionary
                pass
            elif mi.is_null_allowed(obj_type, foreign_key_id):
                continue
            elif foreign_key_id == 'vns':
                create_dict[foreign_key_id] = self.vns_name()
            elif foreign_key_id == 'vns-access-list' and \
              self.get_current_mode_obj_type() == 'vns-access-list':
                create_dict[foreign_key_id] = self.get_current_mode_obj()
            elif foreign_key_id == 'rule':
                # LOOK! this seems to need more work, what's the rule relationship?
                if obj_type == 'vns-interface':
                    create_dict = associate_foreign_key_for_vns_interface(dict)
            else:
                traceback.print_stack()
                print self.error_msg("Internal: %s can't determine value " \
                                     "for foreign key %s" % (obj_type, foreign_key_id))
 
        return create_dict

    #
    # methods to manage the mode_stack, prompts, and mode_obj/mode_obj_type
    #

    #
    # --------------------------------------------------------------------------------
    # set_contoller_for_prompt
    #
    def set_controller_for_prompt(self):
        if self.controller == "127.0.0.1:8000":
            self.controller_for_prompt = socket.gethostname()
        else:
            self.controller_for_prompt = self.controller
            self.update_prompt()

    #
    # --------------------------------------------------------------------------------
    # update_prompt
    #  There are several different prompts depending on the current mode:
    #  'host'>                                  -- login mode
    #  'host'#                                  -- enable mode
    #  'host'(config)#                          -- config mode
    #  'host'(config-vns-definition-name)#      -- vns-definition mode
    #  'host'(config-vns-definition-interface-rule-name)# -- vns-defn,
    #                                              interface-rule mode
    #
    def update_prompt(self):
        if self.current_mode().startswith("config"):
            current_mode = "(" + self.current_mode()
            if self.get_current_mode_obj() != None:
                if self.in_config_submode("config-vns"):
                    # substitute '|' with '-'
                    parts = self.get_current_mode_obj().split('|')
                    current_mode += "-" + '-'.join(parts)
            self.prompt = str(self.controller_for_prompt) + current_mode + ")# "
        elif self.current_mode() == "enable":
            self.prompt = str(self.controller_for_prompt) + "# "
        else:
            self.prompt = str(self.controller_for_prompt) + "> "

    #
    # --------------------------------------------------------------------------------
    # push_mode
    #  Every pushed mode is a quad: <modeName, tableName, specificRow, exitCallback>
    #
    #  obj_type is the name of an associated table/model (tableName)
    #  obj is the key's value for the table/model's key (specificRow)
    # 
    #  The cli currently supports a mode of table/model row edit, where the
    #  name of the table/mode is entered, along with an associated value for
    #  key-column of the table.   Once in that mode, other fields of the table
    #  can be edited by entering the name of the field, along with a new value.
    #
    #  The exitCallback is the nane of a method to call when the current pushed
    #  level is getting pop'd.
    #
    def push_mode(self, mode_name, obj_type=None, obj=None, exitCallback=None):
        self.mode_stack.append( { 'mode_name' : mode_name,
                                  'obj_type' : obj_type,
                                  'obj' : obj,
                                  'exit' : exitCallback} )
        self.update_prompt()

    #
    # --------------------------------------------------------------------------------
    # pop_mode
    #  Pop the top of the stack of mode's.
    #
    def pop_mode(self): 
        m = self.mode_stack.pop()
        if len(self.mode_stack) == 0:
            self.run = False
        else:
            self.update_prompt()
        return m
    
    #
    # --------------------------------------------------------------------------------
    # mode_stack_to_rest_dict
    #  Convert the stack of pushed modes into a collection of keys.
    #  Can be used to build the rest api dictionary used for row creates
    #
    def mode_stack_to_rest_dict(self, rest_dict):
        #
        for x in self.mode_stack:
            if x['mode_name'].startswith('config-'):
                rest_dict[x['obj_type']] = x['obj']

        return rest_dict

    #
    # --------------------------------------------------------------------------------
    # current_mode
    #  Return the string describing the current (top) mode.
    #
    def current_mode(self): 
        if len(self.mode_stack) < 1:
            return ""
        return self.mode_stack[-1]['mode_name']

    #
    # --------------------------------------------------------------------------------
    # in_config_submode
    #  Return true when the current mode is editing the contents of one of the
    #  rows of the table/model store.
    #
    def in_config_submode(self, prefix = "config-"):
        return self.current_mode().startswith(prefix)

    #
    # --------------------------------------------------------------------------------
    # in_config_mode
    #  Returns true for any config mode; this is any nested edit mode,
    #  along with the base config mode
    #
    def in_config_mode(self):
        return self.current_mode().startswith("config")
    #
    # --------------------------------------------------------------------------------
    # in_config_switch_mode
    #  Returns true when the switch mode has been entered via the 'switch <dpid>' command.
    #
    def in_config_switch_mode(self):
        return self.current_mode() == "config-switch"
    #
    # --------------------------------------------------------------------------------
    # in_config_switch_if_mode
    #  Returns true when the switch-interface mode has been entered via the
    # 'switch <dpid>' command, then the interface <name> command
    #
    def in_config_switch_if_mode(self):
        return self.current_mode() == "config-switch-if"

    #
    # --------------------------------------------------------------------------------
    # vns_name
    #
    def vns_name(self):
        mode_dict = self.mode_stack_to_rest_dict({})
        if 'vns' in mode_dict:
            return mode_dict['vns']
        if 'vns-definition' in mode_dict:
            return mode_dict['vns-definition']
        return None

    #
    # --------------------------------------------------------------------------------
    # in_config_vns_mode
    #  Returns true when the vns mode has been entered via the 'vns <vnsId>' command.
    #
    def in_config_vns_mode(self):
        return self.current_mode() == "config-vns"
    #
    # --------------------------------------------------------------------------------
    # in_config_vns_def_mode
    #  Returns true when the vns mode has been entered via the
    #  'vns-definition <vnsId>' command.
    #
    def in_config_vns_def_mode(self):
        return self.current_mode() == "config-vns-def"
    #
    # --------------------------------------------------------------------------------
    # in_config_vns_def_if_rule_mode
    #  Returns true when the vns mode has been entered via the
    #  'vns-definition <vnsId>' command, then into interface-rule mode.
    #
    def in_config_vns_def_if_rule_mode(self):
        return self.current_mode() == "config-vns-def-if-rule"

    #
    # --------------------------------------------------------------------------------
    # in_config_vns_acl_mode
    #  Returns true when the vns mode has been entered via the
    #  'vns <vnsId>' command, then into acl mode.
    #
    def in_config_vns_acl_mode(self):
        return self.current_mode() == "config-vns-acl"

    #
    # --------------------------------------------------------------------------------
    # in_config_vns_if_mode
    #  Returns true when the vns mode has been entered via the
    #  'vns <vnsId>' command, then into interface mode.
    #
    def in_config_vns_if_mode(self):
        return self.current_mode() == "config-vns-if"

    #
    # --------------------------------------------------------------------------------
    # in_config_host_mode
    #  Returns true when the vns mode has been entered via the
    #  'host <host-id>' command
    #
    def in_config_host_mode(self):
        return self.current_mode() == "config-host"

    #
    # --------------------------------------------------------------------------------
    # in_config_controller_node_mode
    #  Returns true when the vns mode has been entered via the
    #  'controller-node <controller-node-id>' command
    #
    def in_config_controller_node_mode(self):
        return self.current_mode() == "config-controller-node"

    #
    # --------------------------------------------------------------------------------
    # in_config_controller_interface_mode
    #  Returns true when the controller interface mode has been entered via the
    #  'interface Ethernet <#>' command from the controller-node config mode
    #
    def in_config_controller_interface_mode(self):
        return self.current_mode() == "config-controller-if"

    #
    # --------------------------------------------------------------------------------
    # in_config_port_channel_mode
    #
    def in_config_port_channel_mode(self):
        return self.current_mode() == "config-port-channel"

    # --------------------------------------------------------------------------------
    # set_current_mode_obj
    #  Sets the name of the selected row (key's value)
    #
    def set_current_mode_obj(self, obj):
        self.mode_stack[-1]['obj'] = obj
        
    #
    # --------------------------------------------------------------------------------
    # get_current_mode_obj
    #  Gets the name of the current mode's selected row value (key's value)
    #  This can return None.
    #
    def get_current_mode_obj(self):
        return self.mode_stack[-1]['obj']

    #
    # --------------------------------------------------------------------------------
    # set_current_mode_obj_type
    #  Set the table/model name for this current mode.
    #
    def set_current_mode_obj_type(self, obj_type):
        self.mode_stack[-1]['obj_type'] = obj_type

    #
    # --------------------------------------------------------------------------------
    # get_current_mode_obj_type
    #  Get the table/model name for this current mode.
    #
    def get_current_mode_obj_type(self):
        return self.mode_stack[-1]['obj_type']

    #
    # --------------------------------------------------------------------------------
    # get_nested_mode_obj
    #  Get the id of the object that matches the given object type
    #  starting from the current mode and working backwards to the
    #  top-level mode. If there's no mode that matches the given
    #  object type, then return None (maybe should handle as exception?).
    #
    def get_nested_mode_obj(self, obj_type):
        for i in range(1, len(self.mode_stack)+1):
            # Use negative index so we search from the top/end of the stack
            mode = self.mode_stack[-i]
            if mode['obj_type'] == obj_type:
                return mode['obj']
        return None
    
    #
    # helper functions to access commands, obj_types, and fields
    #

    #
    # --------------------------------------------------------------------------------
    # all_obj_types_starting_with
    #  Returns a list of all the current object types starting with the text
    #  parameter.
    #
    #
    def all_obj_types_starting_with(self, text=""):
        if onos == 0:
            netvirt_feature = self.netvirt_feature_enabled()
        else:
            netvirt_feature = False

        matched_obj_types = [x for x in mi.obj_types
                             if x.startswith(text) and
                                self.debug_obj_type(x) and
                                (netvirt_feature or (x != 'vns-definition')) ]
        # synthetic object type based on the vns config submode.
        if self.in_config_vns_def_mode() and "interface-rule".startswith(text):
            matched_obj_types.append("interface-rule")
        if self.in_config_vns_mode() and "access-list".startswith(text):
            matched_obj_types.append("access-list")
        if self.in_config_vns_mode() and "interfaces".startswith(text):
            matched_obj_types.append("interfaces")
        return matched_obj_types
    #
    # --------------------------------------------------------------------------------
    # feature_enabled
    #  Return True when a particular feature is enabled.
    #
    def feature_enabled(self, feature):
        # features not managed via store
        #
        if feature == 'experimental':
            return os.path.exists(self.feature_allow_experimental)

        if feature == 'ha':
            try:
                with open(self.boot_config_filename, "r") as f:
                    for line in f:
                        if line.startswith('ha-config='):
                            parts = line.split('=')
                            if len(parts) > 0 and parts[1] == 'enabled\n':
                                return True
            except:
                pass
            return False

        # only current features which can be enabled disabled
        if feature not in [
                'vns', 'static-flow-pusher', 'performance-monitor']:
            return False

        #
        try:
            entry = self.get_table_from_store('feature')
        except Exception, e:
            errors = self.rest_error_to_dict(e, 'feature')
            print self.rest_error_dict_to_message(errors)
            return True

        feature_to_field_dict = {
            'vns'                 : 'netvirt-feature',
            'static-flow-pusher'  : 'static-flow-pusher-feature',
            'performance-monitor' : 'performance-monitor-feature',
        }

        if len(entry) == 0:
            if feature in feature_to_field_dict:
                field = feature_to_field_dict[feature]
                return mi.field_default_value('feature', field)
            return True

        if len(entry) != 1:
            # need a mechanism to select one from the list
            return True

        if feature in feature_to_field_dict:
            return entry[0][feature_to_field_dict[feature]]

        # use the default value from the model (every feature needs a default value)
        defauilt_value = mi.field_default_value('feature', feature_to_field_dict[feature])
        if default_value == None:
            print self.error_msg('Feature %s missing default value' % feature)
            return True
        return default_value

    '''
    #
    # --------------------------------------------------------------------------
    # address_space_default_create
    #
    #  Create a default address space if it doesn't exist, which enables
    #  'address-space default',
    #
    def address_space_default_create(self):
        key = mi.pk('address-space')
        try:
            entries = self.get_table_from_store('address-space',
                                                key, 'default', 'exact')
            errors = None
        except Exception, e:
            errors = self.rest_error_to_dict(e, 'address-space')
            if not 'see_other' in errors:
                print self.rest_error_dict_to_message(errors)
            return

        if len(entries) == 0:
            self.create_row('address-space', 'default')

    #
    # --------------------------------------------------------------------------
    # tenant_default_create
    #
    #  Create default tenant and system tenant if it doesn't exist, which enables
    #  'tenant default' and tenant system, router vrsystem,
    #
    def tenant_default_create(self):
        key = mi.pk('tenant')
        try:
            entries = self.get_table_from_store('tenant',
                                                key, 'default', 'exact')
            errors = None
        except Exception, e:
            errors = self.rest_error_to_dict(e, 'tenant')
            if not 'see_other' in errors:
                print self.rest_error_dict_to_message(errors)
            return

        if len(entries) == 0:
            self.create_row('tenant', 'default')
        #external tenant
        try:
            entries = self.get_table_from_store('tenant',
                                                key, 'external', 'exact')
            errors = None
        except Exception, e:
            errors = self.rest_error_to_dict(e, 'tenant')
            if not 'see_other' in errors:
                print self.rest_error_dict_to_message(errors)
            return

        if len(entries) == 0:
            self.create_row('tenant', 'external')

        #system tenant and system router: vrsystem
        try:
            entries = self.get_table_from_store('tenant',
                                                key, 'system', 'exact')
            errors = None
        except Exception, e:
            errors = self.rest_error_to_dict(e, 'tenant')
            if not 'see_other' in errors:
                print self.rest_error_dict_to_message(errors)
            return

        if len(entries) == 0:
            self.create_row('tenant', 'system')
        
        try:
            entries = self.get_table_from_store('virtualrouter',
                                                key, 'vrsystem', 'exact')
            errors = None
        except Exception, e:
            errors = self.rest_error_to_dict(e, 'virtualrouter')
            if not 'see_other' in errors:
                print self.rest_error_dict_to_message(errors)
            return

        if len(entries) == 0:
            self.create_row('virtualrouter', 'vrsystem',{"tenant":"system","vrname":"vrsystem"})
 
    #
    # --------------------------------------------------------------------------
    # netvirt_feature_init
    #  perform vns featrue enablement:
    #  Create a default vns if it doesn't exist, which enables 'vns default',
    #
    def netvirt_feature_init(self):
        self.address_space_default_create()
        self.tenant_default_create()
        key = mi.pk('vns-definition')
        try:
            entries = self.get_table_from_store('vns-definition', key, 'default|default', 'exact')
            errors = None
        except Exception, e:
            errors = self.rest_error_to_dict(e, 'vns-definition')
            if not 'see_other' in errors:
                print self.rest_error_dict_to_message(errors)
            return

        if len(entries) == 0:
            self.create_row('vns-definition', 'default', {"tenant":"default","vnsname":"default"})

    #
    # --------------------------------------------------------------------------------
    # netvirt_feature_enabled
    #  Return True when the vns feature is enabled
    #  
    #  When vns is disabled, particular vns commands are no longer
    #  available, along with a few specific objects.  Particular
    #  code sites which are specifically concerned with these issues
    #  disable these items.  Another possible approach would be to
    #  modify the base information sources  when a feature is
    #  enabled or disabled, ie: mi.obj_types and command_dict.
    #  This more active approach isn't taken since during
    #  the initialization process, a variety of different object
    #  relationships are constructed; foreign key xref's,  alias
    #  key xref's,  object key dictionaries, etc.  If the feature
    #  enabled were more active, then all these relationships would also
    #  need to be recomputed.
    #
    def netvirt_feature_enabled(self):
        controller_netvirt_feature = self.feature_enabled("vns")
        if self.netvirt_feature_enabled_cached != controller_netvirt_feature:
            self.netvirt_feature_enabled_cached = controller_netvirt_feature
            if self.netvirt_feature_enabled_cached:
                self.netvirt_feature_init()
        if controller_netvirt_feature == False:
            return False
        return True
    '''

    #
    # --------------------------------------------------------------------------------
    # get_obj_of_type
    #  Return a single row, or None, of the table who's name is passed as obj_type
    #  Returns None when when there's multiple matches of the nane in the table/model
    #  Performs no error processing
    #
    def get_obj_of_type(self, obj_type, name):
        key = mi.pk(obj_type)
        if key:
            errors = None
            try:
                entries = self.get_table_from_store(obj_type)
            except Exception, e:
                errors = self.rest_error_to_dict(e, obj_type)

            if errors:
                print self.rest_error_dict_to_message(errors)
                return None

            entries = [x for x in entries if x.get(key, 'None') == name]
            if len(entries) != 1:
                return None
            return entries[0]
        else:
            return None
        
    #
    # --------------------------------------------------------------------------------
    # fields_for_current_submode_starting_with
    #  Return a list of choices which are fields names of model/store objects
    #  Any fields which are primary keys are excluded from edit, as are any
    #  foreign keys, this is managed through is_editable()
    #
    def fields_for_current_submode_starting_with(self, start_text=""):
        if not self.in_config_submode():
            return []
        if self.in_config_vns_mode():
            return []
        obj_type = self.get_current_mode_obj_type()
        if not obj_type in mi.obj_type_info_dict:
            return []
        fields = [x for x in mi.obj_type_info_dict[obj_type]['fields'].keys() \
                  if mi.is_editable(obj_type, x)]

        return [x for x in fields if x.startswith(start_text)]

    #
    # --------------------------------------------------------------------------------
    # obj_types_for_config_mode_starting_with
    #
    # what obj types are available in the given submode
    # e.g., top-level config mode has switch and config-switch has
    # flow-entry but flow-entry should not be available in top-level
    # config nor should switch be available in config-switch submode!
    # LOOK! hardwired for now to test parsing - need to merge with model
    #
    def obj_types_for_config_mode_starting_with(self, start_text=""):
        if not self.in_config_mode():
            return []
        #
        # vns features
        if onos == 0:
            netvirt_features = self.netvirt_feature_enabled()
        else:
            netvirt_features = False
        vns_objects = [ 'vns-definition' ]

        ret_list = [x for x in mi.obj_types
                    if self.debug_obj_type(x) and 
                       not mi.is_obj_type_source_not_user_config(x)]
        return [x for x in ret_list if x.startswith(start_text) and
                    (netvirt_features or not x in vns_objects) ]

    @staticmethod
    def title_of(command):
        return command['title'] if type(command) is dict else command

    #
    # --------------------------------------------------------------------------------
    # commands_feature_enabled
    #
    def commands_feature_enabled(self, commands):
        return [self.title_of(x) for x in commands
                if (not self.title_of(x) in self.command_name_feature) or
                    command.isCommandFeatureActive(self.title_of(x),
                           self.command_name_feature[self.title_of(x)])]

    #
    # --------------------------------------------------------------------------------
    # commands_for_mode
    #
    def commands_for_mode(self, mode):
        """
        Walk the command dict, using interior submodes and compiling
        the list of available commands (could rebuild command_dict()
        to contain all the possible commands, but its good to know
        exactly which commands apply to this submode)
        """

        # make a new list, so that items don't get added to the source
        ret_list = list(self.command_nested_dict.get('login', []))
        if mode == 'login':
            ret_list += self.command_dict.get('login', [])
            return ret_list
        ret_list += self.command_nested_dict.get('enable', [])
        if mode == 'enable':
            ret_list += self.command_dict.get('enable', [])
            return ret_list

        if mode == 'config':
            ret_list += self.command_nested_dict.get('config', [])
            ret_list += self.command_dict.get('config', [])
            return ret_list
        
        for idx in [x for x in self.command_nested_dict.keys() if mode.startswith(x)]:
            ret_list += self.command_nested_dict.get(idx, [])

        ret_list += self.command_dict.get(mode, [])

        # manage command who's names are regular expressions
        result = [x['re'] if type(x) == dict else x  for x in ret_list]

        return result

    #
    # --------------------------------------------------------------------------------
    # commands_for_current_mode_starting_with
    #
    def commands_for_current_mode_starting_with(self,
                                                start_text = "", completion = None):
        """
        One of the difficult issues here is when the first item
        isn't a token, but rather a regular expression.  This currently occur
        in a few places in the command description, and the mechanism for
        dealing with the issue here is ... uhm ... poor.  The code here is
        a stopgap, and assumes the only regular expression supported
        is the <digits> one.  This could be make a bit better based on
        the submode, but really, this entire first-token management should
        be improved.
        """
        if completion == None:
            completion = False
        #
        # vns features commands include:
        netvirt_feature_commands = ['vns', 'vns-definition']
        if onos == 0:
            netvirt_feature = self.netvirt_feature_enabled()
        else:
            netvirt_feature = False

        mode_list = self.commands_for_mode(self.current_mode())
        ret_list = self.commands_feature_enabled(utif.unique_list_from_list(mode_list))

        def prefix(x, start_text, completion):
            if type(x) == str and x.lower().startswith(start_text.lower()):
                return True
            if not completion and type(x) == re._pattern_type:
                return x.match(start_text)
            return False

        def pattern_items(ret_list, prefix):
            matches = []
            for p in [x for x in ret_list if type(x) == re._pattern_type]:
                for c in command.command_registry:
                    if c['mode'] != self.current_mode():
                        continue
                    if type(c['name']) != dict:
                        continue
                    first_word = c['name']
                    if 'completion' not in first_word:
                        continue
                    completion = first_word['completion']
                    if first_word['pattern'] == p.pattern:
                        result = {}
                        scopes = [ first_word,
                                   {
                                    'completions' : result,
                                    'data'        : {},
                                    'text'        : prefix,
                                   },
                                 ]
                        command._call_proc(completion,
                                           command.completion_registry,
                                           scopes, c)
                        matches = result.keys()
            return matches

        matches = [x for x in ret_list if prefix(x, start_text, completion)]
        if completion:
               matches += pattern_items(ret_list, start_text)
        return matches


    #
    # --------------------------------------------------------------------------------
    # complete_optional_parameters
    #
    # Parse optional parameters.  These can occur in any order.
    # Params argument is a hash mapping a parameter name to type
    # information.
    # words argument are remaining words in the command
    # line that aren't yet parsed
    #
    def complete_optional_parameters(self, params, words, text):
        i = 0
        while i < len(words):
            final = i+1 >= len(words)
            word = words[i]
            possible = [x for x in params if x.startswith(word)]
            param_name = possible[0]
            param = params[param_name]
             
            if (param['type'] != 'flag'):
                if (final):
                    argument = text
                    if (param['type'] == 'enum'):
                        return [x 
                                for x in param['values'] 
                                if x.startswith(argument)]
                    elif argument == '':
                        if ('syntax_help' in param):
                            self.print_completion_help(param['syntax_help'])
                        else:
                            self.print_completion_help('[%s argument]' % word)
                        return
                i += 1
            i += 1

        return [x for x in params if x.startswith(text)]

    #
    # --------------------------------------------------------------------------------
    # parse_optional_parameters
    #
    @staticmethod
    def parse_optional_parameters(params, words):
        parsed = {}
        i = 0
        while i < len(words):
            word = words[i]
            possible = [x for x in params if x.startswith(word)]
            if len(possible) == 0:
                raise ParamException('unknown option: %s' % word)
            elif len(possible) > 1:
                raise ParamException('ambiguous option: %s\n%s' % 
                                     (word, "\n".join(possible)))
            else:
                param_name = possible[0]
                param = params[param_name]
                if (param['type'] == 'flag'):
                    parsed[param_name] = True
                else:
                    if i+1 < len(words):
                        argument = words[i+1]
                        if (param['type'] == 'string'):
                            parsed[param_name] = argument
                        elif (param['type'] == 'int'):
                            try:
                                parsed[param_name] = int(argument)
                            except ValueError:
                                raise ParamException('option %s requires ' + 
                                                     'integer argument'
                                                     % word)
                        elif (param['type'] == 'enum'):
                            arg_possible = [x 
                                            for x in param['values'] 
                                            if x.startswith(argument)]
                            if (len(arg_possible) == 0):
                                raise ParamException('option %s value must be in (%s)' % 
                                                     (word,", ".join(param['values'])))
                            elif (len(arg_possible) > 1):
                                raise ParamException('ambiguous option %s value:\n%s' % 
                                                     (word, "\n".join(arg_possible)))
                            else:
                                parsed[param_name] = arg_possible[0]
                        i += 1
                    else:
                        raise ParamException('option %s requires an argument' 
                                                 % word)
            i += 1
        return parsed

    #
    # --------------------------------------------------------------------------------
    # annotated_obj_type_id
    #
    #  Given an id's value for a compound key, crack the value into
    #  parts, and annotate each part with the compound key name.
    #
    #  For 'Not Found' errors, the obj_type is known, along with the value
    #  for the id which wasn't found.  If this is an id with a compound key,
    #  leaking information about the key's implementiion should be avoided. 
    #  Here the key's value is cracked based on the composition character,
    #  and the items are displayed with their key-value name.
    #  eg: Error: Not Found vns:xXx rule-id:snapple  (vns-interface-rule)
    #
    def annotated_obj_type_id(self, obj_type, error):
        key = mi.pk(obj_type)
        if mi.is_compound_key(obj_type, key):
            result = { key : error}
            mi.split_compound_into_dict(obj_type, key, result)
            return ', '.join(["%s:%s" % tuple(x) for x in result.items()
                             if x[0] != key])
        return error

    #
    # --------------------------------------------------------------------------------
    #
    def find_master(self):
        """
        Return a dictionary with two items: 'master', and 'ips'
        'master' identifes the ip address of the master, a string
        which is an ip address, or None.
        'ips' is a list of interface rows with populated ip addresses.
        """
        # collect all the controller-interfaces
        ips = [x for x in local_interfaces_firewall_open('tcp', [80, 8000], 'all')
               if (x['ip'] != '' or x['discovered-ip'] != '')]

        master = None
        for ip in ips:
            if ip['ip'] != '':
                url = "http://%s/rest/v1/system/ha/role" % ip['ip']
            if ip['discovered-ip'] != '': # select discovered ip over ip
                url = "http://%s/rest/v1/system/ha/role" % ip['discovered-ip']
            result = self.store.rest_simple_request(url, use_cache = False)
            self.check_rest_result(result)
            ha_role = json.loads(result)
            if ha_role['role'] == 'MASTER':
                if ip['ip'] != '':
                    master = ip['ip']
                if ip['discovered-ip'] != '':
                    master = ip['discovered-ip']

        return {'master': master, 'ips': ips}

    #
    # --------------------------------------------------------------------------------
    # rest_error_to_dict
    #   Turn an exception into an error dictionary, which can later be printed.
    #   using rest_error_dict_to_message().  
    #
    def rest_error_to_dict(self, e, detail=None):
        errors = None
        # try to identifify validation requests
        if isinstance(e, httplib.BadStatusLine):
            errors = {'connection_error' : 'REST API server %s: '
                                           'server not running' %
                                           self.controller}
            return errors

        elif isinstance(e, urllib2.HTTPError):
            code = e.code
            error_returned = e.readline()

            if code == 404:
                if detail:
                    errors = {'not_found_error' : 'Not Found: %s' % detail}
                else:
                    errors = {'not_found_error' : 'Not Found: %s' % error_returned}
            elif code == 500 or code == 403:
                # traceback.print_stack()
                errors = {'connection_error' : 'REST API server %s failure: %s' %
                                                (self.controller, error_returned)}
            elif code == 400:
                try:
                    errors = json.loads(error_returned)
                except:
                    # if the error can't be converted into a dictionary, then imbed the complete
                    # errors as the value for a specific error key.
                    errors = {'error_result_error': "Can't convert returned error: %s" % error_returned}
            elif code == 301:
                errors = {'moved_error': 'HttpError Moved Permanently %s' % e}
            elif code == 303:
                # Attempt to determine what list of ip addresses is for
                # the controller, try to find the Master.  if any failure 
                # occurs anywhere, drop down to a simple error message.
                try:
                    minfo = self.find_master()
                    ips = [x['ip'] for x in minfo['ips']]
                    master = minfo['master']
                
                    if master:
                        errors = {'see_other': 'This controller is in SLAVE '
                                  'mode. The command must be run in MASTER mode.'
                                  '\nMASTER at %s' % master}
                    elif len(ips):
                        errors = {'see_other': 'This controller is in SLAVE mode. '
                                    'The command must be run in MASTER mode.'
                                    '\nNo MASTER found, possible ip\'s %s' %
                                    (', '.join(ips))}
                    else:
                        errors = {'see_other': 'This controller is in SLAVE mode. '
                                    'The command must be run in MASTER mode.'
                                    '\nNo MASTER currently exists '}
                except:
                    errors = {'see_other': 'This controller is in SLAVE mode. '
                              'The command must be run in MASTER mode.'
                              '\nNo ip addresses for controller available'}
            else:
                errors = {'unknown_error': 'HttpError %s' % error_returned}
        elif isinstance(e, NotFound):
            if e.obj_type in mi.obj_type_info_dict:
                errors = {'not_found_error' : 'Not Found: %s (%s)' % 
                                              (self.annotated_obj_type_id(e.obj_type,
                                                                          e.name),
                                               e.obj_type)}
            else:
                errors = {'not_found_error' : 'Not Found: %s (%s)' % 
                                              (e.name, e.obj_type)}
        else:
            if self.debug or self.debug_backtrace:
                traceback.print_stack()
            errors = {'unknown_error': "Need error management for error %s" % type(e)}

        return errors

    #
    #
    # --------------------------------------------------------------------------------
    # rest_error_is_not_found
    #  Return True if this specific error was the result of a not-found situation
    #
    @staticmethod
    def rest_error_is_not_found(rest_error_dict):
        if 'not_found_error' in rest_error_dict:
            return True
        return False

    #
    # --------------------------------------------------------------------------------
    # rest_error_dict_to_message
    #   Turn an rest_error_dict returned from rest_error_to_dict
    #   into an error message which can ge printed.  Code assumes multiple errors
    #   won't occur; if a 'field_error' exists, for example, a 'model_error' won't
    #   also be posted in the error
    #
    def rest_error_dict_to_message(self, rest_error_dict):
        if rest_error_dict == None:
            return rest_error_dict
        error_msg = ""
        if 'field_errors' in rest_error_dict:
            for (k, v) in rest_error_dict['field_errors'].items():
                error_msg += "Syntax error: field %s: %s" % (k, v)
            # traceback.print_stack(), to find out why the error occured
        elif 'model_error' in rest_error_dict:
            error_msg += "%s" % rest_error_dict['model_error']
        elif 'not_found_error' in rest_error_dict:
            error_msg += "Error: %s" % rest_error_dict['not_found_error']
        elif 'connection_error' in rest_error_dict:
            error_msg += rest_error_dict['connection_error']
        elif 'error_result_error' in rest_error_dict:
            error_msg += rest_error_dict['error_result_error']
        elif 'moved_error' in rest_error_dict:
            error_msg += rest_error_dict['moved_error']
        elif 'see_other' in rest_error_dict:
            error_msg += rest_error_dict['see_other']
        elif 'unknown_error' in rest_error_dict:
            error_msg += rest_error_dict['unknown_error']
        elif 'description' in rest_error_dict and  \
          rest_error_dict["description"] == 'saved':
            # not an error: { 'description' : 'saved' }
            return None
        elif 'error_type' in rest_error_dict: # http 400 errors
            description = rest_error_dict['description']
            if description.startswith('Error: '):
                description = description[len('Error: '):]
            return '%s (%s)' % (description,
                                rest_error_dict['error_type'])
        else:
            error_msg = "REST API server on controller-node %s " % self.controller
            error_msg += "had %s error:\n" % rest_error_dict['error_type']
            error_msg += rest_error_dict['description']
        return error_msg

    #
    # --------------------------------------------------------------------------------
    #
    # Commands of the CLI. A command "foo" should have two methods:
    #   cp_foo(self, text, state) - completion for this command, return list of options
    #   do_foo(self, line) - execute the command
    #
    # Given a string 'word', not containing any spaces, nor any break
    #  characters associated with python, return the a invocable method
    #  note that '-' are permitted, and converted to '_''s
    #
    # When in the vns or vns-definition mode, the selected functions
    #  to call back have an additional component added to the called
    #  back function.  In the non-vns case, for example, the "show"
    #  command would result in a method called do_show, while in the
    #  vns modes, 'vns_' in inserted between the 'verb' and the noun,
    #  for example, resulting in 'do_vns_show'

    #
    # --------------------------------------------------------------------------------
    # method_from_name
    #
    def method_from_name(self, prefix, name):
        if type(name) != str:
            return None
        if self.in_config_submode("config-vns") and \
           getattr(self, prefix + "vns_" + name.replace("-","_"), None):
            return getattr(self, prefix + "vns_" + name.replace("-","_"))
        return getattr(self, prefix+name.replace("-","_"), None)
        
    #
    # --------------------------------------------------------------------------------
    # command_method_from_name
    #
    def command_method_from_name(self, name):
        return self.method_from_name("do_", name)               # do_XXX methods

    #
    # --------------------------------------------------------------------------------
    # command_show_method_from_name
    #
    def command_show_method_from_name(self, name):
        return self.method_from_name("do_show_", name)          # do_show_XXX methods

    #
    # --------------------------------------------------------------------------------
    # cloud_method_from_name
    #
    def cloud_method_from_name(self, name):
        return self.method_from_name("cloud_", name)            # cloud_XXX methods

    #
    # --------------------------------------------------------------------------------
    # completion_method_from_name
    #
    def completion_method_from_name(self, name):
        return self.method_from_name("cp_", name)               # cp_XXX (completion) methods

    #
    # --------------------------------------------------------------------------------
    # completion_show_method_from_name
    #
    def completion_show_method_from_name(self, name):
        return self.method_from_name("cp_show_", name)          # cp_show_XXX (completion) methods

    #
    # --------------------------------------------------------------------------------
    # unique_key_from_non_unique
    #
    # Primary keys for cassandra for some keys are contenations of
    #  several non-unique keys separated by a character not used for
    #  any other purpose (in this case '|').  The concatenation
    #  of non-unique keys is intended to create a unique key.
    #
    def unique_key_from_non_unique(self, words):
        return "|".join(words)
    
    #
    # --------------------------------------------------------------------------------
    # prefix_search_key
    #  Prefix's of primary keys for keys's built through unique_key_from_non_unique()
    #

    def prefix_search_key(self, words):
        return self.unique_key_from_non_unique(words) + "|"

    #
    # --------------------------------------------------------------------------------
    # implement_connect
    #
    def implement_connect(self, data):
        new_ip = data.get('ip-address')
        if new_ip == None:
            new_ip = data.get('controller-id')
        if not self.IP_ADDR_RE.match(new_ip):
            controller_id = alias_lookup('controller-alias', new_ip)

            if controller_id == None:
                controller_id = new_ip

            try:
                ifs = self.rest_query_objects('controller-interface',
                                              { 'controller' : controller_id } )
                if len(ifs) == 1:
                    new_ip = ifs[0]['ip']
            except:
                return self.error_msg('Can\'t find controller named %s' % new_ip)
                pass

        if 'port' in data:
            new_ip += str(data['port'])
        else:
            new_ip += ":80"
        #
        # request the version, if it fails, then don't allow the switch
        try:
            version_url = 'http://%s/rest/v1/system/version' % new_ip
            data = self.rest_simple_request_to_dict(version_url)
        except Exception, e:
            return self.error_msg('Could not connect to %s' % new_ip)

        self.controller = new_ip
        self.store.set_controller(new_ip)
        self.set_controller_for_prompt()
        while (self.current_mode() != "login"):
            self.pop_mode()
        print "Switching to controller %s" % self.controller

        return self.pp.format_entry(data[0], 'version')

    def cp_exit(self, words, text, completion_char):
        self.print_completion_help("<cr>")

    def do_exit(self, words=None):
        if self.mode_stack[-1]['exit']:
            method = self.mode_stack[-1]['exit']
            method()
        self.pop_mode()

    def cp_logout(self, words, text, completion_char):
        self.print_completion_help("<cr>")

    def do_logout(self, words=None):
        self.run = False

    def cp_end(self, words, text, completion_char):
        self.print_completion_help("<cr>")

    def do_end(self, words=None):
        while self.current_mode().startswith("config"):
            self.pop_mode()


    #
    # --------------------------------------------------------------------------------
    # do_show_tunnel
    #  Command descriptions has no practical support for show commands yet.
    #
    def do_show_tunnel(self, words):
        if len(words) < 2:
            print self.syntax_msg("Usage: show tunnel [ <switch> | all ] active")
            return
        if words[1] != "active":
            return self.error_msg("Unknown request %s" % words[1])

        # active --

        if words[0] != 'all':
            words[0] = convert_alias_to_object_key("switch", words[0])

        try:
            data = self.rest_simple_request_to_dict(
                            'http://%s/rest/v1/tunnel-manager/%s/' %
                             (self.controller, words[0]))
        except:
            return self.error_msg('Could not load tunnel-manager details')

        if 'error' in data and data['error'] != None:
            return self.error_msg('tunnel-manager response: %s' % data['error'])

        entries = []
        for entry in data['tunnMap'].keys():
            item = data['tunnMap'][entry]
            for remote in item['tunnelPorts']:
                remoteIp = "%s.%s.%s.%s" % ( int(remote[3:6]),
                                             int(remote[6:9]),
                                             int(remote[9:12]),
                                             int(remote[12:]))
                entries.append({ 'dpid': entry,
                                 'localTunnelIPAddr' : item['localTunnelIPAddr'],
                                 'tunnelPorts' : remoteIp
                               })

        return self.display_obj_type_rows('tunnel-details', entries)
    

    #
    # --------------------------------------------------------------------------------
    # cp_show_vns_access_list_entry
    #
    def cp_show_vns_access_list_entry(self, words, text, completion_char):
        return self.cp_vns_access_list_entry(words, text)

    #
    # --------------------------------------------------------------------------------
    # do_show_vns_access_list_entry
    #
    def do_show_vns_access_list_entry(self, words):
        with_search_key = "<no_key>"
        if self.vns_name() is None:
            if len(words) > 0:
                search_object = ["vns-access-list-entry", words[0]]
            else:
                search_object = ["vns-access-list-entry"] 
        elif len(words) > 0:
            with_search_key = '-'.join(words)
            words.insert(0, self.get_current_mode_obj())
            search_object = ["vns-access-list-entry", 
                             self.unique_key_from_non_unique(words)]
        else:
            search_object = ["vns-access-list-entry",
                             self.prefix_search_key([self.get_current_mode_obj()])]
        return self.do_show_object(search_object, with_search_key)

    #
    # --------------------------------------------------------------------------------
    # do_vns_no
    #  implement the no command while in the context of vns/vns-definition
    #
    def do_vns_no(self, words):
        if len(words) < 1:
            return "Syntax: no <item> <key> : delete from the named item the specific key"
        else:
            vns_name_to_table_name = { "interfaces"        : "vns-interface",
                                       "interface-rule"    : "vns-interface-rule",
                                       "access-list"       : "vns-access-list",
                                       "access-list-entry" : "vns-access-list-entry",
                                       "access-group"      : "vns-interface-access-list",
                                     }
            if words[0] in vns_name_to_table_name:
                if len(words) < 2:
                    return "Syntax: no %s <item> <key>" % words[0]
                #
                # the item to remove in for access-list-entry is an integer,
                # canonicalize the name before its used to search
                if words[0] == 'access-list-entry':
                    if self.ACL_RE.match(words[1]):
                        words[1] = str(int(words[1]))
                    else:
                        return self.error_msg('%s key %s must be an integer' % 
                                             (words[0], words[1]))

                name = self.unique_key_from_non_unique([self.get_current_mode_obj(), words[1]])
                table = vns_name_to_table_name[words[0]]
                errors = None

                if words[0] == "entry" and not self.in_config_vns_acl_mode():
                    return self.do_no(words) # let do_no() print error messages
                elif words[0] == "access-group" and not self.in_config_vns_if_mode():
                    return self.do_no(words) # let do_no() print error messages

                # access-group/vns-interface-access-list has 'id's with an additional field,
                # the in-out parameter, which is required to be able to delete the entry
                if words[0] == "access-group":
                    if len(words) < 3:
                        return self.syntax_msg('no access-group <acl-name> <in|out>')
                    choices = [x for x in ["in", "out"] if x.startswith(words[2])]
                    if len(choices) != 1:
                        return self.syntax_msg('no access-group <acl-name> <in|out>')
                    name = self.unique_key_from_non_unique([self.get_current_mode_obj(),
                                                            self.vns_name(),
                                                            words[1]])
                    name = name + "|" + choices[0]

                try:
                    self.rest_delete_object(table, name)
                except Exception, e:
                    errors = self.rest_error_to_dict(e, words[0] + " " + words[1])
                    
                if errors:
                    return self.rest_error_dict_to_message(errors)
                #
                # cascade delete?
                if not errors:
                    self.cascade_delete(table, name)

                return None

            return self.do_no(words)

    #
    # --------------------------------------------------------------------------------
    # do_no_tag
    #  Since the name and value must be present, this is currently a special
    #  case.  additionally, the two tables 'tag-mapping' and 'tag' are 
    #  intermingled.  the 'tag' table manages the <namespace><name><value>
    #  tuple, while the tag-mapping add <host> to that relationship  When
    #  the removal of the entry from the tag-mapping table leaves no further
    #  <namespace><name><value>'s for any hosts, then the row from the
    #  'tag' table must be removed
    #
    def implement_no_tag(self, words):
        if not words or len(words) != 2 or words[1].find('=') == -1:
            return  "Syntax: no tag <namespace.name>=<value>"
        else:
            name_and_value = words[1].split("=")
            if len(name_and_value) > 2:
                return "Syntax: no tag <namespace.name>=<value>"

            name_part = name_and_value[0].split('.')
            if len(name_part) == 1:
                namespace = 'default'
                name = name_part[0]
            elif len(name_part) >= 2:
                namespace = '.'.join(name_part[:-1])
                name = name_part[-1]

            value = name_and_value[1]

            item = self.unique_key_from_non_unique([namespace,
                                                    name,
                                                    value,
                                                    self.get_current_mode_obj()])
            #
            # To prevent leaking the unique key value in the 'Not Found'
            # error message, look up the item first, and display a unique
            # error message for this case
            #
            errors = None
            try:
                self.get_object_from_store('tag-mapping', item)
            except Exception, e:
                errors = self.rest_error_to_dict(e, "tag " + item)

            if errors:
                if self.rest_error_is_not_found(errors):
                    return self.error_msg("tag %s.%s=%s not found" %
                                          (namespace, name, value))
                else:
                    return self.rest_error_dict_to_message(errors)
                
            try:
                self.rest_delete_object('tag-mapping', item)
            except Exception, e:
                errors = self.rest_error_to_dict(e, "tag " + item)

            if errors:
                return self.rest_error_dict_to_message(errors)
            #
            # if there are no more items in tag-mapping for the
            # <namespace>|<name>|<value>, then an entry needs to
            # removed from the 'tag' table (for cleanup)
            #
            key = self.unique_key_from_non_unique([namespace,
                                                   name,
                                                   value])
            try:
                tags = self.get_table_from_store('tag-mapping', 'tag', key)
            except Exception, e:
                errors = self.rest_error_to_dict(e, "tag-mapping tag " + key)

            if errors:
                print self.rest_error_dict_to_message(errors)
                return
            if len(tags) == 0:
                try:
                    self.rest_delete_object('tag', key)
                except Exception, e:
                    errors = self.rest_error_to_dict(e, "tag " + item)
                    
                if errors:
                    print self.rest_error_dict_to_message(errors)
                    return
            #
            # cascade delete?

    #
    # --------------------------------------------------------------------------------
    # vns_interface_rule_tags_validate
    #  Provides a warning when the associated tag doesn't exist
    #
    def vns_interface_rule_tags_validate(self, obj_type, field, value):
        for tag_pair in value.split(','):
            if tag_pair.find('=') == -1 or len(tag_pair.split('=')) != 2:
                # field validation won't match the regular expression
                return 
            (tag_name, tag_value) = tag_pair.split('=')
            tag_name_parts = tag_name.split('.')
            if len(tag_name_parts) == 1:
                tag_namespace = 'default'
                tag_name = tag_name_parts[0]
            elif len(tag_name_parts) >= 2:
                tag_namespace = '.'.join(tag_name_parts[:-1])
                tag_name = tag_name_parts[-1]
            else:
                # XXX not reached
                pass

            # Validating using the 'tag' model to determine whether the
            # tag exists depends on having the tag value removed when there's
            # no more references to the entry.  the cli manages the 
            # 'tag'/'tag-mapping' models that way, but other uses of the 
            # rest api may not.
            #
            key = self.unique_key_from_non_unique([tag_namespace, tag_name, tag_value])
            try:
                table = self.get_object_from_store('tag', key)
            except Exception, e:
                errors = self.rest_error_to_dict(e, 'tag')
                # special case for 'not found' error message
                if self.rest_error_is_not_found(errors):
                    self.warning("tag `%s.%s %s' not yet defined" % \
                                 (tag_namespace, tag_name, tag_value))
                else:
                    print self.rest_error_dict_to_message(errors)
        return None

    #
    # --------------------------------------------------------------------------------
    # validate_switch_core_switch
    #  Intended to display a warning message when the value is set to True
    #
    def validate_switch_core_switch(self, obj_type, field, value):
        if value == 'True': # XXX odd that the value needs to be quoted.
            self.warning("enabling core-switch on a switch with "
                         "directly connected hosts will cause the same to "
                         "be unable to connect")

    #
    # --------------------------------------------------------------------------------
    # handle_specific_tag_fields
    #  Called by handle_specific_obj_type to convert fields values from the
    #  rest api into a displayable table
    #
    @staticmethod
    def handle_specific_tag_fields(entries):
        for entry in entries:
            fields = entry['id'].split('|')
            # XXX error if there's not four parts
            entry['namespace'] = fields[0]
            entry['name'] = fields[1]
            entry['value'] = fields[2]

    #
    # --------------------------------------------------------------------------------
    # append_when_missing
    #
    @staticmethod
    def append_when_missing(unique_list, item):
        if not item in unique_list:
            unique_list.append(item)

    #
    # --------------------------------------------------------------------------------
    # show_command_prefix_matches
    #  show command's prefix matches, return True when the command matches
    #  fpr the prefix described, used by get_valid_show_options() during
    #  cp_show() to collect available command choice.
    #
    def show_command_prefix_matches(self, command, prefix):
        # convert any '-'s in the prefix tp "_"'s since func's have _ separators
        prefix = prefix.replace("-", "_")
        if command.startswith("do_show_"+prefix) and not command.startswith("do_show_vns_"):
            return True
        elif command.startswith("do_show_vns_" + prefix):
            if self.in_config_submode("config-vns"):
                if command == 'do_show_vns_access_list' and self.in_config_vns_mode():
                    return True
                return self.vns_debug_show_commands(command)
            return False
        return False

    #
    # --------------------------------------------------------------------------------
    # get_valid_show_options 
    #  used by cp_show to identify completion optinos
    #
    # returns a dictionary with two elements: 'commands', and 'objects'.
    # the 'commands' element is a list of possible commands while
    # the 'objects' element is a list of possible objects (tables/models in the store)
    #
    def get_valid_show_options(self, text):
        ret_hash = {}
        # first get commands
        opts = []
        matching_methods = [x for x in dir(self)
                            if self.show_command_prefix_matches(x, text)]

        if onos == 0:
            netvirt_feature = self.netvirt_feature_enabled()
        else:
            netvirt_feature = False

        for method in matching_methods:
            m = re.search("do_show_(.*)", method)
            n = re.search("do_show_vns_(.*)", method)
            if n and self.in_config_submode('config-vns'):
                self.append_when_missing(opts, n.group(1).replace("_","-"))
            elif m:
                if netvirt_feature or m.group(1) != 'vns':
                    self.append_when_missing(opts, m.group(1).replace("_","-"))
        #
        # remove command cases
        opts = [x for x in opts if x not in ["statistics", "object"]]
        if "access-group" in opts and not self.in_config_vns_if_mode():
            if not self.vns_debug_show_commands('vns-access-group'):
                opts.remove("access-group")
        if "access-list" in opts and not self.in_config_vns_mode():
            if not self.vns_debug_show_commands('vns-access-list'):
                opts.remove("access-list")
        if "interface" in opts and not self.in_config_vns_mode():
            if not self.vns_debug_show_commands('vns-interface'):
                opts.remove("interface")
        if "interface-rule" in opts and not self.in_config_vns_def_mode():
            if not self.vns_debug_show_commands('vns-interface-rule'):
                opts.remove("interface-rule")
        if "firewall" in opts and not self.in_config_controller_interface_mode():
            opts.remove("firewall")
        # synthetic object type based on the vnsconfig submode.
        if "access-list-entry" in opts and not self.in_config_vns_acl_mode():
            if not self.vns_debug_show_commands('vns-access-list-entry'):
                opts.remove("access-list-entry")
        ret_hash["commands"] = opts

        # now get obj_types we can show
        opts = self.all_obj_types_starting_with(text)
        if self.in_config_submode() and "this".startswith(text):
            opts.append("this")
        ret_hash["objects"] = opts
        return ret_hash


    #
    # --------------------------------------------------------------------------------
    # cp_show_object
    #  show <obj_type> (words[0] == obj_type)
    #
    def cp_show_object(self, words, text, completion_char):
        if len(words) == 1:
            return objects_starting_with(words[0], text)
        else:
            self.print_completion_help("<cr>")
    #
    # --------------------------------------------------------------------------------
    # get_attachment_points
    #
    @staticmethod
    def get_attachment_points(host, host_dap_dict):
        items = host_dap_dict.get(host['mac'])
        if not items or len(items) <= 1:
            return items
        #
        # sort by most recent items, if the last-seen field
        # exists for all entries
        #
        for item in items:
            if not 'last-seen' in item or item['last-seen'] == '':
                return items

        ordered = sorted(items,
                         key=lambda i: i['last-seen'],
                         cmp=lambda x,y: cmp(y,x))
        ordered[0]['prime'] = True
        return ordered

    #
    # --------------------------------------------------------------------------------
    # create_attachment_dict
    #
    def create_attachment_dict(self):
        return create_obj_type_dict('host-attachment-point', 'mac')

    #
    # --------------------------------------------------------------------------------
    # get_ip_addresses
    #
    @staticmethod
    def get_ip_addresses(host, host_ip_dict):
        items = host_ip_dict.get(host['mac'])
        if not items or len(items) <= 1:
            return items

        for item in items:
            if not 'last-seen' in item or item['last-seen'] == '':
                return items
        #
        # sort by most recent items, if every row has a 'last-seen' field
        #
        ordered = sorted(items,
                         key=lambda i: i['last-seen'],
                         cmp=lambda x,y: cmp(y,x))
        ordered[0]['prime'] = True
        return ordered

    #
    # --------------------------------------------------------------------------------
    # create_ip_dict
    #  Returns a dictionary with the host id (mac address) as the key,
    #  and a list of associated rows for that host id.
    #
    def create_ip_dict(self):
        return create_obj_type_dict('host-network-address', 'mac')

    #
    # --------------------------------------------------------------------------------
    # show_sort_obj_type
    #  Returns a sorted list of entries based on the sort described by
    #  the obj-dict
    #
    def show_sort_obj_type(self, obj_type, entries):
        sort = mi.obj_type_show_sort(obj_type)
        if not sort:
            return entries
        if sort == 'integer':
            key = mi.pk(obj_type)
            return sorted(entries, key=lambda k: k[key].split('|')[-1],
                                   cmp=lambda x,y: cmp(utif.try_int(x), utif.try_int(y)))
        elif sort == 'tail-integer':
            key = mi.pk(obj_type)
            def comparer(left, right):
                prefix = cmp(left[:-1], right[:-1])
                if prefix != 0:
                    return prefix
                return cmp(utif.try_int(left[-1]), utif.try_int(right[-1]))

            return sorted(entries, key=lambda k: k[key].split('|'), cmp=comparer)
        else:
            return self.error_msg("Unknown sort %s" % sort)

    #
    # --------------------------------------------------------------------------------
    # display_obj_type_rows
    #  Given an obj_type, rows, and whether or not a key was provided to search
    #  with, generate the output table.
    #
    def display_obj_type_rows(self, obj_type, rows, with_key = '<no_key>', detail = "default"):
        #
        # handle spedicific issues with particular tables returned from storage
        # - change vns-id's with "|" into separate columns
        # - the host case does a 'merge' for attachment-points and IPs
        #   (used in 'show host')
        def handle_specific_obj_type(obj_type, entries, field_orderings = 'default'):
            if obj_type == "host":
                # host_tag_dict = create_obj_type_dict('tag-mapping', 'host')
                for host in entries:
                    host['vendor'] = self.vendordb.get_vendor(host['mac'])
                    # host['tag'] = host_tag_dict.get(host['mac'], [])
            if obj_type == "host-config":
                host_dap_dict = self.create_attachment_dict()
                host_ip_dict = self.create_ip_dict()
                host_tag_dict = create_obj_type_dict('tag-mapping', 'mac')
                for host in entries:
                    host['vendor'] = self.vendordb.get_vendor(host['mac'])
                    host['attachment-points'] = self.get_attachment_points(host, host_dap_dict)
                    host['ips'] = self.get_ip_addresses(host, host_ip_dict)
                    host['tag'] = host_tag_dict.get(host['mac'], [])
            if obj_type == 'controller-node':
                for controller_node in entries:
                    domain_name_servers = []
                    domain_name_servers = self.rest_query_objects(
                        'controller-domain-name-server',
                        {'controller': controller_node['id'],
                         'orderby' : 'timestamp'})
                    controller_node['domain-name-servers'] = [domain_name_server['ip']
                        for domain_name_server in domain_name_servers]
                    controller_node['id'] = ' '.join(controller_node['id'].split('|'))
            if obj_type == 'controller-interface':
                for intf in entries:
                    rules = [x['rule'] for x in self.get_firewall_rules(intf['id'])]
                    intf['firewall'] = ', '.join(rules)
                    # del intf['id'] XXX should the id really get displayed?
            tables_with_vns_ids = [ "vns-interface-rule", "vns-interface",
                                    "host-vns-interface", "vns-access-list",
                                    "vns-access-list-entry", "vns-interface-access-list" ]
            if obj_type in tables_with_vns_ids:
                self.vns_table_id_to_vns_column(obj_type, entries)
                if self.in_config_submode("config-vns") and field_orderings == 'default':
                    field_orderings = 'vns-config'
                self.vns_join_host_fields(obj_type, entries)
                self.vns_foreign_key_to_base_name(obj_type, entries)
            if obj_type == 'vns-access-list-entry':
                # display the alternative access-list-text format 
                vns_acl_entries_to_brief(entries)
                # field_orderings = 'acl-brief'
            if obj_type == 'vns-access-list-entry-brief':
                # display the alternative access-list-text format 
                vns_acl_entries_to_brief(entries)
                field_orderings = 'acl-brief'
            #if obj_type == 'tag-mapping':
                #self.handle_specific_tag_fields(entries)

            # XXX may need to revisit to prevent don't leak vns information

            if obj_type in ['dvs-port-group', 'firewall-rule', 'tag-mapping']:
                for entry in entries:
                    mi.split_compound_into_dict(obj_type,
                                                mi.pk(obj_type),
                                                entry)
            #
            # objects where foreigh keys are references to
            # compount key's, needing to be split. 
            # XXX these can be identified by scanning the objects during init
            if obj_type in ['switch-interface-alias',
                           ]:
                # only pick foreign keys which are compound keys
                fks = [x for x in mi.obj_type_foreign_keys(obj_type)
                       if mi.is_compound_key(obj_type,x)]
                for entry in entries:
                    for fk in fks:
                        if fk in entry: # fk may be null-able
                            mi.split_compound_into_dict(obj_type, fk, entry)
                    if 'switch-interface' in entry:
                        si = entry['switch-interface']
 
            #
            if obj_type == 'firewall-rule':
                self.firewall_rule_add_rule_to_entries(entries)
            return field_orderings
     
        field_orderings = handle_specific_obj_type(obj_type, rows, detail)
        #
        # join alias names.  there is a good chance the alias's tables
        #  are small.  since iteration over all the rows is needed,
        #  first identify the alias tables involved, then snap the
        #  complete table into memory, and then decorae with the
        #  specific alias fields.  XXX it would be even better to
        #  get a size of 'rows' vs the 'alias' table, and choose
        #  the more performance path...
        #
        if obj_type in mi.alias_obj_type_xref:
            obj_key = mi.pk(obj_type)
            for alias in mi.alias_obj_type_xref[obj_type]:
                alias_field = mi.alias_obj_type_field(alias)
                if not alias_field:
                    print self.error_msg("internal alias in display_obj_type")
                try:
                    alias_rows = self.get_table_from_store(alias)
                except Exception, e:
                    errors = self.rest_error_to_dict(e, alias)
                    print self.rest_error_dict_to_message(errors)
                    alias_rows = []

                # invert the row once, moving the key to the data.
                alias_key = mi.pk(alias)
                rows_alias = dict([[a[alias_field], a[alias_key]] for a in alias_rows])

                # collect the name of the field to join (fk_name)
                # 
                (fk_obj_type, fk_name) = \
                    mi.foreign_key_references(alias, alias_field)
                # now associate alias's with the row's field:
                for row in rows:
                    if fk_name in row:
                        if row[fk_name] in rows_alias:
                            row[alias] = rows_alias[row[fk_name]]
                    elif fk_obj_type in row:
                        if row[fk_obj_type] in rows_alias:
                            row[alias] = rows_alias[row[fk_obj_type]]
            #
            # this choice is better if the alias's table is large.
            if 0: #for row in rows:
                key = mi.pk(obj_type)
                for alias in mi.alias_obj_type_xref[obj_type]:
                    field = mi.alias_obj_type_field(alias)
                    if not field:
                        print self.error_msg("internal alias in display_obj_type")
                    alias_row = self.get_table_from_store(alias,
                                                          field,
                                                          row[key],
                                                          "exact")
                    if len(alias_row) > 1:
                        print 'Error: multiple aliases for %s' % \
                              alias
                    elif len(alias_row) == 1:
                        row[alias] = alias_row[0][mi.pk(alias)]

        if len(rows) == 0:
            if with_key != '<no_key>':
                return self.error_msg("No %s %s found" % (obj_type, with_key))
            else:
                return self.pp.format_table(rows, obj_type, field_orderings)
        elif len(rows) == 1 and with_key != '<no_key>':
            return self.pp.format_entry(rows[0], obj_type,
                                        debug = self.debug)

        return self.pp.format_table(self.show_sort_obj_type(obj_type, rows),
                                    obj_type,
                                    field_orderings)

    #
    # --------------------------------------------------------------------------------
    # do_show_object
    #  Implements the show command for objects (table/model output of rows)
    #
    def do_show_object(self, words, with_search_key = None):
        obj_type = words[0]

        #
        # The cli replaces some user names with table names
        if obj_type == 'tag':
            obj_type = 'tag-mapping'

        match = "startswith"
        #
        # Allow "this" reference if we are in config-submode, change the
        # match to an exact match to prevent prefix matching
        if obj_type == "this":
            if self.in_config_submode():
                obj_type = self.get_current_mode_obj_type()
                words = [obj_type, "this"]
                match = "exact"
            else:
                return self.error_msg("\"this\" can only be used in configuration"
                                      " submode, such as switch, port, host, etc.")
        #
        # complete table lookup: 'show <table>'
        if len(words) == 1:
            if with_search_key == None:
                with_search_key = "<no_key>"
            errors = None
            try:
                entries = self.get_table_from_store(obj_type)
            except Exception, e:
                errors = self.rest_error_to_dict(e, obj_type)
                
            if errors:
                return self.rest_error_dict_to_message(errors)
            return self.display_obj_type_rows(obj_type, entries, with_search_key)

        # table with key:  "show <table> <key>"
        if len(words) == 2:
            obj = words[1]
            if with_search_key == None:
                with_search_key = obj

            # Allow "this" reference if we are in config-submode
            if obj == "this" and \
              obj_type == self.get_current_mode_obj_type() \
              and self.in_config_submode():
                obj = self.get_current_mode_obj()

            key = mi.pk(obj_type)
            if key:
                obj = convert_alias_to_object_key(obj_type, obj)
                if mi.obj_type_has_model(obj_type):
                    entries = self.get_table_from_store(obj_type, key, obj, match)
                else:
                    # XXX raise internal error?  model doesn't exist.
                    print command._line(), obj_type
                    entries = []
                return self.display_obj_type_rows(obj_type, entries, with_search_key)
            else:
                return self.pp.format_table(self.get_table_from_store(obj_type),
                                            obj_type)
        elif "stats".startswith(words[2]):
            return self.helper_show_object_stats(words)
        else:
            return "Syntax: show <table> <key>:  " \
                    "Unrecognized input: " + " ".join(words[2:])

    #
    # --------------------------------------------------------------------------------
    # helper_show_object_stats
    #
    def helper_show_object_stats(self, words):
        if self.stats_metadata == None:
            self.init_stats_metadata()

        # get object type
        object_type = words[0]

        # The rest stats api differs from the CLI in some of the
        # object names, so this map allows us to fix it
        if object_type in self.stats_restapi_map:
            object_type = self.stats_restapi_map[object_type]

        if object_type not in self.stats_type_metadata:
            return self.error_msg('no statistics available for object type %s' % 
                                  object_type)

        # Get the specific object to operate on
        sobject = words[1];
        
        # the controller-node objects don't currently have any real
        # concept of a unique ID for a controller; for now the stats
        # are always labeled 'localhost' even though that will never
        # appear in the controller-node list
        if ('controller-node'.startswith(object_type)):
            sobject = 'localhost'

        tocheck = []
        # get statistic name
        if len(words) > 3:
            if (words[3] not in self.stats_metadata or 
                self.stats_metadata[words[3]]['target_type'] != object_type):
                return self.error_msg('no statistic %s available for object type %s' % 
                                      (words[3], object_type))
            tocheck.append(words[3])
        else:
            tocheck = [item['name'] 
                       for item in self.stats_type_metadata[object_type]]

        parsed_options = {}
        if (len(words) > 4):
            try:
                parsed_options = \
                    self.parse_optional_parameters(self.stats_optional_params, 
                                                   words[4:])
            except ParamException as e:
                return self.error_msg(e)

        display = 'latest-value'
        timespec = False
        now = int(time.time()*1000)
        query_params = {'start-time': now - 3600000,
                        'end-time': now,
                        'sample-count': 25,
                        'data-format': 'value'}

        if 'start-time' in parsed_options:
            timespec = True
            try:
                query_params['start-time'] = self.parse_date(parsed_options['start-time'])
            except Exception as e:
                return self.error_msg('invalid start time %s: %s' % 
                                      (parsed_options['start-time'], e))

        if 'end-time' in parsed_options:
            timespec = True
            try:
                query_params['end-time'] = self.parse_date(parsed_options['end-time'])
            except Exception as e:
                return self.error_msg('invalid end time %s: %s' % 
                                      (parsed_options['end-time'], e))

        if 'duration' in parsed_options:
            timespec = True
            try:
                query_params['duration'] = parsed_options['duration']
                if 'start-time' in parsed_options:
                    del query_params['end-time']
                else:
                    del query_params['start-time']

            except:
                return self.error_msg('invalid duration %s' % 
                                      parsed_options['duration'])

        if 'display' in parsed_options:
            display = parsed_options['display']

        if timespec and display == 'latest-value':
            display = 'graph'

        if display == 'graph':
            query_params['sample-count'] = self.pp.get_terminal_size()[0]

        for p in ['sample-count', 'limit', 'sample-window', 
                  'sample-interval', 'data-format']:
            if p in parsed_options:
                query_params[p] = parsed_options[p]

        if display == 'latest-value':
            data = {}
            for item in tocheck:
                url = ('http://%s/rest/v1/stats/data/%s/%s/%s/%s/' % 
                       (self.controller, self.cluster, object_type, 
                        sobject, item))
                try:
                    (timestamp, value) = self.rest_simple_request_to_dict(url)
                    data[self.stats_metadata[item]['name']] = "%d" % value
                except:
                    data[self.stats_metadata[item]['name']] = "[Null]"

            return self.pp.format_entry(data, 'stats-%s' % object_type)
        else:
            item = tocheck[0]
            url = ('http://%s/rest/v1/stats/data/%s/%s/%s/%s/?%s' % 
                       (self.controller, self.cluster, object_type, 
                        sobject, item, "&".join(['%s=%s' % (k,v)
                                                 for k,v 
                                                 in query_params.iteritems()])))
            try:
                json_data = self.rest_simple_request_to_dict(url)
            except Exception as e:
                if self.debug_backtrace:
                    print 'FAILED URL', url
                return self.error_msg('could not load stats data: %s' % e)

            if display == 'table':
                data = []
                for (timestamp, value) in json_data:
                    data.append({'timestamp': int(timestamp),
                             'value': value})
                return self.pp.format_table(data, 'stats-%s-%s-%s' % 
                                            (object_type, item, 
                                             query_params['data-format']))
            elif display == 'graph':
                return self.pp.format_time_series_graph(json_data, 
                                                        'stats-%s-%s-%s' % 
                                                        (object_type, item, 
                                                         query_params['data-format']))
    #
    # --------------------------------------------------------------------------------
    # parse_date
    #
    @staticmethod
    def parse_date(text):
        if (text == 'now' or text == 'current'):
            return int(time.time()*1000)

        try:
            return int(text)
        except: 
            pass

        for f, pre in [('%Y-%m-%dT%H:%M:%S', None),
                       ('%Y-%m-%d %H:%M:%S', None),
                       ('%Y-%m-%dT%H:%M:%S%z', None),
                       ('%Y-%m-%d %H:%M:%S%z', None),
                       ('%Y-%m-%d', None),
                       ('%m-%d', '%Y-'),
                       ('%H:%M', '%Y-%m-%dT')]:
            try:
                t = text
                if pre:
                    pref = datetime.datetime.now().strftime(pre)
                    f = pre + f
                    t = pref + t

                thetime = datetime.datetime.strptime(t, f)
                return int(time.mktime(thetime.timetuple())*1000)
            except: 
                pass

        raise ValueError('count not parse %s as a timestamp' % text)


    #
    # --------------------------------------------------------------------------------
    # display_vns_interface
    #  Search dist is a collection of compund key entities
    #
    def display_vns_interface(self, vns_name, search_dict, with_search_key, detail = 'default'):
        obj_type = 'vns-interface'
        obj_key = mi.pk(obj_type)
        try:
            entries = rest_to_model.get_model_from_url(obj_type, search_dict)
            #entries = self.rest_query_objects(obj_type,
                                              #search_dict)
            errors = None
        except Exception, e:
            errors = self.rest_error_to_dict(e, obj_type)
                
        if errors:
            return self.rest_error_dict_to_message(errors)
        vns_rules = create_obj_type_dict('vns-interface-rule',
                                         mi.pk('vns-interface-rule'),
                                         search_dict
                                         )
        #
        # divide up the result into two parts, the first part is
        # the physical interfaces, the second is the mac interfaces...
        phys = []
        macs = []
            
        for entry in entries:
            fields = entry[obj_key].split('|')
            entry['tenant'] = fields[0]
            entry['vns']=fields[1]
            # all these fields must have two parts.
            if len(fields) != 3:
                continue
            
            # choose between switch based rules and mac/ip based rules
            rule = 'default'
            switch = None
            virt = None
            #
            # Each address-space would have a default vns named
            # named <as>-default, except the 'default' adddress-space which
            # has a default vns named just 'default'
            #
            if fields[1] == "default" or fields[1].endswith("-default"):
                virt = 'default'
                if fields[2].find('/') >= 0:
                    virt = fields[2].split('/')[1]
            else:
                if not 'rule' in entry or entry['rule']=='default':
                    if_rule = []
                    virt = True
                    # continue
                else:
                    rule = entry['rule']
                    if_rule = vns_rules[rule][0]
                
                if 'switch' in if_rule:
                    switch = if_rule['switch']
                elif 'mac' in if_rule:
                    virt = if_rule['mac']
                    entry['mac'] = virt
                elif 'ip-subnet' in if_rule:
                    virt = {'ip-address': if_rule['ip-subnet']}
                    if 'ips' in entry:
                        entry['ips'].append(virt)
                    else:
                        entry['ips'] = [virt]
                elif 'tags' in if_rule:
                    virt = if_rule['tags']
                    entry['tags'] = virt
                elif 'vlans' in if_rule:
                    virt = "vlan %s" % if_rule['vlans']
                    entry['vlans'] = virt

            if switch:
                phys.append(entry)
            if virt:
                entry['veth'] = entry[obj_key].split('|')[2]
                macs.append(entry)

        output = ''
        if len(phys):
            self.vns_join_switch_fields(vns_name, phys)
            output += self.display_obj_type_rows('vns-interface-phys', phys, with_search_key, detail)
        if len(macs):
            if len(phys):
                output += '\n'
            self.vns_join_host_fields(obj_type, macs)
            output += self.display_obj_type_rows('vns-interface-macs', macs, with_search_key, detail)

        if output != '':
            return output
        return self.pp.format_table([],'display-vns-interface')

    #
    # --------------------------------------------------------------------------------
    # find_and_display_vns_interfaces
    #
    def find_and_display_vns_interface(self, vns_name, words):
        with_search_key = "<no_key>"
        search_dict = { 'vns' : vns_name }
        if len(words) == 1:
            search_dict['interface'] = words[0]
        elif len(words) > 1:
            return self.error_msg("Additional search keys after interace")

        return self.display_vns_interface(vns_name, search_dict, with_search_key)
        
    #
    # --------------------------------------------------------------------------------
    # do_show_vns_interfaces
    #  This definition is needed to allow the vns-interface table/model to
    #  be displayed in basic config mode.  do_show() searches names of functions
    #  using the prefix of the 'show' argument; without this function,
    #  it find 'do_show_vns_interface_rule' and selects that function to
    #  display results for 'show vns-interface`.
    #
    def do_show_vns_interfaces(self, words):
        with_search_key = "<no_key>"
        local_vns_name = self.vns_name()
        if self.vns_name() is None:
            if len(words) > 0:
                local_vns_name = words[0]
                search_dict = { 'vns' : local_vns_name }
            else:
                # only case where the vns name is included is the output 
                return self.do_show_object(['vns-interface'], with_search_key)
        else:
            search_dict = { 'vns' : local_vns_name }
            if len(words) == 1:
                with_search_key = words
                search_dict['interface'] = words[0]
            elif len(words) > 2:
                return self.error_msg("Additional search keys after interace")

        return self.display_vns_interface(local_vns_name, search_dict, with_search_key)


    #
    # --------------------------------------------------------------------------------
    # display_vns_mac_address_table
    #  Used by 'show vns <n> mac-address-table', and vns mode 'show mac-address-table'
    #
    def display_vns_mac_address_table(self, vns_name, words):
        # note: 'config-vns' matches both vns and vns-definition mode,
        #  while 'config-vns-' matches only vns-definition mode.
        # the id for the host-vns-interface table has the host as the 'prefix',
        # preventing searching based on the prefix.  the vns is not even a foreign
        # key, which means the complete table must be read, then the vns association
        # must be determined, and then matched
        filter = { 'vns' : vns_name } if vns_name != 'all' else {}
        if len(words):
            filter['mac'] = words[0]
        entries = rest_to_model.get_model_from_url('host-vns-interface', filter)
        for entry in entries:
            fields=entry['vns'].split('|')
            entry['tenant']=fields[0]
            entry['vns']=fields[1]
        with_key = '<no_key>'
        if len(words) > 0:
            with_key = words[0]

        #detail = 'vns'          # exclude vns column, vns is named
        detail = 'default'          # exclude vns column, vns is named
        if vns_name == 'all':
            detail = 'default'  # include vns column, vns not named

        # self.vns_join_host_fields('host-vns-interface', entries)
        return self.display_obj_type_rows('host-vns-interface-vns', entries, with_key, 'default')
        
    #
    # --------------------------------------------------------------------------------
    # do_show_vns_mac_address_table
    #  config and vns mode 'show mac-address-table' command
    #
    def do_show_vns_mac_address_table(self, words):
        if words == None or len(words) > 2:
            return self.syntax_msg('show mac-address-table <host>')

        if self.in_config_submode('config-vns'):
            return self.display_vns_mac_address_table(self.vns_name(), words)

        if len(words) > 0:
            return self.do_show_object(['host'] + words, 'with_key')
        return self.do_show_object(['host'])

    #
    # --------------------------------------------------------------------------------
    # do_show_switch_cluster
    #
    def do_show_switch_cluster(self, words):
        data = self.rest_simple_request_to_dict(
                    'http://%s/rest/v1/realtimestatus/network/cluster/' % self.controller)

        formatted_data = []
        for (clusterid, switchids) in data.items():
            row = {}
            row['switches'] = switchids
            row['cluster-id'] = clusterid
            formatted_data.append(row)
        return self.display_obj_type_rows('switch-cluster', formatted_data)
    
    #
    # --------------------------------------------------------------------------------
    # do_show_controller_summary
    #
    def do_show_controller_summary(self, words):
        data = self.rest_simple_request_to_dict(
                    'http://%s/rest/v1/controller/summary' % self.controller)

        # XXX Need a way to sort the data in a way that makes sense
        for (key, value) in data.items():
            yield key + ":  " + str(value) + "\n"
    
    #
    # --------------------------------------------------------------------------------
    # get_statistics_type
    #
    @staticmethod
    def get_statistics_type(stat_type):
        for s in ["flow", "port", "table", "desc", "aggregate", "features", "trace",]:
            if s.startswith(stat_type):
                return s
        return None

    #
    # --------------------------------------------------------------------------------
    # fix_realtime_flows_wildcard_fields
    #
    def fix_realtime_flow_wildcard_fields(self, in_data):
        for l in in_data:
            if 'wildcards' in l:
                wildcards = l['wildcards']
                bit_field_map = {
                    0 : 'inputPort',
                    1 : 'dataLayerVirtualLan',
                    2 : 'dataLayerSource',
                    3 : 'dataLayerDestination',
                    4 : 'dataLayerType',
                    5 : 'networkProtocol',
                    6 : 'transportSource',
                    7 : 'transportDestination',
                    13 : 'networkSource',
                    19 : 'networkDestination',
                    20 : 'dataLayerVirtualLanPriorityCodePoint',
                    21 : 'networkTypeOfService',
                    }
                for (k, v) in bit_field_map.items():
                    if wildcards & (1 << k):
                        l[v] = "*"

    #
    # --------------------------------------------------------------------------------
    # fix_realtime_flows
    #
    def fix_realtime_flows(self, in_data):
        if not in_data:
            return
        # flatten match data
        for l in in_data:
            match_dict = l['match']
            l.update(match_dict)
            del(l['match'])

        self.fix_realtime_flow_wildcard_fields(in_data)
        return in_data

    #
    # --------------------------------------------------------------------------------
    # add_dpid_to_data
    #
    @staticmethod
    def add_dpid_to_data(data):
        if not type(data) is dict: # backward-compatible
            return data 
        formatted_list = []
        for (dpid, rows) in data.items():
            if rows != None:
                for row in rows:
                    row['switch'] = dpid
                    formatted_list.append(row)
        ## TODO - Alex - handle timeouts + sorting
        return formatted_list

    #
    # --------------------------------------------------------------------------------
    # do_show_statistics
    #
    # LOOK! we could get rid of show statistics at this point as it is all under
    # show switch!
    #
    # it's confusing to remap it over here...
    # we could remove show flow-entry realtime too for now
    #
    def do_show_statistics(self, words):
        if len(words) < 1:
            return "Syntax: show statistics < flow | port | table | desc | aggregate | " \
                                              "features | trace > < Switch DPID | Switch alias | all >"
        stat_type = self.get_statistics_type(words[0])
        dpid = None
        if len(words) > 1:
            words[1] = convert_alias_to_object_key("switch", words[1])
            dpid = words[1] # LOOK! Eventually optional so we can show across switches
            if not dpid in objects_starting_with("switch", dpid) and dpid != "all": 
                return self.error_msg("No switch %s found" % dpid)
        if stat_type == "flow":
            data = self.rest_simple_request_to_dict(
                             'http://%s/rest/v1/realtimestats/flow/%s/' % (self.controller,dpid))            
            data = self.add_dpid_to_data(data)            
            data = self.fix_realtime_flows(data)            

            # 
            # it may make sense to move ['details', 'brief'] tp some sort of
            # 'show_object_optional_format_keywords' list
            field_ordering = "default"
            if len(words) == 3:
                choices = [x for x in ["details", "brief"] if x.startswith(words[2])]
                if len(choices) != 1:
                    return self.error_msg("switch flow options are either 'details' or 'brief'")
                else:
                    field_ordering = choices[0]
            table_data = self.pp.format_table(data, "realtime_flow", field_ordering)
            return table_data
        elif stat_type == "trace":
            return self.do_trace(words)
        elif words[0] == "switches":
            data = self.rest_simple_request_to_dict(
                            'http://%s/rest/v1/controller/stats/%s/' % (self.controller, words[0]))
            table_data = self.pp.format_table(data, "controller_"+words[0])
            return table_data
        else:
            data = self.rest_simple_request_to_dict(
                            'http://%s/rest/v1/realtimestats/%s/%s/' % (self.controller, stat_type, dpid))
            if stat_type == "features":
                for dpid in data:
                    data[dpid] = data[dpid]["ports"]
            data = self.add_dpid_to_data(data)
            table_data = self.pp.format_table(data, "realtime_"+stat_type)
            return table_data

    #
    # --------------------------------------------------------------------------------
    # do_show_version
    #
    def do_show_version(self, words):
        # LOOK! this should probably come from the controller, but for now
        # we assume the CLI/controller are from the same build
        version_string = "SDNOS 1.0 - custom version"
        try:
            fh = open("/opt/sdnplatform/release") 
            version_string = fh.readline().rstrip()
            fh.close()
        except:
            pass
        return version_string

    #
    # --------------------------------------------------------------------------------
    # do_date
    #
    @staticmethod
    def do_date(words):
        return time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime())

    #
    # --------------------------------------------------------------------------------
    # cp_show_logging
    #
    def cp_show_logging(self, words, text, completion_char):
        if len(words) == 1:
            return [x for x in ["sdnplatform", "cassandra", "console-access",
                                 "syslog", "authlog", "orchestrationlog",
                                 "all" ] if x.startswith(text)]
        else:
            self.print_completion_help("<cr>")

    #
    # --------------------------------------------------------------------------------
    # generate_subpprocess_output
    #
    def generate_subprocess_output(self, cmd):
        process = subprocess.Popen(cmd, shell=True,
                                   stdout=subprocess.PIPE, 
                                   stderr=subprocess.STDOUT,
                                   bufsize=1)
        while True:
            line = process.stdout.readline()
            if line != None and line != "":
                yield line
            else:
                break

    #
    # --------------------------------------------------------------------------------
    #
    def implement_show_logging(self, words):
        log_files = { "sdnplatform" : "cat /opt/sdnplatform/sdnplatform/log/sdnplatform.log",
                      "cassandra" : "cat /opt/sdnplatform/db/log/system.log",
                      "console-access" : "cat /opt/sdnplatform/con/log/access.log",
                      "syslog" : "cat /var/log/syslog",
                      "authlog" : "cat /var/log/auth.log",
                      "orchestrationlog" : "cat /tmp/networkservice.log",
                      "dmesg" : "dmesg",
                      "all" : ""  # special
                      }
        if len(words) < 1:
            yield "Syntax: show logging < %s > " % " | ".join(log_files.keys())
            return
        for (f, cmd) in log_files.items():
            if (f.startswith(words[0]) or "all".startswith(words[0])) and f != "all":
                yield "*"*80 + "\n"
                yield "output of %s for %s\n" % (cmd, f)
                yield "*"*80 + "\n"
                for item in self.generate_subprocess_output(cmd):
                    yield item

    #
    # --------------------------------------------------------------------------------
    # do_show_tech_support
    #
    def do_show_tech_support(self, words):

        oldd = self.debug
    
        tech_support_table = []

        # Add the user customized command in tech-support-config table
        entries = self.get_table_from_store('tech-support-config')
        for entry in entries:
            # need explicit type casting str() to make command handling work
            tech_support_table.append([str(entry['cmd-type']), str(entry['cmd']), None])

        # Add the list of command configured for the basic support
        for entry in tech_support.get_show_tech_cmd_table():
            tech_support_table.append(entry)

    
        for entry in tech_support_table:
            cmd_type = entry[0]
            cmd = entry[1]
            feature = entry[2]
    
            # If feature is non-null, then check feature is enabled 
            # before executing the command
            if feature != None and self.feature_enabled(feature) == False :
                continue
    
            if cmd_type == 'cli':
                yield "\n\n" + "-"*80 + "\nExecute cli: " + cmd + "\n\n"
                try:
                    for item in self.generate_command_output(self.handle_single_line(cmd)):
                        yield item
                except Exception as e:
                    yield "Failed to execute %s: %s\n" % (cmd, e)
            elif cmd_type == 'shell':
                yield "\n\n" + "-"*80 + "\nExecuting os command: " + cmd + "\n\n"
                try:
                    for item in self.generate_subprocess_output(cmd):
                        yield item
                except Exception as e:
                    yield "Failed to run command %s: %s\n" % (cmd, e)
            else:
                yield "Unknown command type %s: %s\n" % (cmd_type, cmd)
    
        self.debug = oldd



    #
    # --------------------------------------------------------------------------------
    # ell_ess_minus_r
    #  Do "ls -R", returing the list of files underneath "prefix".
    #  The intended external call is 
    #  ell_ess_minus_r(returned_items, "/opt/sdnplatform/...",  ""),
    #  where the path parameter is null to begin the walk.
    #
    #  The returned items won't have the original prefix in the items
    #
    #  XXX: There's no bounding for the recursive descent.
    #
    def ell_ess_minus_r(self, items, prefix, path):
        p = os.path.join(prefix, path)
        if os.path.isdir(p):
            for entry in os.listdir(p):
                new_path = os.path.join(path, entry)
                if os.path.isdir(os.path.join(prefix, new_path)):
                    self.ell_ess_minus_r(items, prefix, new_path)
                else:
                    items.append(os.path.join(path, entry))
        return items
            
    #
    # --------------------------------------------------------------------------------
    # implement_show_config_file
    #  'show config file' displays the local files under self.saved_configs_dirname
    #   currently /opt/sdnplatform/run/saved-configs
    #
    def implement_show_config_file(self, words):
        items = []
        self.ell_ess_minus_r(items, self.saved_configs_dirname, "")

        if len(words) == 1:
            entries = []
            for i in items:
                cf = os.path.join(self.saved_configs_dirname, i)
                t = time.strftime("%Y-%m-%d.%H:%M:%S",
                                  time.localtime(os.path.getmtime(cf)))
                entries.append({'name' : i,
                                'timestamp': t,
                                'length' : str(os.path.getsize(cf)),
                               })
            return self.pp.format_table(entries,'config')
        elif len(words) == 2:
            if words[1] in items:
                src_file = self.path_concat(self.saved_configs_dirname, words[1])
                if src_file == "":
                    return self.error_msg("file %s could not be " 
                                          "interpreted as a valid source" % words[1])
                try:
                    return self.store.get_text_from_url("file://" + src_file)
                except Exception, e:
                    return self.error_msg(words[1] + ":" + str(e))
            else:
                return self.error_msg("%s file unknown" % words[1])
    #
    #
    # --------------------------------------------------------------------------------
    # implement_show_config
    #
    def implement_show_config(self, words):
        name = None
        show_version = "latest"
        # handle sh config [ <name> [ all | <version #> ] ]

        if len(words) == 1:
            if words[0] == "all":
                show_version = "all"
            elif words[0] == "file":
                return self.implement_show_config_file(words)
            elif words[0].startswith('config://'):
                name = words[0][len('config://'):]
            else:
                name = words[0]
        elif len(words) == 2:
            if words[0] == 'file':
                return self.implement_show_config_file(words)
            name = words[0]
            show_version = words[1]
        elif len(words) == 3 and words[1] == "diff":
            return self.diff_two_configs(words[0], words[2])
        elif len(words) == 4 and words[1] == "diff":
            return self.diff_two_versions(words[0], words[2], words[3])

        data = self.store.get_user_data_table(name, show_version)
        if data and len(data) > 1 or name == None:
            return self.pp.format_table(data,'config')
        elif data and len(data) == 1:
            return self.store.get_user_data_file(data[0]['full_name'])[:-1]

    #
    # --------------------------------------------------------------------------------
    # diff_two_versions
    #
    def diff_two_versions(self, name, va, vb):
        va_info = self.store.get_user_data_table(name, va)
        if len(va_info) == 0:
            return self.error_msg("Version %s missing for %s" %  (va, name))
        va_txt = self.store.get_user_data_file(va_info[0]['full_name'])
        vb_info = self.store.get_user_data_table(name, vb)
        if len(vb_info) == 0:
            return self.error_msg("Version %s missing for %s" % (vb, name))
        vb_txt = self.store.get_user_data_file(vb_info[0]['full_name'])
        import tempfile
        fa = tempfile.NamedTemporaryFile(delete=False)
        fa.write(va_txt)
        fa.close()
        fb = tempfile.NamedTemporaryFile(delete=False)
        fb.write(vb_txt)
        fb.close()
        cmd = 'diff %s %s ' % (fa.name, fb.name)
        process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
        (output, stderr) = process.communicate()
        os.unlink(fa.name)
        os.unlink(fb.name)
        return output

    #
    # --------------------------------------------------------------------------------
    # diff_two_configs
    #
    def diff_two_configs(self, config_a, config_b):
        items = self.store.get_user_data_table(config_a, "latest")
        if len(items) == 0:
            if config_a == 'running-config':
                txt_a = run_config.implement_show_running_config([]) + "\n"
            else:
                return self.error_msg("%s config missing" % config_a)
        else:
            txt_a = self.store.get_user_data_file(items[0]['full_name'])

        items = self.store.get_user_data_table(config_b, "latest")
        if len(items) == 0:
            if config_b == 'running-config':
                txt_b = run_config.implement_show_running_config([]) + "\n"
            else:
                return self.error_msg("%s config missing" % config_b)
        else:
            txt_b = self.store.get_user_data_file(items[0]['full_name'])

        import tempfile
        fa = tempfile.NamedTemporaryFile(delete=False)
        fa.write(txt_a)
        fa.close()
        fb = tempfile.NamedTemporaryFile(delete=False)
        fb.write(txt_b)
        fb.close()
        cmd = 'diff %s %s ' % (fa.name, fb.name)
        process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
        (output, stderr) = process.communicate()
        os.unlink(fa.name)
        os.unlink(fb.name)
        return output

    #
    # --------------------------------------------------------------------------
    #

    def get_host_attachment_switch_port (self, query_dict):
        """ 
        Get a host's attachment point if it is not already provided.
        see if the host has an attachment point, use the switch and port
        of the attachment point, if its available
        """
        host = rest_to_model.get_model_from_url('host', query_dict)
        if len(host) == 0:
            print self.error_msg('Can\'t identify host details: %s' % query_dict)
            return (False,None,None)
        attachment_points = host[0]['attachment-points']
        if attachment_points == None or len(attachment_points) == 0:
            print self.error_msg('Can\'t identify attachment point %s' % query_dict)
            return (False,None,None)
        if len(attachment_points) == 1:
            src_sw      = attachment_points[0]['switch']
            src_sw_port = attachment_points[0]['ingress-port']
            return (True, src_sw, src_sw_port)

        interface_dict = create_obj_type_dict('interfaces', 'id')
        show_list = []
        for ap in attachment_points:
            dpid = ap['switch']
            ingress_port = ap['ingress-port']

            # alias for dpid
            switch_name = alias_lookup_with_foreign_key('switch-alias', dpid)
            if not switch_name:
                switch_name = dpid
            # interface name for attachment point
            ap_port_id = dpid + '|' + str(ingress_port)
            if ap_port_id in interface_dict:
                show_list.append("%s/%s" % (switch_name,
                                            interface_port[ap_port_od][0]['portName']))
            else:
                show_list.append("%s/port %s" % (switch_name, ingress_port))
                
        print self.error_msg('src-host %s: multiple attachment points: %s' %
                             (src_mac, ', '.join(show_list)))
        print self.error_msg('rerun, and identify src-switch and interface')
        return (False,None,None)


    #
    # --------------------------------------------------------------------------
    # test packet-in: swap source and destination attributes 
    #
    def test_pkt_in_swap_src_dest_attributes(self, post_data):
        # Remove the source switch and port if needed
        if ("srcSwitchDpid" in post_data):
            post_data.pop("srcSwitchDpid")
        if ("srcSwitchInPort" in post_data):
            post_data.pop("srcSwitchInPort")

        #
        # Get destination host's attachment switch/port information
        #
        (result, src_sw, src_sw_port) = self.get_host_attachment_switch_port(
                                            { 'mac' : post_data["destinationMACAddress"]})
        if not result:
            return
        post_data["srcSwitchDpid"] = src_sw
        post_data["srcSwitchInPort"] = src_sw_port

        # Swap the macs
        temp = post_data["sourceMACAddress"]
        post_data["sourceMACAddress"] = post_data["destinationMACAddress"]
        post_data["destinationMACAddress"] = temp
        # swap the IP addresses if specified
        tempSrc = None
        tempDst = None
        if ("sourceIpAddress" in post_data):
            tempSrc = post_data["sourceIpAddress"]
            post_data.pop("sourceIpAddress")
        if ("destinationIpAddress" in post_data):
            tempDst = post_data["destinationIpAddress"]
            post_data.pop("destinationIpAddress")
        if (tempSrc is not None):
            post_data["destinationIpAddress"] = tempSrc
        if (tempDst is not None):
            post_data["sourceIpAddress"] = tempDst
        # swap the IP ports if specified
        tempSrc = None
        tempDst = None
        if ("ipL4SourcePort" in post_data):
            tempSrc = post_data["ipL4SourcePort"]
            post_data.pop("ipL4SourcePort")
        if ("ipL4DestinationPort" in post_data):
            tempDst = post_data["ipL4DestinationPort"]
            post_data.pop("ipL4DestinationPort")
        if (tempSrc is not None):
            post_data["ipL4DestinationPort"] = tempSrc
        if (tempDst is not None):
            post_data["ipL4SourcePort"] = tempDst

    #
    # --------------------------------------------------------------------------
    # test packet-in: display packet-in processing result for test packet-in
    #
    def test_pkt_in_result_display(self, response):
        out =  "\nResult of packet-in processing\n"
        out += ("------------------------------\n")
        src_vns_name = response['srcVNSName']
        dst_vns_name = response['destVNSName']

        if (response['explanation'] == "Source switch not found"):
            out += response['explanation']
            return out

        out +=  "\nVirtual Routing Processing iterations\n"
        out += ("--------------------------------------\n")
        ep_vrouting = response['expPktVRouting']
        for ep_vr in ep_vrouting:
            srcIface = ep_vr['srcIface']
            dstIface = ep_vr['dstIface']
            action = ep_vr['action']
            out += ("src VNS iface           : %s\n" % srcIface)
            out += ("dst VNS iface           : %s\n" % dstIface)
            out += ("action                  : %s\n" % action)
            if action == 'DROP':
                dropReason = ep_vr['dropReason']
                out += ("drop reason             : %s\n" % dropReason)
            else:
                nextHopIp = ep_vr['nextHopIp']
                out += ("next hop IP             : %s\n" % nextHopIp)
                nextHopGatewayPool = ep_vr['nextHopGatewayPool']
                if (nextHopGatewayPool != None):
                    out += ("next hop Gateway Pool   : %s\n" % nextHopGatewayPool)
            out += "\n"

        if (src_vns_name == None) and (dst_vns_name == None):
            out += "Source and destination hosts are not in the same vns"
            return out

        out += ("Status      : %s\n" % response['status'])
        out += ("Explanation : %s\n" % response['explanation'])

        out +=  "\nResult of Virtual Routing\n"
        out += ("--------------------------\n")
        out += ("Source VNS  : %s\n" % src_vns_name)
        out += ("Dest. VNS   : %s\n" % dst_vns_name)
        out += ("Input ACL:\n")
        out += ("  Input ACL Name    : %s\n" % response['inputAcl']['aclName'])
        out += ("  Input ACL Entry   : %s\n" % response['inputAcl']['aclEntry'])
        out += ("  Input ACL Action  : %s\n" % response['inputAcl']['aclResult'])
        out += ("Output ACL:\n")
        out += ("  Output ACL Name   : %s\n" % response['outputAcl']['aclName'])
        out += ("  Output ACL Entry  : %s\n" % response['outputAcl']['aclEntry'])
        out += ("  Output ACL Action : %s\n" % response['outputAcl']['aclResult'])

        if response['expPktRoute'] == None:
            out += "\n"
            return out

        out += ("Routing Action : %s\n" % response['routingAction'])

        obj_type_show_alias_update('test-pktin-route')
        out += ('\nFlow Path:\n')
        ep_route = response['expPktRoute']
        for ep_cluster in ep_route:
            ep_cluster_path = ep_cluster['path']
            hop = 1
            route_data = []
            for ep_path in ep_cluster_path:
                oneHop = {}
                oneHop['cluster'] = ep_cluster['clusterNum']
                oneHop['hop'] = hop
                hop += 1
                oneHop.update(ep_path)
                route_data.append(oneHop)
            route_data = self.pp.format_table(route_data, 'test-pktin-route')
            out += route_data
            out += "\n"
        return out

    #
    # --------------------------------------------------------------------------------
    # implement_test_packet_in
    #
    def implement_test_packet_in(self, data):
        # Currently only supports <test packet-in> for "explain packet" feature
        self.debug_msg("In do_test(): data=%s" % (data))

        # REST API expects MAC not host aliases
        if not 'src-host' in data:
            print self.error_msg("Missing src-host")
            return
        src_mac = data['src-host']

        if not 'dst-host' in data:
            print self.error_msg("Missing dst-host")
            return
        dst_mac = data['dst-host']

        # Check that src and dest hosts are not the same
        if src_mac == dst_mac:
            print self.error_msg("source and destination hosts can not be same")
            return

        #
        if 'src-switch' in data:
            src_sw      = data['src-switch']
            src_sw_port = data['src-switch-port']
        else:

            #
            # Get host's attachment switch/port information
            #
            (result, src_sw, src_sw_port) = \
                self.get_host_attachment_switch_port({'mac' : src_mac})
            if not result:
                return

        post_data = {
            "sourceMACAddress": src_mac, "destinationMACAddress": dst_mac,
            "srcSwitchDpid"   : src_sw,  "srcSwitchInPort"      : src_sw_port
        }

        if 'vlan' in data:
            post_data["vlanID"] = data['vlan']
        if 'ether-type' in data:
            post_data["etherType"] = data['ether-type']
            if (post_data['etherType'] != "2048"):
                yield(self.error_msg("Supported ethertypes: 2048 (ip)"))
                return
        if 'priority' in data:
            post_data["priorityCode"] = data['priority']
        if 'src-ip-address' in data:
            post_data["sourceIpAddress"] = data['src-ip-address']
        if 'dst-ip-address' in data:
            post_data["destinationIpAddress"] = data['dst-ip-address']
        if 'protocol' in data:
            post_data["ipv4Protocol"] = data['protocol']
        if 'tos' in data:
            #Uncomment the line below once we support tos in the REST API
            #post_data["tos"] = data['tos']
            pass
        if 'src-port' in data:
            post_data["ipL4SourcePort"] = data['src-port']
        if 'dst-port' in data:
            post_data["ipL4DestinationPort"] = data['dst-port']

        self.debug_msg("Post Data = %s" % post_data)

        url = "http://%s/rest/v1/realtimetest/network/explain-packet" % self.controller

        try:
            jresponse = self.store.rest_post_request(url, post_data)
        except Exception, e:
            errors = self.rest_error_to_dict(e, url)
            yield(self.error_msg(self.rest_error_dict_to_message(errors)))
            return

        response = json.loads(jresponse)
        self.debug_msg("Response = %s" % response)


        yield ("Input packet\n")
        yield ("------------\n")
        explPkt = response['explainPktParams']
        switch_alias   = alias_lookup_with_foreign_key("switch-alias", explPkt['srcSwitchDpid'])
        src_host_alias = alias_lookup_with_foreign_key("host-alias", explPkt['sourceMACAddress'])
        dst_host_alias = alias_lookup_with_foreign_key("host-alias", explPkt['destinationMACAddress'])

        if (src_host_alias):
            yield ("Source host        : %s (%s), ip=%s\n" % 
                   (explPkt['sourceMACAddress'], src_host_alias, explPkt['sourceIpAddress']))
        else:
            yield ("Source host        : %s, ip=%s\n" % (explPkt['sourceMACAddress'], explPkt['sourceIpAddress']))

        if (dst_host_alias):
            yield ("Destination host   : %s (%s), ip=%s\n" % 
                    (explPkt['destinationMACAddress'], dst_host_alias, explPkt['destinationIpAddress']))
        else:
            yield "Destination host   : %s, ip=%s\n" % (explPkt['destinationMACAddress'], explPkt['destinationIpAddress'])
        if (explPkt['vlanID'] == '-1'):
            yield "VLAN               : %s (Untagged)\n" % explPkt['vlanID']
        else:
            yield "VLAN               : %s\n" % explPkt['vlanID']        
        yield "802.1Q priority    : %s\n" % explPkt['priorityCode']
        yield "Ether type         : %s\n" % explPkt['etherType']
        if (switch_alias):
            yield "Source switch/port : %s (%s)/%s\n" % (explPkt['srcSwitchDpid'], switch_alias, explPkt['srcSwitchInPort'])
        else:
            yield "Source switch/port : %s/%s\n" % (explPkt['srcSwitchDpid'], explPkt['srcSwitchInPort'])
        yield "Protocol           : %s\n" % explPkt['ipv4Protocol']
        yield "L4 source port     : %s\n" % explPkt['ipL4SourcePort']
        yield "L4 destination port: %s\n" % explPkt['ipL4DestinationPort']                

        yield("\nForward path:")
        yield("=============\n")
        yield(self.test_pkt_in_result_display(response))

        # Now send the reverse test packet
        self.test_pkt_in_swap_src_dest_attributes(post_data)
        try:
            jresponse = self.store.rest_post_request(url, post_data)
        except Exception, e:
            errors = self.rest_error_to_dict(e, url)
            yield(self.error_msg(self.rest_error_dict_to_message(errors)))
            return

        response = json.loads(jresponse)
        self.debug_msg("Response = %s" % response)
        yield("\nReverse path:")
        yield("=============\n")
        yield(self.test_pkt_in_result_display(response))

    #
    # --------------------------------------------------------------------------------
    # 
    def implement_test_path(self, data):

        # compute source
        #
        if 'src-switch' in data:
            src_sw      = data['src-switch']
            src_sw_port = data['src-switch-port']
        elif 'src-host' in data:
            (result, src_sw, src_sw_port) = \
                self.get_host_attachment_switch_port({ 'mac' : data['src-host']})
            if not result:
                return
        elif 'src-ip' in data:
            # look up the ip in the device api
            (result, src_sw, src_sw_port) = \
                self.get_host_attachment_switch_port({ 'ipv4' : data['src-ip']})
            if not result:
                return
        else:
            return self.error_msg('No source attachment point in request')

        # compute dest
        if 'dst-switch' in data:
            dst_sw      = data['dst-switch']
            dst_sw_port = data['dst-switch-port']
        elif 'dst-host' in data:
            (result, dst_sw, dst_sw_port) = \
                self.get_host_attachment_switch_port({ 'mac' : data['dst-host']})
            if not result:
                return
        elif 'dst-ip' in data:
            # look up the ip in the device api
            (result, dst_sw, dst_sw_port) = \
                self.get_host_attachment_switch_port({ 'ipv4' : data['dst-ip']})
            if not result:
                return
        else:
            return self.error_msg('No dest attachment point in request')

        url = "http://%s/rest/v1/realtimetest/network/path" % self.controller
        request = {
                    'src-switch'      : src_sw,
                    'src-switch-port' : src_sw_port,
                    'dst-switch'      : dst_sw,
                    'dst-switch-port' : dst_sw_port,
                  }

        try:
            response = self.store.rest_post_request(url, request)
            self.debug_msg("Response = %s" % response)
            if response != '':
                command.query_result = json.loads(response)
            else:
                command.query_result = None

        except Exception, e:
            errors = self.rest_error_to_dict(e, url)
            return self.error_msg(self.rest_error_dict_to_message(errors))


    #
    # --------------------------------------------------------------------------------
    #
    def cp_help(self, words, text, completion_char):
        """
        Completion for the help command must be done using the collection
        of command descriptions; ie: help uses the command descriptions
        to complete the help commands.
        """
        if completion_char == ord('?'):
            if len(words) > 1:
                command.do_command_completion_help(words[1:], text)
            else:
                print self.help_splash([], text)
            return
        if len(words) == 1:
            items = self.commands_for_current_mode_starting_with(text)
            return utif.add_delim(items, ' ')
        else:   
            return command.do_command_completion(words[1:], text)


    #
    # --------------------------------------------------------------------------------
    # command_short_help
    #  Associate short help strings with known commands
    #  These ought to be associated with the COMMAND_DESCRIPTIONs,
    #  but since not all command use that mechanism yet, provide
    #  these short descriptions here.
    #
    command_short_help = {
        'access-list'    : 'Define access-list',
        'access-group'   : 'Configure access-list to interface association',
        'boot'           : "Configure boot configuration",
        'clock'          : 'Configure timezone or set clock',
        'clear'          : 'Reset counters',
        'connect'        : "Connect to a controller's REST API via ip[:port]",
        'date'           : 'Display current date and time',
        'debug'          : 'Enter various debug modes',
        'echo'           : 'Echo remaining arguments',
        'enable'         : 'Move to enable mode',
        'exit'           : 'Exit current mode',
        'feature'        : 'Enable or disable features',
        'firewall'       : 'Enable controller interfaces acls',
        'help'           : 'Help on commands or topics',
        'history'        : 'Display history of commands',
        'ip'             : 'Configure various controller node ip values',
        'logout'         : 'Exit from cli',
        'logging'        : 'Configure logging/syslog',
        'ntp'            : 'Configure ntp',
        'ping'           : 'Ping request from controller to switch or ip address',
        'show'           : 'Display configuration or settings',
        'test'           : 'Test various behaviors',
        'trace'          : 'Trace various streams',
        'traceroute'     : 'Traceroute from controller to switch or ip address',
        'configure'      : 'Enter configuration mode',
        'reload'         : 'Reboot controller, reload configuration',
        'write'          : 'Write configuraion',
        'no'             : 'Delete or disable configuration parameters',
        'vns-definition' : 'Enter vns-definiton submode, describe membership',
        'vns'            : 'Enter vns submode, manage access lists',
        'copy'           : 'Copy configurations',
        'switchto'       : 'Switch to another vns definition',
        'interface-rule' : 'VNS Membership rule',
        'end'            : 'End all nested configuration modes',
        'interface'      : 'Enter interface submode',
        'watch'          : 'Iterate indicated command displaying results',
    }

    #
    # --------------------------------------------------------------------------------
    # obj_type_short_help
    #
    obj_type_short_help = {
        'controller-node'           : 'Configure specific controller nodes',
        'host'                      : 'Configure host details',
        'statd-config'              : 'Statd Configuration',
        'statdropd-config'          : 'Stat dropd configuration',
        'statdropd-progress-info'   : 'Stat dropd progress configuration',
        'switch'                    : 'Switch Configuration',

        # -- debug only tables
        'vns-access-list'           : 'VNS Access List object',
        'vns-access-list-entry'     : 'VNS Access List Entry object',
        'vns-interface'             : 'VNS Interface object',
        'vns-interface-access-list' : 'VNS Interface Access List object',
        'vns-interface-rule'        : 'VNS Interface Rule object',
        'host-alias'                : 'Host Alias object',
        'port-alias'                : 'Port Alias object',
        'switch-alias'              : 'Switch Alias object',
    }

    #
    # --------------------------------------------------------------------------------
    # help_splash
    #
    def help_splash(self, words, text):
        ret = ""
        if not words:
            if text == "":
                ret += "For help on specific commands type help <topic>\n"

            count = 0
            longest_command = 0
            # this submode commands
            s_ret = ""
            mode = self.current_mode()
            nested_mode_commands = [self.title_of(x) for x in
                                    self.command_nested_dict.get(mode, [])]
            possible_commands = [self.title_of(x) for x in
                                 self.command_dict.get(mode, []) ] + \
                                nested_mode_commands
            available_commands = self.commands_feature_enabled(possible_commands)
            submode_commands = sorted(utif.unique_list_from_list(available_commands))
            if len(submode_commands):
                longest_command = len(max(submode_commands, key=len))
            for i in submode_commands:
                if not i.startswith(text):
                    continue
                count += 1
                short_help = command.get_command_short_help(i)
                if not short_help:
                    short_help = self.command_short_help.get(i, None)
                if short_help:
                    s_ret += "  %s%s%s\n" % (i,
                                          ' ' * (longest_command - len(i) + 1),
                                          short_help)
                else:
                    s_ret += "  %s\n" % i

            # commands
            c_ret = ""
            upper_commands = [x for x in self.commands_for_current_mode_starting_with()
                              if not x in submode_commands]
            commands = sorted(upper_commands)
            if len(commands):
                longest_command = max([len(x) for x in commands] + [longest_command])
            for i in commands:
                if not i.startswith(text):
                    continue
                count += 1
                short_help = command.get_command_short_help(i)
                if not short_help:
                    short_help = self.command_short_help.get(i, None)
                if short_help:
                    c_ret += "  %s%s%s\n" % (i,
                                          ' ' * (longest_command - len(i) + 1),
                                          short_help)
                else:
                    c_ret += "  %s\n" % i
                
            # objects
            o_ret = ""
            if self.in_config_mode():
                obj_types = sorted(self.obj_types_for_config_mode_starting_with())
                if len(obj_types) > 0:
                    for i in obj_types:
                        longest_command = max([len(x) for x in commands] +
                                              [longest_command])
                    for i in obj_types:
                        if i in commands:
                            continue
                        if i.startswith(text):
                            count += 1
                            short_help = self.obj_type_short_help.get(i, None)
                            if short_help:
                                o_ret += "  %s%s%s\n" % (i,
                                            ' ' * (longest_command - len(i) + 1),
                                            short_help)
                            else:
                                o_ret += "  %s\n" % i

            # fields
            f_ret = ""
            if self.in_config_submode():
                # try to get both the fields and the commands to line up
                longest_field = longest_command
                for i in self.fields_for_current_submode_starting_with():
                    if i.startswith(text):
                        longest_field = max(longest_field, len(i))
 
                f_count = 0
                # LOOK! could be getting the help text for each of these...
                for i in sorted(self.fields_for_current_submode_starting_with()):
                    if not i.startswith(text):
                        continue
                    count += 1
                    field_info = mi.obj_type_info_dict[
                                    self.get_current_mode_obj_type()]['fields'].\
                                        get(i, None)
                    if not field_info and self.debug:
                        print 'no field for %s:%s' % (self.get_current_mode_obj_type(), i)
                    if field_info and field_info.get('help_text', None):
                        f_ret += "  %s%s%s\n" % (i,
                                          ' ' * (longest_field - len(i) + 1),
                                          field_info.get('help_text'))
                    else:
                        f_ret += "  %s\n"% i

            if (text == "" or count > 1) and s_ret != "":
                ret += "Commands:\n"
                ret += s_ret

            if (text == "" or count > 1) and c_ret != "":
                ret += "All Available commands:\n"
                ret += c_ret

            if (text == "" or count > 1) and o_ret != "":
                ret += "\nAvailable config submodes:\n"
                ret += o_ret
            
            if (text == "" or count > 1) and f_ret != "":
                ret += "\nAvailable fields for %s:\n" % self.get_current_mode_obj_type() 
                ret += f_ret
        elif words[0] in ["show", "help", "copy", "watch" ]:
            method = self.command_method_from_name(words[0])
            if method:
                ret = method(None)
            else:
                #try:
                    #ret = command.get_command_syntax_help(words, 'Command syntax:')
                #except:
                    #if self.debug or self.debug_backtrace:
                        #traceback.print_exc()
                    #ret = "No help available for command %s" % words[0]

                try:
                    ret = command.get_command_documentation(words)
                except:
                    if self.debug or self.debug_backtrace:
                        traceback.print_exc()
                    ret = "No help available for command %s" % words[0]
        else:
            #try:
                #ret = command.get_command_syntax_help(words, 'Command syntax:')
            #except:
                #if self.debug or self.debug_backtrace:
                    #traceback.print_exc()
                #ret = "No help available for command %s" % words[0]
            try:
                ret = command.get_command_documentation(words)
            except:
                if self.debug or self.debug_backtrace:
                    traceback.print_exc()
                ret = "No help available for command %s" % words[0]
        return ret

    #
    # --------------------------------------------------------------------------------
    # do_help
    #
    def do_help(self, words):
        return self.help_splash(words, "")
        
    #
    # --------------------------------------------------------------------------------
    # do_lint
    #
    def do_lint(self, words):
        return command.lint_command(words)


    #
    # --------------------------------------------------------------------------------
    # cp_history
    #
    def cp_history(self, words, text, completion_char):
        if len(words) == 1:
            ret_val = "  <num>      - to display a specific number of commands (default:all)\n"
            ret_val += "  <cr>\n"
            self.print_completion_help(ret_val)
        else:
            self.print_completion_help("<cr>")

    #
    # --------------------------------------------------------------------------------
    # do_history
    #
    def do_history(self, words = None):
        ret_val = ""
        how_many = num_commands = readline.get_current_history_length()
        if words:
            how_many = words[0]
        for i in range(num_commands-int(how_many) + 1, num_commands):
            yield "%s: %s\n" % (i, readline.get_history_item(i))
        return


    debug_cmd_options = ["python", "bash", "cassandra-cli", "netconfig", "tcpdump",
                         "cli", "cli-backtrace", "cli-batch", "cli-interactive"]

    #
    # --------------------------------------------------------------------------------
    # do_debug
    #
    def implement_debug(self, words):
        if len(words) < 1 or len([x for x in self.debug_cmd_options if x.startswith(words[0])]) < 1:
            return "Syntax: debug < %s >" % " | ".join(self.debug_cmd_options)
        def shell(args):
            subprocess.call(["env", "SHELL=/bin/bash", "/bin/bash"] + list(args), cwd=os.environ.get("HOME"))
            print
        print "\n***** Warning: this is a debug command - use caution! *****"
        if "python".startswith(words[0]):
            print '***** Type "exit()" or Ctrl-D to return to the SDNOS CLI *****\n'
            shell(["-l", "-c", "python"])
        elif "bash".startswith(words[0]):
            print '***** Type "exit" or Ctrl-D to return to the SDNOS CLI *****\n'
            shell(["-l", "-i"])
        elif "cassandra-cli".startswith(words[0]):
            print '***** Type "exit" or Ctrl-D to return to the SDNOS CLI *****\n'
            shell(["-l", "-c", "/opt/sdnplatform/db/bin/cassandra-cli --host localhost"])
        elif "netconfig".startswith(words[0]):
            if not re.match("/dev/ttyS?[\d]+$", os.ttyname(0)):
                print '***** You seem to be connected via SSH or another remote protocol;'
                print '***** reconfiguring the network interface may disrupt the connection!'
            print '\n(Press Control-C now to leave the network configuration unchanged)\n'
            subprocess.call(["sudo", "env", "SHELL=/bin/bash", "/opt/sdnplatform/sys/bin/bscnetconfig", "eth0"], cwd=os.environ.get("HOME"))
        elif "tcpdump".startswith(words[0]):
            print '***** Type Ctrl-C to return to the SDNOS CLI *****\n'
            try:
                shell(["-l", "-c", "sudo /opt/openflow/sbin/tcpdump " + " ".join(words[1:])])
            except:
                pass # really, we need to ignore this unconditionally!
            time.sleep(0.2)
        elif "cli".startswith(words[0]):
            if self.debug:
                self.debug = False
                print "debug disabled"
            else:
                self.debug = True
                print "debug enabled"
        elif "cli-backtrace".startswith(words[0]):
            # This feature is separated from the cli debug mode so that backtraces
            # can be collected during cli qa
            self.debug_backtrace = True
            print '***** Enabled cli debug backtrace *****'
        elif "cli-batch".startswith(words[0]):
            self.batch = True
            print '***** Enabled cli batch mode *****'
        elif "cli-interactive".startswith(words[0]):
            self.batch = False
            print '***** Disabled cli batch mode *****'
        else:
            return self.error_msg("invoking debug")
    #
    # --------------------------------------------------------------------------------
    # do_echo
    #
    def do_echo(self, words):
        print " ".join(words)

    #
    # --------------------------------------------------------------------------------
    # cp_trace
    #
    trace_optional_params = {
        'screen': {'type': 'flag'},
#        'port': {'type': 'string',
#                     'syntax_help': "Enter <switch dpid> <physical port#>, where the packets traces are spanned."},
        'file': {'type': 'string',
                     'syntax_help': "Enter <filename> where the packets traces are captured."},
        }

    trace_cmds = ["detail", "oneline", "vns", "in", "out", "both", 
                      "echo_reply",  "echo_request", "features_rep", "flow_mod", "flow_removed", "get_config_rep", "hello", 
                      "packet_in", "packet_out", "port_status", "set_config", "stats_reply", "stats_reques"]

    def cp_trace(self, words, text, completion_char):
        vns_cache = objects_starting_with('vns-definition')
        if len(words) == 1:
            return [x for x in self.trace_cmds if x.startswith(text)]
        elif len(words) == 2 and words[1].lower().startswith("vns"):
            return vns_cache
        elif len(words) == 2 and words[1].lower().startswith("output"):
            return self.complete_optional_parameters(self.trace_optional_params,
                                                         words[len(words):], text)
        elif (len(words) == 3 and 
             words[1].lower().startswith("vns") and
             words[2].lower() in vns_cache):
            return [x for x in ["in", "out", "both", "output"] if x.startswith(text)] 
        elif (len(words) == 4 and 
             words[1].lower().startswith("vns") and
             words[2].lower() in objects_starting_with('vns-definition') and
             words[3].lower() in ["in", "out", "both"]):
            return [x for x in ["output"] if x.startswith(text)] 
        elif len(words) == 2 and words[1].lower()in ["in", "out", "both"]:
            return [x for x in ["output"] if x.startswith(text)] 
        elif (len(words) > 2 and 
             (words[1].lower().startswith("vns") or
              words[1].lower().startswith("output") or
              words[2].lower().startswith("output"))) :
            offset = len(words)
            if words[len(words)-1].lower() == 'screen':
                self.print_completion_help("<cr>")
                return []
            elif words[len(words)-1].lower() in ['file']:
                offset = len(words) - 1
            return self.complete_optional_parameters(self.trace_optional_params, words[offset:], text)

        self.print_completion_help("<cr>")

    #
    # --------------------------------------------------------------------------------
    # do_trace
    #
    def do_trace(self, *args):
        dpid = None
        if len(args) > 0:
            args = args[0]  # first element is the array of 'real' args
        if len(args) > 1 and args[0].lower() in ['vns', 'in', 'out', 'both', 'output']:
            try :
                return self.do_sdnplatform_trace(args)
            except KeyboardInterrupt, e:
                return

        if len(args) > 1 and args[0].lower() == 'trace':
            dpid = args[1]
            args = args[2:] # And in this case, args are after the first 2 parameters
        return self.do_tcpdump_trace(dpid, args)

    def do_sdnplatform_trace(self, args):
        vns = None
        direction = 'both'
        output = 'screen'
        dpid = None
        port = None
        file_name = None
        sessionId = None
        error = 'Error: Invalid command syntax.\n' + \
                'trace [vns <vnsId>] [in|out|both] output [screen]'
#                'trace [vns <vnsId>] [in|out|both] output [screen|port <dpid> <physical port>|file <filename>]'

        if args[0].lower() == 'vns':
            if len(args) > 1:
                vns = args[1]
                args = args[2:]
            else:
                return error

        while args:
            if args[0].lower() == 'output':
                args = args[1:]
                continue
            if args[0].lower() in ['in', 'out', 'both']:
                direction = args[0].lower() 
                args = args[1:]
                continue
            if args[0].lower() == 'screen':
                output = 'screen'
                break
            if args[0].lower() == 'port':
                output = 'port'
                if len(args) > 2:
                    dpid = args[1]
                    port = args[2:]
                    break
                else:
                    return error
            if args[0].lower() == 'file':
                output = 'file'
                if len(args) > 1:
                    file_name = args[1]
                    break
                else:
                    return error

        filter_request = {FT_DIRECTION:direction, FT_OUTPUT:output, FT_PERIOD:FT_PERIOD_DEFAULT}
        if vns :
            filter_request[FT_VNS] = vns
        if dpid and port :
            filter_request[FT_PORT] = {FT_PORT_DPID:dpid, FT_PORT_PORT:port}


        post_data = json.dumps(filter_request)

        while 1:
            response_text = None
            sessionId = None
            url = 'http://%s/rest/v1/packettrace/' % cli.controller
            request = urllib2.Request(url, post_data, {'Content-Type':'application/json'})
            try:
                response = urllib2.urlopen(request)
                response_text = response.read()
                response_text = json.loads(response_text)
            except Exception, e:
                return "Error: failed to get a response for a trace request. %s" % e

            if response_text and SESSIONID in response_text:
                sessionId = response_text[SESSIONID]
            else :
                return "Error: failed to get a trace session. %s" % response_text

            # Span to a physical port
            # No data is shown on cli. ^C to stop the trace
            if output.lower() == 'port':
                while 1:
                    try :
                        time.sleep(1000)
                    except KeyboardInterrupt, e:
                        self.terminateTrace(sessionId)
                        return

            lpurl = None

            if sessionId:
                lpurl = 'http://%s/poll/packets/%s' % (cli.controller, sessionId)
            else:
                return "Error: failed to start a trace session. %s" % response_text

            FILE = None
            if file_name:
                FILE = open(file_name, "w")

            flagTimeout = False
            while 1:
                try:
                    response_text = urllib2.urlopen(lpurl).read()
                    data = json.loads(response_text)
                    if output.lower() == "screen":
                        flagTimeout = self.dumpPktToScreen(data)
                    elif output.lower() == 'file' and FILE != None:
                        self.dumpPktToFile(FILE, data)
                except KeyboardInterrupt, e:
                    self. terminateTrace(sessionId)
                    return
                except Exception, e:
                    return "Error: failed to start a trace session. %s" % e

                if flagTimeout:
                    continueString = raw_input("Do you want to continue tracing? [y/n]:  ")
                    if 'y' in continueString.lower():
                        break
                    else:
                        return


    @staticmethod
    def dumpPktToScreen(data):
        for entry in data:
            if FT_TIMEOUT in entry:
                return True
            else:
                print entry
        return False

    @staticmethod
    def dumpPktToFile(FILE, data):
        FILE.writelines(data)

    @staticmethod
    def terminateTrace(sid):
        post_data = json.dumps({SESSIONID:sid, FT_PERIOD:-1})
        url = 'http://%s/rest/v1/packettrace/' % cli.controller
        request = urllib2.Request(url, post_data, {'Content-Type':'application/json'})
        try:
            response = urllib2.urlopen(request)
            response_text = response.read()
        except Exception, e:
            # Sdnplatform may not be running, but we don't want that to be a fatal
            # error, so we just ignore the exception in that case.
            pass

    def do_tcpdump_trace(self, dpid, args):
        ret = ''
        bsc_port = '6633' # LOOK: listen addr/port are wrong in the controller-node, so hard code 6633 for now
        trace_cmd = 'sudo /opt/sdnplatform/cli/bin/trace --filter \'%s\' %s'
        trace_rule = '((tcp) and (port %s))' % (bsc_port,)
        single_session = False

        trace_args = '--alias'
        if 'detail' in args:
            trace_args += ' --detail'
            args.remove('detail')
        if 'oneline' in args:
            trace_args += ' --oneline'
            args.remove('oneline')
        if 'single_session' in args:
            single_session = True
            args.remove('single_session')

        if dpid:
            query_dict = { 'dpid' : dpid }
            row = rest_to_model.get_model_from_url('switches', query_dict)
            if len(row) >= 1:
                if not 'ip-address' in row[0] or row[0].get('ip-address') == '':
                    return self.error_msg("switch %s currently not connected " % dpid)
            addr = row[0]['ip-address']
            port = row[0]['tcp-port']
            if single_session:
                trace_rule = '((tcp) and (port %s) and (host %s) and (port %s))' % (bsc_port, addr, port)
            else:
                trace_rule = '((tcp) and (port %s) and (host %s))' % (bsc_port, addr)
        if len(args) > 0:
            trace_args += (' ' + ' '.join(args))
        try:
            # print args, dpid, trace_cmd % (trace_rule, trace_args)
            process = subprocess.Popen(trace_cmd % (trace_rule, trace_args), shell=True)
            status = os.waitpid(process.pid, 0)[1]
            if status != 0:
                ret = 'Errno: %d' % (status, )
        except:
            pass # really, we need to ignore this unconditionally!

        time.sleep(0.2)
        return ret

    
    #
    # --------------------------------------------------------------------------------
    # get_auth_token_file_path
    #
    @staticmethod
    def get_auth_token_file_path():
        auth_token_path = os.environ.get('BSC_AUTH_TOKEN_PATH')
        if auth_token_path is None:
            auth_token_path = '/opt/sdnplatform'
        auth_token_path += '/auth_token'
        return auth_token_path
    
    #
    # --------------------------------------------------------------------------------
    # play_config_lines
    #
    def play_config_lines(self, src_text):
        """
        The complete collection of lines to replay are in src_text.
        In the future, this would provide for a way to first identify
        what needs to be removed, then apply what needs to be added.

        Some smart diffing from the exiting running-config would
        be needed to support that.   The stanza groups would need to
        be collected, the diff'd
        """
        print "Updating running-config ..."

        num_lines_played = 0
        # scan the lines looking for the version number.
        #
        version = None
        for line in src_text.splitlines():
            m = re.match("(\s*)(\w+)\s*", line) # only match non-blank lines
            if m:
                if m.group(0).startswith('version '):
                    line_parts = line.split()
                    if line_parts > 1:
                        version = line_parts[1]
                        break

        # construct the command to run.
        command = ['env']
        if version:
            command.append('CLI_COMMAND_VERSION=%s' % version)
        command.append('CLI_STARTING_MODE=config')
        command.append('CLI_SUPPRESS_WARNING=True')

        if os.path.exists('/opt/sdnplatform/cli/bin/cli'):
            # controller VM
            command.append('/opt/sdnplatform/cli/bin/cli')
            command.append('--init')
        else:
            # developer setup
            base = os.path.dirname(__file__)
            command.append(os.path.join(base, 'cli.py'))
            command.append('--init')

        # create a subprocess for the configuration, then push
        # each of the lines into that subprocess.
        p = subprocess.Popen(command,
                             stdin=subprocess.PIPE, 
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT,
                             bufsize=1)
        postprocesslines=[]
        for line in src_text.splitlines(1):
            m = re.match("(\s*)(\w+)\s*", line) # only match non-blank lines
            if m:
                if 'tenant' or 'router' in line:  #special handling for routing rule commands VNS-226
                    postprocesslines.append(line)
                p.stdin.write(line)
                num_lines_played += 1
        for line in postprocesslines:
            p.stdin.write(line)
            num_lines_played += 1
        p.stdin.close()
        output = p.stdout.read()
        if output and (self.debug or self.debug_backtrace or self.description):  
            print output
        p.stdout.close()
        return "Num lines applied: %s\n" % num_lines_played

    #
    # --------------------------------------------------------------------------------
    # path_concat
    #  Concatenate a suffix path to a prefix, making the guarantee that the
    #  suffix will always be "under" the prefix. the suffix is normalized,
    #  then any prefix up-dirs ("..") are removed.
    #
    def path_concat(self, prefix, path):
        suffix = posixpath.normpath(path.lstrip('/').rstrip('/'))
        (head, tail) = os.path.split(suffix)
        tails = [tail]
        while head:
            (head, tail) = os.path.split(head)
            tails.insert(0, tail)
        drop = ''
        while tails[0] == '..':
            drop = os.path.join(drop, tails.pop(0))
        if drop != '':
            self.note("Ignoring %s prefix" % drop)
        for t in tails:
            prefix = os.path.join(prefix, t)
        return prefix

    #
    # --------------------------------------------------------------------------------
    # implement_copy
    #  startup-config and update-config are simply abbreviations for 
    #  config://startup-config and config://update_config
    #
    def implement_copy(self, words):
        if not words or len(words) > 3:
            print "Syntax: copy <src> <dst>"
            print "where <src> and <dst> can be"
            print "  running-config startup-config update-config"
            print "  config://<name-of-config-in-db> - A-Za-z0-9_-.@ "
            print "  <url> - starting with either tftp://, ftp://, http:// or file://"
            return
        if len(words) == 1:
            src = words[0]
            dst = "terminal"
        elif len(words) == 2:
            (src, dst) = (words[0], words[1])

        # Complete as required.
        # NOTE: No completion for upgrade-config as only our scripts should be using it
        if "running-config".startswith(src):
            src = "running-config"
        elif "startup-config".startswith(src):
            src = "startup-config"
        if "running-config".startswith(dst):
            dst = "running-config"
        elif "startup-config".startswith(dst):
            dst = "startup-config"
        elif "terminal".startswith(dst):
            dst = "terminal"

        if src == dst:
            print "src and dst for copy command cannot be equal"
            return

        # get from the source first
        src_text = ""

        # map any abbreviations
        abbreviations = {'startup-config': 'config://startup-config',
                         'upgrade-config': 'config://upgrade-config'
                        }
        src = abbreviations.get(src, src)
        data = None

        if src == "running-config": # get running
            src_text = run_config.implement_show_running_config([]) + "\n"
        elif src.startswith("config://"): # get local file
            m = re.search(self.local_name_pattern, src)
            if m:
                data = self.store.get_user_data_table(m.group(1), "latest")
                if data and len(data) > 0:
                    src_text = self.store.get_user_data_file(data[0]['full_name'])
            else:
                print self.error_msg("src name does not match %s" % self.local_name_pattern)
                return
        elif src.startswith("ftp") or src.startswith("http"): # get URL
            src_text = self.store.get_text_from_url(src)
        elif src.startswith("file://"):
            #src_file = self.saved_configs_dirname + posixpath.normpath(src[7:]).lstrip('/').rstrip('/')
            src_file = self.path_concat(self.saved_configs_dirname, src[7:])
            if src_file == "":
                return self.error_msg("src %s could not be " 
                                      "interpreted as a valid source for a file" % src)
            try:
                src_text = self.store.get_text_from_url("file://" + src_file)
            except Exception, e:
                return self.error_msg(src + ":" + str(e))
        else:
            return self.error_msg("Unknown configuration")

        message = ""
        if len(words) > 2:
            message = " ".join(words[2:]).strip('"')

        #
        # map any abbreviations
        dst = abbreviations.get(dst, dst)

        # now copy to dest
        if dst == "running-config":
            return self.play_config_lines(src_text)
        elif dst == "terminal":
            return src_text # returning src_text here allow '|' to work
        elif dst.startswith("config://"):
            m = re.search(self.local_name_pattern, dst)
            if m:
                store_result = self.store.set_user_data_file(m.group(1), src_text)
                if store_result:
                    result = json.loads(store_result)
                else:
                    return self.error_msg("rest store result not json format")
                if 'status' in result and result['status'] == 'success':
                    return None
                elif 'message' not in result:
                    return self.error_msg("rest store result doesn't contain error message")
                else:
                    return self.error_msg(result['message'])
            else:
                return self.error_msg("dst name does not match %s" % self.local_name_pattern)
        elif dst.startswith("ftp") or dst.startswith("http"):
            self.store.copy_text_to_url(dst, src_text, message)
        elif dst.startswith("file://"):
            dst_file = self.path_concat(self.saved_configs_dirname, dst[7:])
            dst_dir = '/'.join(dst_file.split('/')[:-1])
            if not os.path.exists(dst_dir):
                try:
                    os.makedirs(dst_dir)
                except Exception as e:
                    return self.error_msg("in creating destination directory: %s [%s]"
                                          % (str(e), dst_dir))
            if not os.path.isdir(dst_dir):
                return self.error_msg("destination directory is not a "
                                      "valid directory: %s" % dst_dir)
            with open(dst_file, 'w') as f:
                try:
                    f.write(src_text)
                except Exception as e:
                    return self.error_msg("in saving config file: %s [%s]" %
                                          (str(e), dst_file))
        elif dst == 'trash':
            if data:
                result = self.store.delete_user_data_file(data[0]['full_name'])
                if 'status' in result and result['status'] == 'success':
                    return None
                elif 'message' not in result:
                    return self.error_msg("rest store result doesn't contain error message")
                else:
                    return self.error_msg(result['message'])
        else:
            print self.error_msg("source file retrieved,"
                                 "but could not copy to destination %s" % dst)
        return

    #
    # --------------------------------------------------------------------------------
    # cp_conf_object_type
    #   Completion function for a named object, returns names of
    #   available obj_types
    #
    def cp_conf_object_type(self, words, text):
        if words[0] in mi.obj_types and len(words) == 1:
            return utif.add_delim(objects_starting_with(words[0], text), ' ')
        self.print_completion_help("<cr>")
        return []

    #
    # --------------------------------------------------------------------------------
    # cp_conf_field
    #  Handle if we've got a bunch of fields being concatenated,
    #  e.g., priority 42 src-port 80
    #
    def cp_conf_field(self, obj_type, words, text):
        if len(words) % 2 == 1: 
            latest_field_name = words[-1]
                    
            field_info = mi.obj_type_info_dict[obj_type]['fields'].get(latest_field_name, None)
            # if there was no shallow match of text, do deep match of xrefs if any
            if field_info is None:
                if obj_type in mi.alias_obj_type_xref:
                    if latest_field_name in mi.alias_obj_type_xref[obj_type]:
                        field_info = mi.obj_type_info_dict[latest_field_name]['fields']['id']

            if field_info:
                completion_text = "< %s >: " % field_info['verbose-name']
                completion_text += field_info.get('help_text', "")
                self.print_completion_help(completion_text)


            # return choices based on the types
            if mi.is_field_boolean(obj_type, latest_field_name):
                return utif.add_delib([x for x in ["True", "False"] if x.startswith(text)],
                                      ' ')

            # Use the 'Values:' prefix in the help_text as a way
            # of enumerating the different choices
            if field_info.get('help_text', "").startswith('Values:'):
                values = field_info.get('help_text').replace("Values:", "")
                return utif.add_delim([x for x in values.replace(" ","").split(',')
                                      if x.startswith(text)], ' ')

            #
            # special cases:
            if obj_type == 'vns-interface-rule' and latest_field_name == 'mac':
                return utif.add_delim(objects_starting_with('host', text), ' ')
            elif obj_type == 'vns-interface-rule' and latest_field_name == 'switch':
                return utif.add_delim(objects_starting_with('switch', text), ' ')
        else:
            # we've got an even number of field-value pairs, so just give the list
            # of fields for this obj_type
            return utif.add_fields(
                    self.fields_for_current_submode_starting_with(text),
                    ' ')

    #
    # --------------------------------------------------------------------------------
    # vns methods.
    #

    #
    # --------------------------------------------------------------------------------
    # vns_obj_type
    #  return True for an obj_type associated with vns, intended to identify
    #  tables which are or aren't available in debug mode 
    #
    @staticmethod
    def vns_obj_type(obj_type):
        if obj_type in [ 'vns-interface', 'vns-access-list-entry', 'vns-access-list',
                         'vns-interface-access-list', 'vns-interface-rule',
                         'vns-access-group', 'vns-interfaces', 'host-vns-interface']:
            return True
        return False

    #
    # --------------------------------------------------------------------------------
    # vns_debug_obj_type
    #  return True if the obj_type is available in the non-debug mode
    #
    def vns_debug_obj_type(self, obj_type):
        if self.debug:
            return True
        if self.in_config_submode("config-vns-") and obj_type == 'vns-access-list-entry':
            return False
        return not self.vns_obj_type(obj_type)

    #
    # --------------------------------------------------------------------------------
    # vns_debug_show_commands
    #  return True if the show command vns option is availabe in the current debug mode
    #
    def vns_debug_show_commands(self, show_command):
        if self.debug:
            return True
        if self.in_config_submode() and show_command == 'do_show_vns_interface_rule':
            return True
        if self.in_config_vns_if_mode() and show_command == 'do_show_vns_access_group':
            return True
        if show_command == 'do_show_vns':
            return True
        return not self.vns_obj_type(show_command.replace('_', '-').replace('do-show-', '', 1))

    #
    # --------------------------------------------------------------------------------
    # vns_find_name
    #  Return True when found, False otherwise
    #
    def vns_find_name(self, name):
        try:
            self.get_object_from_store("vns-definition", name)
            return True
        except Exception, e:
            pass
        return False

    #
    # --------------------------------------------------------------------------------
    # vns_find_and_set_name
    #  Return True when the name is known, as a side effect, set self.vns_name
    #  Invalid names are managed by the model, see VnsNameValidator
    #
    def vns_find_and_set_name(self, words):
        if len(words) == 0:
            print self.error_msg("vns <name> required")
            return False
        elif len(words) > 1:
            print self.error_msg("Additional text after vns name ignored")
        name = words[0]
        if self.vns_find_name(name):
            return True
        return False
        
    #
    # --------------------------------------------------------------------------------
    # vns_find_and_set_existing_name
    #  Return True when the name is known, as a side effect, set self.vns_name
    #  And display an error message concerning the failure.
    #
    def vns_find_and_set_existing_name(self, words):
        if self.vns_find_and_set_name(words):
            return True
        if len(words) > 0:
            print self.error_msg("Not Found: vns '%s'" % words[0])
        return False
        
    #
    # --------------------------------------------------------------------------------
    # vns_find_or_add_name
    #  Return True when either the vns name currently exists, or of a create
    #  for the vns name succeeded.
    #
    def vns_find_or_add_name(self, words):
        if self.vns_find_and_set_name(words):
            return True
        name = words[0]
        errors = None
        ident = {mi.pk("vns-definition"): name }
        try:
            self.rest_create_object("vns-definition", ident)
        except Exception, e:
            errors = self.rest_error_to_dict(e, 'vns-definition')
            print self.rest_error_dict_to_message(errors)
            return False

        return True
   

    #
    # --------------------------------------------------------------------------------
    # vns_all_ids
    #
    def vns_all_ids(self):
        return [x['id'] for x in self.get_table_from_store("vns-definition")]

    #
    # --------------------------------------------------------------------------------
    # vns_convert_table_id
    #  return a list of two entries, the first is the vns name, the second is the
    #  updated column value
    #
    def vns_convert_table_id(self, obj_type, row, id):
        fields = row[id].split('|')
        if len(fields) == 1:
            # Just in case there's an error in the table
            return [fields[0], "<error>"]
        if len(fields) == 2:
            return fields
        elif len(fields) == 3:
            if obj_type == 'host-vns-interface':
                return [fields[1], fields[2]]
            elif obj_type == 'vns-access-list-entry':
                row['vns-access-list'] = fields[1]
                return [fields[0], fields[2]]
            else:
                print self.error_msg("3: vns_convert_table_id case %s" % obj_type)
        elif len(fields) == 4:
            if obj_type == 'vns-interface-access-list':
                # XXX ought to validate
                if row['vns-access-list'].split('|')[1] != fields[2]:
                    print self.error_msg('vns-interface-access-list inconsistent %s and id %d' % \
                                         (row['vns-access-list'], row[id]))
                row['vns-access-list'] = fields[2]
                row['vns-interface'] = fields[1]
                return [fields[0], fields[2]]
            else:
                print self.error_msg("4: vns_convert_table_id case %s" % obj_type)
        else:
            print self.error_msg("vns_convert_table_id: length %d not managed" % len(fields))
    #
    # --------------------------------------------------------------------------------
    # vns_table_id_to_vns_column
    #
    #  vns related tables in the model have unique id's created by concatenating the
    #  vns name with other fields.  For those tables, separate the vns id's from the
    #  associated fields, and transform the vns association into its own column.
    #
    #  obj_type is the name of the table.
    #
    #  for the vns_interface, the vns name is extracted from several fields,
    #  validated, updated to exclude the vns name, then a new column is added
    #
    def vns_table_id_to_vns_column(self, obj_type, entries):
        id = mi.pk(obj_type)
        for row in entries:
            if row[id]:
                type_info = mi.obj_type_info_dict[obj_type]['fields'][id]['type']
                if type_info == 'compound-key':
                    mi.split_compound_into_dict(obj_type, id, row)
                else:
                    convert_id = self.vns_convert_table_id(obj_type, row, id)
                    row['vns'] = convert_id[0]
                    row[id] = convert_id[1]

    #
    # --------------------------------------------------------------------------------
    # vns_foreign_key_to_base_name
    #  For foreign key's which vns wants to 'show', convert the
    #  foriegn key to the last entry for the field, and display
    #  that entry
    #
    def vns_foreign_key_to_base_name(self, obj_type, entries):
        foreign_keys = mi.obj_type_foreign_keys(obj_type)
        for row in entries:
            # convert the rule id into the rule suffix
            for foreign_key in foreign_keys:
                if foreign_key in row and row[foreign_key].find('|'):
                    fields = row[foreign_key].split('|')
                    row[foreign_key] = fields[-1]

    #
    # --------------------------------------------------------------------------------
    # vns_join_host_fields
    #  For vns-interfaces new fields are joined from the host table.
    #
    def vns_join_host_fields(self, obj_type, entries):
        if obj_type == 'vns-interface':
            #
            host_dap_dict = self.create_attachment_dict()
            host_ip_dict = self.create_ip_dict()
            #
            vns_interface_key = mi.pk('vns-interface')
            #
            # for vns-interface, currently vlan is shown in the output,
            # and this must be joined from the host's table.  Again, it
            # is better to collect the complee host table, then create
            # a host dictionary

            hosts_rows_dict = create_obj_type_dict('host', 'mac')

            #
            # re-index host_rows_dict based not on mac, but on attachment point,
            #  which is the sum of the switch+port.  the objective here is to
            #  identify the number of items on a specific-switch port.
            #
            ap_dict = {} # indexed by dpid|port
            for (mac, values) in host_dap_dict.items():
                for value in values:
                    key = "%s|%s" % (value['switch'], value['ingress-port'])
                    if not key in ap_dict:
                        ap_dict[key] = 0
                    ap_dict[key] += 1
            #
            # the ap_dict counts the number of mac's associated with an ap.
            # sort the host_rows_dict based on the lowest ap in each group.
            #
            for (mac, value) in host_dap_dict.items():
                new_value = sorted(value,
                                   key=lambda k:ap_dict["%s|%s" % (
                                                        k['switch'],
                                                        k['ingress-port'])],
                                   cmp=lambda x,y: int(x) - int(y))
                # add a tag to the dictionary of the first list item
                # when the ap_dict's entry's count is 1.
                first = new_value[0]
                if ap_dict['%s|%s' % (first['switch'], first['ingress-port'])] == 1:
                    new_value[0]['prime'] = True
                host_dap_dict[mac] = new_value
                    
            for row in entries:
                fields = row['id'].split('/')
                if not 'rule' in row:
                    row['rule'] = fields[0]
                if len(fields) != 2:
                    continue # silently ignore any id's not containing hosts
                host = fields[1]

                row['mac'] = host
                host_dict = {'mac' : host}
                row['attachment-points'] = self.get_attachment_points(
                                                   host_dict,
                                                   host_dap_dict)
                row['ips'] = self.get_ip_addresses(host_dict, host_ip_dict)

                host_row = hosts_rows_dict.get(host, None)
                if host_row and len(host_row) == 1 and 'vlan' in host_row[0]:
                    row['vlan'] = host_row[0]['vlan']
  
    #
    # --------------------------------------------------------------------------------
    # vns_join_switch_fields
    #  For vns-interfaces with entries arising from switch interface rules,
    #  join in the switch and port.
    #
    def vns_join_switch_fields(self, vns_name, entries):
        #
        # store all the rules associated with a specific vns,
        # index them by the primary key.
        key = mi.pk('vns-interface-rule')
        if vns_name == None:
            # vns_name == None, this means 'all'
            vns_ifr_dict = create_obj_type_dict('vns-interface-rule',
                                                key)
        else:
            search_key = self.unique_key_from_non_unique([vns_name])
            vns_ifr_dict = create_obj_type_dict('vns-interface-rule',
                                                key,
                                                key,
                                                search_key)
        for entry in entries:
            if 'rule' in entry:
                rule = entry['rule']
                if rule in vns_ifr_dict:
                    entry['switch'] = vns_ifr_dict[rule][0].get('switch', "")
                    entry['ports'] = vns_ifr_dict[rule][0].get('ports', "")

    #
    # end of vns methods.
    # --------------------------------------------------------------------------------
    #

    #
    #
    # --------------------------------------------------------------------------------
    # debug_obj_type
    #  Return True when the object is available, in self.debug mode, more objects
    #  are available.
    #
    def debug_obj_type(self, obj_type):
        if self.debug:
            return True
        if mi.is_obj_type_source_debug_only(obj_type):
            return False
        if self.vns_debug_obj_type(obj_type):
            if not obj_type in mi.alias_obj_types:
                return True
        return False

    #
    # generic parsing routines
    # 

    #
    # --------------------------------------------------------------------------------
    # completion_reset
    #
    def completion_reset(self):
        self.last_line = None
        self.last_options = None
        self.completion_cache = True
        self.last_completion_char = readline.get_completion_type()


    #
    # --------------------------------------------------------------------------------
    # completer
    #  This is the main function that is called in order to complete user input
    #
    def completer(self, text, state):
        question_mark = ord('?')
        if readline.get_completion_type() == question_mark:
            if len(readline.get_line_buffer()) == 0:
                #
                # manage printing of help text during command completion
                help_text = self.help_splash(None, text)
                if help_text != "":
                    self.print_completion_help(help_text)
                    return
        
        try:
            origline = readline.get_line_buffer()
            # See if we have a cached reply already
            if (self.completion_cache and origline == self.last_line and 
                self.last_completion_char == readline.get_completion_type() and
                self.last_options):

                if state < len(self.last_options):
                    return self.last_options[state]
                else:
                    # apparently, for the linux VM choice don't print 
                    if self.last_options and \
                      len(self.last_options) > 1 and \
                      self.last_completion_char == ord('\t'):
                        choices_text = self.choices_text_builder(self.last_options)
                        self.print_completion_help(choices_text)

                    if self.completion_skip:
                        self.completion_cache = False
                        self.completion_skip = False
                    return None

            self.completion_reset()

            # parse what user has typed so far

            begin = readline.get_begidx()
            end = readline.get_endidx()

            # Find which command we're in for a semicolon-separated list of single commands
            # LOOK! This doesn't handle cases where an earlier command in the line changed
            # the mode so the completion for later commands in the line should be different.
            # For example, if you typed "enable; conf" it won't detect that it should be
            # able to complete "conf" to "configure" because the enable command has not been
            # executed yet, so you're not in enable mode yet. Handling that case would be
            # non-trivial I think, at least with the current CLI framework.
            command_begin = 0
            command_end = 0
            while True:
                command_end = self.find_with_quoting(origline, ';', start_index=command_begin)
                if command_end < 0:
                    command_end = len(origline)
                    break
                if begin >= command_begin and end <= command_end:
                    break
                command_begin = command_end + 1
            
            # Skip past any leading whitespace in the command
            while command_begin < begin and origline[command_begin].isspace():
                command_begin += 1
            
            words = origline[command_begin:end].split()
            
            # remove last term if it is the one being matched
            if begin != end:
                words.pop()

            # LOOK! there are at least three places that try to parse the valid options:
            # 1. When actually handling a command
            # 2. When trying to show completions (here)
            # 3. When displaying help

            # complete the first word in a command line            
            if not words or begin == command_begin:
                options = self.commands_for_current_mode_starting_with(text, completion = True)
                if self.in_config_mode():
                    for item in self.obj_types_for_config_mode_starting_with(text):
                        self.append_when_missing(options, item)
                if self.in_config_submode():
                    for item in self.fields_for_current_submode_starting_with(text):
                        self.append_when_missing(options, item)
                options = [x if x.endswith(' ') else x + ' '  for x in sorted(options)]
            # Complete the 2nd word or later
            else:
                commands = self.commands_for_current_mode_starting_with(words[0])
                obj_types = self.obj_types_for_config_mode_starting_with(words[0]) if self.in_config_mode() else []
                fields = self.fields_for_current_submode_starting_with(words[0]) if self.in_config_submode() else []
                if len(commands) + len(obj_types) + len(fields) > 1:
                    if len(fields) > 1:
                        fields = [words[0]] if words[0] in fields else []
                    if len(commands) > 1:
                        commands = [words[0]] if words[0] in commands else []
                    if len(obj_types) > 1:
                        obj_types = [words[0]] if words[0] in obj_types else []
                
                if len(fields) == 1:
                    options = self.cp_conf_field(self.get_current_mode_obj_type(), words, text)
                elif len(obj_types) == 1:
                    options = self.cp_conf_object_type(obj_types + words[1:], text)
                elif len(commands) == 1: 
                    try:
                        # options[0] is expanded while words[0] is not
                        method = self.completion_method_from_name(commands[0]) 
                        if method:
                            options = method(words, text, readline.get_completion_type())
                            if not options:
                                # no match
                                return None
                        else:
                            if readline.get_completion_type() == question_mark:
                                options = command.do_command_completion_help(words, text)
                            else:
                                options = command.do_command_completion(words, text)
                            #else:
                                #if options:
                                    #print syntax_help
                                #else:
                                    #pass
                                    #self.print_completion_help(syntax_help)
                            
                    except AttributeError:
                        if self.debug or self.debug_backtrace:
                            traceback.print_exc()
                        return None

                else:
                    options = None
                    
        except Exception, e:
            if self.debug or self.debug_backtrace:
                traceback.print_exc()
            # errors in connect are caught silently, complain here
            # TODO - Maybe we should log this in a file we can review
            # at a later date?
        
        try:
            if options:
                self.last_line = origline
                self.last_options = options
                self.last_completion_char = readline.get_completion_type()
                return options[state]
        except IndexError:
            return None

        return None

    #
    # --------------------------------------------------------------------------------
    # handle_alias
    #  Manage alias creation for an obj_type, only manage one alias for each of the
    #  targets, although that requirement exists so that a single alias
    #  can be displayed for output from (show) commands
    #
    #  Note that setting the alias to its current value currently causes the
    #  alias to be created (ie: there's no specific search to find the item)
    #
    def handle_alias(self, obj_type, alias_obj_type, alias_value):

        if alias_value in self.reserved_words:
            return self.error_msg("alias value %s is a reserved word (%s)" % 
                                  (alias_value, ', '.join(self.reserved_words)))
        #
        # allow the use of 'alias' when only one alias entry
        # exists for the obj_type.  only-one ought to be typical.
        # this may need to be removed after a compatability period.
        if alias_obj_type == 'alias':
            # there should be only one alias table for this obj_type
            aliases = mi.alias_obj_type_xref[obj_type]
            if len(aliases) != 1:
                print self.error_msg("Internal more than one alias choice")
            alias_obj_type = aliases[0]

        obj = self.get_current_mode_obj()
        alias_key = mi.pk(alias_obj_type)

        #
        # create row for table with foreign key
        # find the name of the field which is the foreign key...
        foreign_field =  mi.alias_obj_type_field(alias_obj_type)
        if not foreign_field:
            print self.error_msg("internal handle_alias: alias_obj_type_field")
            return None

        #
        # delete the current alias if it exists
        try:
            exists = self.get_object_from_store(alias_obj_type, alias_value)
            if len(exists):
                self.rest_delete_object(alias_obj_type, alias_value)
        except:
            pass

        try:
            create_dict = { alias_key : alias_value, foreign_field : obj }
            self.rest_create_object(alias_obj_type, create_dict)
            errors = None
        except Exception, e:
            errors = self.rest_error_to_dict(e, alias_obj_type)

        if errors:
            return self.error_msg("could not create %s for %s (%s): %s" %
                                  (alias_obj_type, alias_value, obj_type,
                                 self.rest_error_dict_to_message(errors)))
        #
        # remove other existing alias for the same foreign key
        # find any other alias for this config object, then remove them
        #
        try:
            rows = self.get_table_from_store(alias_obj_type,
                                             foreign_field,
                                             obj,
                                             "exact")
        except Exception, e:
            errors = self.rest_error_to_dict(e, alias_obj_type)
            print self.rest_error_dict_to_message(errors)
            rows = []
        #
        #
        for row in rows:
            #
            # skip the entry which was just inserted
            if row[alias_key] == alias_value and row[foreign_field] == obj:
                continue
            try:
                self.rest_delete_object(alias_obj_type, row[alias_key])
                self.warning("removed other alias '%s' for %s '%s'" %
                             (row[alias_key], foreign_field, row[foreign_field]))
            except:
                pass

        return None
        

    #
    # --------------------------------------------------------------------------------
    # update_foreign_key
    #  Given an obj_type, its primary key name, and the old and new
    #  id values, find any associated tables which have foreign keys
    #  associated with this table, and update the foreign key so that
    #  the table again points to a valid id.
    #
    #  its unlikely, although not impossible, for the foreign key
    #  update to need to cascade.
    #
    def update_foreign_key(self, obj_type, obj_key, old_id, new_id):
        if obj_type in mi.foreign_key_xref and \
           obj_key in mi.foreign_key_xref[obj_type]:
            for (fk_obj_type, fk_name) in mi.foreign_key_xref[obj_type][obj_key]:
                #
                # find any affected rows
                try:
                    rows = self.get_table_from_store(fk_obj_type,
                                                     fk_name,
                                                     old_id,
                                                     "exact")
                except:
                    rows = []

                key = mi.pk(fk_obj_type)
                for row in rows:
                    self.warning("updating %s key %s field %s to %s" % \
                                (fk_obj_type, row[key], fk_name, new_id))
                    try:
                        self.rest_update_object(fk_obj_type,
                                                key,
                                                row[key],
                                                { fk_name : new_id })
                        errors = None
                    except Exception, e:
                        errors = self.rest_error_to_dict(e, fk_obj_type)

                    if errors:
                        print self.rest_error_dict_to_message(errors)

    #
    # --------------------------------------------------------------------------------
    # handle_field
    #
    # handle_field calls itself recursively to parse fields and build
    # a field dict. It then passes the field dict to one rest call.
    #
    def handle_field(self, words, accumulated_data=None):
        if accumulated_data is None:
            accumulated_data = {}
        if len(words) < 2:
            return self.error_msg("incorrect number of args (must be <field> <value>)")
        obj_type = self.get_current_mode_obj_type()
        obj = self.get_current_mode_obj()
        last_word = 2
        field = words[0]
        value = words[1]
        
        # complete the field if needed
        field_choices = self.fields_for_current_submode_starting_with(words[0])
        # LOOK!: robv: Fix to work with a field names which is a prefix of another
        if len(field_choices) > 1:
            for field_choice in field_choices:
                if field_choice == words[0]:
                    field_choices = [field_choice]
                    break
        if len(field_choices) > 1:
            return "Multiple matches for field name %s." % field
        if len(field_choices) == 0:
            return self.error_msg("%s has no field named %s." % (obj_type, field))
        field = field_choices[0]

        #
        # handle special case alias's which aren't understood via xref
        # (this is because vns-interface-rule doesn't foreignKey neigther
        #  switch or mac references to the switch/host tables)
        #  
        if obj_type == 'vns-interface-rule' and field == 'switch':
            if not self.DPID_RE.match(value):
                alias_value = alias_lookup('switch-alias', value)
                if alias_value:
                    value = alias_value
                else:
                    return "Syntax: Unknown switch alias '%s'; Specify switch as DPID or alias" % value
        if obj_type == 'vns-interface-rule' and field == 'mac':
            if not self.MAC_RE.match(value):
                alias_value = alias_lookup('host-alias', value)
                if alias_value:
                    value = alias_value
                else:
                    return "Syntax: Unknown host alias '%s'; Specify host as MAC or alias" % value
                
        #
        # Replace common type values with expected types, for example true or false
        #  for True/False. 
        if mi.is_field_boolean(self.get_current_mode_obj_type(), field):
            if value.lower() == 'false':
                value = 'False'
            elif value.lower() == 'true':
                value = 'True'
        # 
        elif mi.is_hex_allowed(obj_type, field) and self.HEX_RE.match(value):
            value = str(int(value, 16))
        #
        # Look up any validation or value changing callouts...
        validate = mi.field_validation(self.get_current_mode_obj_type(), field)
        if validate:
            validate_error = validate(obj_type, field, value)
            if validate_error:
                return validate_error

        accumulated_data[field] = value

        ret_val = None

        if len(words) > last_word:
            # more to munch
            ret_val = self.handle_field(words[last_word:], accumulated_data)
        else:
            # munched everything, now update
            obj_key = mi.pk(obj_type)

            prepare_update = mi.obj_type_prepare_row_update(obj_type)
            if prepare_update:
                accumulated_data = prepare_update(obj_type, obj_key, obj,
                                                  accumulated_data)
                # in case the obj_type's key is updated
                obj = accumulated_data[obj_key]

            #
            # Note: if all the fields for a row are all manually reverted
            # to a default value, perhaps the row ought to be deleted.
            errors = None
            try:
                self.rest_update_object(obj_type, obj_key, obj, accumulated_data)
            except Exception, e:
                errors = self.rest_error_to_dict(e, obj_type)

            if errors:
                ret_val = self.rest_error_dict_to_message(errors)
            else:
                #
                # if the primary key was part of the update. find relatred
                # tables and update the foreign key.  XXX perhaps this is
                # the rest api's problem?
                #
                if obj_key in accumulated_data and \
                   accumulated_data[obj_key] != obj:

                    self.update_foreign_key(obj_type, obj_key, obj,
                                            accumulated_data[obj_key])
                    #
                    # delete the old key.
                    self.rest_delete_object(obj_type, obj)

                    #
                    # move the the current id
                    self.set_current_mode_obj(accumulated_data[obj_key])

        return ret_val

    #
    # --------------------------------------------------------------------------------
    # convert_hex_to_decimal
    #  Review the contents of all the values, looking for hex
    #  valued fields.  When a hex value is identified, change
    #  it to decimal when 'is_hex_allowed' is true.
    #
    def convert_hex_to_decimal(self, obj_type, field_dict):
        for key in field_dict.keys():
            if mi.is_hex_allowed(obj_type, key) and \
               self.HEX_RE.match(field_dict[key]):
                field_dict[key] = int(field_dict[key], 16)

    #
    # --------------------------------------------------------------------------------
    # handle_obj_type
    #  In config mode, this handles if first word is an object-type
    #  (ex: "flow-entry catch-web")
    #
    def handle_obj_type(self, words):
        if len(words) < 2:
            return "Syntax: %s <key>: where key is an id of %s" % (words[0], words[0])

        (obj_type, obj_name) = (words[0], words[1])

        obj_name = convert_alias_to_object_key(obj_type, obj_name)
        # First check if this is something we can actually configure
        if obj_type not in mi.obj_types:
            return self.error_msg("unknown command or object.")

        # Next, find the object
        #  Deal with any changes to the lookup name based on the 'concatenation'
        #  of the config mode name to the named identifer.
        #
        found_obj = self.get_obj_of_type(obj_type, obj_name) 

        if found_obj == None:
            # need to create object, obj_data is the rest api dictionary used
            # to create the new row.
            obj_data = { mi.pk(obj_type): obj_name }

            if self.in_config_submode():
                # add in all the key value from modes in the stack
                # LOOK! this is brittle as it depends on the name of 
                # the mode matching the name of the attribute.
                #
                obj_data = self.mode_stack_to_rest_dict(obj_data)

                # 
                self.convert_hex_to_decimal(obj_type, obj_data)

                # make sure all the foreign keys are populated
                #
                for key in mi.obj_type_foreign_keys(obj_type):
                    if not key in obj_data:
                        print self.error_msg("foreign key '%s' missing from mode stack %s" %
                                             (key, obj_data))

            prepare_update = mi.obj_type_prepare_row_update(obj_type)
            if prepare_update:
                obj_data = prepare_update(obj_type,
                                          mi.pk(obj_type), obj_name,
                                          obj_data)

            # create the object
            errors = None
            try:
                self.rest_create_object(obj_type, obj_data)
            except Exception, e:
                errors = self.rest_error_to_dict(e, obj_type)

            if errors:
                return self.rest_error_dict_to_message(errors)

            # get it back, populating found_obj
            found_obj = self.get_obj_of_type(obj_type, obj_name) 
            
        # push on the submode for the object 
        # LOOK! assumes all object commands drop you into a submode...
        if found_obj:
            sub_mode = "config-%s" % obj_type
            self.push_mode(sub_mode, obj_type, obj_name)

            # hand off the rest of the line to handle_field
            if len(words) > 2:
                return self.handle_field(words[2:])
        else:
            return self.error_msg("No %s with %s = %s" %
                                  (obj_type, mi.pk(obj_type), obj_name))

    #
    # --------------------------------------------------------------------------------
    # print_completion_help
    #
    def print_completion_help(self, completion_help_text):
        origline = readline.get_line_buffer()
        end = readline.get_endidx()
        cur_command = origline[0:end]

        help_text = "\n%s\n%s%s" % ( completion_help_text, 
                                    self.prompt, 
                                    cur_command)
        self.completion_skip = True
        sys.stdout.write(help_text)
        
    #
    # --------------------------------------------------------------------------------
    # get_ip_from_switch_dpid_or_alias
    #    Returns the IP associated with the switch if it exists
    #    or the original string if it's not a dpid or alias.
    #
    def get_ip_from_switch_dpid_or_alias(self, alias):
        dpid = convert_alias_to_object_key("switches", alias)
        if self.DPID_RE.match(dpid):
            query_dict = { 'dpid' : dpid }
            row = rest_to_model.get_model_from_url('switches', query_dict)
            if len(row) >= 1:
                if not 'ip-address' in row[0] or row[0].get('ip-address') == '':
                    return self.error_msg("switch %s currently not connected "
                                          % alias)
                return row[0].get('ip-address')
        return alias

    #
    # --------------------------------------------------------------------------------
    # implement_write
    #
    def implement_write(self, words):
        if len(words) == 1:
            if "memory".startswith(words[0]):
                return self.implement_copy(["running-config", "startup-config"])
            elif "erase".startswith(words[0]):
                print "This will clear the startup-config and set it to be empty."
                resp = raw_input("Are you sure that want to proceed? [n]")
                if resp and "yes".startswith(resp.lower()):
                    print "Erasing startup config ..."
                    result = self.store.delete_user_data_file("startup-config/time/len/version")
                    if 'status' in result and result['status'] == 'success':
                        return None
                    elif 'message' not in result:
                        return self.error_msg("rest store result doesn't contain error message")
                    else:
                        return self.error_msg(result['message'])
                else:
                    print "Command aborted by user: write erase"
                return
            elif "terminal".startswith(words[0]):
                return self.implement_copy(["running-config", "terminal"])
        return "Syntax: write < terminal | memory | erase>"

    #
    # --------------------------------------------------------------------------------
    # 
    
    @staticmethod
    def set_clock_action(data):
        time_values = data['time'].split(':')
        if len(time_values) != 3:
            raise error.CommandError('Invalid time; must be HH:MM:SS')
        hour = int(time_values[0])
        minute = int(time_values[1])
        second = int(time_values[2])
        
        MONTH_NAMES =  ('January', 'February', 'March', 'April', 'May', 'June',
                        'July', 'August', 'September', 'October', 'November', 'December')

        day_of_month = int(data['day-of-month'])
        month_name = data['month']
        if month_name not in MONTH_NAMES:
            raise error.CommandError('Invalid month name (e.g. January, May, July)')
        month = MONTH_NAMES.index(month_name) + 1
        year = int(data['year'])
        
        date_time_info = {
            'year': year,
            'month': month,
            'day': day_of_month,
            'hour': hour,
            'minute': minute,
            'second': second
        }
        url = 'http://%s/rest/v1/system/clock/local' % cli.controller
        result = cli.store.rest_post_request(url, date_time_info)
        date_time_info = json.loads(result)
        clock_string = SDNSh.get_clock_string(date_time_info, False)
        return clock_string
    
    #
    # --------------------------------------------------------------------------------
    # get_misconfigured_default_gateway
    #  
    @staticmethod
    def get_misconfigured_default_gateway():
        """
        Determine if the controller is configured with a default gateway
        setting that doesn't match (i.e. is not on the same subnet)
        any of the interfaces configured with static IP addresses.
        This is used by the begin_default_gateway_check_action and
        end_default_gateway_check_action actions that check if a command
        results in a misconfigured default gateway setting and, if so,
        emit an error message.
        If the default gateway is misconfigured, the return value is the
        default gateway value. Otherwise, the return value is None.
        """
        # First figure out which controller-node we're working with.
        # This is a little kludgy right now. We check the mode stack
        # looking for a controller node element.
        controller_id = cli.get_nested_mode_obj('controller-node')
        if not controller_id:
            raise error.CommandDescriptionError('check_default_gateway_action must be called from a (possibly nested) controller node config mode')
        
        controller = cli.get_object_from_store('controller-node', controller_id)
        if not controller:
            # This shouldn't really happen unless someone/thing has mucked with the
            # controller object out from under this instance of the CLI
            # but just to be safe...
            raise error.CommandInvocationError('Current controller settings have been deleted.')
        
        # Check if the controller node is configured with a default gateway.
        # If not, then there's no possible misconfiguration and we're done.
        default_gateway = controller.get('default-gateway')
        if default_gateway == '':
            return
        
        # There is a default gateway configured, so we need to check if there's
        # an interface that matches (i.e. is on the same subnet as) the default
        # gateway
        interfaces = cli.rest_query_objects('controller-interface', {'controller': controller_id})
        for interface in interfaces:
            mode = interface.get('mode')
            if mode == 'static':
                ip = interface.get('ip')
                netmask = interface.get('netmask')
                if (ip != '') and (netmask != '') and same_subnet(default_gateway, ip, netmask):
                    return None

        return default_gateway
        
    #
    # --------------------------------------------------------------------------------
    # check_default_gateway_action
    #  
    @staticmethod
    def begin_default_gateway_check_action():
        """
        This is an action proc for the data-driven command module that is used
        in conjunction with the end_default_gateway_check_action to check if a
        CLI command results in an improperly configured default gateway setting.
        Currently the backend code that maps the network/interface settings
        for the controller to the /etc/network/interfaces file will only
        apply the default gateway setting if it's on the same subnet as an
        interface that's configured with a static IP address/netmask.
        So if there's no interface that matches the default gateway (either
        because it's configured to use DHCP or the subnet doesn't match)
        then the default gateway setting will be ignored and we want to warn
        the user about the misconfiguration. The check should be performed
        on any configuration change that could affect this check. This includes:
        
        1) setting the default gateway
        2) setting the mode of an interface to DHCP
        3) setting/resetting the ip/netmask of an interface
        4) deleting an interface
        
        We only want to emit the warning if the default gateway was previously
        not misconfigured and the current command resulted in a misconfiguration,
        so we want to check for a misconfiguration before applying the command
        and then check again after the settings have been updated. The
        begin_default_gateway_check_action is the action that is performed before
        the settings are updated and the corresponding end_default_gateway_check_action
        action is the one that is performed after the settings are updated.
        
        LOOK!: Ideally we should be doing this check in the sdncon code instead
        of here in the CLI code. That way the warning would also be returned
        for clients that are changing these settings directly via the REST
        API instead of via the CLI. But there isn't a really good mechanism
        currently for the REST API to return a warning but still apply the
        config change.
        """
        # Stash away if the gateway setting was already misconfigured at the
        # beginning of the current command. 
        # LOOK! This is a bit kludgy to stash this away in the CLI object.
        # When the command module action API is changed to allow access to the
        # context, this code should be updated to stash the value in the context
        # instead of the CLI.
        cli.begin_misconfigured_default_gateway = SDNSh.get_misconfigured_default_gateway()

    @staticmethod
    def end_default_gateway_check_action():
        """
        This is an action proc for the data-driven command module that is used
        in conjunction with the begin_default_gateway_check_action to check if a
        CLI command results in an improperly configured default gateway setting.
        Check the doc comments for begin_default_gateway_check_action for more
        details about how the two actions are intended to be used.
        """
        end_misconfigured_default_gateway = SDNSh.get_misconfigured_default_gateway()
        if (end_misconfigured_default_gateway and
            (end_misconfigured_default_gateway != cli.begin_misconfigured_default_gateway)):
            return  ('The controller is configured with a default gateway setting (%s), that\n'
                     'is not on the same subnet as any of the interfaces configured to use a\n'
                     'static IP address. The default gateway setting will be ignored.' %
                     end_misconfigured_default_gateway)
 
 
    #
    # --------------------------------------------------------------------------------
    # load_time_zone_list
    #  Use the rest api to collect all the known time zones
    #
    @staticmethod
    def load_time_zone_list():
        if not cli.time_zone_list:
            url = "http://%s/rest/v1/system/timezones/all" % cli.controller
            cli.time_zone_list = cli.rest_simple_request_to_dict(url)
 
    #
    # --------------------------------------------------------------------------------
    # time_zone_completion
    #
    @staticmethod
    def time_zone_completion(words, text, completions):
        SDNSh.load_time_zone_list()
        completion_dict = {}
        tz_completions = []
        for tz in cli.time_zone_list:
            if tz.lower().startswith(text.lower()):
                tz_completions.append(tz)
                for index in range(len(text), len(tz)):
                    if tz[index] == '/':
                        tz = tz[:index+1]
                        break
                completion_dict[tz] = 'Timezone Choice'
        
        if len(completion_dict) >= 1:
            completions.update(completion_dict)
    
    #
    # --------------------------------------------------------------------------------
    # time_zone_validation
    #
    @staticmethod
    def time_zone_validation(typedef, value):
        SDNSh.load_time_zone_list()
        if value not in cli.time_zone_list:
            raise error.ArgumentValidationError('Invalid time zone')
    
    #
    # --------------------------------------------------------------------------------
    # cp_clock
    #
    @staticmethod
    def cp_clock(words, text, completion_char):
        return command.do_command_completion(words, text)
                
    #
    # --------------------------------------------------------------------------------
    # do_clock
    #
    @staticmethod
    def do_clock(words):
        return command.do_command(['clock'] + words)
    
    #
    # --------------------------------------------------------------------------------
    # do_show_clock
    #
    def cp_show_clock(self, words, text, completion_char):
        if len(words) == 1 and 'detail'.startswith(text.lower()):
            return ['detail']
    
    
    @staticmethod
    def get_clock_string(time_info, detail = None):
        # The tz item contains the abbreviated time zone string (e.g. PST, EST)
        # This is different from the full time zone string (e.g. America/Los_Angeles)
        # which we get from the controller-node object below when we're showing
        # detail info.
        tz = time_info['tz']
        del time_info['tz']
        dt = datetime.datetime(**time_info)
        if detail:
            time_info['tz'] = tz
        
        # Arista-style format
        #show_result = dt.strftime('%c')
        
        # Cisco-style format
        clock_string = dt.strftime('%H:%M:%S '+ tz + ' %a %b %d %Y')
        
        return clock_string

    #
    # --------------------------------------------------------------------------------
    # do_show_clock
    #
    @staticmethod
    def do_show_clock(words):
        syntax_help = "Syntax: show clock [detail]"
        
        if len(words) == 0:
            detail = False
        elif len(words) == 1:
            if not 'detail'.startswith(words[0].lower()):
                return syntax_help
            detail = True
        else:
            return syntax_help

        url = "http://%s/rest/v1/system/clock/local/" % cli.controller
        time_info = cli.rest_simple_request_to_dict(url)
        clock_string = SDNSh.get_clock_string(time_info, detail)
        return clock_string

    #
    # --------------------------------------------------------------------------------
    # cp_show_vns
    #
    def cp_show_vns(self, words, text, completion_char):
        if len(words) == 1:
            return objects_starting_with('vns-definition', text)
        elif len(words) == 2:
            return [x for x in
                    [ 'interface', 'mac-address-table', 'interface-rules',  \
                       'access-lists', 'running-config', 'switch', 'flow' ]
                    if x.startswith(text)]
        elif len(words) == 3 and 'switch'.startswith(words[2]):
            return objects_starting_with("switch", text)
        elif (len(words) >= 3) and (words[2] == 'flow'):
            return self.cp_show_vns_flow(words, text)
        else:
            self.print_completion_help("<cr>")

    #
    # --------------------------------------------------------------------------------
    # show_vns_definition_running_config
    # Display the vns-definition -- the interface rules for the vns.
    #
    def show_vns_definition_running_config(self, config, vns_name,tenant=None,indent=0):
        if tenant==None and vns_name!='all':
            vns_id='default|'+vns_name
        else:
            vns_id=tenant +'|'+vns_name
        try:
            vns = self.get_object_from_store('vns-definition', vns_id)
        except:
            return self.error_msg('no vns named %s' % vns_name)

        config.append(' ' *2*indent + "vns-definition %s\n" % vns_name)
        run_config.running_config_vns_details(config, vns, indent+1)

        vns_rules = None
        try:
            vns_rules = self.get_table_from_store('vns-interface-rule',
                                                  'vns', vns_id, "exact")
        except Exception:
            pass
        
        if vns_rules:
            run_config.running_config_vns_if_rule(config,
                                                  vns_rules,indent+1)

    #
    # --------------------------------------------------------------------------------
    # show_vns_running_config
    #  In the larger 'running-config' for vns, the complete vns tables are read
    #  since the complete 'running-config' will display all the data from the
    #  fields.  Here, the tables are searched only for specific vns entries.
    #
    #  The procedure's name is choosen carefully, since its not intended to
    #  part of any of show command, completion, or command processing
    #
    def show_vns_running_config(self, vns_name, tenant=None, indent=0):
        config=[]
        preconfig=[' '*2*indent +"vns %s\n" % vns_name]
        if tenant==None and vns_name!='all':
            vns_name='default|'+vns_name
        if tenant!=None:
            vns_name=tenant+'|'+vns_name
        try:
            self.get_object_from_store('vns-definition', vns_name)
        except:
            return self.error_msg('no vns named %s' % vns_name)
        vns_acls = []
        try:
            vns_acls = self.get_table_from_store('vns-access-list',
                                                 'vns', vns_name, 'exact')
        except Exception, e:
            pass

        for acl in vns_acls:
            # note use of key initialized above

            vns_acl_entries = None
            try:
                vns_acl_entries = self.get_table_from_store('vns-access-list-entry',
                                                            'vns-access-list',
                                                            acl['id'],
                                                            'exact')
            except Exception:
                pass
            run_config.running_config_vns_acl(config, vns_name, acl, vns_acl_entries,indent+1)

        vns_interface_acl = None
        try:
            vns_interface_acl = self.get_table_from_store('vns-interface-access-list')
        except Exception:
            pass

        for vns_if in run_config.running_config_active_vns_interfaces(vns_name, vns_interface_acl):
            config.append(' ' *2*(indent+1) + "interface %s\n" % vns_if)
            run_config.running_config_vns_if_and_access_group(config,
                                                              vns_name,
                                                              vns_if,
                                                              vns_interface_acl,indent+2)
        if len(config) > 0:
            config = preconfig + config
        return ''.join(config)

    #generate tenant xxx running config
    def show_tenant_running_config(self, config, tenant_name):
        try:
                tenants = self.get_object_from_store('tenant', tenant_name)
        except:
                return self.error_msg('no tenant named %s' % tenant_name)
    
        config.append("!\ntenant %s\n" % tenant_name)
        run_config.running_config_tenant_details(config,tenants)

        try:
            vnses = self.get_table_from_store('vns-definition','tenant',tenant_name,"exact")
        except Exception:
            vnses = {}
            pass
        try:
            virtual_routers = self.get_table_from_store('virtualrouter','tenant', tenant_name, "exact")
        except Exception:
            virtual_routers = {}
            pass

        for vns in vnses:
            vns_name=vns['vnsname']
            self.show_vns_definition_running_config(config, vns_name, tenant=tenant_name,indent=1)
            config += self.show_vns_running_config(vns_name, tenant=tenant_name,indent=1)
            
        for virtual_router in virtual_routers:
            virtual_router_name=virtual_router['vrname']
            virtual_router_id=virtual_router['id']
            config.append("  router %s\n" % virtual_router_name)
            run_config.running_config_tenant_router_details(config,virtual_router,indent=1)
            try:
                vr_interfaces = self.get_table_from_store('virtualrouter-interface','virtual-router', virtual_router_id, "exact")
            except Exception:
                vr_interfaces = {}
            pass
            try:
                vr_routes = self.get_table_from_store('virtualrouter-routingrule','virtual-router', virtual_router_id, "exact")
            except Exception:
                vr_routes = {}
            pass
            try:
                vr_gwpools = self.get_table_from_store('virtualrouter-gwpool','virtual-router', virtual_router_id, "exact")
            except Exception:
                vr_gwpools = {}
            pass

            for vr_interface in vr_interfaces:
                run_config.running_config_router_interface_details(config,vr_interface,indent=2)
            for vr_route in vr_routes:
                run_config.running_config_router_rule_details(config,vr_route,indent=2)
            for vr_gwpool in vr_gwpools:
                run_config.running_config_router_gwpool_details(config,vr_gwpool,indent=2)
      
    #
    # --------------------------------------------------------------------------------
    # switch_port_match
    #  Return True when the port matches a port specirfication "pattern"
    #
    #  The port specification of an interface rule is a command separated list,
    #  which can contain a tail of "-<d>".  That tail describes a range.
    #  With a port range, determine whether or not the 'port' parameter
    #  is a match.
    #
    def switch_port_match(self, port, pattern):
        # XXX validate port is something which ends in a number?
        for field in pattern.split(','):
            m = re.match(r'^([A-Za-z0-9-]*?)(\d+)-(\d+)$', pattern)
            if not m:
                if field == port:
                    return True
                continue
            prefix = m.group(1)
            startport = int(m.group(2))
            endport = int(m.group(3))
            if not port.startswith(prefix):
                continue
            tail = port[len(prefix):]
            if not self.DIGITS_RE.match(tail):
                print self.error_msg("port name tail %s must be all digits" % tail)
                continue
            m = re.search(r'(\d+)$', port)
            if not m:
                continue
            port = m.group(1)
            if int(port) >= int(startport) and int(port) <= int(endport):
                return True
            else:
                print self.error_msg("port %s out of port-spec range %s-%s" %
                                     (port, startport, endport))
        return False

    #
    # ---------------------------------------------------------------------------
    # cp_show_event_history
    #  Command completion for the following command to see
    #  last <n> events of <name> events
    #  Used in "show event-history <name> [ last <n> ]"
    #
    def cp_show_event_history(self, words, text, completion_char):
        options = ['attachment-point', 
                   'packet-in',
                   'topology-link',
                   'topology-switch',
                   'topology-cluster',
                   # Add more event history options above this line
                   # Add the same item in do_show_event_history() below also
                  ]
        completion_help = ''
        for op in options:
            ev_help = '%s  show %s events\n' % (op, op)
            completion_help = completion_help + ev_help

        # syntax: show event-history <name> [ last <n> ]
        if (len(words) == 1) and text=='':
            self.print_completion_help(completion_help)
            return options
        elif (len(words) == 1):
            return [op for op in options if op.startswith(text)]
        elif (len(words) == 2):
            if text == '':
                self.print_completion_help("last  Show lastest <n> events\n" +
                                           "<cr>  Enter")
                return ['last', '<cr>']
            elif "last".startswith(text):
                return ["last"]
        elif (len(words) == 3):
            self.print_completion_help("<number>  Enter number of latest events to display (1-10000)")
            return range(0, 10000)
        else:
            self.print_completion_help('<cr>')

    #
    # --------------------------------------------------------------------------
    # do_show_event_history
    #
    # Show the event history of the specified events
    # Syntax: show event-history <event-history-name> [last <count>]
    # <event-history-name> is words[0], <count> is words[2]
    #
    def do_show_event_history(self, words):
        self.debug_msg("do-show-event-history words: %s" % words)

        # Check syntax of the command
        syntax = self.syntax_msg('show event-history <name> [ last <n> ]')
        options = ['attachment-point', 
                   'packet-in',
                   'topology-link',
                   'topology-switch',
                   'topology-cluster',
                   # Add more event history options above this line
                   # Add the same item in do_cp_event_history() above also
                  ]
        if (words[0] not in options):
            yield("Event history name %s not found" % words[0])
            return
        if (len(words) >= 3) and (words[1] != 'last'):
            yield(syntax)
            return
        if (len(words) == 2) or (len(words) > 4):
            yield(syntax)
            return
        if (len(words) >= 3) and (not words[2].isdigit()):
            yield(syntax)
            return
        if (len(words) >= 3) and (words[2].isdigit()):
            count = int(words[2])
            if (count < 1) or (count > 10000):
                yield("Number of events must be between 1 and 10000")
                return

        last_n_count = 1024 # default
        if (len(words) >= 3):
            last_n_count = words[2]
        ev_hist_name = words[0]
        ev_hist_field_name = 'ev-hist-' + ev_hist_name
        url = 'http://%s/rest/v1/event-history/%s/%s' % \
                               (self.controller, ev_hist_name, last_n_count)
        ev_hist = self.rest_simple_request_to_dict(url)
        #ev_hist - json.dumps(ev_hist)
        events = ev_hist['events']
        tableData = []
        for ev in events:
            info      = ev['info']
            base_info = ev['base_info']
            info.update(base_info)
            tableData.append(info)
        # Prepare the date for CLI display
        tableData = self.pp.format_table(tableData, ev_hist_field_name)
        yield("\n")
        yield(tableData)

    #
    # -------------------------------------------------------------------------------
    # cp_show_vns
    #  Command completion for the following command
    #  Used in "show vns { <vns-name> | all } flow [ brief | full-detail | detail | summary ]
    #
    def cp_show_vns_flow(self, words, text, completion_char):
        cmd1 = 'brief        show flow information in brief format'
        cmd2 = 'detail       show detailed flow information'
        cmd3 = 'full-detail  show full details of flow information'
        cmd4 = 'summary      show summarized flow information'

        syntax = self.syntax_msg('show vns {<vns-name> | all} flow [ brief | detail | full-detail | summary ]')
        if (len(words) == 3) and text=='':
            self.print_completion_help(cmd1+'\n'+cmd2+'\n'+cmd3+'\n'+cmd4)
            return ['brief', 'detail', 'full-detail', 'summary', '<cr>' ]
        elif (len(words) == 3) and ('detail'.startswith(text)):
            return ['detail']
        elif (len(words) == 3) and ('full-detail'.startswith(text)):
            return ['full-detail']
        elif (len(words) == 3) and ('summary'.startswith(text)):
            return ['summary']
        elif (len(words) == 3) and ('brief'.startswith(text)):
            return ['brief']
        elif (len(words) == 4) and (words[3] not in ['brief', 'detail', 'full-detail', 'summary']):
            self.print_completion_help(syntax)
        elif (len(words) >= 3) and (text != ''):
            self.print_completion_help(syntax)
        else:
            self.print_completion_help('<cr>')

    #
    # --------------------------------------------------------------------------------
    # show_vns_flow_annotated
    #
    # For a given vns-name, show all the active flows in that vns 
    # or
    # for show active-flows in all vnses, categorized by vns
    # Used in "show vns { <vns-name> | all } flow [ brief | full-detail | detail | summary ]
    # flow records are annotated in the sdnplatform with vns name
    #
    def show_vns_flow_annotated(self, words):

        syntax = self.syntax_msg('show vns {<vns-name> | all} flow [ brief | detail | full-detail |summary ]')
        if (len(words) == 3) and (words[2] not in ['brief', 'details', 'full-detail', 'summary']):
            print syntax
            return

        if (len(words) > 3):
            print syntax
            return
        
        # all = False is this used anywhere
        
        vns = words[0]
        
        option = 'none'
        if (len(words) == 3):
            option = words[2]        

        # Get all the flows in the network
        annotated_flow_data = {}
        url = 'http://%s/rest/v1/vns/realtimestats/flow/%s' % (self.controller, vns)
        annotated_flow_data = self.rest_simple_request_to_dict(url)
        #print "Data=%s" % json.dumps(annotated_flow_data, sort_keys=True, indent=4)
        # annotated_flow_data response is in the following format:
        # Data={
        #   "vnsCount": 1, 
        #   "vnsFlowMap": {
        #            "two": {
        #                "flowCount": 10, 
        #                "flowList": [
        #                     {
        #                       "dpid": "00:00:00:00:00:00:00:0f", 
        #                       "flowEntry": {
        #                          "actions": [
        #                               {

        # vnsCount = annotated_flow_data["vnsCount"]
        vnsFlowMap = annotated_flow_data["vnsFlowMap"]
        vnsAddressSpaceMap = annotated_flow_data["vnsAddressSpaceMap"]
        
        if (option == "brief"):
            table_field_ordering = "vns_flow"
        elif (option == "detail"):
            table_field_ordering = "details"
        elif (option == "full-detail"):
            table_field_ordering = "undefined" # prints everything!
        elif (option == "summary"):
            table_field_ordering = "summary"            
        else:
            table_field_ordering = "default"        
        
        summaryTable = [] # used for holding the data for "summary" option
        for vnsName in vnsFlowMap:
            if (option == 'brief') or (option == "summary"):
                flow_tuple_list = []
                briefFlowCnt = 0
            # Table Data will hold all the flow entries, one list element per row of output
            # It is reinitilized for each VNS   
            tableData  = []
            vnsFlowCnt = vnsFlowMap[vnsName]["flowCount"]                    
            vnsFlowList = vnsFlowMap[vnsName]["flowList"]
            for vnsFlowEntry in vnsFlowList:                
                flowEntry = vnsFlowEntry["flowEntry"]
                dpid      = vnsFlowEntry["dpid"]
                if (option == "brief") or (option == "summary"):                    
                    src_mac   = flowEntry['match']['dataLayerDestination']
                    dst_mac   = flowEntry['match']['dataLayerSource']
                    vlan      = flowEntry['match']['dataLayerVirtualLan']
                    etherType = flowEntry['match']['dataLayerType']
                    flowList  = []
                    flowList.append(src_mac)
                    flowList.append(dst_mac)
                    flowList.append(vlan)
                    flowList.append(etherType)
                    if flowList in flow_tuple_list:
                        # duplicate flow (due to same flow entry on multiple switches along the path, 
                        # skip it if the option if brief or summary
                        continue
                    else:
                        flow_tuple_list.append(flowList)
                        briefFlowCnt += 1
                #print "DPID = %s" % dpid
                #print " New Data = %s" % json.dumps(flowEntry, indent=4)
                if (option != "summary"):
                    tableEntry = {}
                    tableEntry[dpid] = []
                    tableEntry[dpid].append(flowEntry)
                    tableEntry = self.add_dpid_to_data(tableEntry)
                    tableEntry = self.fix_realtime_flows(tableEntry)
                    #print "Table Entry : %s" % json.dumps(tableEntry, indent=4)
                    tableData.append(tableEntry[0])
            #print "*** Table Data: %s" % json.dumps(tableData[0], indent=4)
            #printf tenant + vnsname
            names=vnsName.split('|')
            tenant=names[0]
            vns=names[1]
            if (option == "brief"):
                yield("\nTenant %s VNS %s (address-space %s) flows (count: %s)" % (tenant, vns, vnsAddressSpaceMap[vnsName], briefFlowCnt))
            elif (option != "summary"):
                yield("\nTenant %s VNS %s (address-space %s) flow entries (count: %s)" % (tenant, vns, vnsAddressSpaceMap[vnsName], vnsFlowCnt))
            # Print flow data for one vns, unless option is summary
            if (option == "summary"):
                summaryData = dict()
#                summaryData['tenant']       =tenant
                summaryData["vnsName"]      = vns
                summaryData["flowEntryCnt"] = vnsFlowCnt
                summaryData["vnsFlowCnt"]   = briefFlowCnt
                summaryTable.append(summaryData)
            else:
                yield("\n") 
                # print "*** TD = %s" % tableData
                tableData = self.pp.format_table(tableData, "realtime_flow", table_field_ordering)
                yield(tableData)
                
        if (option == "summary"):            
            # print "*** ST %s" % summaryTable
            yield("\n")
            summaryTable = self.pp.format_table(summaryTable, "realtime_flow", table_field_ordering)            
            yield(summaryTable)
        print(" ") 
        return
  
    #
    # --------------------------------------------------------------------------------
    # show_vns_switch_ports
    #  For some vns-name, collect all the interfaces, and from that,
    #  collect all the attachment points.  The objective here is to
    #  name all the switch's and ports associated with a vns
    #
    def show_vns_switch_ports(self, words):
        if len(words) < 1:
            return

        # words:  [ vns_name, 'switch', switch_name ]
        vns_name = words[0]
        switch = None
        if len(words) > 2:
            switch = convert_alias_to_object_key('switch', words[2])
        port = None
        if len(words) > 3:
            port = words[3]

        vns_interface_key = mi.pk('vns-interface')
        if vns_name == 'all':
            vns_ifs = create_obj_type_dict('vns-interface',
                                           vns_interface_key,
                                           'id')
            vns_rules = create_obj_type_dict('vns-interface-rule',
                                             mi.pk('vns-interface-rule'),
                                             'id',)
        else:
            vns_ifs = create_obj_type_dict('vns-interface',
                                           vns_interface_key,
                                           'vns',
                                           vns_name)
            vns_rules = create_obj_type_dict('vns-interface-rule',
                                             mi.pk('vns-interface-rule'),
                                             'vns',
                                             vns_name)
        host_dap_dict = self.create_attachment_dict()

        bsp = {}  # _b_vs _s_witch _p_ort
        for ifs in vns_ifs:
            fields = ifs.split('|')
            # all these fields must have two parts.
            if len(fields) != 3:
                continue
            # choose between switch based rules and mac/ip based rules
            rule = 'default'
            vns_name = vns_ifs[ifs][0]['vns']
            switch_rule = None
            if fields[1] != 'default':
                rule = vns_ifs[ifs][0]['rule']
                if not rule in vns_rules:
                    continue
                if_rule = vns_rules[rule][0]
                if 'switch' in if_rule:
                    switch_rule = if_rule['switch']
            else:
                if_rule = { 'mac' : 'defaultLie' } # for default rules

            # There's two major classes of rules: host and switch
            # Use existance of a 'switch' to differentiate between the two.
            if switch_rule:
                # if_rule/switch are both set, part after the '/' is the port
                if fields[2].find('/') < 0:
                    # skip Eth<n> general interface
                    continue
                #
                # Prefix this port with a plus sign, which will be recognized
                # in the printing code as already describing an openflow port name
                port = '+' + fields[2].split('/')[1]
                tenant_vns=vns_name.split('|')
                tenant_name=tenant_vns[0]
                vns_real_name=tenant_vns[1] 
                key = "%s|%s|%s|%s" % (tenant_name,vns_real_name, switch, port)

                if not key in bsp:
                    bsp[key] = {
                            'tenant'      : tenant_name,
                            'vns'         : vns_real_name,
                            'switch'      : switch_rule,
                            'port'        : port,
                            'reason'      : ["Rule:%s" % rule.split('|')[-1], fields[1]],
                    }
                else:
                    pass # should only be one.
            else:
                # the second part (fields[1]) is the interface-long name,
                items = fields[2].split('/')
                if len(items) == 1:
                    if items[0].startswith('VEth'):
                        if not 'mac' in rule:
                            continue
                        mac = if_rule['mac']
                    elif items[0].startswith('Eth'):
                        self.debug_msg('should have been a switch in if_rule')
                        continue
                    else:
                        self.debug_msg('item length of 1')
                        continue
                else:
                    mac = items[1]
                    if not re.match(r'^(([A-Fa-f\d]){2}:?){5}[A-Fa-f\d]{2}$', mac):
                        print 'Not a mac address: %s' % mac
                # currently just use the mac to find the attachment points.
                if mac in host_dap_dict:
                    for attachment_point in host_dap_dict[mac]:
                        # if switch is named, skip any which don't match
                        if switch and attachment_point['switch'] != switch:
                            continue
                        if port and attachment_point['ingress-port'] != port:
                            continue

                        tenant_vns=vns_name.split('|')
                        tenant_name=tenant_vns[0]
                        vns_real_name=tenant_vns[1] 
                        key = "%s|%s|%s|%s" % (tenant_name,
                                            vns_real_name,
                                            attachment_point['switch'],
                                            attachment_point['ingress-port'])
                        if not key in bsp:
                            bsp[key] = {
                                    'tenant' : tenant_name,
                                    'vns'    : vns_real_name,
                                    'switch' : attachment_point['switch'],
                                    'port'   : utif.try_int(attachment_point['ingress-port']),
                                    'reason' : ["Rule:%s" % rule.split('|')[-1], mac]
                                    }
                        else:
                            self.append_when_missing(bsp[key]['reason'],
                                                    "Rule:%s" % rule.split('|')[-1])
                            self.append_when_missing(bsp[key]['reason'], mac)

        sort = [bsp[x] for x in sorted(bsp.keys(),
                                       cmp=lambda a,b: cmp(utif.try_int(a.split('|')[2]),
                                                           utif.try_int(b.split('|')[2]))
                                           if a.split('|')[1] == b.split('|')[1]
                                           else cmp(b.split('|')[1],a.split('|')[1]))]

        return self.display_obj_type_rows('vns-switch-ports', sort)


    #
    # --------------------------------------------------------------------------------
    # show_switch_ports_vns
    #
    def show_switch_ports_vns(self, words):
        switch = None
        if len(words) > 1 and words[0] != 'all':
            switch = words[0]
            #
            # switch alias conversion
            value = alias_lookup('switch-alias', switch)
            if value:
                switch = value

        #
        # dictionary from the vns side, indexed by host.
        vns_ifs_dict = create_obj_type_dict('vns-interface',
                                            mi.pk('vns-interface'))
        #
        # dictionary of the interface-rules, by rule
        vns_rules = create_obj_type_dict('vns-interface-rule',
                                         mi.pk('vns-interface-rule'))
        #
        # from the list of hosts, identify the attachment points
        host_dap_dict = self.create_attachment_dict()

        #
        # there can be multiple attachment points for each of the
        # hosts.  iterate over the hosts,  find all the attachment points,
        # manage an association for the entries
        spb = {}  # _s_witch _p_ort _b_vs
        for ifs in vns_ifs_dict:
            fields = vns_ifs_dict[ifs][0]['id'].split('|')
            # all these fields must have two parts.
            if len(fields) != 2:
                continue
            # id parts are vns|interface
            vns_name = fields[0]

            # choose between switch based rules and mac/ip based rules
            rule = 'default'

            switch_rule = None
            mac_rule = None
            rule_fields = [rule]
            if vns_name == 'default':
                if fields[1].find('/') >= 0:
                    mac_rule = fields[1].split('/')[1]
            else:
                if not 'rule' in vns_ifs_dict[ifs][0]:
                    continue
                rule = vns_ifs_dict[ifs][0]['rule']
                rule_fields = rule.split('|')
                if_rule = vns_rules[rule][0]
                if 'switch' in if_rule:
                    if switch and if_rule['switch'] != switch:
                        continue
                    switch_rule = if_rule['switch'] # switch may be None.
                elif 'mac' in if_rule:
                    mac_rule = if_rule['mac']
                elif 'ip-subnet' in if_rule:
                    mac_rule = if_rule['ip-subnet']
                elif 'tags' in if_rule:
                    mac_rule = if_rule['tags']
                elif 'vlans' in if_rule:
                    mac_rule = if_rule['vlans']
            if mac_rule:
                if not mac_rule in host_dap_dict:
                    self.debug_msg("Unknown attachment point for %s" % mac_rule)
                    continue

                for attachment_point in host_dap_dict[mac_rule]:
                    key = "%s|%s" % (attachment_point['switch'],
                                      attachment_point['ingress-port'])
                    if switch and attachment_point['switch'] != switch:
                        continue

                    if not key in spb:
                        spb[key] = {
                                'switch' : attachment_point['switch'],
                                'port'   : utif.try_int(attachment_point['ingress-port']),
                                'vns'    : {vns_name : 1},
                                'reason' : ["Rule:%s" % rule_fields[-1], mac_rule]
                                }
                    else:
                        if vns_name in spb[key]['vns']:
                            spb[key]['vns'][vns_name] += 1
                        else:
                            spb[key]['vns'][vns_name] = 1
                        self.append_when_missing(spb[key]['reason'],
                                                 "Rule:%s" % rule_fields[-1])
                        self.append_when_missing(spb[key]['reason'], mac_rule)
            if switch_rule:
                if fields[1].find('/') >= 0:
                    #
                    # Prefix this port with a plus sign, which will be recognized
                    # in the printing code as already describing an openflow port name
                    port = '+' + fields[1].split('/')[1]
                    key = "%s|%s" % (switch_rule, port)

                    if not key in spb:
                        spb[key] = {
                                'switch' : switch_rule,
                                'port'   : port,
                                'vns'    : {vns_name : 1},
                                'reason' : ["Rule:%s" % rule_fields[-1], fields[1]]
                        }

        sort = [spb[x] for x in sorted(spb.keys(),
                                        cmp=lambda a,b: cmp(utif.try_int(a.split('|')[1]),
                                                            utif.try_int(b.split('|')[1]))
                                            if a.split('|')[0] == b.split('|')[0]
                                            else cmp(b.split('|')[0],a.split('|')[0]))]

        return self.display_obj_type_rows('switch-ports-vns', sort)
                                          # [spb[x] for x in sorted(spb.keys())])

    #
    # --------------------------------------------------------------------------------
    # do_show_vns
    #
    def do_show_vns(self, words):
        choices = ['interface', 'mac-address-table',
                   'interface-rules', 'access-lists', 'running-config', 'switch', 'flow' ]
        if words == None or len(words) > 2:
            if words[1] not in ['switch', 'flow']:
                return self.syntax_msg('show vns <vns-name> [ %s ] ' %
                                       ' | '.join(choices))
        if len(words) in [3, 4]:
            if words[1] == 'switch':
                return self.show_vns_switch_ports(words)
            elif words[1] == 'flow':
                return self.show_vns_flow_annotated(words)
            else:
                return self.syntax_msg('show vns <vns-name> [ %s ] ' %
                                       ' | '.join(choices))
        elif len(words) == 2:
            # words[0] ought to an existing vns
            # Allow show vns all flow [detail]
            if (not self.vns_find_name(words[0])) and (words[1] != 'flow'):
                return self.error_msg("show vns '%s': vns Not Found" % words[0])

            vns_key = self.prefix_search_key([words[0]])
            selection = utif.full_word_from_choices(words[1], choices)
            if not selection:
                return self.syntax_msg('show vns <vns-name> [ %s ' %
                                       ' | '.join(choices))
            if selection == 'interface':
                return self.find_and_display_vns_interface(words[0], words[2:])
            elif selection == 'mac-address-table':
                # the id for the host-vns-interface table has the host as the 'prefix',
                # preventing searching based on the prefix.  the vns is not even a foreign
                # key, which means the complete table must be read, then the vns association
                # must be determined, and then matched
                return self.display_vns_mac_address_table(words[0], words[2:])
            elif selection == 'interface-rules':
                return self.do_show_object(['vns-interface-rule', vns_key], "<no_key>")
            elif selection == 'access-lists':
                return self.do_show_object(['vns-access-list-entry', vns_key], "<no_key>")
            elif selection == 'running-config':
                return self.show_vns_running_config(words[0])
            elif selection == 'switch':
                return self.show_vns_switch_ports(words)
            elif selection == 'flow':
                return self.show_vns_flow_annotated(words)
        elif len(words) == 1:
            return self.do_show_object(["vns-definition", words[0]])
        else:
            return self.do_show_object(["vns-definition"])

    #
    # --------------------------------------------------------------------------------
    # do_show_vns_interface_rule
    #  do_show_object is used to construct the output for the table search.
    #  However, since a vns prefix key search is used to display the table,
    #  and since do_show_object behaves differently when displaying tables
    #  depending on whether the table is a key search or not, the 'with_search_key'
    #  parameter is set to "with_key" when the caller included an additional
    #  prefix for (key) for the rule, and otherwise '<no_key>' is used when
    #  the caller wants the complete interface-rule table for a single vns
    #  (which obvioulsy also implies a key search for 'vns|' prefied rules.
    #
    def do_show_vns_interface_rule(self, words):
        with_search_key = "<no_key>"
        if self.vns_name() is None:
            if len(words) > 0:
                search_object = ["vns-interface-rule", words[0]]
            else:
                search_object = ["vns-interface-rule"] 
        elif len(words) > 0:
            with_search_key = '-'.join(words)
            words.insert(0, self.vns_name())
            search_object = ["vns-interface-rule", 
                             self.unique_key_from_non_unique(words)]
        else:
            search_object = ["vns-interface-rule",
                             self.prefix_search_key([self.vns_name()]) ] 
            obj_type = 'vns-interface-rule'

            # --- this ought to be promoted to be used more ..
            s_dict = {}
            # for all foreign keys in this obj_type
            mode_dict = self.mode_stack_to_rest_dict({})

            # for fk in mi.obj_type_foreign_keys(obj_type):
            for kf in mi.compound_key_fields(obj_type, mi.pk(obj_type)):
                if mi.is_foreign_key(obj_type, kf):
                    (ref_ot, ref_fn) = mi.foreign_key_references(obj_type, kf)
                    if ref_ot in mode_dict:
                        s_dict[kf] = mode_dict[ref_ot]

            # for (n,v) in self.mode_stack_to_rest_dict({}).items():
                # for (fk_ot, fk_fn) in mi.foreign_key_xref[n][mi.pk(n)]:
                    # print n, fk_ot, fk_fn
                    # if fk_ot == obj_type:
                        # s_dict[fk_fn] = v
            entries = self.store.rest_query_objects(obj_type, s_dict)
            return self.display_obj_type_rows(obj_type, entries, with_search_key)
        return self.do_show_object(search_object, with_search_key)

    #
    # --------------------------------------------------------------------------------
    # cp_is_alias
    #  Used in cp_no to determine if the particular request is an alias completion
    #
    def cp_is_alias(self, words, text):
        if not self.in_config_submode() or len(words) != 2:
            return False
        obj_type = self.get_current_mode_obj_type()
        # LOOK! robv: Tweaked this from the commented out version below
        return obj_type in mi.alias_obj_type_xref
 

    #
    # --------------------------------------------------------------------------------
    # cascade_delete
    #  Delete interior objects' rows related via foreign keys
    #
    def cascade_delete(self, obj_type, id_value):
        global modi

        obj_key = mi.pk(obj_type)
        if obj_type in mi.foreign_key_xref and \
           obj_key in mi.foreign_key_xref[obj_type]:
            for (fk_obj_type, fk_name) in mi.foreign_key_xref[obj_type][obj_key]:
                if mi.is_cascade_delete_enabled(fk_obj_type):
                    #
                    # find any affected rows
                    try:
                        rows = self.get_table_from_store(fk_obj_type,
                                                         fk_name,
                                                         id_value,
                                                         "exact")
                    except Exception, e:
                        if self.debug or self.debug_backtrace:
                            errors = self.rest_error_to_dict(e, fk_obj_type)
                            print self.rest_error_dict_to_message(errors)
                        rows = []

                    # determine whether the foreign key can have a null
                    # value, in which case the row doesn't have to be deleted,
                    # just updated the foreign key to `None'.
                    if mi.is_force_delete_enabled(fk_obj_type):
                        delete = True
                    elif mi.is_null_allowed(fk_obj_type, fk_name):
                        delete = False
                    else:
                        delete = True

                    key = mi.pk(fk_obj_type)
                    for row in rows:
                        try:
                            if delete:
                                self.rest_delete_object(fk_obj_type, row[key])
                            else: # update
                                self.rest_update_object(fk_obj_type, key, row[key], 
                                                        { fk_name : None } )
                            errors = None
                        except Exception, e:
                            errors = self.rest_error_to_dict(e,
                                                             fk_obj_type + " "
                                                             + row[key])
                        if errors:
                            return self.rest_error_dict_to_message(errors)
                        self.debug_msg("cascade delete: %s: %s" % \
                                       (fk_obj_type, ', '.join(row[key].split('|'))))
                        if delete:
                            self.cascade_delete(fk_obj_type, row[key])

    #
    # --------------------------------------------------------------------------------
    # do_no
    #  Delete rows from a table, or update a field.  For fields which
    #  have defaults, 'no' referts the field to its default value.
    #
    def do_no(self, words):
        # format is no < obj_type > < id >
        if not self.in_config_mode():
            if len(words) < 1 or words[0] != 'debug':
                return self.error_msg("'no' command only valid in config mode")
        obj_type = self.get_current_mode_obj_type()
        option = words[0]
        #
        # manage deletion of complete rows in obj_types'
        #
        if option in self.obj_types_for_config_mode_starting_with():
            if not len(words) > 1:
                return self.error_msg("<id> must be specified for the object to delete")
            item = convert_alias_to_object_key(option, words[1])
 
            try:
                self.rest_delete_object(option, item)
                errors = None
            except Exception, e:
                errors = self.rest_error_to_dict(e, option + " " + item)
            #
            # cascade delete?
            if not errors:
                self.cascade_delete(option, item)
        #
        # manage removal/set-to-default of values in fields of an obj_type
        #
        elif option in self.fields_for_current_submode_starting_with(option):
            #
            # replace the obj_type with the alias obj_type when for
            # fields called 'alias' when the obj_type has one alias 
            if obj_type in mi.alias_obj_type_xref:
                aliases = mi.alias_obj_type_xref[obj_type]
                if option in aliases:
                    obj_type = option
                if len(aliases) == 1 and option == 'alias':
                    obj_type = aliases[0]
            if len(aliases) != 1:
                print self.error_msg("Internal 'no' more than one alias choice")
                if len(words) < 2:
                    return "Syntax: no %s <value>" % option
                item = words[1]
                try:
                    self.rest_delete_object(obj_type, item)
                    errors = None
                except Exception, e:
                    errors = self.rest_error_to_dict(e, obj_type + " " + item)
                return self.rest_error_dict_to_message(errors)
 
            key = mi.pk(obj_type)
            #
            # note: field_default_value returns None when no default is
            # provided.  its not clear whether default values are always
            # provided for fields which don't accept null values.
            #
            default_value = mi.field_default_value(obj_type, option)

            if mi.is_null_allowed(obj_type, option) and default_value:
                self.warning("'%s' accepts null and had a default "
                             "value; %s is set to the default value '%s" %
                             (obj_type, option, default_value))

            errors = self.rest_update_object(obj_type,
                                             key,
                                             self.get_current_mode_obj(),
                                             {option:default_value})
            # fall through to return
        elif self.in_config_vns_acl_mode() and self.ACL_RE.match(option):
            return self.do_vns_no(['access-list-entry'] + words)
        #elif self.in_config_controller_interface_mode() and 'firewall'.startswith(option):
        #    return self.do_no_firewall(words)
        else:
            try:
                command_words = ['no'] + words
                # Just try to execute the command. It will either succeed or
                # throw an exception
                return command.do_command(command_words)
            except urllib2.HTTPError, e:
                raise e
            except Exception, e:
                if self.debug or self.debug_backtrace:
                    traceback.print_exc()
                return self.error_msg("'%s' must be either a valid object type or a field" %
                                  option)

        # when errors == None, rest_error_dict_to_message returns None.
        return self.rest_error_dict_to_message(errors)


    #
    # --------------------------------------------------------------------------------
    # implement_ping
    #    Performs a traceroute to a switch or host.
    #    Input can either be a DPID, switch alias, or host (IP or domain).
    def implement_ping(self, data):
        
        count = '-c %d ' % data.get('count', 5)
        if not 'ip-address' in data:
            yield('Can\'t determine ping target')
            return

        ip_host = data['ip-address']
        if self.DPID_RE.match(ip_host):
            ip_host = self.get_ip_from_switch_dpid_or_alias(ip_host)

        cmd = 'ping %s%s' % (count, self.shell_escape(ip_host))
        for item in self.generate_subprocess_output(cmd):
            yield item


    #
    # --------------------------------------------------------------------------------
    # implement_traceroute
    #    Performs a traceroute to a switch or host.
    #    Input can either be a DPID, switch alias, or host (IP or domain).
    def implement_traceroute(self, data):

        if not 'ip-address' in data:
            yield('Can\'t determine traceroute target')
            return

        ip_host = data['ip-address']
        if self.DPID_RE.match(ip_host):
            ip_host = self.get_ip_from_switch_dpid_or_alias(ip_host)

        cmd = 'traceroute %s' % self.shell_escape(ip_host)
        for item in self.generate_subprocess_output(cmd):
            yield item

 
    #
    # --------------------------------------------------------------------------------
    # do_no_firewall
    #
    #def do_no_firewall(self, words):
    #    return self.do_firewall(words[1:], True)
        

    #
    # --------------------------------------------------------------------------------
    # firewall_rule_add_rule_to_entries
    #
    def firewall_rule_add_rule_to_entries(self, entries):
        for entry in entries:
            entry['rule'] = run_config.firewall_rule(entry)
        return entries


    #
    # --------------------------------------------------------------------------------
    # get_firewall_rules
    #  Returns a list of strings describing the firewall rules for a particular
    #  controller-node name.
    #
    def get_firewall_rules(self, node):
        key = mi.pk('firewall-rule')
        key_value = self.unique_key_from_non_unique([node])
        entries = self.get_table_from_store('firewall-rule', key, key_value)

        return self.firewall_rule_add_rule_to_entries(entries)

    #
    # --------------------------------------------------------------------------------
    # do_show_firewall
    #  Depends on get_firewall_rules to add 'rule' to entries so that
    #  the 'firewall-rule' table can display the rule's value in a
    #  easily identified syntax.
    #
    def do_show_firewall(self, words):
        return self.display_obj_type_rows('firewall-rule',
                                          self.get_firewall_rules(self.get_current_mode_obj()))

    # --------------------------------------------------------------------------------
    # handle_command
    #
    def handle_command(self, command_word, words):
        if type(command_word) == str:
            method = self.command_method_from_name(command_word)
            if method:
                return method(words)
        # XXX It would be better to only call do_command if it
        # was clear that this command actually existed.
        return command.do_command([command_word] + words)


    #
    # --------------------------------------------------------------------------------
    # find_with_quoting
    #
    #  Assumes start_index is not inside a quoted string.
    #
    @staticmethod
    def find_with_quoting(line, find_char, reverse=False, start_index=0):
        in_quoted_arg = False
        line_length = len(line)
        i = start_index
        found_index = -1;
        while i < line_length:
            c = line[i]
            if c in "\"'":
                if not in_quoted_arg:
                    quote_char = c
                    in_quoted_arg = True
                elif c == quote_char:
                    in_quoted_arg = False
                # otherwise leave in_quoted_arg True
            elif c == "\\" and in_quoted_arg:
                i += 1
            elif (c == find_char) and not in_quoted_arg:
                found_index = i
                if not reverse:
                    break
            i += 1
            
        return found_index
    
    #
    # --------------------------------------------------------------------------------
    # split_with_quoting
    #
    @staticmethod
    def split_with_quoting(line, separators=" \t"):
        word_list = []
        current_word = ""
        in_quoted_arg = False
        line_length = len(line)
        i = 0
        while i < line_length:
            c = line[i]
            i += 1
            if c in "\"'":
                if not in_quoted_arg:
                    in_quoted_arg = True
                    quote_char = c
                elif c == quote_char:
                    in_quoted_arg = False
                    word_list.append(current_word)
                    current_word = ""
                else:
                    current_word += c
            elif c == "\\" and in_quoted_arg:
                if i < line_length:
                    c = line[i]
                    current_word += c
                    i += 1
            elif (c in separators) and not in_quoted_arg:
                if current_word:
                    word_list.append(current_word)
                    current_word = ""
            else:
                current_word += c
                
        if current_word:
            word_list.append(current_word)
        
        return word_list
    
    #
    # --------------------------------------------------------------------------------
    # quote_item
    #  Some of the new model columns available as choices to select have the '|' 
    #  character as a separator.  For these choices to word, they need to be
    #  quoted
    #
    @staticmethod
    def quote_item(obj_type, item):
        if item.find("|") >= 0:
            return  '"' + str(item) + '"' 
        else:
            return str(item)

    #
    # --------------------------------------------------------------------------------
    # 
    def replay(self, file, verbose = True, command_replay = False):
        # Only replay the STR values, since the code ought to
        # stuff back the JSON values.
        play = open(file)
        rest_line_format = re.compile(r'^REST ([^ ]*)(  *)([^ ]*)(  *)(.*)$')
        cmd_line_format = re.compile(r'^COMMAND (.*)$')
        skip_command = True
        for line in play.read().split('\n'):
            # the format ought to be url<space>[STR|JSON]<space> ...
            match = rest_line_format.match(line)
            if match:
                if match.group(3) == 'STR':
                    if verbose:
                        print 'REST STR', match.group(1)
                    url_cache.save_url(match.group(1), match.group(5), 1000000)
                elif match.group(3) == 'JSON':
                    if verbose:
                        print 'REST JSON', match.group(1)
                    entries = json.loads(match.group(5))
                    url_cache.save_url(match.group(1), entries, 1000000)
                else:
                    print 'REST REPLAY NOT STR|JSON'
            elif len(line):
                match = cmd_line_format.match(line)
                if command_replay and match:
                    # skip the first command since it ought to be the replay enablement
                    if skip_command:
                        if verbose:
                            print 'SKIP COMMAND %s' % match.group(1)
                        skip_command = False
                    else:
                        line = self.split_with_quoting(match.group(1))
                        if verbose:
                            print 'COMMAND %s' % line
                        output = self.handle_multipart_line(line[0])
                        if output != None:
                            print output
                else:
                    print 'no MATCH +%s+' % line
        play.close()

    #
    # --------------------------------------------------------------------------------
    # handle_single_line
    #
    def handle_single_line(self, line):
        ret_val = None
        if len(line) > 0 and line[0]=="!": # skip comments
            return
        words = self.split_with_quoting(line)
        if not words:
            return
        #
        self.completion_reset()

        # Look for the replay keyword, use the first two tokens if the replay
        # keyword is in the first part of the command.
        if self.debug and len(words) >= 2:
            if words[0] == 'replay':
                # replay the file, remove the first two keywords
                self.replay(words[1], command_replay = len(words) == 2)
                if len(words) == 2:
                    return
                words = words[2:]

        # the first word of a line is either:
        # - a command - dependent on mode (show anywhere but configure only in enable)
        # - an object type - if we're in a config mode (either config or config submode)
        # - a field for an object - if we're in a config submode
        matches = [(x, "command") for x in self.commands_for_current_mode_starting_with(words[0])]
        matches.extend([(x, "config object") for x in self.obj_types_for_config_mode_starting_with(words[0])])
        matches.extend([(x, "field") for x in self.fields_for_current_submode_starting_with(words[0])])
        # LOOK!: robv Fix to work with field names where one name is a prefix of another
        if len(matches) > 1:
            for match_tuple in matches:
                if match_tuple[0] == words[0]:
                    matches = [match_tuple]
                    break
        if len(matches) == 1:
            match = matches[0]
            # Replace the (possibly) abbreviated argument with the full name.
            # This is so that the handlers don't need to all handle abbreviations.
            if type(match[0]) == str:
                words[0] = match[0]

            if match[1] == "field":
                ret_val = self.handle_field(words)
            elif match[1] == "config object":
                ret_val = self.handle_obj_type(words)
            else:
                ret_val = self.handle_command(words[0], words[1:])
                #ret_val = self.handle_command(match[0], words[1:])
        elif len(matches) > 1:
            ret_val = self.error_msg("%s is ambiguous\n" % words[0])
            for m in matches:
                ret_val += "%s (%s)\n" % m
        else:
            ret_val = self.error_msg("Unknown command: %s\n" % words[0])

        url_cache.command_finished(words)
        return ret_val

    #
    # --------------------------------------------------------------------------------
    # generate_pipe_output
    #
    def generate_pipe_output(self, p, output):
        fl = fcntl.fcntl(p.stdout, fcntl.F_GETFL)
        fcntl.fcntl(p.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK)

        for item in output:
            try:
                p.stdin.write(item)
            except IOError:
                break

            try:
                out_item = p.stdout.read()
                yield out_item
            except IOError:
                pass
            
        p.stdin.close()

        fcntl.fcntl(p.stdout, fcntl.F_SETFL, fl)
        while True:
            out_item = p.stdout.read()
            if (out_item):
                yield out_item
            else:
                p.stdout.close()
                break
        p.wait()

    #
    # --------------------------------------------------------------------------------
    # write_to_pipe
    #
    def write_to_pipe(self, p, output):
        for item in output:
            try:
                p.stdin.write(item)
            except IOError:
                break
        p.stdin.close()
        p.wait()
            
    #
    # --------------------------------------------------------------------------------
    # shell_escape
    #  Return a string, quoting the complete string, and correctly prefix any
    #  quotes within the string.
    #
    def shell_escape(self, arg):
        return "'" + arg.replace("'", "'\\''") + "'"

    #
    # --------------------------------------------------------------------------------
    # handle_pipe_and_redirect
    #
    def handle_pipe_and_redirect(self, pipe_cmds, redirect_target, output):
        # if redirect target is tftp/ftp/http/file, then we should actually stick
        # curl at the end of the pipe_cmds so it gets handled below
        if redirect_target:
            if redirect_target.startswith("tftp") or redirect_target.startswith("ftp") or \
               redirect_target.startswith("http") or redirect_target.startswith("file"):
                redirect_target = self.shell_escape(redirect_target)
                # add so it can be used below
                if pipe_cmds == None:
                    pipe_cmds = ""
                else:
                    pipe_cmds += " | "

                if redirect_target.startswith("ftp"): # shell_escape added quote
                    pipe_cmds += " curl -T - %s" % self.shell_escape(redirect_target)
                else:
                    pipe_cmds += " curl -X PUT -d @- %s" % self.shell_escape(redirect_target)

        if pipe_cmds:
            new_pipe_cmd_list = []
            for pipe_cmd in [x.strip() for x in pipe_cmds.split('|')]:
                # doing it this way let us handles spaces in the patterns
                # as opposed to using split/join which would compress space
                new_pipe_cmd = pipe_cmd
                m = re.search('^(\w+)(.*)$', pipe_cmd) 
                if m: 
                    first_tok = m.group(1)
                    rest_of_cmd = m.group(2).strip()
                    if first_tok.startswith("in"):
                        new_pipe_cmd = "grep -e " + rest_of_cmd
                    elif first_tok.startswith("ex"):
                        new_pipe_cmd = "grep -v -e" + rest_of_cmd
                    elif first_tok.startswith("begin"):
                        new_pipe_cmd =  "awk '/%s/,0'" % rest_of_cmd
                new_pipe_cmd_list.append(new_pipe_cmd)

            new_pipe_cmds = "|".join(new_pipe_cmd_list)
            if new_pipe_cmds:
                if redirect_target:
                    p = subprocess.Popen(new_pipe_cmds, 
                                         shell=True, 
                                         stdin=subprocess.PIPE, 
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.STDOUT)
                    output = self.generate_pipe_output(p, output)
                else:
                    p = subprocess.Popen(new_pipe_cmds, 
                                         shell=True, 
                                         stdin=subprocess.PIPE)
                    self.write_to_pipe(p, output)
                    output = None

        # only handle local file here as http/ftp were handled above via pipe
        if redirect_target:
            if redirect_target.startswith("config://"):
                m = re.search(self.local_name_pattern, redirect_target)
                if m:
                    join_output = ''.join(iter(output))
                    store_result = self.store.set_user_data_file(m.group(1), join_output)
                    if store_result:
                        result = json.loads(store_result)
                    else:
                        return self.error_msg("rest store result not json format")
                    if 'status' in result and result['status'] == 'success':
                        return None
                    elif 'message' not in result:
                        return self.error_msg("rest store result doesn't contain error message")
                    else:
                        return self.error_msg(result['message'])
                else:
                    print self.error_msg("invalid name-in-db (%s)\n" % redirect_target)
            else:
                return output

        return None

    #
    # --------------------------------------------------------------------------------
    # generate_command_output
    #
    @staticmethod
    def generate_command_output(ret_val):
        if (isinstance(ret_val, str) or \
            isinstance(ret_val, buffer) or \
            isinstance(ret_val, bytearray) or \
            isinstance(ret_val, unicode)):

            # yield ret_val
            if len(ret_val) and ret_val[-1] == '\n':
                ret_val = ret_val[:-1]
            for line in ret_val.split('\n'):
                yield line + '\n'
        elif ret_val != None:
            for item in ret_val:
                yield item

    #
    # --------------------------------------------------------------------------------
    # generate_line_output
    #
    # This is a generator that will generate the output of the 
    # command either as a string, or by iterating over a returned
    # iterable.  This way, a subcommand can return an iterable to 
    # lazily evaluate large amounts of output
    #
    def generate_line_output(self, line, dont_ask):
        while line:
            subline_index = self.find_with_quoting(line, ';')
            if subline_index < 0:
                subline_index = len(line)
            subline = line[:subline_index]
            line = line[subline_index+1:]
            ret_val = self.handle_single_line(subline)
            cnt = 1
            total_cnt = 0

            (col_width, screen_length) = self.pp.get_terminal_size()
            if type(self.length) == int:
                screen_length = self.length

            for item in self.generate_command_output(ret_val):
                if not dont_ask:
                    incr = 1 + (max((len(item.rstrip()) - 1), 0) / col_width)
                    if screen_length and cnt + incr >= screen_length:
                        raw_input('-- hit return to continue, %s) --' % total_cnt)
                        cnt = 0
                    cnt += incr
                    total_cnt += incr
                yield item

    #
    # --------------------------------------------------------------------------------
    # handle_multipart_line
    #
    # this is the outermost handler that should print
    #
    def handle_multipart_line(self, line):
        pipe_cmds = None
        redirect_target = None
        output = None

        # pattern is:
        # single line [; single line]* [| ...] [> {conf|ftp|http}]

        # first take off the potential redirect part then the pipe cmds
        redirect_index = self.find_with_quoting(line, '>', True)
        if redirect_index >= 0:
            redirect_target = line[redirect_index+1:].strip()
            line = line[:redirect_index].strip()
        pipe_index = self.find_with_quoting(line, '|')
        if pipe_index >= 0:
            pipe_cmds = line[pipe_index+1:].strip()
            line = line[:pipe_index].strip()
        # remaining text is single lines separated by ';' - handle them
        output = self.generate_line_output(line, pipe_cmds or redirect_target)

        # now output everything
        if pipe_cmds or redirect_target:
            output = self.handle_pipe_and_redirect(pipe_cmds, redirect_target, output)

        if output != None:
            for line in output:
                print line.rstrip()

    #
    # --------------------------------------------------------------------------------
    # cp_watch
    #
    def cp_watch(self, words, text, completion_char):
        if completion_char == ord('?'):
            if len(words) > 1:
                command.do_command_completion_help(words[1:], text)
            else:
                self.print_completion_help(self.help_splash([], text))
            return
        if len(words) == 1:
            items = self.commands_for_current_mode_starting_with(text)
            return utif.add_delim(items, ' ')
        else:   
            return command.do_command_completion(words[1:], text)

    #
    # --------------------------------------------------------------------------------
    # do_watch
    #   only called to display help
    #
    def do_watch(self, words):
        return 'watch: repeat indicated command after watch keyword'

    #
    # --------------------------------------------------------------------------------
    # handle_watch_command
    #
    # handle this here because this is a CLI-only command
    # LOOK! This could be using curses, but that has some complications with 
    # potentially messing up the terminal.  This is cheap but downside
    # is it uses up the scrollbuffer...
    #
    def handle_watch_command(self, line):
        #
        words = line.split()
        if len(words) == 0:
            return self.syntax_msg('watch: command to watch missing')
            
        if len(words) and words[0] == 'watch':
            return self.error_msg('watch command not supported for watch')

        while True: # must control-C to get out of this
            output = self.handle_multipart_line(line) 
            if output:
                os.system("clear")
                print "Executing %s " % line
                print output
            else:
                print "Executing %s " % line
            time.sleep(2)

    #
    #
    # --------------------------------------------------------------------------------
    # loop
    #  this is just dispatching the command and handling errors
    #
    def loop(self):
        command.action_invoke('wait-for-controller', (5))

        if self.controller:
            try:
                version_url = 'http://%s/rest/v1/system/version' % self.controller
                version = self.rest_simple_request_to_dict(version_url)
            except Exception, e:
                version = [{'controller' : 'REST API FAILURE\n'}]

            print "default controller: %s, %s" % (self.controller, 
                                                  version[0]['controller'])
            #
            # vns feature enablement.
            #  when vns is enabled, call a init procedure
            #
            if onos == 0:
                self.netvirt_feature_enabled()

        while self.run:
            # Get command line - this will use the command completion above
            try:
                #rest_to_model.validate_switch()
                url_cache.clear_cached_urls()
                line = raw_input(self.prompt)
                if self.batch:
                    print line
                m = re.search('^watch (.*)$', line) 
                if m:
                    self.handle_watch_command(m.group(1))
                else:
                    self.handle_multipart_line(line)
            except KeyboardInterrupt:
                self.completion_reset()
                print "\nInterrupt."
            except EOFError:
                print "\nExiting."
                return
            except urllib2.HTTPError, e:
                errors = self.rest_error_to_dict(e)
                print self.error_msg("%s" % self.rest_error_dict_to_message(errors))
            except urllib2.URLError, e:
                print self.error_msg("communicating with REST API server on %s " 
                                     "- Network error: %s" %
                                     (self.controller, e.reason))
            except Exception, e:
                print "\nError running command '%s'.\n" % line
                if self.debug or self.debug_backtrace:
                    traceback.print_exc()


#
# --------------------------------------------------------------------------------
# Initialization crazyness to make it work across platforms. Many platforms don't include
# GNU readline (e.g. mac os x) and we need to compensate for this

try:
    import readline
except ImportError:
    try:
        import pyreadline as readline
    except ImportError:
        print "Can't find any readline equivalent - aborting."
else:
    if 'libedit' in readline.__doc__:
        # needed for Mac, please fix Apple
        readline.parse_and_bind ("bind ^I rl_complete")
    else:
        readline.parse_and_bind("tab: complete")
        readline.parse_and_bind("?: possible-completions")

  
#
# --------------------------------------------------------------------------------
# Run the shell

def main():
    global cli
    # Uncomment the next two lines to enable remote debugging with PyDev
    # LOOK! Should have logic here that enables/disables the pydevd stuff
    # automatically without requiring uncommenting (and, more importantly,
    # remembering to recomment before committing).
    # (e.g. checking environment variable or something like that)
    #python_path = os.environ.get('PYTHONPATH', '')
    #if 'pydev.debug' in python_path:
    try:
        import pydevd
        pydevd.settrace()
    except Exception, e:
        pass

    # Process '--init' argument since it  gates progress to rest of processing
    # as this is a special argument, it is required to be first argument (if used)
    check_ready_file = True
    if len(sys.argv) > 1:
        if sys.argv[1] == '--init':
            check_ready_file = False
    
    # Do not start CLI till the systemn is ready
    # (allow user to ^C and get to SDNSh for debug etc)
    not_ready_file = '/opt/sdnplatform/run/starting'
    if check_ready_file:
        try:
            while True:
                if os.path.exists(not_ready_file):
                    with open(not_ready_file, "r") as f:
                        message = f.read()
                        if len(message):
                            print message,
                        else:
                            print 'Controller not yet ready ... waiting 5 sec'
                    time.sleep(5)
                else:
                    break
        except:
            if os.path.exists(not_ready_file):
                resp = raw_input('Controller is not yet ready. Do you still want to continue to the CLI? [n]')
                if resp and "yes".startswith(resp.lower()):
                    print 'Continuing with CLI despite initialization error ...'
                else:
                    print 'Aborting Controller CLI login.'
                    time.sleep(1)
                    return

    # Start CLI
    cli = SDNSh()
    cli.init()
    cli.loop()              

if __name__ == '__main__':
    main()
