content: # Copyright 2015 Spotify AB. All rights reserved.
  #
  # The contents of this file are licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
  #
  # 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.
  
  import sys
  from types import TracebackType
  from typing import Optional, Dict, Type, Any, List, Union
  
  from typing_extensions import Literal
  
  from netmiko import ConnectHandler, NetMikoTimeoutException
  from netutils.interface import canonical_interface_name
  
  # local modules
  import napalm.base.exceptions
  import napalm.base.helpers
  from napalm.base import constants as c
  from napalm.base import validate
  from napalm.base.exceptions import ConnectionException
  from napalm.base import models
  
  
  class NetworkDriver(object):
      hostname: str
      username: str
      password: str
      timeout: int
      force_no_enable: bool
      use_canonical_interface: bool
  
      def __init__(
          self,
          hostname: str,
          username: str,
          password: str,
          timeout: int = 60,
          optional_args: Optional[Dict] = None,
      ) -> None:
          """
          This is the base class you have to inherit from when writing your own Network Driver to
          manage any device. You will, in addition, have to override all the methods specified on
          this class. Make sure you follow the guidelines for every method and that you return the
          correct data.
  
          :param hostname: IP or FQDN of the device you want to connect to.
          :param username: Username you want to use
          :param password: Password
          :param timeout: Time in seconds to wait for the device to respond.
          :param optional_args: Pass additional arguments to underlying driver
          :return:
          """
          raise NotImplementedError
  
      def __enter__(self) -> "NetworkDriver":  # type: ignore
          try:
              self.open()
              return self
          except:  # noqa: E722
              # Swallow exception if __exit__ returns a True value
              if self.__exit__(*sys.exc_info()):
                  pass
              else:
                  raise
  
      def __exit__(  # type: ignore
          self,
          exc_type: Optional[Type[BaseException]],
          exc_value: Optional[BaseException],
          exc_traceback: Optional[TracebackType],
      ) -> Optional[Literal[False]]:
          self.close()
          if exc_type is not None and (
              exc_type.__name__ not in dir(napalm.base.exceptions)
              and exc_type.__name__ not in __builtins__.keys()  # type: ignore
          ):
              epilog = (
                  "NAPALM didn't catch this exception. Please, fill a bugfix on "
                  "https://github.com/napalm-automation/napalm/issues\n"
                  "Don't forget to include this traceback."
              )
              print(epilog)
              return False
          return None
  
      def __del__(self) -> None:
          """
          This method is used to cleanup when the program is terminated suddenly.
          We need to make sure the connection is closed properly and the configuration DB
          is released (unlocked).
          """
          try:
              if self.is_alive()["is_alive"]:
                  self.close()
          except Exception:
              pass
  
      def _netmiko_open(
          self, device_type: str, netmiko_optional_args: Optional[Dict] = None
      ) -> ConnectHandler:
          """Standardized method of creating a Netmiko connection using napalm attributes."""
          if netmiko_optional_args is None:
              netmiko_optional_args = {}
          try:
              self._netmiko_device = ConnectHandler(
                  device_type=device_type,
                  host=self.hostname,
                  username=self.username,
                  password=self.password,
                  timeout=self.timeout,
                  **netmiko_optional_args
              )
          except NetMikoTimeoutException:
              raise ConnectionException("Cannot connect to {}".format(self.hostname))
  
          # Disable enable mode if force_no_enable is true (for NAPALM drivers
          # that support force_no_enable)
          try:
              if not self.force_no_enable:
                  self._netmiko_device.enable()
          except AttributeError:
              self._netmiko_device.enable()
  
          return self._netmiko_device
  
      def _netmiko_close(self) -> None:
          """Standardized method of closing a Netmiko connection."""
          if getattr(self, "_netmiko_device", None):
              self._netmiko_device.disconnect()
              self._netmiko_device = None
          self.device: Optional[ConnectHandler] = None
  
      def open(self) -> None:
          """
          Opens a connection to the device.
          """
          raise NotImplementedError
  
      def close(self) -> None:
          """
          Closes the connection to the device.
          """
          raise NotImplementedError
  
      def is_alive(self) -> models.AliveDict:
          """
          Returns a flag with the connection state.
          Depends on the nature of API used by each driver.
          The state does not reflect only on the connection status (when SSH), it must also take into
          consideration other parameters, e.g.: NETCONF session might not be usable, althought the
          underlying SSH session is still open etc.
          """
          raise NotImplementedError
  
      def pre_connection_tests(self) -> None:
          """
          This is a helper function used by the cli tool cl_napalm_show_tech. Drivers
          can override this method to do some tests, show information, enable debugging, etc.
          before a connection with the device is attempted.
          """
          raise NotImplementedError
  
      def connection_tests(self) -> None:
          """
          This is a helper function used by the cli tool cl_napalm_show_tech. Drivers
          can override this method to do some tests, show information, enable debugging, etc.
          before a connection with the device has been successful.
          """
          raise NotImplementedError
  
      def post_connection_tests(self) -> None:
          """
          This is a helper function used by the cli tool cl_napalm_show_tech. Drivers
          can override this method to do some tests, show information, enable debugging, etc.
          after a connection with the device has been closed successfully.
          """
          raise NotImplementedError
  
      def load_template(
          self,
          template_name: str,
          template_source: Optional[str] = None,
          template_path: Optional[str] = None,
          **template_vars: Any
      ) -> None:
          """
          Will load a templated configuration on the device.
  
          :param cls: Instance of the driver class.
          :param template_name: Identifies the template name.
          :param template_source: Custom config template rendered and loaded on device
          :type template_source: optional
          :param template_path: Absolute path to directory for the configuration templates
          :type template_path: optional
          :param template_vars: Dictionary with arguments to be used when the template is rendered.
          :raise DriverTemplateNotImplemented: No template defined for the device type.
          :raise TemplateNotImplemented: The template specified in template_name does not exist in \
          the default path or in the custom path if any specified using parameter `template_path`.
          :raise TemplateRenderException: The template could not be rendered. Either the template \
          source does not have the right format, either the arguments in `template_vars` are not \
          properly specified.
          """
          return napalm.base.helpers.load_template(
              self,
              template_name,
              template_source=template_source,
              template_path=template_path,
              **template_vars
          )
  
      def load_replace_candidate(
          self, filename: Optional[str] = None, config: Optional[str] = None
      ) -> None:
          """
          Populates the candidate configuration. You can populate it from a file or from a string.
          If you send both a filename and a string containing the configuration, the file takes
          precedence.
  
          If you use this method the existing configuration will be replaced entirely by the
          candidate configuration once you commit the changes. This method will not change the
          configuration by itself.
  
          :param filename: Path to the file containing the desired configuration. By default is None.
          :param config: String containing the desired configuration.
          :raise ReplaceConfigException: If there is an error on the configuration sent.
          """
          raise NotImplementedError
  
      def load_merge_candidate(
          self, filename: Optional[str] = None, config: Optional[str] = None
      ) -> None:
          """
          Populates the candidate configuration. You can populate it from a file or from a string.
          If you send both a filename and a string containing the configuration, the file takes
          precedence.
  
          If you use this method the existing configuration will be merged with the candidate
          configuration once you commit the changes. This method will not change the configuration
          by itself.
  
          :param filename: Path to the file containing the desired configuration. By default is None.
          :param config: String containing the desired configuration.
          :raise MergeConfigException: If there is an error on the configuration sent.
          """
          raise NotImplementedError
  
      def compare_config(self) -> str:
          """
          :return: A string showing the difference between the running configuration and the \
          candidate configuration. The running_config is loaded automatically just before doing the \
          comparison so there is no need for you to do it.
          """
          raise NotImplementedError
  
      def commit_config(self, message: str = "", revert_in: Optional[int] = None) -> None:
          """
          Commits the changes requested by the method load_replace_candidate or load_merge_candidate.
  
          NAPALM drivers that support 'commit confirm' should cause self.has_pending_commit
          to return True when a 'commit confirm' is in progress.
  
          Implementations should raise an exception if commit_config is called multiple times while a
          'commit confirm' is pending.
  
          :param message: Optional - configuration session commit message
          :type message: str
          :param revert_in: Optional - number of seconds before the configuration will be reverted
          :type revert_in: int|None
          """
          raise NotImplementedError
  
      def confirm_commit(self) -> None:
          """
          Confirm the changes requested via commit_config when commit_confirm=True.
  
          Should cause self.has_pending_commit to return False when done.
          """
          raise NotImplementedError
  
      def has_pending_commit(self) -> bool:
          """
          :return Boolean indicating if a commit_config that needs confirmed is in process.
          """
          raise NotImplementedError
  
      def discard_config(self) -> None:
          """
          Discards the configuration loaded into the candidate.
          """
          raise NotImplementedError
  
      def rollback(self) -> None:
          """
          If changes were made, revert changes to the original state.
  
          If commit confirm is in process, rollback changes and clear has_pending_commit.
          """
          raise NotImplementedError
  
      def get_facts(self) -> models.FactsDict:
          """
          Returns a dictionary containing the following information:
           * uptime - Uptime of the device in seconds.
           * vendor - Manufacturer of the device.
           * model - Device model.
           * hostname - Hostname of the device
           * fqdn - Fqdn of the device
           * os_version - String with the OS version running on the device.
           * serial_number - Serial number of the device
           * interface_list - List of the interfaces of the device
  
          Example::
  
              {
              'uptime': 151005.57332897186,
              'vendor': u'Arista',
              'os_version': u'4.14.3-2329074.gaatlantarel',
              'serial_number': u'SN0123A34AS',
              'model': u'vEOS',
              'hostname': u'eos-router',
              'fqdn': u'eos-router',
              'interface_list': [u'Ethernet2', u'Management1', u'Ethernet1', u'Ethernet3']
              }
  
          """
          raise NotImplementedError
  
      def get_interfaces(self) -> Dict[str, models.InterfaceDict]:
          """
          Returns a dictionary of dictionaries. The keys for the first dictionary will be the \
          interfaces in the devices. The inner dictionary will containing the following data for \
          each interface:
  
           * is_up (True/False)
           * is_enabled (True/False)
           * description (string)
           * last_flapped (float in seconds)
           * speed (float in Mbit)
           * MTU (in Bytes)
           * mac_address (string)
  
          Example::
  
              {
              u'Management1':
                  {
                  'is_up': False,
                  'is_enabled': False,
                  'description': '',
                  'last_flapped': -1.0,
                  'speed': 1000.0,
                  'mtu': 1500,
                  'mac_address': 'FA:16:3E:57:33:61',
                  },
              u'Ethernet1':
                  {
                  'is_up': True,
                  'is_enabled': True,
                  'description': 'foo',
                  'last_flapped': 1429978575.1554043,
                  'speed': 1000.0,
                  'mtu': 1500,
                  'mac_address': 'FA:16:3E:57:33:62',
                  },
              u'Ethernet2':
                  {
                  'is_up': True,
                  'is_enabled': True,
                  'description': 'bla',
                  'last_flapped': 1429978575.1555667,
                  'speed': 1000.0,
                  'mtu': 1500,
                  'mac_address': 'FA:16:3E:57:33:63',
                  },
              u'Ethernet3':
                  {
                  'is_up': False,
                  'is_enabled': True,
                  'description': 'bar',
                  'last_flapped': -1.0,
                  'speed': 1000.0,
                  'mtu': 1500,
                  'mac_address': 'FA:16:3E:57:33:64',
                  }
              }
          """
          raise NotImplementedError
  
      def get_lldp_neighbors(self) -> Dict[str, List[models.LLDPNeighborDict]]:
          """
          Returns a dictionary where the keys are local ports and the value is a list of \
          dictionaries with the following information:
              * hostname
              * port
  
          Example::
  
              {
              u'Ethernet2':
                  [
                      {
                      'hostname': u'junos-unittest',
                      'port': u'520',
                      }
                  ],
              u'Ethernet3':
                  [
                      {
                      'hostname': u'junos-unittest',
                      'port': u'522',
                      }
                  ],
              u'Ethernet1':
                  [
                      {
                      'hostname': u'junos-unittest',
                      'port': u'519',
                      },
                      {
                      'hostname': u'ios-xrv-unittest',
                      'port': u'Gi0/0/0/0',
                      }
                  ],
              u'Management1':
                  [
                      {
                      'hostname': u'junos-unittest',
                      'port': u'508',
                      }
                  ]
              }
          """
          raise NotImplementedError
  
      def get_bgp_neighbors(self) -> Dict[str, models.BGPStateNeighborsPerVRFDict]:
          """
          Returns a dictionary of dictionaries. The keys for the first dictionary will be the vrf
          (global if no vrf). The inner dictionary will contain the following data for each vrf:
  
            * router_id
            * peers - another dictionary of dictionaries. Outer keys are the IPs of the neighbors. \
              The inner keys are:
               * local_as (int)
               * remote_as (int)
               * remote_id - peer router id
               * is_up (True/False)
               * is_enabled (True/False)
               * description (string)
               * uptime (int in seconds)
               * address_family (dictionary) - A dictionary of address families available for the \
                 neighbor. So far it can be 'ipv4' or 'ipv6'
                  * received_prefixes (int)
                  * accepted_prefixes (int)
                  * sent_prefixes (int)
  
              Note, if is_up is False and uptime has a positive value then this indicates the
              uptime of the last active BGP session.
  
              Example::
  
                  {
                    "global": {
                      "router_id": "10.0.1.1",
                      "peers": {
                        "10.0.0.2": {
                          "local_as": 65000,
                          "remote_as": 65000,
                          "remote_id": "10.0.1.2",
                          "is_up": True,
                          "is_enabled": True,
                          "description": "internal-2",
                          "uptime": 4838400,
                          "address_family": {
                            "ipv4": {
                              "sent_prefixes": 637213,
                              "accepted_prefixes": 3142,
                              "received_prefixes": 3142
                            },
                            "ipv6": {
                              "sent_prefixes": 36714,
                              "accepted_prefixes": 148,
                              "received_prefixes": 148
                            }
                          }
                        }
                      }
                    }
                  }
          """
          raise NotImplementedError
  
      def get_environment(self) -> models.EnvironmentDict:
          """
          Returns a dictionary where:
  
              * fans is a dictionary of dictionaries where the key is the location and the values:
                   * status (True/False) - True if it's ok, false if it's broken
              * temperature is a dict of dictionaries where the key is the location and the values:
                   * temperature (float) - Temperature in celsius the sensor is reporting.
                   * is_alert (True/False) - True if the temperature is above the alert threshold
                   * is_critical (True/False) - True if the temp is above the critical threshold
              * power is a dictionary of dictionaries where the key is the PSU id and the values:
                   * status (True/False) - True if it's ok, false if it's broken
                   * capacity (float) - Capacity in W that the power supply can support
                   * output (float) - Watts drawn by the system
              * cpu is a dictionary of dictionaries where the key is the ID and the values
                   * %usage
              * memory is a dictionary with:
                   * available_ram (int) - Total amount of RAM installed in the device
                   * used_ram (int) - RAM in use in the device
          """
          raise NotImplementedError
  
      def get_interfaces_counters(self) -> Dict[str, models.InterfaceCounterDict]:
          """
          Returns a dictionary of dictionaries where the first key is an interface name and the
          inner dictionary contains the following keys:
  
              * tx_errors (int)
              * rx_errors (int)
              * tx_discards (int)
              * rx_discards (int)
              * tx_octets (int)
              * rx_octets (int)
              * tx_unicast_packets (int)
              * rx_unicast_packets (int)
              * tx_multicast_packets (int)
              * rx_multicast_packets (int)
              * tx_broadcast_packets (int)
              * rx_broadcast_packets (int)
  
          Example::
  
              {
                  u'Ethernet2': {
                      'tx_multicast_packets': 699,
                      'tx_discards': 0,
                      'tx_octets': 88577,
                      'tx_errors': 0,
                      'rx_octets': 0,
                      'tx_unicast_packets': 0,
                      'rx_errors': 0,
                      'tx_broadcast_packets': 0,
                      'rx_multicast_packets': 0,
                      'rx_broadcast_packets': 0,
                      'rx_discards': 0,
                      'rx_unicast_packets': 0
                  },
                  u'Management1': {
                       'tx_multicast_packets': 0,
                       'tx_discards': 0,
                       'tx_octets': 159159,
                       'tx_errors': 0,
                       'rx_octets': 167644,
                       'tx_unicast_packets': 1241,
                       'rx_errors': 0,
                       'tx_broadcast_packets': 0,
                       'rx_multicast_packets': 0,
                       'rx_broadcast_packets': 80,
                       'rx_discards': 0,
                       'rx_unicast_packets': 0
                  },
                  u'Ethernet1': {
                       'tx_multicast_packets': 293,
                       'tx_discards': 0,
                       'tx_octets': 38639,
                       'tx_errors': 0,
                       'rx_octets': 0,
                       'tx_unicast_packets': 0,
                       'rx_errors': 0,
                       'tx_broadcast_packets': 0,
                       'rx_multicast_packets': 0,
                       'rx_broadcast_packets': 0,
                       'rx_discards': 0,
                       'rx_unicast_packets': 0
                  }
              }
          """
          raise NotImplementedError
  
      def get_lldp_neighbors_detail(
          self, interface: str = ""
      ) -> models.LLDPNeighborsDetailDict:
          """
          Returns a detailed view of the LLDP neighbors as a dictionary
          containing lists of dictionaries for each interface.
  
          Empty entries are returned as an empty string (e.g. '') or list where applicable.
  
          Inner dictionaries contain fields:
  
              * parent_interface (string)
              * remote_port (string)
              * remote_port_description (string)
              * remote_chassis_id (string)
              * remote_system_name (string)
              * remote_system_description (string)
              * remote_system_capab (list) with any of these values
                  * other
                  * repeater
                  * bridge
                  * wlan-access-point
                  * router
                  * telephone
                  * docsis-cable-device
                  * station
              * remote_system_enabled_capab (list)
  
          Example::
  
              {
                  'TenGigE0/0/0/8': [
                      {
                          'parent_interface': u'Bundle-Ether8',
                          'remote_chassis_id': u'8c60.4f69.e96c',
                          'remote_system_name': u'switch',
                          'remote_port': u'Eth2/2/1',
                          'remote_port_description': u'Ethernet2/2/1',
                          'remote_system_description': u'''Cisco Nexus Operating System (NX-OS)
                                Software 7.1(0)N1(1a)
                                TAC support: http://www.cisco.com/tac
                                Copyright (c) 2002-2015, Cisco Systems, Inc. All rights reserved.''',
                          'remote_system_capab': ['bridge', 'repeater'],
                          'remote_system_enable_capab': ['bridge']
                      }
                  ]
              }
          """
          raise NotImplementedError
  
      def get_bgp_config(
          self, group: str = "", neighbor: str = ""
      ) -> models.BGPConfigGroupDict:
          """
          Returns a dictionary containing the BGP configuration.
          Can return either the whole config, either the config only for a group or neighbor.
  
          :param group: Returns the configuration of a specific BGP group.
          :param neighbor: Returns the configuration of a specific BGP neighbor.
  
          Main dictionary keys represent the group name and the values represent a dictionary having
          the keys below.  A default group named "_" will contain information regarding global
          settings and any neighbors that are not members of a group.
  
              * type (string)
              * description (string)
              * apply_groups (string list)
              * multihop_ttl (int)
              * multipath (True/False)
              * local_address (string)
              * local_as (int)
              * remote_as (int)
              * import_policy (string)
              * export_policy (string)
              * remove_private_as (True/False)
              * prefix_limit (dictionary)
              * neighbors (dictionary)
  
          Neighbors is a dictionary of dictionaries with the following keys:
  
              * description (string)
              * import_policy (string)
              * export_policy (string)
              * local_address (string)
              * local_as (int)
              * remote_as (int)
              * authentication_key (string)
              * prefix_limit (dictionary)
              * route_reflector_client (True/False)
              * nhs (True/False)
  
          The inner dictionary prefix_limit has the same structure for both layers::
  
              {
                  [FAMILY_NAME]: {
                      [FAMILY_TYPE]: {
                          'limit': [LIMIT],
                          ... other options
                      }
                  }
              }
  
          Example::
  
              {
                  'PEERS-GROUP-NAME':{
                      'type'              : u'external',
                      'description'       : u'Here we should have a nice description',
                      'apply_groups'      : [u'BGP-PREFIX-LIMIT'],
                      'import_policy'     : u'PUBLIC-PEER-IN',
                      'export_policy'     : u'PUBLIC-PEER-OUT',
                      'remove_private_as' : True,
                      'multipath'         : True,
                      'multihop_ttl'      : 30,
                      'neighbors'         : {
                          '192.168.0.1': {
                              'description'   : 'Facebook [CDN]',
                              'prefix_limit'  : {
                                  'inet': {
                                      'unicast': {
                                          'limit': 100,
                                          'teardown': {
                                              'threshold' : 95,
                                              'timeout'   : 5
                                          }
                                      }
                                  }
                              }
                              'remote_as'             : 32934,
                              'route_reflector_client': False,
                              'nhs'                   : True
                          },
                          '172.17.17.1': {
                              'description'   : 'Twitter [CDN]',
                              'prefix_limit'  : {
                                  'inet': {
                                      'unicast': {
                                          'limit': 500,
                                          'no-validate': 'IMPORT-FLOW-ROUTES'
                                      }
                                  }
                              }
                              'remote_as'               : 13414
                              'route_reflector_client': False,
                              'nhs'                   : False
                          }
                      }
                  }
              }
          """
          raise NotImplementedError
  
      def cli(
          self, commands: List[str], encoding: str = "text"
      ) -> Dict[str, Union[str, Dict[str, Any]]]:
          """
          Will execute a list of commands and return the output in a dictionary format.
  
          Example::
  
              {
                  u'show version and haiku':  u'''Hostname: re0.edge01.arn01
                                                  Model: mx480
                                                  Junos: 13.3R6.5
  
                                                          Help me, Obi-Wan
                                                          I just saw Episode Two
                                                          You're my only hope
                                              ''',
                  u'show chassis fan'     :   u'''
                      Item               Status  RPM     Measurement
                      Top Rear Fan       OK      3840    Spinning at intermediate-speed
                      Bottom Rear Fan    OK      3840    Spinning at intermediate-speed
                      Top Middle Fan     OK      3900    Spinning at intermediate-speed
                      Bottom Middle Fan  OK      3840    Spinning at intermediate-speed
                      Top Front Fan      OK      3810    Spinning at intermediate-speed
                      Bottom Front Fan   OK      3840    Spinning at intermediate-speed'''
              }
          """
          raise NotImplementedError
  
      def get_bgp_neighbors_detail(
          self, neighbor_address: str = ""
      ) -> Dict[str, models.PeerDetailsDict]:
          """
          Returns a detailed view of the BGP neighbors as a dictionary of lists.
  
          :param neighbor_address: Retuns the statistics for a spcific BGP neighbor.
  
          Returns a dictionary of dictionaries. The keys for the first dictionary will be the vrf
          (global if no vrf).
          The keys of the inner dictionary represent the AS number of the neighbors.
          Leaf dictionaries contain the following fields:
  
              * up (True/False)
              * local_as (int)
              * remote_as (int)
              * router_id (string)
              * local_address (string)
              * routing_table (string)
              * local_address_configured (True/False)
              * local_port (int)
              * remote_address (string)
              * remote_port (int)
              * multihop (True/False)
              * multipath (True/False)
              * remove_private_as (True/False)
              * import_policy (string)
              * export_policy (string)
              * input_messages (int)
              * output_messages (int)
              * input_updates (int)
              * output_updates (int)
              * messages_queued_out (int)
              * connection_state (string)
              * previous_connection_state (string)
              * last_event (string)
              * suppress_4byte_as (True/False)
              * local_as_prepend (True/False)
              * holdtime (int)
              * configured_holdtime (int)
              * keepalive (int)
              * configured_keepalive (int)
              * active_prefix_count (int)
              * received_prefix_count (int)
              * accepted_prefix_count (int)
              * suppressed_prefix_count (int)
              * advertised_prefix_count (int)
              * flap_count (int)
  
          Example::
  
              {
                  'global': {
                      8121: [
                          {
                              'up'                        : True,
                              'local_as'                  : 13335,
                              'remote_as'                 : 8121,
                              'local_address'             : u'172.101.76.1',
                              'local_address_configured'  : True,
                              'local_port'                : 179,
                              'routing_table'             : u'inet.0',
                              'remote_address'            : u'192.247.78.0',
                              'remote_port'               : 58380,
                              'multihop'                  : False,
                              'multipath'                 : True,
                              'remove_private_as'         : True,
                              'import_policy'             : u'4-NTT-TRANSIT-IN',
                              'export_policy'             : u'4-NTT-TRANSIT-OUT',
                              'input_messages'            : 123,
                              'output_messages'           : 13,
                              'input_updates'             : 123,
  