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 when using a DICT in the attr section of a task for my custom plugin #300

Open
byrn-baker opened this issue Jan 2, 2024 · 3 comments
Labels
status: gathering feedback Further discussion is needed to determine this issue's scope and/or implementation

Comments

@byrn-baker
Copy link

byrn-baker commented Jan 2, 2024

ISSUE TYPE
  • Bug Report
SOFTWARE VERSIONS
pynautobot

1.5.0

Ansible:

ansible [core 2.13.13]

Nautobot:

1.5.7

Collection:

networktocode.nautobot 4.4.0

SUMMARY

When describing a task to create or modify a field in my plugin the attributes failes when attempting to utilize a dictionary

STEPS TO REPRODUCE

Run the playbook that creates or updates a model in my plugin. ansible-playbook pb.load-betacdn-to-dev.yml
If the attributes are not referenced by the UUID then the playbook will fail with An exception occurred during task execution. To see the full traceback, use -vvv. The error was: TypeError: expected string or bytes-like object

playbook:

- include_vars: ./tmp/beta_data/sites.yml
- name: Create Beta Sites on Dev
  networktocode.nautobot.plugin:
    url: "{{ dev_nb_url }}"
    token: "{{ dev_nb_token }}"
    plugin: nautobot-cdn-models
    endpoint: cdnsite
    validate_certs: false
    identifiers:
      name: "{{ item.name }}"
    attrs:
      status: "active"
      cdn_site_role:
        name: Beta_Site
      region:
        name: "COLOCATION"
      abbreviatedName: "{{ item.abbreviatedName | default(omit) }}"
      bandwidthLimitMbps: "{{ item.bandwidthLimitMbps | default(omit) }}"
      enableDisklessMode: "{{ item.enableDisklessMode | default(omit) }}"
      siteId: "{{ item.siteId | default(999) | int }}"
  loop: "{{ sites }}"

input data:

---
sites:
  - name: Texas_Dallas_TX_linear_hpc
    siteId: 4
    abbreviatedName: dllbtx_l_hpc
    bandwidthLimitMbps: 390000
    enableDisklessMode: True
    cacheMemoryProfileId: 2562
    neighbors:
        - preference: 1000
          siteId: 11
          name: NorthWest_NCWest_CO_linear_shield
        - preference: 750
          siteId: 9
          name: Carolinas_NCEast_NC_linear_shield
EXPECTED RESULTS
TASK [load_betacdn_data : Create Beta Sites on Dev] **********************************************************************************************************************************************************************************************************************************************************************************************************************************
changed: [localhost] => (item={'name': 'Texas_Dallas_TX_linear_hpc', 'siteId': 4, 'abbreviatedName': 'dllbtx_l_hpc', 'bandwidthLimitMbps': 390000, 'enableDisklessMode': True, 'cacheMemoryProfileId': 2562, 'neighbors': [{'preference': 1000, 'siteId': 11, 'name': 'NorthWest_NCWest_CO_linear_shield'}, {'preference': 750, 'siteId': 9, 'name': 'Carolinas_NCEast_NC_linear_shield'}]})
ACTUAL RESULTS
TASK [load_betacdn_data : Create Beta Sites on Dev] **********************************************************************************************************************************************************************************************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: TypeError: expected string or bytes-like object
failed: [localhost] (item={'name': 'Texas_Dallas_TX_linear_hpc', 'siteId': 4, 'abbreviatedName': 'dllbtx_l_hpc', 'bandwidthLimitMbps': 390000, 'enableDisklessMode': True, 'cacheMemoryProfileId': 2562, 'neighbors': [{'preference': 1000, 'siteId': 11, 'name': 'NorthWest_NCWest_CO_linear_shield'}, {'preference': 750, 'siteId': 9, 'name': 'Carolinas_NCEast_NC_linear_shield'}]}) => changed=false 
  ansible_loop_var: item
  item:
    abbreviatedName: dllbtx_l_hpc
    bandwidthLimitMbps: 390000
    cacheMemoryProfileId: 2562
    enableDisklessMode: true
    name: Texas_Dallas_TX_linear_hpc
    neighbors:
    - name: NorthWest_NCWest_CO_linear_shield
      preference: 1000
      siteId: 11
    - name: Carolinas_NCEast_NC_linear_shield
      preference: 750
      siteId: 9
    siteId: 4
  module_stderr: |-
    Traceback (most recent call last):
      File "/Users/bbaker4/.ansible/tmp/ansible-tmp-1704209060.585809-78436-163245221387566/AnsiballZ_plugin.py", line 107, in <module>
        _ansiballz_main()
      File "/Users/bbaker4/.ansible/tmp/ansible-tmp-1704209060.585809-78436-163245221387566/AnsiballZ_plugin.py", line 99, in _ansiballz_main
        invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
      File "/Users/bbaker4/.ansible/tmp/ansible-tmp-1704209060.585809-78436-163245221387566/AnsiballZ_plugin.py", line 47, in invoke_module
        runpy.run_module(mod_name='ansible_collections.networktocode.nautobot.plugins.modules.plugin', init_globals=dict(_module_fqn='ansible_collections.networktocode.nautobot.plugins.modules.plugin', _modlib_path=modlib_path),
      File "/opt/homebrew/opt/[email protected]/Frameworks/Python.framework/Versions/3.8/lib/python3.8/runpy.py", line 207, in run_module
        return _run_module_code(code, init_globals, run_name, mod_spec)
      File "/opt/homebrew/opt/[email protected]/Frameworks/Python.framework/Versions/3.8/lib/python3.8/runpy.py", line 97, in _run_module_code
        _run_code(code, mod_globals, init_globals,
      File "/opt/homebrew/opt/[email protected]/Frameworks/Python.framework/Versions/3.8/lib/python3.8/runpy.py", line 87, in _run_code
        exec(code, run_globals)
      File "/var/folders/kk/dmtlj_3s06j5nxxqrs0v6v_r0000gn/T/ansible_networktocode.nautobot.plugin_payload_5k9u6_4q/ansible_networktocode.nautobot.plugin_payload.zip/ansible_collections/networktocode/nautobot/plugins/modules/plugin.py", line 170, in <module>
      File "/var/folders/kk/dmtlj_3s06j5nxxqrs0v6v_r0000gn/T/ansible_networktocode.nautobot.plugin_payload_5k9u6_4q/ansible_networktocode.nautobot.plugin_payload.zip/ansible_collections/networktocode/nautobot/plugins/modules/plugin.py", line 165, in main
      File "/var/folders/kk/dmtlj_3s06j5nxxqrs0v6v_r0000gn/T/ansible_networktocode.nautobot.plugin_payload_5k9u6_4q/ansible_networktocode.nautobot.plugin_payload.zip/ansible_collections/networktocode/nautobot/plugins/module_utils/utils.py", line 472, in __init__
      File "/var/folders/kk/dmtlj_3s06j5nxxqrs0v6v_r0000gn/T/ansible_networktocode.nautobot.plugin_payload_5k9u6_4q/ansible_networktocode.nautobot.plugin_payload.zip/ansible_collections/networktocode/nautobot/plugins/module_utils/utils.py", line 916, in _normalize_data
      File "/var/folders/kk/dmtlj_3s06j5nxxqrs0v6v_r0000gn/T/ansible_networktocode.nautobot.plugin_payload_5k9u6_4q/ansible_networktocode.nautobot.plugin_payload.zip/ansible_collections/networktocode/nautobot/plugins/module_utils/utils.py", line 893, in _to_slug
      File "/opt/homebrew/opt/[email protected]/Frameworks/Python.framework/Versions/3.8/lib/python3.8/re.py", line 210, in sub
        return _compile(pattern, flags).sub(repl, string, count)
    TypeError: expected string or bytes-like object
  module_stdout: ''
  msg: |-
    MODULE FAILURE
    See stdout/stderr for the exact error
  rc: 1

I played around with the utils.py and updated the _to_slug function from:

def _to_slug(self, value):
        """
        :returns slug (str): Slugified value
        :params value (str): Value that needs to be changed to slug format
        """
        if value is None:
            return value
        elif isinstance(value, int) or self.is_valid_uuid(value):
            return value
        else:
            removed_chars = re.sub(r"[^\-\.\w\s]", "", value)
            convert_chars = re.sub(r"[\-\.\s]+", "-", removed_chars)
            return convert_chars.strip().lower()

to:

def _to_slug(self, value):
        """
        :returns slug (str): Slugified value
        :params value (str): Value that needs to be changed to slug format
        """
        if value is None:
            return value
        elif isinstance(value, int) or self.is_valid_uuid(value):
            return value
        elif isinstance(value, dict):
            value = value.get('name', '')
        else:
            removed_chars = re.sub(r"[^\-\.\w\s]", "", value)
            convert_chars = re.sub(r"[\-\.\s]+", "-", removed_chars)
            return convert_chars.strip().lower()

This resolves my issue when using attributes in the plugins module.

Here is the plugin repo
https://github.com/byrn-baker/nautobot-cdn-models

@joewesch
Copy link
Contributor

joewesch commented Jan 2, 2024

@byrn-baker since you are talking about slugs I assume this is only related to Nautobot v1.6? Do you know if this is also an issue in the latest version?

@byrn-baker
Copy link
Author

I've got another issue pending that is affecting my plugin on both 1.6.6 and 2.0.x that is preventing me from being able to test on those versions of Nautobot, Ansible Module and Pynautobot

nautobot/nautobot#4853

@byrn-baker
Copy link
Author

I was messing with the _to_slug function because it looked to me like this is where the UUID look up was being performed. With out that change I could not even use a DICT for the Region or Site in the Attributes of the plugin module. It would only work with the UUID.

I assumed this could be an issue on other plugins that attempted to use the plugin module to manage the plugin elements for nautobot.

@joewesch joewesch added the status: gathering feedback Further discussion is needed to determine this issue's scope and/or implementation label Mar 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: gathering feedback Further discussion is needed to determine this issue's scope and/or implementation
Projects
None yet
Development

No branches or pull requests

2 participants