fake_switches/cisco/command_processor/enabled.py
class EnabledCommandProcessor(BaseCommandProcessor):
    def __init__(self, config):
        super(EnabledCommandProcessor, self).__init__()
        self.config_processor = config

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

    def do_enable(self, *args):
        pass

    def do_configure(self, *_):
        self.write_line("Enter configuration commands, one per line.  End with CNTL/Z.")
        self.move_to(self.config_processor)

    def do_show(self, *args):
        if "running-config".startswith(args[0]):
            if len(args) < 2:
                self.show_run()
            elif "vlan".startswith(args[1]):
                self.write_line("Building configuration...")
                self.write_line("")
                self.write_line("Current configuration:")
                for vlan in self.switch_configuration.vlans:
                    if vlan.number == int(args[2]):
                        self.write_line("\n".join(["!"] + build_running_vlan(vlan)))
                self.write_line("end")
                self.write_line("")
            elif "interface".startswith(args[1]):
                if_name = "".join(args[2:])
                port = self.switch_configuration.get_port_by_partial_name(if_name)

                if port:
                    self.write_line("Building configuration...")
                    self.write_line("")

                    data = ["!"] + build_running_interface(port) + ["end", ""]

                    self.write_line("Current configuration : %i bytes" % (len("\n".join(data)) + 1))
                    [self.write_line(l) for l in data]
                else:
                    self.write_line("                               ^")
                    self.write_line("% Invalid input detected at '^' marker.")
                    self.write_line("")

        elif "vlan".startswith(args[0]):
            self.write_line("")
            self.write_line("VLAN Name                             Status    Ports")
            self.write_line("---- -------------------------------- --------- -------------------------------")
            for vlan in sorted(self.switch_configuration.vlans, key=lambda v: v.number):
                ports = [port.get_subname(length=2) for port in self.switch_configuration.get_physical_ports()
                         if port.access_vlan == vlan.number or (vlan.number == 1 and port.access_vlan is None)]
                formatted_membership = []
                if ports:
                    ports_membership = ["    {}".format(l) for l in get_port_groups(ports, max_line_length=30)]
                    formatted_membership.append(ports_membership.pop(0))
                    for remaining_line in ports_membership:
                        formatted_membership.append(' ' * 44 + remaining_line)

                self.write_line("%-4s %-32s %s%s" % (
                    vlan.number,
                    vlan_display_name(vlan),
                    "active",
                    '\n'.join(formatted_membership)
                ))
            if len(args) == 1:
                self.write_line("")
                self.write_line("VLAN Type  SAID       MTU   Parent RingNo BridgeNo Stp  BrdgMode Trans1 Trans2")
                self.write_line("---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------")
                for vlan in sorted(self.switch_configuration.vlans, key=lambda v: v.number):
                    self.write_line("%-4s enet  10%04d     1500  -      -      -        -    -        0      0" % (vlan.number, vlan.number))
                self.write_line("")
                self.write_line("Remote SPAN VLANs")
                self.write_line("------------------------------------------------------------------------------")
                self.write_line("")
                self.write_line("")
                self.write_line("Primary Secondary Type              Ports")
                self.write_line("------- --------- ----------------- ------------------------------------------")
                self.write_line("")
        elif "etherchannel".startswith(args[0]) and len(args) == 2 and "summary".startswith(args[1]):
            ports = sorted(self.switch_configuration.ports, key=lambda x: x.name)
            port_channels = sorted(
                [p for p in ports if isinstance(p, AggregatedPort)],
                key=port_channel_number)
            self.write_line("Flags:  D - down        P - bundled in port-channel")
            self.write_line("        I - stand-alone s - suspended")
            self.write_line("        H - Hot-standby (LACP only)")
            self.write_line("        R - Layer3      S - Layer2")
            self.write_line("        U - in use      f - failed to allocate aggregator")
            self.write_line("")
            self.write_line("        M - not in use, minimum links not met")
            self.write_line("        u - unsuitable for bundling")
            self.write_line("        w - waiting to be aggregated")
            self.write_line("        d - default port")
            self.write_line("")
            self.write_line("")
            self.write_line("Number of channel-groups in use: {}".format(len(port_channels)))
            self.write_line("Number of aggregators:           {}".format(len(port_channels)))
            self.write_line("")
            self.write_line("Group  Port-channel  Protocol    Ports")
            self.write_line("------+-------------+-----------+-----------------------------------------------")
            for port_channel in port_channels:
                members = [short_name(p) for p in ports
                           if p.aggregation_membership == port_channel.name]
                self.write_line(
                    "{: <6} {: <13} {: <11} {}".format(
                        port_channel_number(port_channel),
                        "{}(S{})".format(short_name(port_channel), "U" if members else ""),
                        "  LACP",
                        "  ".join("{}(P)".format(m) for m in members)))
            self.write_line("")
        elif "ip".startswith(args[0]):
            if "interface".startswith(args[1]):
                if_list = None
                if len(args) > 2:
                    interface = self.switch_configuration.get_port_by_partial_name("".join(args[2:]))
                    if interface:
                        if_list = [interface]
                    else:
                        self.write_line("                                 ^")
                        self.write_line("% Invalid input detected at '^' marker.")
                        self.write_line("")
                else:
                    if_list = self.switch_configuration.get_vlan_ports() + self.switch_configuration.get_physical_ports()
                if if_list:
                    for interface in if_list:
                        self.write_line("%s is down, line protocol is down" % interface.name)
                        if not isinstance(interface, VlanPort):
                            self.write_line("  Internet protocol processing disabled")
                        else:
                            if len(interface.ips) == 0:
                                self.write_line("  Internet protocol processing disabled")
                            else:
                                self.write_line("  Internet address is %s" % interface.ips[0])
                                for ip in interface.ips[1:]:
                                    self.write_line("  Secondary address %s" % ip)
                                self.write_line("  Outgoing access list is %s" % (interface.access_group_out if interface.access_group_out else "not set"))
                                self.write_line("  Inbound  access list is %s" % (interface.access_group_in if interface.access_group_in else "not set"))
                                if interface.vrf is not None:
                                    self.write_line("  VPN Routing/Forwarding \"%s\"" % interface.vrf.name)
            elif "route".startswith(args[1]):
                if "static".startswith(args[2]):
                    routes = self.switch_configuration.static_routes
                    for route in routes:
                        self.write_line("S        {0} [x/y] via {1}".format(route.destination, route.next_hop))
                self.write_line("")
        elif "version".startswith(args[0]):
            self.show_version()

    def do_copy(self, source_url, destination_url):
        dest_protocol, dest_file = destination_url.split(":")
        self.write("Destination filename [%s]? " % strip_leading_slash(dest_file))
        self.continue_to(partial(self.continue_validate_copy, source_url))

    def continue_validate_copy(self, source_url, _):
        self.write_line("Accessing %s..." % source_url)
        try:
            url, filename = re.match('tftp://([^/]*)/(.*)', source_url).group(1, 2)
            SwitchTftpParser(self.switch_configuration).parse(url, filename, self.config_processor)
            self.write_line("Done (or some official message...)")
        except Exception as e:
            self.logger.warning("tftp parsing went wrong : %s" % str(e))
            self.write_line("Error opening %s (Timed out)" % source_url)

    def do_terminal(self, *args):
        pass

    def do_write(self, *args):
        self.write_line("Building configuration...")
        self.switch_configuration.commit()
        self.write_line("OK")

    def do_exit(self):
        self.is_done = True

    def show_run(self):

        all_data = [
            "version 12.1",
            "!",
            "hostname %s" % self.switch_configuration.name,
            "!",
            "!",
        ]
        for vlan in self.switch_configuration.vlans:
            all_data = all_data + build_running_vlan(vlan) + ["!"]
        for interface in self.switch_configuration.get_physical_ports() + self.switch_configuration.get_vlan_ports():
            all_data = all_data + build_running_interface(interface) + ["!"]
        if self.switch_configuration.static_routes:
            for route in self.switch_configuration.static_routes:
                all_data.append(build_static_routes(route))
            all_data.append("!")

        all_data += ["end", ""]

        self.write_line("Building configuration...")
        self.write_line("")

        self.write_line("Current configuration : %i bytes" % (len("\n".join(all_data)) + 1))
        [self.write_line(l) for l in all_data]

    def show_version(self):
        self.write_line(version_text(
            hostname=self.switch_configuration.name,
            vlan_port_count=len(self.switch_configuration.get_vlan_ports()),
            port_count=len(self.switch_configuration.get_physical_ports()),
        ))
fake_switches/command_processing/shell_session.py
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
fake_switches/cisco/command_processor/config_vrf.py
class ConfigVRFCommandProcessor(BaseCommandProcessor):
    def init(self, switch_configuration, terminal_controller, logger, piping_processor, *args):
        super(ConfigVRFCommandProcessor, self).init(switch_configuration, terminal_controller, logger, piping_processor)
        self.vrf = args[0]

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

    def do_exit(self):
        self.is_done = True
fake_switches/cisco/command_processor/config_vlan.py
class ConfigVlanCommandProcessor(BaseCommandProcessor):
    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)#"

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

    def do_exit(self):
        self.is_done = True
fake_switches/cisco/command_processor/config_interface.py
class ConfigInterfaceCommandProcessor(BaseCommandProcessor):
    def init(self, switch_configuration, terminal_controller, logger, piping_processor, *args):
        super(ConfigInterfaceCommandProcessor, self).init(switch_configuration, terminal_controller, logger, piping_processor)
        self.description_strip_chars = "\""
        self.port = args[0]

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

    def do_switchport(self, *args):
        if args[0:1] == ("mode",):
            self.port.mode = args[1]
        elif args[0:2] == ("access", "vlan"):
            self.port.access_vlan = int(args[2])
        elif args[0:2] == ("trunk", "encapsulation"):
            self.port.trunk_encapsulation_mode = args[2]
        elif args[0:4] == ("trunk", "allowed", "vlan", "add"):
            if self.port.trunk_vlans is not None: #for cisco, no list = all vlans
                self.port.trunk_vlans += parse_vlan_list(args[4])
        elif args[0:4] == ("trunk", "allowed", "vlan", "remove"):
            if self.port.trunk_vlans is None:
                self.port.trunk_vlans = list(range(1, 4097))
            for v in parse_vlan_list(args[4]):
                if v in self.port.trunk_vlans:
                    self.port.trunk_vlans.remove(v)
        elif args[0:4] == ("trunk", "allowed", "vlan", "none"):
            self.port.trunk_vlans = []
        elif args[0:4] == ("trunk", "allowed", "vlan", "all"):
            self.port.trunk_vlans = None
        elif args[0:3] == ("trunk", "allowed", "vlan"):
            self.port.trunk_vlans = parse_vlan_list(args[3])
        elif args[0:3] == ("trunk", "native", "vlan"):
            self.port.trunk_native_vlan = int(args[3])

    def do_no_switchport(self, *args):
        if args[0:2] == ("access", "vlan"):
            self.port.access_vlan = None
        elif args[0:1] == ("mode",):
            self.port.mode = None
        elif args[0:3] == ("trunk", "allowed", "vlan"):
            self.port.trunk_vlans = None
        elif args[0:3] == ("trunk", "native", "vlan"):
            self.port.trunk_native_vlan = None

    def do_channel_group(self, *args):
        port_channel_id = args[0]
        port_channel_name = "Port-channel%s" % port_channel_id

        if not self.port_channel_exists(port_channel_name):
            self.write_line("Creating a port-channel interface Port-channel %s" % port_channel_id)
            self.create_port_channel(port_channel_name)
        self.port.aggregation_membership = port_channel_name

    def do_no_channel_group(self, *_):
        self.port.aggregation_membership = None

    def do_description(self, *args):
        self.port.description = " ".join(args).strip(self.description_strip_chars)

    def do_no_description(self, *_):
        self.port.description = None

    def do_shutdown(self, *_):
        self.port.shutdown = True

    def do_no_shutdown(self, *_):
        self.port.shutdown = False

    def do_ip(self, *args):

        if "address".startswith(args[0]):
            new_ip = IPNetwork("%s/%s" % (args[1], args[2]))
            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(args) == 4 and "secondary".startswith(args[3]):
                    self.port.add_ip(new_ip)
                else:
                    if len(self.port.ips) == 0:
                        self.port.add_ip(new_ip)
                    else:
                        if ip_owner == self.port:
                            self.port.remove_ip(new_ip)
                        self.port.ips[0] = new_ip
            else:
                if ip_owner.ips.index(existing_ip) == 0:
                    self.write_line("%% %s overlaps with secondary address on %s" % (existing_ip.network, ip_owner.name))
                else:
                    self.write_line("%% %s is assigned as a secondary address on %s" % (existing_ip.network, ip_owner.name))

        if "access-group".startswith(args[0]):
            if "in".startswith(args[2]):
                self.port.access_group_in = args[1]
            if "out".startswith(args[2]):
                self.port.access_group_out = args[1]

        if "vrf".startswith(args[0]):
            if "forwarding".startswith(args[1]):
                if isinstance(self.port, VlanPort):
                    for ip in self.port.ips[:]:
                        self.port.remove_ip(ip)
                vrf = self.switch_configuration.get_vrf(args[2])
                if vrf:
                    self.port.vrf = vrf
                else:
                    self.write_line("%% VRF %s not configured." % args[2])
        if "redirects".startswith(args[0]):
            self.port.ip_redirect = True
        if "proxy-arp".startswith(args[0]):
            self.port.ip_proxy_arp = True
        if "verify".startswith(args[0]) and "unicast".startswith(args[1]) and isinstance(self.port, VlanPort):
            self._handle_ip_verify_unicast()
        if "helper-address".startswith(args[0]):
            if len(args) == 1:
                self.write_line("% Incomplete command.")
                self.write_line("")
            elif len(args) > 2:
                self.write_line(" ^")
                self.write_line("% Invalid input detected at '^' marker.")
                self.write_line("")
            else:
                try:
                    ip_address = _parse_ip(args[1], 4)
                    if ip_address is None:
                        raise InvalidIpError
                    if ip_address not in self.port.ip_helpers:
                        self.port.ip_helpers.append(ip_address)
                except InvalidIpError:
                    self.write_line(" ^")
                    self.write_line("% Invalid input detected at '^' marker.")
                    self.write_line("")
                except IncompleteIpError:
                    self.write_line("% Incomplete command.")
                    self.write_line("")

    def do_no_ip(self, *args):
        if "address".startswith(args[0]):
            if len(args) == 1:
                self.port.ips = []
            else:
                ip = IPNetwork("%s/%s" % (args[1], args[2]))
                is_secondary = "secondary".startswith(args[3]) if len(args) == 4 else False
                if is_secondary:
                    self.port.remove_ip(ip)
                else:
                    if len(self.port.ips) == 1:
                        self.port.remove_ip(ip)
                    else:
                        self.write_line("Must delete secondary before deleting primary")
        if "access-group".startswith(args[0]):
            direction = args[-1]
            if "in".startswith(direction):
                self.port.access_group_in = None
            elif "out".startswith(direction):
                self.port.access_group_out = None
        if "vrf".startswith(args[0]):
            if "forwarding".startswith(args[1]):
                self.port.vrf = None
        if "redirects".startswith(args[0]):
            self.port.ip_redirect = False
        if "verify".startswith(args[0]) and "unicast".startswith(args[1]) and isinstance(self.port, VlanPort):
            self.port.unicast_reverse_path_forwarding = False
        if "helper-address".startswith(args[0]):
            if len(args) > 2:
                self.write_line(" ^")
                self.write_line("% Invalid input detected at '^' marker.")
                self.write_line("")
            else:
                if len(args) == 1:
                    self.port.ip_helpers = []
                else:
                    ip_address = IPAddress(args[1])
                    if ip_address in self.port.ip_helpers:
                        self.port.ip_helpers.remove(ip_address)
        if "proxy-arp".startswith(args[0]):
            self.port.ip_proxy_arp = False

    def do_standby(self, command, *args):
        if "version".startswith(command):
            if len(args) < 1:
                self.write_line("% Incomplete command.")
                self.write_line("")
            elif len(args) == 1 and args[0] == "1":
                self.port.vrrp_version = None
            elif len(args) == 1 and args[0] == "2":
                self.port.vrrp_version = "2"
            else:
                self.write_line(" ^")
                self.write_line("% Invalid input detected at '^' marker.")
                self.write_line("")
        else:
            self._handle_standby_group(command, args[0], *args[1:])

    def do_no_standby(self, command, *args):
        if "version".startswith(command):
            self.port.vrrp_version = None
        else:
            self._handle_no_standby_group(command, *args)

    def do_ntp(self, *args):
        if args[0] == "disable":
            self.port.ntp = False

    def do_no_ntp(self, *args):
        if args[0] == "disable":
            self.port.ntp = None

    def do_exit(self):
        self.is_done = True

    def port_channel_exists(self, name):
        return self.switch_configuration.get_port_by_partial_name(name) is not None

    def create_port_channel(self, name):
        port = self.switch_configuration.new("AggregatedPort", name)
        self.port.switch_configuration.add_port(port)

    def _handle_ip_verify_unicast(self):
        self.write_line("% ip verify configuration not supported on interface Vl{}".format(self.port.vlan_id))
        self.write_line(" - verification not supported by hardware")
        self.write_line("% ip verify configuration not supported on interface Vl{}".format(self.port.vlan_id))
        self.write_line(" - verification not supported by hardware")
        self.write_line(
            "%Restoring the original configuration failed on {} - Interface Support Failure".format(self.port.name))

    def _handle_standby_group(self, group, command, *args):
        vrrp = self.port.get_vrrp_group(group)
        if vrrp is None:
            vrrp = self.switch_configuration.new("VRRP", group)
            self.port.vrrps.append(vrrp)

        if "ip".startswith(command):
            if len(args) == 0:
                vrrp.ip_addresses = vrrp.ip_addresses or []
            else:
                ip = _parse_ip(args[0])
                if ip is not None:
                    in_networks = any(ip in net for net in self.port.ips)
                    if in_networks:
                        vrrp.ip_addresses = vrrp.ip_addresses or []
                        if len(args) > 1 and "secondary".startswith(args[1]):
                            vrrp.ip_addresses.append(ip)
                        else:
                            vrrp.ip_addresses = [ip] + vrrp.ip_addresses[1:]
                    else:
                        self.write_line("% Warning: address is not within a subnet on this interface")

                else:
                    self.write_line(" ^")
                    self.write_line("% Invalid input detected at '^' marker.")
                    self.write_line("")

        if "timers".startswith(command):
            vrrp.timers_hello = args[0]
            vrrp.timers_hold = args[1]

        if "priority".startswith(command):
            vrrp.priority = args[0]

        if "authentication".startswith(command):
            vrrp.authentication = args[0]

        if "track".startswith(command) and "decrement".startswith(args[1]):
            vrrp.track.update({args[0]: args[2]})

        if "preempt".startswith(command):
            vrrp.preempt = True
            if len(args) > 0 and " ".join(args[0:2]) == "delay minimum":
                vrrp.preempt_delay_minimum = args[2]

    def _handle_no_standby_group(self, group, *cmd_args):
        vrrp = self.port.get_vrrp_group(group)

        if vrrp is None:
            return

        if len(cmd_args) == 0:
            self.port.vrrps.remove(vrrp)

        else:
            command = cmd_args[0]
            args = cmd_args[1:]

            if "ip".startswith(command):
                if len(args) == 0:
                    vrrp.ip_addresses = None
                else:
                    vrrp.ip_addresses.remove(IPAddress(args[0]))
                    if len(vrrp.ip_addresses) == 0:
                        vrrp.ip_addresses = None

            if "authentication".startswith(command):
                vrrp.authentication = None

            if "priority".startswith(command):
                vrrp.priority = None

            if "timers".startswith(command):
                vrrp.timers_hello = None
                vrrp.timers_hold = None

            if "track".startswith(command) and args[0] in vrrp.track:
                del vrrp.track[args[0]]

            if "preempt".startswith(command):
                if len(args) > 0 and "delay".startswith(args[0]):
                    vrrp.preempt_delay_minimum = None
                else:
                    vrrp.preempt_delay_minimum = None
                    vrrp.preempt = None
fake_switches/cisco/command_processor/default.py
class DefaultCommandProcessor(BaseCommandProcessor):
    def __init__(self, enabled):
        super(DefaultCommandProcessor, self).__init__()
        self.enabled_processor = enabled

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

    def delegate_to_sub_processor(self, line):
        processed = self.sub_processor.process_command(line)
        if self.sub_processor.is_done:
            self.is_done = True
        return processed

    def do_enable(self):
        self.write("Password: ")
        self.replace_input = ''
        self.continue_to(self.continue_enabling)

    def continue_enabling(self, line):
        self.replace_input = False
        if line == "" or line in self.switch_configuration.privileged_passwords:
            self.move_to(self.enabled_processor)
        else:
            self.write_line("% Access denied")
            self.write_line("")
fake_switches/cisco/command_processor/piping.py
class PipingProcessor(PipingProcessorBase):

    def do_begin(self, *args):
        return StartOutputAt(" ".join(args))

    def do_include(self, *args):
        return Grep(" ".join(args))
fake_switches/switch_core.py
class SwitchCore(object):
    def __init__(self, switch_configuration):
    def launch(self, protocol, terminal_controller):
    def get_default_ports():
    def get_netconf_protocol(self):
    def get_http_resource(self):
fake_switches/cisco/command_processor/config.py
class ConfigCommandProcessor(BaseCommandProcessor):
    interface_separator = ""

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

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

    def do_vlan(self, raw_number, *_):
        number = int(raw_number)
        if number < 0:
            self.write_line("Command rejected: Bad VLAN list - character #1 ('-') delimits a VLAN number")
            self.write_line(" which is out of the range 1..4094.")
        elif number < 1 or number > 4094:
            self.write_line("Command rejected: Bad VLAN list - character #X (EOL) delimits a VLAN")
            self.write_line("number which is out of the range 1..4094.")
        else:
            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_no_ip(self, cmd, *args):
        if "vrf".startswith(cmd):
            self.switch_configuration.remove_vrf(args[0])
        elif "route".startswith(cmd):
            self.switch_configuration.remove_static_route(args[0], args[1])

    def do_ip(self, cmd, *args):
        if "vrf".startswith(cmd):
            vrf = self.switch_configuration.new("VRF", args[0])
            self.switch_configuration.add_vrf(vrf)
            self.move_to(self.config_vrf_processor, vrf)
        elif "route".startswith(cmd):
            static_route = self.switch_configuration.new("Route", *args)
            self.switch_configuration.add_static_route(static_route)

    def do_interface(self, *args):
        interface_name = self.interface_separator.join(args)
        port = self.switch_configuration.get_port_by_partial_name(interface_name)
        if port:
            self.move_to(self.config_interface_processor, port)
        else:
            m = re.match("vlan{separator}(\d+)".format(separator=self.interface_separator), interface_name.lower())
            if m:
                vlan_id = int(m.groups()[0])
                new_vlan_interface = self.make_vlan_port(vlan_id, interface_name)
                self.switch_configuration.add_port(new_vlan_interface)
                self.move_to(self.config_interface_processor, new_vlan_interface)
            elif interface_name.lower().startswith('port-channel'):
                new_int = self.make_aggregated_port(interface_name)
                self.switch_configuration.add_port(new_int)
                self.move_to(self.config_interface_processor, new_int)
            else:
                self.show_unknown_interface_error_message()

    def do_no_interface(self, *args):
        port = self.switch_configuration.get_port_by_partial_name("".join(args))
        if isinstance(port, VlanPort) or isinstance(port, AggregatedPort):
            self.switch_configuration.remove_port(port)

    def do_default(self, cmd, *args):
        if 'interface'.startswith(cmd):
            interface_name = self.interface_separator.join(args)
            port = self.switch_configuration.get_port_by_partial_name(interface_name)
            if port:
                port.reset()
            else:
                self.show_unknown_interface_error_message()

    def do_exit(self):
        self.is_done = True

    def show_unknown_interface_error_message(self):
        self.write_line("              ^")
        self.write_line("% Invalid input detected at '^' marker (not such interface)")
        self.write_line("")

    def make_vlan_port(self, vlan_id, interface_name):
        return self.switch_configuration.new("VlanPort", vlan_id, interface_name.capitalize())

    def make_aggregated_port(self, interface_name):
        return self.switch_configuration.new("AggregatedPort", interface_name.capitalize())
fake_switches/switch_configuration.py
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


Question: import logging
from fake_switches import switch_core
from fake_switches.cisco.command_processor.config import ConfigCommandProcessor
from fake_switches.cisco.command_processor.config_interface import ConfigInterfaceCommandProcessor
from fake_switches.cisco.command_processor.config_vlan import ConfigVlanCommandProcessor
from fake_switches.cisco.command_processor.config_vrf import ConfigVRFCommandProcessor
from fake_switches.cisco.command_processor.default import DefaultCommandProcessor
from fake_switches.cisco.command_processor.enabled import EnabledCommandProcessor
from fake_switches.cisco.command_processor.piping import PipingProcessor
from fake_switches.command_processing.shell_session import ShellSession
from fake_switches.switch_configuration import Port
from fake_switches.terminal import LoggingTerminalController
# Copyright 2015 Internap.
#
# 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 BaseCiscoSwitchCore(switch_core.SwitchCore):
    def __init__(self, switch_configuration):
        super(BaseCiscoSwitchCore, 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.cisco.%s.%s.%s" % (self.switch_configuration.name, self.last_connection_id, protocol))

        processor = self.new_command_processor()
        if not self.switch_configuration.auto_enabled:
            processor = DefaultCommandProcessor(processor)

        processor.init(
            self.switch_configuration,
            LoggingTerminalController(self.logger, terminal_controller),
            self.logger,
            PipingProcessor(self.logger))
        return CiscoShellSession(processor)

    def new_command_processor(self):
        raise NotImplementedError

    def get_netconf_protocol(self):
        return None

    @staticmethod
    def get_default_ports():
        return [
            Port("FastEthernet0/1"),
            Port("FastEthernet0/2"),
            Port("FastEthernet0/3"),
            Port("FastEthernet0/4"),
            Port("FastEthernet0/5"),
            Port("FastEthernet0/6"),
            Port("FastEthernet0/7"),
            Port("FastEthernet0/8"),
            Port("FastEthernet0/9"),
            Port("FastEthernet0/10"),
            Port("FastEthernet0/11"),
            Port("FastEthernet0/12")
        ]


class Cisco2960SwitchCore(BaseCiscoSwitchCore):
    def new_command_processor(self):
        return EnabledCommandProcessor(

Answer:             config=ConfigCommandProcessor(