bb-Ricardo / netbox-sync

Sync objects from VMware or redfish sources to NetBox
MIT License
286 stars 65 forks source link

Sync issue: AttributeError: 'NoneType' object has no attribute 'get_display_name' #19

Closed Epaphus closed 3 years ago

Epaphus commented 3 years ago

Hi,

I upgraded our test Netbox from 2.8 to 2.9.10 and also migrated from vcenter-netbox-sync to netbox-sync since vcenter-netbox-sync hasn't been updated to support Netbox 2.9.

The initial sync went well however follow up syncs are failing with a "AttributeError: 'NoneType' object has no attribute 'get_display_name'" error, If I delete the IP listed from Netbox the sync gets past the error until it hits another IP address.


2020-12-07 16:38:47,214 - DEBUG2: Parsing 'interface' data structure: vmk0 (dc01-esx002.domain.tld)
2020-12-07 16:38:47,214 - DEBUG2: Compiling VLAN list
2020-12-07 16:38:47,215 - DEBUG2: Parsing 'VLAN' data structure: 205 (vCenter: dc01-vc01)
2020-12-07 16:38:47,215 - DEBUG2: Parsing 'site' data structure: vCenter: dc01-vc01
2020-12-07 16:38:47,215 - DEBUG: Updated site object: vCenter: dc01-vc01
2020-12-07 16:38:47,215 - DEBUG: Updated VLAN object: 205 (vCenter: dc01-vc01)
2020-12-07 16:38:47,216 - INFO: Created new interface object: vmk0 (dc01-esx002.domain.tld)
2020-12-07 16:38:47,216 - DEBUG2: Trying to find prefix for IP: 10.8.1.12/24
2020-12-07 16:38:47,219 - DEBUG2: Found IP '10.8.1.12/24' matches global prefix '10.8.1.0/24'
2020-12-07 16:38:47,219 - DEBUG: No exiting IP address object found. Creating a new one.
2020-12-07 16:38:47,219 - DEBUG2: Parsing 'IP address' data structure: 10.8.1.12/24
2020-12-07 16:38:47,220 - INFO: Created new IP address object: 10.8.1.12/24
2020-12-07 16:38:47,220 - DEBUG2: Parsing 'interface' data structure: vmk1 (dc01-esx002.domain.tld)
2020-12-07 16:38:47,220 - DEBUG2: Parsing 'VLAN' data structure: 208 (vCenter: dc01-vc01)
2020-12-07 16:38:47,221 - DEBUG2: Parsing 'site' data structure: vCenter: dc01-vc01
2020-12-07 16:38:47,221 - DEBUG: Updated site object: vCenter: dc01-vc01
2020-12-07 16:38:47,221 - DEBUG: Updated VLAN object: 208 (vCenter: dc01-vc01)
2020-12-07 16:38:47,221 - INFO: Created new interface object: vmk1 (dc01-esx002.domain.tld)
2020-12-07 16:38:47,221 - DEBUG2: Trying to find prefix for IP: 10.8.2.13/24
2020-12-07 16:38:47,224 - DEBUG2: Found IP '10.8.2.13/24' matches global prefix '10.8.2.0/24'
2020-12-07 16:38:47,225 - DEBUG: No exiting IP address object found. Creating a new one.
2020-12-07 16:38:47,225 - DEBUG2: Parsing 'IP address' data structure: 10.8.2.13/24
2020-12-07 16:38:47,225 - INFO: Created new IP address object: 10.8.2.13/24
2020-12-07 16:38:47,225 - DEBUG: Setting IP '10.8.2.13/255.255.255.0' as primary IPv4 for 'dc01-esx002.domain.tld
2020-12-07 16:38:47,225 - DEBUG2: Parsing 'device' data structure: dc01-esx002.domain.tld
2020-12-07 16:38:47,225 - INFO: Device 'dc01-esx002.domain.tld' attribute 'primary_ip4' changed from 'None' to '10.8.2.13/24'
2020-12-07 16:38:47,226 - DEBUG2: Parsing 'interface' data structure: vmk2 (dc01-esx002.domain.tld)
2020-12-07 16:38:47,226 - DEBUG2: Parsing 'VLAN' data structure: 208 (vCenter: dc01-vc01)
2020-12-07 16:38:47,226 - DEBUG2: Parsing 'site' data structure: vCenter: dc01-vc01
2020-12-07 16:38:47,227 - DEBUG: Updated site object: vCenter: dc01-vc01
2020-12-07 16:38:47,227 - DEBUG: Updated VLAN object: 208 (vCenter: dc01-vc01)
2020-12-07 16:38:47,227 - INFO: Created new interface object: vmk2 (dc01-esx002.domain.tld)
2020-12-07 16:38:47,227 - DEBUG2: Trying to find prefix for IP: 10.8.2.14/24
2020-12-07 16:38:47,230 - DEBUG2: Found IP '10.8.2.14/24' matches global prefix '10.8.2.0/24'
Traceback (most recent call last):
  File "/opt/netbox-sync/netbox-sync.py", line 143, in <module>
    main()
  File "/opt/netbox-sync/netbox-sync.py", line 119, in main
    source.apply()
  File "/opt/netbox-sync/module/sources/vmware/connection.py", line 370, in apply
    view_details.get("view_handler")(obj)
  File "/opt/netbox-sync/module/sources/vmware/connection.py", line 1746, in add_host
    p_ipv4=host_primary_ip4, p_ipv6=host_primary_ip6)
  File "/opt/netbox-sync/module/sources/vmware/connection.py", line 1064, in add_device_vm_to_inventory
    log.warning(f"Current interface '{current_nic.get_display_name()}' for IP "
AttributeError: 'NoneType' object has no attribute 'get_display_name'

Any idea on what might be causing the issue, I'd rather not have to spend ages removing each IP it has an issue with, even more sure if its going to have same issue later on :slightly_smiling_face:

Thanks

bb-Ricardo commented 3 years ago

Hi,

This is not good and needs to be fixed 😉

You said this is a follow up sync. I can see in the log that it try's to create new IP addresses and interfaces. Is that correct? Or have these objects been created during the initial sync?

It seems that this IP has been assigned to a different interface before.

Can you try switching off caching? Maybe old data causes the issue.

Let me know how it goes.

Epaphus commented 3 years ago

Hi,

Looking at the change the log for the IP address, it was created on the initial sync but not attached to any interface. Follow up syncs give the error shown in my original post.

Disabling caching causes the same error message.

There hasn't been any changes with regards to the hosts between the syncs. Looking at the host, there are no IPs assigned to it within Netbox.

We have 2 vCenters and I can see the hosts attached to the other vCenter had the vmkX created on them within Netbox, however this one doesn't.

Hosts in vCenter 1 don't have the vmkX interfaces

image

Hosts in vCenter 2 do have the vmkX interfaces

image

bb-Ricardo commented 3 years ago

Thank you for testing. Then the initial sync must have produced some ERRORs about unable of creating IP address objects in NetBox. Do you still have the initial log? do you mind sharing it? you can send it to my eMail (header in main script) if that is ok.

Epaphus commented 3 years ago

I do still have log, It will contain data such as customer names, etc so would need to get it approved before I would be able to send it (GDPR and all that).

I have looked in the log for errors and found quite a few like this, with different interface names and VLANs.

2020-12-07 15:29:20,008 - INFO: Creating new NetBox 'interface' object 'vmk2 (dc01-esx002.domain.tld)' with data: {'tags': [{'name': 'NetBox-synced'}, {'name': 'Source: dc01-vc01'}], 'name': 'vmk2', 'device': 2, 'mac_address': '00:50:56:6D:CC:$
2020-12-07 15:29:20,041 - ERROR: NetBox returned: POST /api/dcim/interfaces/ Bad Request
2020-12-07 15:29:20,042 - ERROR: NetBox returned body: {'untagged_vlan': ["VLAN infra-dc01-iscsi-001 (208) must belong to the same site as the interface's parent device, or it must be global."]}
2020-12-07 15:29:20,042 - ERROR: Request Failed for interface. Used data: {'tags': [{'name': 'NetBox-synced'}, {'name': 'Source: dc01-vc01'}], 'name': 'vmk2', 'device': 2, 'mac_address': '00:50:56:6D:CC:8B', 'mtu': 9000, 'type': 'virtual'$

Looking at the sites, I can see the hosts are in a different site to the VLANs. I'm guessing that will be same with some of the VMs as they would have been imported when we used "vcenter-netbox-sync" on Netbox 2.8.

I will look at the "cluster_site_relation" option and see if that sorts it.

bb-Ricardo commented 3 years ago

Hi, yes that very like is one issue. You would need to move your devices to the proper site. Previous NetBox sync did not care about all of that.

Still, the stack trace should not occure. Will check it out.

Epaphus commented 3 years ago

I'm not very experienced in python so I might be wrong however the change has allowed the sync to continue.

This looks to be grabbing the wrong value, https://github.com/bb-Ricardo/netbox-sync/blob/8205fc821e95c1575443162be6b2afac62d152bb/module/sources/vmware/connection.py#L1046

The "nic_object" has the enabled value under "data_model" rather than "data"

{
    "api_path": "dcim/interfaces",
    "data": {
        "description": "iSCSI-vmnic2 (vSwitch1, vlan ID: 208)",
        "device": "<NBDevice instance 'dc1-esx001.domain.tld' at 139942295038272>",
        "mac_address": "00:50:56:6C:CC:F5",
        "mode": "access",
        "mtu": 9000,
        "name": "vmk1",
        "tagged_vlans": [],
        "tags": [],
        "type": "virtual",
        "untagged_vlan": "<NBVLAN instance '208 (Data Center 1)' at 139942289286592>"
    },
    "data_model": {
        "connection_status": "<class 'bool'>",
        "description": 200,
        "device": "<class 'module.netbox.object_classes.NBDevice'>",
        "enabled": "<class 'bool'>",
        "label": 64,
        "mac_address": "<class 'str'>",
        "mgmt_only": "<class 'bool'>",
        "mode": [
            "access",
            "tagged",
            "tagged-all"
        ],
        "mtu": "<class 'int'>",
        "name": 64,
        "tagged_vlans": "<class 'module.netbox.object_classes.NBVLANList'>",
        "tags": "<class 'module.netbox.object_classes.NBTagList'>",
        "type": [
            "virtual",
            "100base-tx",
            "1000base-t",
            "10gbase-t",
            "25gbase-x-sfp28",
            "40gbase-x-qsfpp",
            "other"
        ],
        "untagged_vlan": "<class 'module.netbox.object_classes.NBVLAN'>"
    },
    "enforce_secondary_key": true,
    "is_new": true,
    "name": "interface",
    "nb_id": 0,
    "primary_key": "name",
    "prune": true,
    "secondary_key": "device",
    "source": "dc1-vc01",
    "unset_items": [],
    "updated_items": [
        "name",
        "device",
        "mac_address",
        "mtu",
        "type",
        "mode",
        "description",
        "untagged_vlan",
        "mac_address"
    ]
}

This what I currently have

                    # get current IP interface status
                    current_nic = grab(ip, "data.assigned_object_id")
                    current_nic_enabled = grab(current_nic, "data.enabled")
                    this_nic_enabled = grab(nic_object, "data_model.enabled")

I'm guessing the grab for the "current_nic" would also to be changed to "data_model.enabled" ?

Now I need to look into the duplicated VLANs I now seem to have

bb-Ricardo commented 3 years ago

Thank you for looking into this. The "enabled" attribute however doesn't get set during parsing of the host virtual interfaces. Will add this, so that it defaults to 'true'.

The duplicate vlans got created because the cluster_site_relation was not initially set.

To fix this you need to assign your hosts to the same site and cluster where your VLANs are configured.

Changing this later is difficult. Delting all the IP adresses and VLANs created by the tool and thwn changing the hosts cluster should help.

bb-Ricardo commented 3 years ago

Hi,

I found a bug and fixed it in the last commit. Can you test it and see if it works now?

Thank you.

Epaphus commented 3 years ago

The sync is working the new code, I also removed some interfaces one of the hosts and created the IPs to simulate the state it was in before when it stopped working and it handled that without issues and recreated the interfaces and attached the IPs.

The duplicate vlans got created because the cluster_site_relation was not initially set.

That is the cause of some of them, some span multiple sites or are pre-configured on multiple vCenters for DR. For these we normally don't assign the VLAN to a site as they are in multiple sites and NB doesn't allow multiple sites to be attached to a single VLAN. Anyway that is getting off topic for this sync issue which seems to working now.

bb-Ricardo commented 3 years ago

Thank you.