__init__.py 7.55 KB
Newer Older
Dmitry Volodin's avatar
Dmitry Volodin committed
1
2
# -*- coding: utf-8 -*-
##----------------------------------------------------------------------
Dmitry Volodin's avatar
Dmitry Volodin committed
3
4
## Vendor: Cisco
## OS:     IOS
Dmitry Volodin's avatar
Dmitry Volodin committed
5
##----------------------------------------------------------------------
Aleksey Shirokih's avatar
Aleksey Shirokih committed
6
## Copyright (C) 2007-2016 The NOC Project
Dmitry Volodin's avatar
Dmitry Volodin committed
7
8
## See LICENSE for details
##----------------------------------------------------------------------
Dmitry Volodin's avatar
Dmitry Volodin committed
9

10
11
## Python modules
import re
12
import six
Dmitry Volodin's avatar
Dmitry Volodin committed
13
## NOC modules
Dmitry Volodin's avatar
Dmitry Volodin committed
14
from noc.core.profile.base import BaseProfile
Dmitry Volodin's avatar
Dmitry Volodin committed
15

16

Dmitry Volodin's avatar
Dmitry Volodin committed
17
class Profile(BaseProfile):
Dmitry Volodin's avatar
Dmitry Volodin committed
18
    name = "Cisco.IOS"
19
20
    pattern_more = [
        (r"^ --More--", "\n"),
21
        (r"(?:\?|interfaces)\s*\[confirm\]", "\n")
22
    ]
Dmitry Volodin's avatar
Dmitry Volodin committed
23
    pattern_unpriveleged_prompt = r"^\S+?>"
24
    pattern_syntax_error = r"% Invalid input detected at|% Ambiguous command:|% Incomplete command."
Dmitry Volodin's avatar
Dmitry Volodin committed
25
26
27
    command_disable_pager = "terminal length 0"
    command_super = "enable"
    command_enter_config = "configure terminal"
28
    command_leave_config = "end"
29
    command_exit = "exit"
Dmitry Volodin's avatar
Dmitry Volodin committed
30
    command_save_config = "copy running-config startup-config\n"
31
    pattern_prompt = r"^(?P<hostname>[a-zA-Z0-9/.]\S{0,35})(?:[-_\d\w]+)?(?:\(config[^\)]*\))?#"
32
    can_strip_hostname_to = 20
Dmitry Volodin's avatar
Dmitry Volodin committed
33
    requires_netmask_conversion = True
Dmitry Volodin's avatar
Dmitry Volodin committed
34
    convert_mac = BaseProfile.convert_mac_to_cisco
Dmitry Volodin's avatar
Dmitry Volodin committed
35
    config_volatile = ["^ntp clock-period .*?^"]
36

37
    rx_cable_if = re.compile(r"Cable\s*(?P<pr_if>\d+/\d+) U(pstream)?\s*(?P<sub_if>\d+)", re.IGNORECASE)
38
    default_parser = "noc.cm.parsers.Cisco.IOS.base.BaseIOSParser"
39
    rx_ver = re.compile(r"(\d+)\.(\d+)[\(.](\d+)[\).]\S*")
Andrey Vertiprahov's avatar
Andrey Vertiprahov committed
40
41
42
43
44

    def cmp_version(self, x, y):
        """12(25)SEC2"""
        return cmp([int(z) for z in self.rx_ver.findall(x)[0]],
            [int(z) for z in self.rx_ver.findall(y)[0]])
45

46
    def convert_interface_name(self, interface):
47
48
49
50
51
52
        if " efp_id " in interface:
            l, r = interface.split(" efp_id ", 1)
            return "%s.SI.%d" % (
                self.convert_interface_name_cisco(l.strip()),
                int(r.strip())
            )
53
54
55
56
57
58
        if "+Efp" in interface:
            l, r = interface.split("+Efp", 1)
            return "%s.SI.%d" % (
                self.convert_interface_name_cisco(l.strip()),
                int(r.strip())
            )
59
60
        if ".ServiceInstance." in interface:
            interface = interface.replace(".ServiceInstance.", ".SI.")
61
62
63
64
65
66
        if ".SI." in interface:
            l, r = interface.split(".SI.", 1)
            return "%s.SI.%d" % (
                self.convert_interface_name_cisco(l.strip()),
                int(r.strip())
            )
67
        if isinstance(interface, six.string_types):
Aleksey Shirokih's avatar
Aleksey Shirokih committed
68
69
70
            il = interface.lower()
        else:
            il = interface.name.lower()
71
72
        if il.startswith("nde_"):
            return "NDE_" + interface[4:]
73
        if il.startswith("dot11radio"):
74
            return "Dot11Radio" + interface[10:]
75
76
        if il.startswith("bdi"):
            return "BDI" + interface[3:]
77
        if il.startswith("bvi"):
Dmitry Volodin's avatar
Dmitry Volodin committed
78
            return "BVI" + interface[3:]
79
        if il.startswith("e1"):
80
            return "E1 %s" % interface[2:].strip()
81
        if il.startswith("t1"):
Dmitry Lukhtionov's avatar
Dmitry Lukhtionov committed
82
            return "T1 %s" % interface[2:].strip()
83
        if il.startswith("fxo null"):
Dmitry Lukhtionov's avatar
Dmitry Lukhtionov committed
84
            return "FXO %s" % interface[8:].strip()
85
        if il.startswith("fxs"):
Dmitry Lukhtionov's avatar
Dmitry Lukhtionov committed
86
            return "FXS %s" % interface[3:].strip()
87
        if il.startswith("efxs"):
Dmitry Lukhtionov's avatar
Dmitry Lukhtionov committed
88
            return "EFXS %s" % interface[4:].strip()
89
        if il.startswith("cpp"):
Dmitry Lukhtionov's avatar
Dmitry Lukhtionov committed
90
            return "CPP"
91
        if il.startswith("srp"):
92
            return "SRP %s" % interface[3:].strip()
93
        if il.startswith("Foreign Exchange Station"):
Dmitry Lukhtionov's avatar
Dmitry Lukhtionov committed
94
            return "FXS %s" % interface[24:].strip()
95
96
97
98
        if il.startswith("cable"):
            match = self.rx_cable_if.search(interface)
            if match:
                return "Ca %s/%s" % (match.group('pr_if'), match.group('sub_if'))
99
100
        if il.startswith("virtual-template"):
            return "Vi %s" % il[16:].strip()
101
102
103
        # Serial0/1/0:15-Signaling -> Serial0/1/0:15
        if il.startswith("se") and "-" in interface:
            interface = interface.split("-")[0]
104
105
106
107
        # Control Plane Interface
        # @todo: Does it relates to CPP?
        if il == "Control Plane Interface":
            return "Control Plane Interface"
108
109
110
        # Fake name. Used only with FM
        if il == "all":
            return "all"
111
        return self.convert_interface_name_cisco(interface)
Dmitry Volodin's avatar
Dmitry Volodin committed
112

Dmitry Volodin's avatar
Dmitry Volodin committed
113
114
115
116
117
118
119
120
121
122
123
124
125
    def generate_prefix_list(self, name, pl):
        """
        Generate prefix list _name_. pl is a list of (prefix, min_len, max_len)
        """
        me = "ip prefix-list %s permit %%s" % name
        mne = "ip prefix-list %s permit %%s le %%d" % name
        r = ["no ip prefix-list %s" % name]
        for prefix, min_len, max_len in pl:
            if min_len == max_len:
                r += [me % prefix]
            else:
                r += [mne % (prefix, max_len)]
        return "\n".join(r)
Dmitry Volodin's avatar
Dmitry Volodin committed
126

127
    def setup_session(self, script):
Dmitry Volodin's avatar
Dmitry Volodin committed
128
129
130
131
132
        """
        Perform session initialization
        Process specific path parameters:
        cluster:id - switch to cluster member
        """
Dmitry Volodin's avatar
Dmitry Volodin committed
133
134
135
136
        path = script.credentials.get("path")
        if path:
            cluster_member = None
            # Parse path parameters
137
            for p in script.credentials.get("path", "").split("/"):
Dmitry Volodin's avatar
Dmitry Volodin committed
138
139
140
141
                if p.startswith("cluster:"):
                    cluster_member = p[8:].strip()
            # Switch to cluster member, if necessary
            if cluster_member:
142
                script.logger.debug("Switching to cluster member '%s'" % cluster_member)
Dmitry Volodin's avatar
Dmitry Volodin committed
143
                script.cli("rc %s" % cluster_member)
Dmitry Volodin's avatar
Dmitry Volodin committed
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
    INTERFACE_TYPES = {
        "As": "physical",  # Async
        "AT": "physical",  # ATM
        "At": "physical",  # ATM
        "Br": "physical",  # ISDN Basic Rate Interface
        "BD": "physical",  # Bridge Domain Interface
        "BV": "aggregated",  # BVI
        "Bu": "aggregated",  # Bundle
        "C": "physical",  # @todo: fix
        "Ca": "physical",  # Cable
        "CD": "physical",  # CDMA Ix
        "Ce": "physical",  # Cellular
        "Em": "physical",  # Embedded Service Engine
        "Et": "physical",  # Ethernet
        "Fa": "physical",  # FastEthernet
        "Fd": "physical",  # Fddi
        "Gi": "physical",  # GigabitEthernet
        "Gm": "physical",  # GMPLS
        "Gr": "physical",  # Group-Async
        "Lo": "loopback",  # Loopback
        "In": "physical",  # Integrated-service-engine
        "M": "management",  # @todo: fix
        "MF": "aggregated",  # Multilink Frame Relay
        "Mf": "aggregated",  # Multilink Frame Relay
        "Mu": "aggregated",  # Multilink-group interface
170
        "ND": "other",      # Netflow Data Exporter
171
172
173
174
175
176
177
178
179
180
        "PO": "physical",  # Packet OC-3 Port Adapter
        "Po": "aggregated",  # Port-channel/Portgroup
        "R": "aggregated",  # @todo: fix
        "SR": "physical",  # Spatial Reuse Protocol
        "Sr": "physical",  # Spatial Reuse Protocol
        "Se": "physical",  # Serial
        "Sp": "physical",  # Special-Services-Engine
        "Te": "physical",  # TenGigabitEthernet
        "To": "physical",  # TokenRing
        "Tu": "tunnel",  # Tunnel
181
        "Vi": "template", # Virtual-Template
182
183
184
185
186
187
188
189
190
191
        "VL": "SVI",  # VLAN, found on C3500XL
        "Vl": "SVI",  # Vlan
        "Vo": "physical",  # Voice
        "XT": "SVI"  # Extended Tag ATM
    }

    @classmethod
    def get_interface_type(cls, name):
        return cls.INTERFACE_TYPES.get(name[:2])

192

Dmitry Volodin's avatar
Dmitry Volodin committed
193
def uBR(v):
Dmitry Volodin's avatar
Dmitry Volodin committed
194
195
196
    """
    uBR series selector
    """
Dmitry Volodin's avatar
Dmitry Volodin committed
197
    return "BC" in v["version"]
198
199
200
201
202
203
204
205
206
207
208


def MESeries(v):
    """
    MExxxx series selector
    :param v:
    :type v: dict
    :return:
    :rtype: bool
    """
    return v["platform"].startswith("ME")