Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugin module fails to create nautobot-device-lifecycle-mgmt hardware entries #306

Open
pugnacity opened this issue Jan 23, 2024 · 4 comments · Fixed by nautobot/nautobot-app-device-lifecycle-mgmt#290
Assignees
Labels
upstream Upstream Project Issue/Feature

Comments

@pugnacity
Copy link
Contributor

ISSUE TYPE
  • Bug Report
SOFTWARE VERSIONS
pynautobot

2.0.2

Ansible:

2.16.2

Nautobot:

2.1.1

Collection:

5.1.0

SUMMARY

creating new hardware EoL entries will fail

STEPS TO REPRODUCE

Run the following task

    - name: Init InfraDB | Device Lifecycle | hardware_notice
      networktocode.nautobot.plugin:
        url: "{{ nautobot_url }}"
        token: "{{ nautobot_token }}"
        validate_certs: "{{ documentation_nautobot['validate_certs'] }}"
        plugin: nautobot-device-lifecycle-mgmt
        endpoint: hardware
        identifiers:
          device_type: "{{ hardware_notice['device'] }}"
        attrs:
          device_type:
            model: "{{ hardware_notice['device'] }}"
          release_date: "{{ hardware_notice['release_date'] }}"
          end_of_sale: "{{ hardware_notice['end_of_sale'] }}"
          end_of_support: "{{ hardware_notice['end_of_support'] }}"
          # yamllint disable-line rule:line-length
          end_of_sw_releases: "{{ hardware_notice['end_of_sw_releases'] | default(omit) }}"
          # yamllint disable-line rule:line-length
          end_of_security_patches: "{{ hardware_notice['end_of_security_patches'] | default(omit) }}"
          # yamllint disable-line rule:line-length
          documentation_url: "{{ hardware_notice['documentation_url'] | default(omit) }}"
        state: present
      loop: "{{ hardware_notices }}"
      loop_control:
        loop_var: hardware_notice

the used variable looks like this

hardware_notices:
  - device: UCS-FI-6332-16UP
    release_date: "2016-11-01"
    end_of_sale: "2023-10-30"
    end_of_support: "2028-10-31"
    end_of_sw_releases: "2028-10-31"
    end_of_security_patches: "2028-10-31"
    # yamllint disable-line rule:line-length
    documentation_url: https://www.cisco.com/c/en/us/products/collateral/servers-unified-computing/ucs-fabric-interconnect-f1-6332-16up-eol.html
EXPECTED RESULTS

Hardware notice is created or at least reported as not changed

ACTUAL RESULTS
failed: [localhost] (item={'device': 'UCS-FI-6332-16UP', 'release_date': '2016-11-01', 'end_of_sale': '2023-10-30', 'end_of_support': '2028-10-31', 'end_of_sw_releases': '2028-10-31', 'end_of_security_patches': '2028-10-31', 'documentation_url': 'https://www.cisco.com/c/en/us/products/collateral/servers-unified-computing/ucs-fabric-interconnect-f1-6332-16up-eol.html'}) => {
    "ansible_loop_var": "hardware_notice",
    "changed": false,
    "hardware_notice": {
        "device": "UCS-FI-6332-16UP",
        "documentation_url": "https://www.cisco.com/c/en/us/products/collateral/servers-unified-computing/ucs-fabric-interconnect-f1-6332-16up-eol.html",
        "end_of_sale": "2023-10-30",
        "end_of_security_patches": "2028-10-31",
        "end_of_support": "2028-10-31",
        "end_of_sw_releases": "2028-10-31",
        "release_date": "2016-11-01"
    },
    "invocation": {
        "module_args": {
            "api_version": null,
            "attrs": {
                "device_type": {
                    "model": "UCS-FI-6332-16UP"
                },
                "documentation_url": "https://www.cisco.com/c/en/us/products/collateral/servers-unified-computing/ucs-fabric-interconnect-f1-6332-16up-eol.html",
                "end_of_sale": "2023-10-30",
                "end_of_security_patches": "2028-10-31",
                "end_of_support": "2028-10-31",
                "end_of_sw_releases": "2028-10-31",
                "release_date": "2016-11-01"
            },
            "endpoint": "hardware",
            "identifiers": {
                "device_type": "UCS-FI-6332-16UP"
            },
            "plugin": "nautobot-device-lifecycle-mgmt",
            "query_params": null,
            "state": "present",
            "token": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "url": "https://nautobot.domain.tld",
            "validate_certs": false
        }
    },
    "msg": "{\"device_type\":[\"Select a valid choice. 4f6c1d14-2571-42f1-83d6-24e870d4ef80 is not one of the available choices.\"]}"
}

When I change the identifiers to:

identifiers:
  device_type_id: "{{ hardware_notice['device'] }}"

The error is changed to

 "msg": "{\"device_type_id\":[\"“UCS-FI-6332-16UP” is not a valid UUID.\"]}"

What I don't understand is, why there is one time the error message with the correct ID and one time with the model name.

@joewesch
Copy link
Contributor

Can you try changing this:

        identifiers:
          device_type: "{{ hardware_notice['device'] }}"
        attrs:
          device_type:
            model: "{{ hardware_notice['device'] }}"

To this:

        identifiers:
          device_type:
            model: "{{ hardware_notice['device'] }}"
        attrs:
          device_type:
            model: "{{ hardware_notice['device'] }}"

@pugnacity
Copy link
Contributor Author

The error is still the same:

failed: [localhost] (item={'device': 'UCS-FI-6332-16UP', 'release_date': '2016-11-01', 'end_of_sale': '2023-10-30', 'end_of_support': '2028-10-31', 'end_of_sw_releases': '2028-10-31', 'end_of_security_patches': '2028-10-31', 'documentation_url': 'https://www.cisco.com/c/en/us/products/collateral/servers-unified-computing/ucs-fabric-interconnect-f1-6332-16up-eol.html'}) => {
    "ansible_loop_var": "hardware_notice",
    "changed": false,
    "hardware_notice": {
        "device": "UCS-FI-6332-16UP",
        "documentation_url": "https://www.cisco.com/c/en/us/products/collateral/servers-unified-computing/ucs-fabric-interconnect-f1-6332-16up-eol.html",
        "end_of_sale": "2023-10-30",
        "end_of_security_patches": "2028-10-31",
        "end_of_support": "2028-10-31",
        "end_of_sw_releases": "2028-10-31",
        "release_date": "2016-11-01"
    },
    "invocation": {
        "module_args": {
            "api_version": null,
            "attrs": {
                "device_type": {
                    "model": "UCS-FI-6332-16UP"
                },
                "documentation_url": "https://www.cisco.com/c/en/us/products/collateral/servers-unified-computing/ucs-fabric-interconnect-f1-6332-16up-eol.html",
                "end_of_sale": "2023-10-30",
                "end_of_security_patches": "2028-10-31",
                "end_of_support": "2028-10-31",
                "end_of_sw_releases": "2028-10-31",
                "release_date": "2016-11-01"
            },
            "endpoint": "hardware",
            "identifiers": {
                "device_type": {
                    "model": "UCS-FI-6332-16UP"
                }
            },
            "plugin": "nautobot-device-lifecycle-mgmt",
            "query_params": null,
            "state": "present",
            "token": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "url": "https://nautobot.domain.tld",
            "validate_certs": false
        }
    },
    "msg": "{\"device_type\":[\"Select a valid choice. 4f6c1d14-2571-42f1-83d6-24e870d4ef80 is not one of the available choices.\"]}"
}

what I don't understand is why sometimes the UUID is used and sometimes the name string.

@pszulczewski
Copy link
Contributor

I'll check that.

@pszulczewski pszulczewski self-assigned this Feb 1, 2024
@pszulczewski
Copy link
Contributor

We use lookup for known core models to automatically extract object UUIDs for well known attributes. In this case for device_type.
I see it fails on verification step after creation, because LCM plugin API expects device_type to be a model string, not UUID, so the get methods fails.

https://github.com/nautobot/nautobot-app-device-lifecycle-mgmt/blob/68e6b781a418607b9ad833793be231d36b413e23/nautobot_device_lifecycle_mgmt/filters.py#L32

I can create it with device_type_id as an identifier. I had to use lookup module to extract it.

    - set_fact:
        attrs:
          device_type: "Cisco Test"
          release_date: "2016-11-01"
          end_of_sale: "2023-10-30"
          end_of_support: "2028-10-31"
          end_of_sw_releases: "2028-10-31"
          end_of_security_patches: "2028-10-31"
          documentation_url: "https://www.cisco.com/c/en/us/products/collateral/servers-unified-computing/ucs-fabric-interconnect-f1-6332-16up-eol.html"

    - set_fact:
        api_filter_str: 'model="{{ attrs.device_type }}"'

    - set_fact:
        device_type: "{{ lookup('networktocode.nautobot.lookup', 'device-types', api_endpoint=nautobot_url, token=nautobot_token, api_filter=api_filter_str) }}"

    - name: Plugin module issue 306 - Create
      networktocode.nautobot.plugin:
        url: "{{ nautobot_url }}"
        token: "{{ nautobot_token }}"
        plugin: nautobot-device-lifecycle-mgmt
        endpoint: hardware
        identifiers:
          device_type_id: "{{ device_type['key'] }}"
        attrs: "{{ attrs }}"
        state: present

    - name: Plugin module issue 306 - Create duplicate
      networktocode.nautobot.plugin:
        url: "{{ nautobot_url }}"
        token: "{{ nautobot_token }}"
        plugin: nautobot-device-lifecycle-mgmt
        endpoint: hardware
        identifiers:
          device_type_id: "{{ device_type['key'] }}"
        attrs: "{{ attrs }}"
        state: present

But unfortunately only on first creation, idempotently it fails.

TASK [regression-latest : Plugin module issue 306] *****************************
changed: [testhost]

TASK [regression-latest : Plugin module issue 306 DUP] *************************
fatal: [testhost]: FAILED! => {"changed": false, "msg": "device_type_id does not exist on existing object. Check to make sure valid field."}

That would need changes in the API in lifecycle_management_app.

I tested that locally by building local test env with lcm branch where I changed api filter.
nautobot/nautobot-app-device-lifecycle-mgmt@053d7d4

And it works fine:

    - set_fact:
        attrs:
          device_type: "Cisco Test"
          release_date: "2016-11-01"
          end_of_sale: "2023-10-30"
          end_of_support: "2028-10-31"
          end_of_sw_releases: "2028-10-31"
          end_of_security_patches: "2028-10-31"
          documentation_url: "https://www.cisco.com/c/en/us/products/collateral/servers-unified-computing/ucs-fabric-interconnect-f1-6332-16up-eol.html"

    - name: Plugin module issue 306 - Create
      networktocode.nautobot.plugin:
        url: "{{ nautobot_url }}"
        token: "{{ nautobot_token }}"
        plugin: nautobot-device-lifecycle-mgmt
        endpoint: hardware
        identifiers:
          device_type: "{{ attrs['device_type'] }}"
        attrs: "{{ attrs }}"
        state: present

    - name: Plugin module issue 306 - Create duplicate
      networktocode.nautobot.plugin:
        url: "{{ nautobot_url }}"
        token: "{{ nautobot_token }}"
        plugin: nautobot-device-lifecycle-mgmt
        endpoint: hardware
        identifiers:
          device_type: "{{ attrs['device_type'] }}"
        attrs: "{{ attrs }}"
        state: present
TASK [regression-latest : set_fact] ********************************************
ok: [testhost]

TASK [regression-latest : Plugin module issue 306 - Create] ********************
changed: [testhost]

TASK [regression-latest : Plugin module issue 306 - Create duplicate] **********
ok: [testhost]

I will submit this branch as a pull request, but that will require new major release of lcm app as this is a backwards breaking change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
upstream Upstream Project Issue/Feature
Projects
None yet
3 participants