class ConfigCommandProcessor(AristaBaseCommandProcessor):
    interface_separator = ""

    def __init__(self, display_class, config_vlan, config_interface):
        super(ConfigCommandProcessor, self).__init__(display_class)
        self.config_vlan_processor = config_vlan
        self.config_interface_processor = config_interface

    def get_prompt(self):
        return self.switch_configuration.name + "(config)#"

    def do_vlan(self, raw_number, *_):
        try:
            number = self.read_vlan_number(raw_number)
        except VlanNumberIsZero:
            self.display.invalid_command(self, "Incomplete command")
            return
        except InvalidVlanNumber:
            self.display.invalid_command(self, "Invalid input")
            return

        vlan = self.switch_configuration.get_vlan(number)
        if not vlan:
            vlan = self.switch_configuration.new("Vlan", number)
            self.switch_configuration.add_vlan(vlan)
        self.move_to(self.config_vlan_processor, vlan)

    def do_no_vlan(self, *args):
        vlan = self.switch_configuration.get_vlan(int(args[0]))
        if vlan:
            self.switch_configuration.remove_vlan(vlan)

    def do_interface(self, *args):
        try:
            interface_name = self.read_interface_name(args)
        except NameIsIncomplete:
            self.display.invalid_command(self, "Incomplete command")
            return
        except InvalidVlanNumber:
            self.display.invalid_command(self, "Invalid input")
            return

        port = self.switch_configuration.get_port_by_partial_name(interface_name)

        if port:
            self.move_to(self.config_interface_processor, port)
        else:
            name, if_id = split_port_name(interface_name)
            if name == "Vlan":
                new_vlan_interface = self.switch_configuration.new("VlanPort", if_id, interface_name)
                self.switch_configuration.add_port(new_vlan_interface)
                self.move_to(self.config_interface_processor, new_vlan_interface)
            else:
                raise NotImplementedError

    def do_no_interface(self, *args):
        port = self.switch_configuration.get_port_by_partial_name(self.read_interface_name(args))
        if port is not None:
            self.switch_configuration.remove_port(port)
        self.sub_processor = None

    def do_exit(self):
        self.is_done = True class ConfigInterfaceCommandProcessor(AristaBaseCommandProcessor):
    def init(self, switch_configuration, terminal_controller, logger, piping_processor, *args):
        super(ConfigInterfaceCommandProcessor, self).init(switch_configuration, terminal_controller, logger,
                                                          piping_processor)
        self.port = args[0]

    def get_prompt(self):
        return self.switch_configuration.name + "(config-if-{})#".format(short_port_name(self.port.name))

    def do_ip(self, *args):
        if "address".startswith(args[0]):
            self._add_ip(args[1:])
        elif "helper-address".startswith(args[0]):
            self._add_ip_helper(args[1:])
        elif "virtual-router".startswith(args[0]) and "address".startswith(args[1]):
            self._add_virtual_router_address(*args[2:])
        else:
            raise NotImplementedError

    def do_no_ip(self, *args):
        if "address".startswith(args[0]):
            self._remove_ip(args[1:])
        elif "helper-address".startswith(args[0]):
            self._remove_ip_helper(args[1:])
        elif "virtual-router".startswith(args[0]) and "address".startswith(args[1]) and len(args) == 2:
            self._remove_all_virtual_router_addresses()
        elif "virtual-router".startswith(args[0]) and "address".startswith(args[1]):
            self._remove_virtual_router_address(*args[2:])
        else:
            raise NotImplementedError

    def do_load_interval(self, *args):
        if len(args) == 0:
            self.display.invalid_command(self, "Incomplete command")
            return None

        load_interval = args[0]
        if not _is_valid_load_interval(load_interval):
            self.display.invalid_command(self, "Invalid input")
            return None

        self.port.load_interval = load_interval

    def do_no_load_interval(self):
        self.port.load_interval = None

    def do_mpls(self, *args):
        if args[0] == 'ip':
            self.port.mpls_ip = True
        else:
            raise NotImplementedError

    def do_no_mpls(self, *args):
        if args[0] == 'ip':
            self.port.mpls_ip = False
        else:
            raise NotImplementedError

    def do_switchport(self, *args):
        operations = [
            (("mode",), self._switchport_mode),
            (("trunk", "allowed", "vlan", "add"), self._switchport_trunk_allowed_vlan_add),
            (("trunk", "allowed", "vlan", "remove"), self._switchport_trunk_allowed_vlan_remove),
            (("trunk", "allowed", "vlan", "none"), self._switchport_trunk_allowed_vlan_none),
            (("trunk", "allowed", "vlan", "all"), self._switchport_trunk_allowed_vlan_all),
            (("trunk", "allowed", "vlan"), self._switchport_trunk_allowed_vlan)
        ]

        for cmd, target in operations:
            if _is_cmd(args, *cmd):
                target(*args[len(cmd):])
                return

        self.display.invalid_command(self, "Incomplete command")

    def do_no_switchport(self, *args):
        if _is_cmd(args, "mode"):
            self.port.mode = None
        elif _is_cmd(args, "trunk", "allowed", "vlan"):
            self.port.trunk_vlans = None
        else:
            raise NotImplementedError

    def do_exit(self):
        self.is_done = True

    def _add_ip(self, args):
        new_ip, remainder = _read_ip(args)
        if len(remainder) > 1:
            raise NotImplementedError
        ip_owner, existing_ip = self.switch_configuration.get_port_and_ip_by_ip(new_ip.ip)
        if not ip_owner or ip_owner == self.port:
            if len(remainder) > 0 and "secondary".startswith(remainder[0]):
                self.port.add_ip(new_ip)
            else:
                if len(self.port.ips) == 0:
                    self.port.add_ip(new_ip)
                else:
                    self.port.ips[0] = new_ip
        else:
            self.display.invalid_result(
                self, "Subnet {new} overlaps with existing subnet {current} of interface {owner}".format(
                    new=new_ip.network,
                    current=existing_ip.network,
                    owner=ip_owner.name))
        self.port.vendor_specific["has-internet-protocol"] = True

    def _remove_ip(self, args):
        if len(args) == 0:
            for ip in list(reversed(self.port.ips)):
                self.port.remove_ip(ip)
        else:
            new_ip, remainder = _read_ip(args)

            if len(remainder) > 0 and "secondary".startswith(remainder[0]):
                if new_ip not in self.port.ips[1:]:
                    self.display.warning(self, "Address {} was not found for deletion".format(new_ip))
                    return
            else:
                if new_ip != self.port.ips[0]:
                    self.display.invalid_command(self, "Address {} does not match primary address {}"
                                                 .format(new_ip, self.port.ips[0]))
                    return

                if len(self.port.ips) > 1:
                    self.display.invalid_command(self, "Primary address cannot be deleted before secondary")
                    return

            self.port.remove_ip(new_ip)

    def _add_ip_helper(self, args):
        helper_address = self._read_helper_address(args)

        if helper_address is not None and args[0] not in self.port.ip_helpers:
            self.port.ip_helpers.append(args[0])

    def _remove_ip_helper(self, args):
        if len(args) == 0:
            self.port.ip_helpers = []
        else:
            helper_address = self._read_helper_address(args)
            if helper_address:
                self.port.ip_helpers.remove(helper_address)

    def _read_helper_address(self, args):
        if len(args) == 0:
            self.display.invalid_command(self, "Incomplete command")
            return None

        if not _is_word(args[0]) or len(args) > 1:
            self.display.invalid_command(self, "Invalid input")
            return None

        if len(args[0]) > 64:
            self.display.invalid_result(
                self,
                "Host name is invalid. Host name must contain only alphanumeric characters, '.' and '-'.\n"
                "It must begin and end with an alphanumeric character.\n"
                "Maximum characters in hostname is 64.")
            return None

        return args[0]

    @with_params(1)
    def _switchport_mode(self, mode):
        mode = mode.lower()
        if mode not in ("trunk",):
            self.display.invalid_command(self, "Invalid input")
            return

        self.port.mode = mode

    @with_params(1)
    @with_vlan_list
    def _switchport_trunk_allowed_vlan_add(self, vlans):
        if not _has_all_vlans(self.port):
            self.port.trunk_vlans += vlans

    @with_params(1)
    @with_vlan_list
    def _switchport_trunk_allowed_vlan_remove(self, vlans):
        if self.port.trunk_vlans is None:
            self.port.trunk_vlans = list(range(1, 4095))
        for v in vlans:
            if v in self.port.trunk_vlans:
                self.port.trunk_vlans.remove(v)

    @with_params(0)
    def _switchport_trunk_allowed_vlan_none(self):
        self.port.trunk_vlans = []

    @with_params(0)
    def _switchport_trunk_allowed_vlan_all(self, *extra):
        self.port.trunk_vlans = None

    @with_params(1)
    @with_vlan_list
    def _switchport_trunk_allowed_vlan(self, vlans):
        self.port.trunk_vlans = vlans

    @with_params(1)
    def _add_virtual_router_address(self, address):
        try:
            ipn = IPNetwork(address)
        except AddrFormatError:
            self.display.invalid_command(self, "Invalid input")
            return

        for i, varp_address in enumerate(self.port.varp_addresses):
            if varp_address.ip == ipn.ip:
                self.port.varp_addresses[i] = ipn
                break
        else:
            self.port.varp_addresses.append(ipn)

    @with_params(1)
    def _remove_virtual_router_address(self, address):
        ipn = IPNetwork(address)

        for i, varp_address in enumerate(self.port.varp_addresses):
            if varp_address.ip == ipn.ip:
                self.port.varp_addresses.pop(i)
                return

        raise NotImplementedError

    def _remove_all_virtual_router_addresses(self):
        self.port.varp_addresses = [] class ConfigVlanCommandProcessor(AristaBaseCommandProcessor):
    def init(self, switch_configuration, terminal_controller, logger, piping_processor, *args):
        super(ConfigVlanCommandProcessor, self).init(switch_configuration, terminal_controller, logger,
                                                     piping_processor)
        self.vlan = args[0]

    def get_prompt(self):
        return self.switch_configuration.name + "(config-vlan-{})#".format(self.vlan.number)

    def do_name(self, *args):
        self.vlan.name = (args[0][:32])

    def do_exit(self):
        self.is_done = True class DefaultCommandProcessor(AristaBaseCommandProcessor):
    def __init__(self, display_class, enabled):
        super(DefaultCommandProcessor, self).__init__(display_class)
        self.enabled_processor = enabled

    def get_prompt(self):
        return self.switch_configuration.name + ">"

    def do_exit(self):
        raise TerminalExitSignal()

    def do_enable(self):
        self.move_to(self.enabled_processor)

    def do_show(self, *args):
        if "vlan".startswith(args[0]):
            self._show_vlan(*args[1:])
        elif "interfaces".startswith(args[0]) and "switchport".startswith(args[-1]):
            self._show_interfaces_switchport(*args[1:-1])
        elif "interfaces".startswith(args[0]):
            self._show_interfaces(*args[1:])
        else:
            raise NotImplementedError

    def _show_vlan(self, *args):
        if len(args) == 1:
            try:
                number = self.read_vlan_number(args[0])
            except VlanNumberIsZero:
                self.display.invalid_command(self, "Incomplete command")
                return
            except InvalidVlanNumber:
                self.display.invalid_command(self, "Invalid input")
                return

            vlans = list(filter(lambda e: e.number == number, self.switch_configuration.vlans))
            if len(vlans) == 0:
                self.display.invalid_result(self, "VLAN {} not found in current VLAN database".format(args[0]),
                                            json_data=_to_vlans_json([]))
                return
        else:
            vlans = self.switch_configuration.vlans

        self.display.show_vlans(self, _to_vlans_json(vlans))

    @with_valid_port_list
    def _show_interfaces(self, ports):
        self.display.show_interface(self, _to_interface_json(ports))

    @with_valid_port_list
    def _show_interfaces_switchport(self, ports):
        phys_ports = filter(lambda p: not isinstance(p, VlanPort), ports)
        self.display.show_interface_switchport(self, _to_switchport_json(phys_ports)) class EnabledCommandProcessor(DefaultCommandProcessor):
    def __init__(self, display_class, config):
        super(EnabledCommandProcessor, self).__init__(display_class, enabled=None)
        self.config_processor = config

    def get_prompt(self):
        return self.switch_configuration.name + "#"

    def do_enable(self, *args):
        pass

    def do_configure(self, *_):
        self.move_to(self.config_processor)

    def do_show(self, *args):
        if "running-config".startswith(args[0]):
            self._show_running_config(*args[1:])
        else:
            super(EnabledCommandProcessor, self).do_show(*args)

    def do_terminal(self, *_):
        self.write("Pagination disabled.")

    def do_write(self, *_):
        self.switch_configuration.commit()
        self.write_line("Copy completed successfully.")

    def _show_running_config(self, *args):
        if "interfaces".startswith(args[0]):
            names = self.read_multiple_interfaces_name(args[1:])
            if names is not None:
                self._show_run_interfaces(sorted(filter(lambda e: e, (self.switch_configuration.get_port_by_partial_name(p) for p in names)), key=lambda e: e.name))
        else:
            self._show_header()
            self._show_run_vlans(sorted(self.switch_configuration.vlans, key=lambda v: v.number))
            self.write_line("end")

    def _show_header(self):
        self.write_line("! Command: show running-config all")
        self.write_line("! device: {} (vEOS, EOS-4.20.8M)".format(self.switch_configuration.name))
        self.write_line("!")
        self.write_line("! boot system flash:/vEOS-lab.swi")
        self.write_line("!")

    def _show_run_vlans(self, vlans):
        for vlan in vlans:
            self.write_line("vlan {}".format(vlan.number))
            self.write_line("   name {}".format(vlan_display_name(vlan)))
            self.write_line("   mac address learning")
            self.write_line("   state active")
            self.write_line("!")

    def _show_run_interfaces(self, ports):
        for port in ports:
            self.write_line("interface {}".format(port.name))
            if port.trunk_vlans is not None:
                self.write_line("   switchport trunk allowed vlan {}".format(to_vlan_ranges(port.trunk_vlans)))
            if port.mode is not None:
                self.write_line("   switchport mode {}".format(port.mode))
            if isinstance(port, VlanPort):
                if port.load_interval is not None:
                    self.write_line("   load-interval {}".format(port.load_interval))
                for ip in port.ips[:1]:
                    self.write_line("   ip address {}".format(ip))
                for ip in port.ips[1:]:
                    self.write_line("   ip address {} secondary".format(ip))
                if port.mpls_ip is False:
                    self.write_line("   no mpls ip")
                for ip_helper in port.ip_helpers:
                    self.write_line("   ip helper-address {}".format(ip_helper))
                for varp_address in sorted(port.varp_addresses):
                    self.write_line("   ip virtual-router address {}"
                                    .format(varp_address if varp_address.prefixlen < 32 else varp_address.ip)) class TerminalDisplay(object):
    def invalid_command(self, processor, message, json_data=None):
        self._error(processor, message)

    def invalid_result(self, processor, message, json_data=None):
        self._error(processor, message)

    def _error(self, processor, message):
        processor.write_line("% {}".format(message))

    def warning(self, processor, message, json_data=None):
        processor.write_line("! {}".format(message))

    def show_vlans(self, processor, vlans_json):
        processor.write_line("VLAN  Name                             Status    Ports")
        processor.write_line("----- -------------------------------- --------- -------------------------------")

        for vlan_number in sorted(vlans_json["vlans"].keys(), key=lambda e: int(e)):
            processor.write_line("{: <5} {: <32} active"
                                 .format(vlan_number, vlans_json["vlans"][vlan_number]["name"]))

        processor.write_line("")

    def show_interface(self, processor, interfaces_json):
        for interface in sorted(interfaces_json["interfaces"].values(), key=lambda e: int(split_port_name(e["name"])[1])):
            if interface["name"].startswith("Vlan"):
                self._show_vlan_port(processor, interface)
            else:
                self._show_phys_port(processor, interface)

    def _show_vlan_port(self, processor, interface):
        processor.write_line("{} is up, line protocol is up (connected)".format(interface["name"]))
        processor.write_line("  Hardware is Vlan, address is {} (bia {})"
                             .format(_mac6to3(interface["physicalAddress"]),
                                     _mac6to3(interface["burnedInAddress"])))
        int_address = next(iter(interface["interfaceAddress"]), None)
        if int_address is not None:
            primary = _to_cidr(int_address["primaryIp"])
            if primary == "0.0.0.0/0":
                processor.write_line("  No Internet protocol address assigned")
            else:
                processor.write_line("  Internet address is {}".format(primary))
                for secondary_ip in int_address["secondaryIpsOrderedList"]:
                    processor.write_line("  Secondary address is {}".format(_to_cidr(secondary_ip)))
                processor.write_line("  Broadcast address is 255.255.255.255")
        processor.write_line("  IP MTU 1500 bytes")
        processor.write_line("  Up 0 minutes, 0 seconds")

    def _show_phys_port(self, processor, interface):
        processor.write_line("{} is up, line protocol is up (connected)".format(interface["name"]))
        processor.write_line("  Hardware is Ethernet, address is {} (bia {})"
                             .format(_mac6to3(interface["physicalAddress"]),
                                     _mac6to3(interface["burnedInAddress"])))
        processor.write_line("  Ethernet MTU 9214 bytes")
        processor.write_line("  Full-duplex, Unconfigured, auto negotiation: off, uni-link: n/a")
        processor.write_line("  Up 0 minutes, 0 seconds")
        processor.write_line("  Loopback Mode : None")
        processor.write_line("  0 link status changes since last clear")
        processor.write_line("  Last clearing of \"show interface\" counters never")
        processor.write_line("  0 minutes input rate 0 bps (- with framing overhead), 0 packets/sec")
        processor.write_line("  0 minutes output rate 0 bps (- with framing overhead), 0 packets/sec")
        processor.write_line("     0 packets input, 0 bytes")
        processor.write_line("     Received 0 broadcasts, 0 multicast")
        processor.write_line("     0 runts, 0 giants")
        processor.write_line("     0 input errors, 0 CRC, 0 alignment, 0 symbol, 0 input discards")
        processor.write_line("     0 PAUSE input")
        processor.write_line("     0 packets output, 0 bytes")
        processor.write_line("     Sent 0 broadcasts, 0 multicast")
        processor.write_line("     0 output errors, 0 collisions")
        processor.write_line("     0 late collision, 0 deferred, 0 output discards")
        processor.write_line("     0 PAUSE output")

    def show_interface_switchport(self, processor, switchport_json):
        ports = switchport_json["switchports"].items()
        if len(ports) > 1:
            processor.write_line("Default switchport mode: access")
            processor.write_line("")

        for name, properties in sorted(iter(ports), key=lambda item: int(split_port_name(item[0])[1])):
            switchport = properties["switchportInfo"]
            processor.write_line("Name: {}"
                                 .format(short_port_name(name)))

            processor.write_line("Switchport: {}"
                                 .format("Enabled" if properties["enabled"] else "Disabled"))

            processor.write_line("Administrative Mode: {}"
                                 .format("static access" if switchport["mode"] == "access" else switchport["mode"]))

            processor.write_line("Operational Mode: {}"
                                 .format("static access" if switchport["mode"] == "access" else switchport["mode"]))

            processor.write_line("MAC Address Learning: {}"
                                 .format("enabled" if switchport["macLearning"] else "disabled"))

            processor.write_line("Dot1q ethertype/TPID: {} ({})"
                                 .format(switchport["tpid"], "active" if switchport["tpidStatus"] else "inactive"))

            processor.write_line("Dot1q Vlan Tag Required (Administrative/Operational): {}"
                                 .format("Yes/Yes" if switchport["dot1qVlanTagRequiredStatus"] else "No/No"))

            processor.write_line("Access Mode VLAN: {} ({})"
                                 .format(switchport["accessVlanId"], switchport["accessVlanName"]))

            processor.write_line("Trunking Native Mode VLAN: {} ({})"
                                 .format(switchport["trunkingNativeVlanId"], switchport["trunkingNativeVlanName"]))

            processor.write_line("Administrative Native VLAN tagging: disabled")

            processor.write_line("Trunking VLANs Enabled: {}"
                                 .format(switchport["trunkAllowedVlans"]))

            processor.write_line("Static Trunk Groups:")

            processor.write_line("Dynamic Trunk Groups:")

            processor.write_line("Source interface filtering: {}"
                                 .format(switchport["sourceportFilterMode"]))

            processor.write_line("") class EAPI(resource.Resource, object):
    isLeaf = True

    def __init__(self, switch_configuration, processor_stack_factory, logger):
        super(EAPI, self).__init__()

        self.switch_configuration = switch_configuration
        self.processor_stack_factory = processor_stack_factory
        self.logger = logger

    def render_POST(self, request):
        content = json.loads(request.content.read().decode())
        self.logger.info("Request in: {}".format(content))

        driver = driver_for(content["params"]["format"])

        command_processor = self.processor_stack_factory(display=driver.display_class())
        command_processor.init(
            switch_configuration=self.switch_configuration,
            terminal_controller=BufferingTerminalController(),
            logger=self.logger,
            piping_processor=NotPipingProcessor()
        )

        result = {
            "jsonrpc": content["jsonrpc"],
            "id": content["id"],
        }

        command_index = 1
        command_results = []
        try:
            for cmd in content["params"]["cmds"]:
                command_processor.process_command(cmd)
                command_results.append(driver.format_output(command_processor))
                command_index += 1
            result["result"] = command_results
        except CommandProcessorError as e:
            command_results.append(driver.format_errors([str(e)], base_obj=e.json_data))
            result["error"] = {
                "data": command_results,
                "message": "CLI command {index} of {count} '{cmd}' failed: {error}".format(
                    index=command_index,
                    count=len(content["params"]["cmds"]),
                    cmd=content["params"]["cmds"][command_index - 1],
                    error=e.error
                ),
                "code": e.code
            }

        return json.dumps(result).encode() class ShellSession(object):
    def __init__(self, command_processor):
        self.command_processor = command_processor

        self.command_processor.show_prompt()

    def receive(self, line):
        self.command_processor.logger.debug("received: %s" % line)
        try:
            processed = self.command_processor.process_command(line)
        except TerminalExitSignal:
            return False

        if not processed:
            self.command_processor.logger.info("Command not supported : %s" % line)

            self.handle_unknown_command(line)

            self.command_processor.show_prompt()

        return not self.command_processor.is_done

    def handle_unknown_command(self, line):
        pass class Port(object):
    def __init__(self, name):
        self.name = name
        self.switch_configuration = None
        self.reset()

    def reset(self):
        self.description = None
        self.mode = None
        self.access_vlan = None
        self.trunk_vlans = None
        self.trunk_native_vlan = None
        self.trunk_encapsulation_mode = None
        self.shutdown = None
        self.vrf = None
        self.speed = None
        self.auto_negotiation = None
        self.aggregation_membership = None
        self.mtu = None
        self.vendor_specific = {}
        self.ip_helpers = []
        self.lldp_transmit = None
        self.lldp_receive = None
        self.lldp_med = None
        self.lldp_med_transmit_capabilities = None
        self.lldp_med_transmit_network_policy = None
        self.spanning_tree = None
        self.spanning_tree_portfast = None
        self.ntp = None

    def get_subname(self, length):
        name, number = split_port_name(self.name)
        return name[:length] + number class SwitchCore(object):
    def __init__(self, switch_configuration):
        self.switch_configuration = switch_configuration

    def launch(self, protocol, terminal_controller):
        raise NotImplementedError()

    @staticmethod
    def get_default_ports():
        raise NotImplementedError()

    def get_netconf_protocol(self):
        raise NotImplementedError()

    def get_http_resource(self):
        raise NotImplementedError()
import logging
from twisted.web import resource
from fake_switches.arista.command_processor.config import ConfigCommandProcessor
from fake_switches.arista.command_processor.config_interface import ConfigInterfaceCommandProcessor
from fake_switches.arista.command_processor.config_vlan import ConfigVlanCommandProcessor
from fake_switches.arista.command_processor.default import DefaultCommandProcessor
from fake_switches.arista.command_processor.enabled import EnabledCommandProcessor
from fake_switches.arista.command_processor.terminal_display import TerminalDisplay
from fake_switches.arista.eapi import EAPI
from fake_switches.command_processing.piping_processor_base import NotPipingProcessor
from fake_switches.command_processing.shell_session import ShellSession
from fake_switches.switch_configuration import Port
from fake_switches.switch_core import SwitchCore
from fake_switches.terminal import LoggingTerminalController
# Copyright 2018 Inap.
#
# 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.





class AristaSwitchCore(SwitchCore):

    def __init__(self, switch_configuration):
        super(AristaSwitchCore, self).__init__(switch_configuration)
        self.switch_configuration.add_vlan(self.switch_configuration.new("Vlan", 1))

        self.logger = None
        self.last_connection_id = 0

    def launch(self, protocol, terminal_controller):
        self.last_connection_id += 1

        self.logger = logging.getLogger("fake_switches.arista.{}.{}.{}"
                                        .format(self.switch_configuration.name, self.last_connection_id, protocol))

        processor = self.processor_stack(display=TerminalDisplay())

        processor.init(self.switch_configuration,
                       LoggingTerminalController(self.logger, terminal_controller),
                       self.logger,
                       NotPipingProcessor())

        return AristaShellSession(processor)

    @staticmethod
    def get_default_ports():
        return [
            Port("Ethernet1"),

            Port("Ethernet2")