mpenning / ciscoconfparse

Parse, Audit, Query, Build, and Modify Arista / Cisco / Juniper / Palo Alto / F5 configurations.
http://www.pennington.net/py/ciscoconfparse/
GNU General Public License v3.0
789 stars 219 forks source link

models_cisco: Advise on the correct way to use `is_portchannel_intf` (AttributeError: 'IOSCfgLine' object has no attribute 'name') #173

Closed FredTourn closed 4 years ago

FredTourn commented 4 years ago

Hi,

I am trying to verify that an interface is a Port-Channel. I have the following error:

/virtualenvs/py3_network/lib/python3.7/site-packages/ciscoconfparse/models_cisco.py", line 288, in is_portchannel_intf return ('channel' in self.name.lower()) AttributeError: 'IOSCfgLine' object has no attribute 'name'

@property
def is_portchannel_intf(self):
    """Return a boolean indicating whether this port is a port-channel intf
    """
    return ('channel' in self.name.lower()) ==> self.text.lower() ?

ciscoconfparse 1.4.11 Python 3.7.3

mpenning commented 4 years ago

Hello @FredTourn ,

Did you parse your configuration with factory=True?

parse = CiscoConfParse('my_config_file.conf', syntax='ios', factory=True)

If not, please do so.

FredTourn commented 4 years ago

Thank you for your reply. I had not tried with factrory = True. I always get the same error

config_text.txt

interface TenGigabitEthernet3/1
 description ETHERCHANNEL vers EF-Z2PPR-1 [ Te1/7 ]
 switchport trunk allowed vlan 697,2182-2184,2259,2260,2369,2370,2372,2374,2424
 switchport trunk allowed vlan add 2520,2608,2825,2896,3011,3021,3031,3041
 switchport mode trunk
 logging event link-status
 channel-group 1 mode active
 service-policy output QUEUEING
 ip dhcp snooping trust
!
interface TenGigabitEthernet4/1
 description ETHERCHANNEL vers EF-Z2PPR-1 [ Te1/8 ]
 switchport trunk allowed vlan 697,2182-2184,2259,2260,2369,2370,2372,2374,2424
 switchport trunk allowed vlan add 2520,2608,2825,2896,3011,3021,3031,3041
 switchport mode trunk
 logging event link-status
 no snmp trap link-status
 channel-group 1 mode active
 service-policy output QUEUEING
 ip dhcp snooping trust
!
interface Port-channel1
 switchport
 switchport trunk allowed vlan 697,2182-2184,2259,2260,2369,2370,2372,2374,2424
 switchport trunk allowed vlan add 2520,2608,2825,2896,3011,3021,3031,3041
 switchport mode trunk
 flowcontrol receive on
 ip dhcp snooping trust
!
from ciscoconfparse import CiscoConfParse
parse = CiscoConfParse('config_text.txt', syntax='ios', factory=True)
for line in c.objs:
    c.is_portchannel_intf

Result :

False
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/virtualenvs/py3_network/lib/python3.7/site-packages/ciscoconfparse/models_cisco.py", line 288, in is_portchannel_intf
    return ('channel' in self.name.lower())
AttributeError: 'IOSCfgLine' object has no attribute 'name'
FredTourn commented 4 years ago

Pour la vérification que le port et un port-channel, le code devrait être celui ci, non ?

@property
def is_portchannel_intf(self):
    """Return a boolean indicating whether this port is a port-channel intf
    """
    intf_regex = r'^interface\s+(.*?\Sort-channel)'
    if self.re_match(intf_regex):
      return True
    return False
mpenning commented 4 years ago

Hello,

Regarding the code you pasted above, this is not correct:

parse = CiscoConfParse('config_text.txt', syntax='ios', factory=True)
for line in c.objs:
    c.is_portchannel_intf

The example above calls is_portchannel_intf on all objects, even objects that are not an interface. You should only call is_portchannel_intf on interface objects... see the example below...

from ciscoconfparse import CiscoConfParse

config = """interface TenGigabitEthernet3/1
 description ETHERCHANNEL vers EF-Z2PPR-1 [ Te1/7 ]
 switchport trunk allowed vlan 697,2182-2184,2259,2260,2369,2370,2372,2374,2424
 switchport trunk allowed vlan add 2520,2608,2825,2896,3011,3021,3031,3041
 switchport mode trunk
 logging event link-status
 channel-group 1 mode active
 service-policy output QUEUEING
 ip dhcp snooping trust
!
interface TenGigabitEthernet4/1
 description ETHERCHANNEL vers EF-Z2PPR-1 [ Te1/8 ]
 switchport trunk allowed vlan 697,2182-2184,2259,2260,2369,2370,2372,2374,2424
 switchport trunk allowed vlan add 2520,2608,2825,2896,3011,3021,3031,3041
 switchport mode trunk
 logging event link-status
 no snmp trap link-status
 channel-group 1 mode active
 service-policy output QUEUEING
 ip dhcp snooping trust
!
interface Port-channel1
 switchport
 switchport trunk allowed vlan 697,2182-2184,2259,2260,2369,2370,2372,2374,2424
 switchport trunk allowed vlan add 2520,2608,2825,2896,3011,3021,3031,3041
 switchport mode trunk
 flowcontrol receive on
 ip dhcp snooping trust
!""".splitlines()

parse = CiscoConfParse(config, syntax='ios', factory=True)
for intfobj in parse.find_objects('^interface'):  # note how we only iterate over intf objects...
    print(intfobj.name, intfobj.is_portchannel_intf)
FredTourn commented 4 years ago

Hello, I had wrongly thought that we could test using directly 'is_portchannel_intf', 'is_ethernet_intf' ... directly as well

class IOSCfg:
    def __init__(self, config, syntax='ios', factory=True):
        self._config = config
        self.CiscoConfParse = CiscoConfParse(config, syntax=syntax, factory=factory)

    @property
    def config(self):
        return self._config

    @property
    def intfs(self):
        for obj in self.CiscoConfParse.objs:
            if obj.is_intf:
                yield obj

    @property
    def ethernet_intfs(self):
        for obj in self.CiscoConfParse.objs:
            if obj.is_ethernet_intf:
                yield obj

    @property
    def loopback_intfs(self):
        for obj in self.CiscoConfParse.objs:
            if obj.is_loopback_intf:
                yield obj

    @property
    def portchannel_intfs(self):
        for obj in self.CiscoConfParse.objs:
            if obj.is_portchannel_intf:
                yield obj

I will therefore change the code as you advised me.

Thank you for your time, your advice and your lib :)