### Setup and Documentation Generation Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/update_module.md These commands set up the Python virtual environment, install project dependencies, and then generate documentation. The `make-docs.sh` script handles the documentation build process. ```bash ❯ poetry shell && poetry install ❯ ./hacking/make-docs.sh rm: tests/output: No such file or directory rm: .pytest_cache: No such file or directory Using /Users/myohman/cloned-repos/nautobot-ansible/ansible.cfg as config file Created collection for networktocode.nautobot at /Users/myohman/cloned-repos/nautobot-ansible/networktocode.nautobot-1.1.0.tar.gz Starting galaxy collection install process [WARNING]: The specified collections path '/Users/myohman/cloned-repos/nautobot-ansible' is not part of the configured Ansible collections paths '/Users/myohman/.ansible/collections:/usr/share/ansible/collections'. The installed collection won't be picked up in an Ansible run. Process install dependency map Starting collection install process Installing 'networktocode.nautobot:1.1.0' to '/Users/myohman/cloned-repos/nautobot-ansible/ansible_collections/networktocode.nautobot' networktocode.nautobot (1.1.0) was installed successfully Installing 'ansible.netcommon:1.4.1' to '/Users/myohman/cloned-repos/nautobot-ansible/ansible_collections/ansible/netcommon' Downloading https://galaxy.ansible.com/download/ansible-netcommon-1.4.1.tar.gz to /Users/myohman/.ansible/tmp/ansible-local-4390k59zwzli/tmp5871aum5 ansible.netcommon (1.4.1) was installed successfully Installing 'community.general:1.3.4' to '/Users/myohman/cloned-repos/nautobot-ansible/ansible_collections/community/general' Downloading https://galaxy.ansible.com/download/community-general-1.3.4.tar.gz to /Users/myohman/.ansible/tmp/ansible-local-4390k59zwzli/tmp5871aum5 community.general (1.3.4) was installed successfully Installing 'google.cloud:1.0.1' to '/Users/myohman/cloned-repos/nautobot-ansible/ansible_collections/google/cloud' Downloading https://galaxy.ansible.com/download/google-cloud-1.0.1.tar.gz to /Users/myohman/.ansible/tmp/ansible-local-4390k59zwzli/tmp5871aum5 google.cloud (1.0.1) was installed successfully Installing 'community.kubernetes:1.1.1' to '/Users/myohman/cloned-repos/nautobot-ansible/ansible_collections/community/kubernetes' Downloading https://galaxy.ansible.com/download/community-kubernetes-1.1.1.tar.gz to /Users/myohman/.ansible/tmp/ansible-local-4390k59zwzli/tmp5871aum5 community.kubernetes (1.1.1) was installed successfully ERROR:antsibull:error=Cannot find plugin:func=get_ansible_plugin_info:mod=antsibull.docs_parsing.ansible_internal:plugin_name=networktocode.nautobot.interface:plugin_type=module|Error while extracting documentation. Will not document this plugin. ``` -------------------------------- ### Setup and Documentation Generation Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/new_module.md Commands to set up the development environment and generate documentation for Nautobot Ansible modules. Ensure you are in a poetry shell and have installed the project dependencies. ```bash ❯ poetry shell && poetry install ❯ ./hacking/make-docs.sh ``` -------------------------------- ### Changelog Fragment Examples Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/changelog_fragments.md Illustrates the correct format for changelog fragment content. The 'Wrong' example shows an incorrect format, while the 'Right' example demonstrates the proper way to write a fixed bug entry. ```plaintext fix critical bug in documentation ``` ```plaintext Fixed critical bug in documentation. ``` -------------------------------- ### Update Module EXAMPLES with New Options Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/update_module.md Include new options such as 'import_targets' and 'export_targets' in the module's example usage to demonstrate their functionality. ```yaml - name: Create vrf with all information vrf: url: http://nautobot.local token: thisIsMyToken data: name: Test VRF rd: "65000:1" tenant: Test Tenant enforce_unique: true import_targets: - "65000:65001" export_targets: - "65000:65001" description: VRF description tags: - Schnozzberry state: present ``` -------------------------------- ### Build and Install Nautobot Ansible Collection from Source Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/installation.md Build the collection locally from the cloned repository and then install it. This is useful for development or testing. ```bash cd nautobot-ansible ansible-galaxy collection build . ansible-galaxy collection install networktocode-nautobot*.tar.gz ``` -------------------------------- ### Start Nautobot Services Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/testing_locally.md Initiate Nautobot and its dependencies in detached mode using the Invoke start command. ```shell ❯ invoke start Starting Nautobot in detached mode... Running docker-compose command "up --detach" Creating network "nautobot_ansible_default" with the default driver Creating nautobot_ansible_postgres_1 ... done Creating nautobot_ansible_redis_1 ... done Creating nautobot_ansible_nautobot_1 ... done Creating nautobot_ansible_worker_1 ... done ``` -------------------------------- ### Multiple Changelog Entries Example Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/changelog_fragments.md Demonstrates how to create multiple changelog entries from a single issue. This example shows how to generate two entries in the 'fixed' category and one in the 'changed' category by creating separate fragment files. ```plaintext Fixed critical bug in documentation. Fixed release notes generation. ``` ```plaintext Changed release notes generation. ``` -------------------------------- ### Module Examples for Route Targets Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/new_module.md Provides examples for creating, updating, and deleting route targets using the Nautobot Ansible module, demonstrating various use cases. ```yaml EXAMPLES = r""" - name: "Test route target creation/deletion" connection: local hosts: localhost gather_facts: false tasks: - name: Create Route Targets networktocode.nautobot.route_target: url: http://nautobot.local token: thisIsMyToken data: name: "{{ item.name }}" tenant: "Test Tenant" tags: - Schnozzberry loop: - { name: "65000:65001", description: "management" } - { name: "65000:65002", description: "tunnel" } - name: Update Description on Route Targets networktocode.nautobot.route_target: url: http://nautobot.local token: thisIsMyToken data: name: "{{ item.name }}" tenant: "Test Tenant" description: "{{ item.description }}" tags: - Schnozzberry loop: - { name: "65000:65001", description: "management" } - { name: "65000:65002", description: "tunnel" } - name: Delete Route Targets networktocode.nautobot.route_target: url: http://nautobot.local token: thisIsMyToken data: name: "{{ item }}" state: absent loop: - "65000:65001" - "65000:65002" """ ``` -------------------------------- ### Custom Nautobot SQL Init File Configuration Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/testing_locally.md Example of how to configure a custom SQL init file for PostgreSQL by mounting './nautobot.sql' into the container using 'docker-compose.override.yml'. ```yaml --- services: postgres: volumes: - "./nautobot.sql:/docker-entrypoint-initdb.d/nautobot.sql" ``` -------------------------------- ### Initialize NautobotModule Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/architecture.md Initializes the NautobotModule by setting up instance attributes, checking for pynautobot installation, and preparing for API connection. ```python class NautobotModule(object): """ Initialize connection to Nautobot, sets AnsibleModule passed in to self.module to be used throughout the class :params module (obj): Ansible Module object :params endpoint (str): Used to tell class which endpoint the logic needs to follow :params nb_client (obj): pynautobot.api object passed in (not required) """ def __init__(self, module, endpoint, nb_client=None): self.module = module self.state = self.module.params["state"] self.check_mode = self.module.check_mode self.endpoint = endpoint query_params = self.module.params.get("query_params") if not HAS_PYNAUTOBOT: self.module.fail_json( msg=missing_required_lib("pynautobot"), exception=PYNAUTOBOT_IMP_ERR ) ``` -------------------------------- ### PDB Session Example Output Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/debugging.md Example output from a PDB debugging session for a Nautobot Ansible module. It shows the debugger prompt and the module's execution, including the final JSON output. ```text > /{REMOVED}/collections/ansible_collections/networktocode/nautobot/plugins/modules/location_type.py(6)() -> from __future__ import absolute_import, division, print_function (Pdb) c {"changed": false, "msg": "location_type My Location Type already exists", "location_type": {"id": "5416fd14-0c14-49e7-8620-2ec4940414ac", "object_type": "dcim.locationtype", "display": "My Location Type", "url": "http://localhost:8000/api/dcim/location-types/5416fd14-0c14-49e7-8620-2ec4940414ac/", "natural_slug": "my-location-type_5416", "tree_depth": null, "content_types": ["dcim.device"], "name": "My Location Type", "description": "My Location Type Description", "nestable": false, "parent": null, "created": "2025-02-28T10:41:47.679777Z", "last_updated": "2025-02-28T10:41:47.679792Z", "notes_url": "http://localhost:8000/api/dcim/location-types/5416fd14-0c14-49e7-8620-2ec4940414ac/notes/", "custom_fields": {}}, "invocation": {"module_args": {"url": "http://localhost:8000", "token": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", "name": "My Location Type", "description": "My Location Type Description", "nestable": false, "content_types": ["dcim.device"], "state": "present", "validate_certs": true, "query_params": null, "api_version": null, "custom_fields": null, "parent_location_type": null}}} The program exited via sys.exit(). Exit status: 0 > /{REMOVED}/collections/ansible_collections/networktocode/nautobot/plugins/modules/location_type.py(6)() -> from __future__ import absolute_import, division, print_function (Pdb) q ``` -------------------------------- ### EDA Event Output Example Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/eda.md This output demonstrates the events received by the `ansible-rulebook` when running the Nautobot changelog example. It shows the loading of the rulebook and the details of two distinct events, including metadata and event payloads. ```text bash-5.1$ ansible-rulebook --rulebook networktocode.nautobot.demo_nautobot_rulebook --print-events ** 2025-03-15 14:36:03.207838 [collection] ********************************************************************************************************************************************************************************************* Loading rulebook from /app/.ansible/collections/ansible_collections/networktocode/nautobot/extensions/eda/rulebooks/demo_nautobot_rulebook.yml **************************************************************************************************************************************************************************************************************************************** ** 2025-03-15 14:36:04.449732 [received event] ***************************************************************************************************************************************************************************************** Ruleset: Watch for new changelog entries Event: {'approval_required': False, 'approval_required_override': False, 'created': '2025-03-15T04:01:37.503Z', 'custom_fields': {}, 'default_job_queue': 'f575b43d-adb9-4315-8814-8d3a8c157819', 'default_job_queue_override': False, 'description': '', 'description_override': False, 'dryrun_default': False, 'dryrun_default_override': False, 'enabled': False, 'grouping': 'Demo Designs', 'grouping_override': False, 'has_sensitive_variables': False, 'has_sensitive_variables_override': False, 'hidden': False, 'hidden_override': False, 'installed': True, 'is_job_button_receiver': False, 'is_job_hook_receiver': False, 'is_singleton': False, 'is_singleton_override': False, 'job_class_name': 'CoreSiteDesign', 'job_queues_override': False, 'last_updated': '2025-03-15T04:01:38.576Z', 'meta': {'received_at': '2025-03-15T14:36:04.448846Z', 'source': {'name': 'networktocode.nautobot.nautobot_changelog', 'type': 'networktocode.nautobot.nautobot_changelog'}, 'uuid': '8d496cd9-5987-414a-9937-56bf6fe71703'}, 'module_name': 'demo_designs.jobs.core_site', 'name': 'Backbone Site Design', 'name_override': False, 'read_only': False, 'soft_time_limit': 0, 'soft_time_limit_override': False, 'supports_dryrun': True, 'tags': [], 'time_limit': 0, 'time_limit_override': False} **************************************************************************************************************************************************************************************************************************************** ** 2025-03-15 14:36:04.451269 [received event] ***************************************************************************************************************************************************************************************** Ruleset: Watch for new changelog entries Event: {'branch': 'main', 'created': '2025-03-15T04:01:36.631Z', 'current_head': '398aee38734c552b869a33a41ce300903b539722', 'custom_fields': {}, 'last_updated': '2025-03-15T04:01:37.349Z', 'meta': {'received_at': '2025-03-15T14:36:04.449687Z', 'source': {'name': 'networktocode.nautobot.nautobot_changelog', 'type': 'networktocode.nautobot.nautobot_changelog'}, 'uuid': '1eacd8fe-97e8-40cf-91b0-66c6bac74a52'}, 'name': 'Demo Designs', 'provided_contents': ['extras.job'], 'remote_url': 'https://github.com/nautobot/demo-designs.git', 'secrets_group': None, 'slug': 'demo_designs', 'tags': []} ********************************************************************************************************************************************************************************************************************************** ``` -------------------------------- ### Install Nautobot Ansible Collection via Ansible Galaxy Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/installation.md Use this command to install the collection directly from Ansible Galaxy. Ensure you have Ansible installed. ```bash ansible-galaxy collection install networktocode.nautobot ``` -------------------------------- ### Install Specific Version of Nautobot Ansible Collection Source: https://github.com/nautobot/nautobot-ansible/blob/develop/README.md Install a specific version of the Nautobot Ansible collection, for example, version 1.0.0. ```bash ansible-galaxy collection install networktocode.nautobot:==1.0.0 ``` -------------------------------- ### M2M Field Structure Example Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/inline_m2m.md Illustrates the general structure for M2M fields, including the 'state' and 'objects' keys. ```yaml : state: merge # merge (default), replace, or delete objects: - : "value" - : "another value" ``` -------------------------------- ### Install Nautobot Ansible Collection via requirements.yml Source: https://github.com/nautobot/nautobot-ansible/blob/develop/README.md Include the collection in your requirements.yml file for automated installation with Ansible. ```yaml collections: - name: networktocode.nautobot ``` -------------------------------- ### Configure Device with Location ID Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/modules.md Configure a device by specifying the location using its ID. This example uses a lookup to retrieve the location details. ```yaml --- ... tasks: - name: "Configure a device in Nautobot by specifying the ID for the location" networktocode.nautobot.device: data: name: "asdf" device_type: "asdf" role: "Router" location: "{{ location['key'] }}" status: "Inventory" state: present vars: location: "{{ lookup('networktocode.nautobot.lookup', 'locations', api_endpoint=nautobot_url, token=nautobot_token, api_filter='name=\"Child Location\" parent=\"Parent Location\"') }}" ``` -------------------------------- ### Applying Tags to a Device Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/modules.md This example demonstrates how to assign tags to a Nautobot device using the `networktocode.nautobot.device` module. Tags are provided as a list of dictionaries, where each dictionary specifies the unique fields for a tag, such as its name. ```yaml --- ... tasks: - name: "Example using tags" networktocode.nautobot.device: url: "http://nautobot.local" token: "thisIsMyToken" data: name: "Test Device" tags: - name: "My New Tag1" - name: "My New Tag2" state: "present" ``` -------------------------------- ### Add a Note to a Device Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/inline_m2m.md Example of adding a note to a specific device using the `networktocode.nautobot.device` module. The `state: present` ensures the note is added if it doesn't exist. ```yaml - name: Add a note to a device networktocode.nautobot.device: url: http://nautobot.local token: thisIsMyToken name: Test Device notes: objects: - note: This device was provisioned by Ansible. state: present ``` -------------------------------- ### Ansible Playbook Execution Output Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/new_module.md Example output from running an Ansible playbook that utilizes a custom Nautobot module. This demonstrates the successful creation and updating of route targets within Nautobot. ```bash ❯ ansible-playbook pb.test-rt.yml -vv ansible-playbook 2.10.4 config file = /Users/myohman/cloned-repos/nautobot-ansible/ansible.cfg configured module search path = ['/Users/myohman/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /Users/myohman/.virtualenvs/main3.8/lib/python3.8/site-packages/ansible executable location = /Users/myohman/.virtualenvs/main3.8/bin/ansible-playbook python version = 3.8.6 (default, Nov 17 2020, 18:43:06) [Clang 12.0.0 (clang-1200.0.32.27)] Using /Users/myohman/cloned-repos/nautobot-ansible/ansible.cfg as config file [WARNING]: No inventory was parsed, only implicit localhost is available [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' Skipping callback 'default', as we already have a stdout callback. Skipping callback 'minimal', as we already have a stdout callback. Skipping callback 'oneline', as we already have a stdout callback. PLAYBOOK: pb.test-rt.yml ********************************************************************************************************************************************************************************************************************************************************************************************* 1 plays in pb.test-rt.yml PLAY [Test route target creation/deletion] *************************************************************************************************************************************************************************************************************************************************************************** META: ran handlers TASK [Create Route Targets] ****************************************************************************************************************************************************************************************************************************************************************************************** task path: /Users/myohman/cloned-repos/nautobot-ansible/pb.test-rt.yml:7 changed: [localhost] => (item={'name': '65000:65001', 'description': 'management'}) => {"ansible_loop_var": "item", "changed": true, "item": {"description": "management", "name": "65000:65001"}, "msg": "route_target 65000:65001 updated", "route_target": {"created": "2021-01-13", "custom_fields": {}, "description": "", "id": 1, "last_updated": "2021-01-13T23:06:40.211082Z", "name": "65000:65001", "tags": [4], "tenant": 1, "url": "http://192.168.50.10:8000/api/ipam/route-targets/1/"}} changed: [localhost] => (item={'name': '65000:65002', 'description': 'tunnel'}) => {"ansible_loop_var": "item", "changed": true, "item": {"description": "tunnel", "name": "65000:65002"}, "msg": "route_target 65000:65002 created", "route_target": {"created": "2021-01-13", "custom_fields": {}, "description": "", "id": 2, "last_updated": "2021-01-13T23:59:29.946943Z", "name": "65000:65002", "tags": [4], "tenant": 1, "url": "http://192.168.50.10:8000/api/ipam/route-targets/2/"}} ``` -------------------------------- ### VS Code Debugging Arguments Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/debugging.md Example of a debugging arguments file for VS Code. These files are used in conjunction with the workspace configuration to launch the debugger. ```json { "debug": true, "log_level": "DEBUG", "log_file": "/tmp/nautobot-ansible-debug.log" } ``` -------------------------------- ### Docker Compose Override Configuration Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/testing_locally.md Example configuration for overriding default Docker Compose settings by creating a 'docker-compose.override.yml' file and including it in 'invoke.yml'. ```yaml nautobot_ansible: compose_files: - "docker-compose.yml" - "docker-compose.override.yml" ``` -------------------------------- ### Nautobot Changelog EDA Rulebook Example Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/eda.md This YAML rulebook configures Nautobot's changelog as an event source, setting a polling interval of 5 seconds and an empty query parameter. It includes a rule to trigger on any new changelog entry and print the event for debugging. ```yaml --- # This example changes the polling interval to 5 seconds. It also adds query params to filter down the events coming into the platform. - name: "Watch for new changelog entries" hosts: "localhost" sources: - networktocode.nautobot.nautobot_changelog: instance: "https://demo.nautobot.com" token: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" interval: 5 validate_certs: true # query: "?time__gte={{ '2024-07-15 12:00:00' | to_datetime }}" query: "" rules: - name: "New changelog created" condition: "event.id is defined" # Action is triggered if condition is `true`. action: # For simple examples just print the event as a debug message. debug: ``` -------------------------------- ### Associate Contact and Team with a Device Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/inline_m2m.md Example of associating a specific contact and team with a Nautobot device using the `networktocode.nautobot.device` module. Ensure the `url` and `token` are correctly configured. ```yaml - name: Associate a contact and a team with a device networktocode.nautobot.device: url: "{{ nautobot_url }}" token: "{{ nautobot_token }}" name: "my-router" contacts: objects: - contact: "Jane Doe" role: "Admin" status: "Active" teams: objects: - team: "Network Operations" role: "On-Call" status: "Active" state: present ``` -------------------------------- ### Nautobot Endpoint Name Mapping Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/architecture.md Provides an example of the `ENDPOINT_NAME_MAPPING` dictionary used to translate endpoint keys to display names within Nautobot modules. ```python ENDPOINT_NAME_MAPPING = { ... "devices": "device", ... } ``` -------------------------------- ### Update Non-Unique IP Address (Failing Example) Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/advanced.md This Ansible task demonstrates an attempt to update an IP address that results in a failure due to duplicate entries. It highlights the need for specific query parameters when multiple objects match. ```yaml --- ... tasks: - name: "Update non-unique IP address" networktocode.nautobot.ip_address: url: "http://nautobot.local" token: "thisIsMyToken" data: address: "192.168.100.1/24" ``` -------------------------------- ### Run Nautobot Ansible Module with JSON Args Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/debugging.md Execute a Nautobot Ansible module directly using Python and a JSON arguments file. This is useful for quick debugging iterations without a full Ansible playbook. Ensure the collection is installed in `./collections/` and `PYTHONPATH` is set. ```bash export PYTHONPATH=./collections && python -m ansible_collections.networktocode.nautobot.plugins.modules.location_type ./debugging_args/location_type.json | jq . ``` -------------------------------- ### Create a Device using Nautobot Module Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/modules.md Use the `networktocode.nautobot.device` module with `state: present` to create a new device. Ensure 'name', 'device_type', 'role', and 'location' are provided. ```yaml --- ... tasks: - name: "Example for state: present" networktocode.nautobot.device: url: "http://nautobot.local" token: "thisIsMyToken" data: name: "Test Device" device_type: "C9410R" role: "Core Switch" location: "{{ location['key'] }}" state: present ``` -------------------------------- ### View Invoke Integration Test Options Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/testing_locally.md Display all available command-line options for the 'invoke integration' command. ```shell # See all available options ❯ invoke integration -h ``` -------------------------------- ### Bootstrap Nautobot with Route Targets for Integration Testing Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/update_module.md Define and create route targets in the 'nautobot-deploy.py' script to be used in integration tests for new module options. ```python ... route_targets = [ {"name": "4000:4000"}, {"name": "5000:5000"}, {"name": "6000:6000"}, ] created_route_targets = make_calls(nb.ipam.route_targets, route_targets) if ERRORS: sys.exit( "Errors have occurred when creating objects, and should have been printed out. Check previous output." ) ``` -------------------------------- ### Configure Device with Role Dictionary Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/modules.md Configure a device by providing the role as a dictionary. This allows for more specific role definitions. ```yaml --- ... tasks: - name: "Configure a device in Nautobot by specifying dictionary for role" networktocode.nautobot.device: data: name: "asdf" device_type: "asdf" role: model: "Router" location: "{{ location['key'] }}" state: present vars: location: "{{ lookup('networktocode.nautobot.lookup', 'locations', api_endpoint=nautobot_url, token=nautobot_token, api_filter='name=\"Child Location\" parent=\"Parent Location\"') }}" ``` -------------------------------- ### Directory Structure Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/update_module.md This command displays the directory structure of the integration tests, showing the organization of tasks for different VRF configurations. ```bash ❯ tree tests/integration/targets tests/integration/targets ├── latest │ └── tasks │ ├── main.yml │ ├── ... │ ├── vm_interface.yml │ └── vrf.yml 12 directories, 143 files ``` -------------------------------- ### NautobotDcimModule Initialization Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/architecture.md Shows the initialization of a Nautobot DCIM module, subclassing `NautobotModule` and setting up constants for API endpoints. ```python from __future__ import absolute_import, division, print_function __metaclass__ = type from ansible_collections.networktocode.nautobot.plugins.module_utils.utils import ( NautobotModule, ENDPOINT_NAME_MAPPING, ) NB_CABLES = "cables" NB_CONSOLE_PORTS = "console_ports" NB_CONSOLE_PORT_TEMPLATES = "console_port_templates" ... ``` ```python class NautobotDcimModule(NautobotModule): def __init__(self, module, endpoint): super().__init__(module, endpoint) def run(self): ... ``` -------------------------------- ### Initialize and Run Nautobot Ansible Module Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/new_module.md Initialize the standard AnsibleModule with the defined argument specification and then pass it to your custom Nautobot module class. Execute the module's run method to perform the intended operation. ```python def main(): ... module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) route_target = NautobotIpamModule(module, NB_ROUTE_TARGETS) route_target.run() ``` -------------------------------- ### Module Argument Validation Failure Example Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/modules.md This output indicates a module failure due to missing required arguments. The 'msg' field shows that the 'role' field is required for the operation. ```bash failed: [localhost] (item={'unit': 2, 'type': 'nexus-child'}) => {"ansible_loop_var": "item", "changed": false, "item": {"type": "nexus-child", "unit": 2}, "msg": "{\"role\":[\"This field is required.\"]}"} ``` -------------------------------- ### Nautobot Module Run Method Logic Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/architecture.md Demonstrates the core logic within the `run` method of a Nautobot module, including fetching endpoint names, initializing results, and identifying the relevant Nautobot application and endpoint. ```python def run(self): ... # Used to dynamically set key when returning results endpoint_name = ENDPOINT_NAME_MAPPING[self.endpoint] self.result = {"changed": False} application = self._find_app(self.endpoint) nb_app = getattr(self.nb, application) nb_endpoint = getattr(nb_app, self.endpoint) user_query_params = self.module.params.get("query_params") ``` -------------------------------- ### Replace All Notes with a Single New Note Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/inline_m2m.md Demonstrates how to use `state: replace` to remove all existing notes on a device and enforce a single new note. This is useful for ensuring a specific set of notes is present. ```yaml # Device currently has the note "Old note" - name: Replace all notes with a single new note networktocode.nautobot.device: url: http://nautobot.local token: thisIsMyToken name: Test Device notes: state: replace objects: - note: New note state: present # Result: only "New note" remains on the device. ``` -------------------------------- ### Include Module Tasks in Latest Target Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/new_module.md Example of how to include specific module tasks within the 'latest' integration test target's main.yml file. This uses Ansible's 'include_tasks' to reference a separate task file for the module. ```yaml --- ... - name: "NAUTOBOT_ROUTE_TARGET_TESTS" include_tasks: "route_target.yml" ``` -------------------------------- ### Importing Utility Functions and Argument Specs Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/new_module.md Imports necessary utility functions and argument specifications from the Nautobot Ansible collection for module development. ```python from ansible_collections.networktocode.nautobot.plugins.module_utils.utils import ( NAUTOBOT_ARG_SPEC, TAGS_ARG_SPEC, CUSTOM_FIELDS_ARG_SPEC, ) from ansible_collections.networktocode.nautobot.plugins.module_utils.ipam import ( NautobotIpamModule, NB_ROUTE_TARGETS, ) from ansible.module_utils.basic import AnsibleModule from copy import deepcopy ``` -------------------------------- ### Activate Poetry Shell Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/testing_locally.md Activate the project's virtual environment using Poetry to access Invoke commands. ```shell ❯ poetry shell ``` -------------------------------- ### Update Module DOCUMENTATION for New Options Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/update_module.md Add new options like 'import_targets' and 'export_targets' to the module's documentation string, specifying their type and version. ```yaml ... import_targets: description: - Import targets tied to VRF required: false type: list elements: str version_added: "1.0.0" export_targets: description: - Export targets tied to VRF required: false type: list elements: str version_added: "1.0.0" ... ``` -------------------------------- ### Module Documentation Structure Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/new_module.md Defines the metadata for the 'route_target' module, including its purpose, author, version, and supported fragments for documentation. ```python DOCUMENTATION = r""" --- module: route_target short_description: Creates or removes route targets from Nautobot description: - Creates or removes route targets from Nautobot notes: - Tags should be defined as a YAML list - This should be ran with connection C(local) and hosts C(localhost) author: - Network to Code requirements: - pynautobot version_added: "1.0.0" extends_documentation_fragment: - networktocode.nautobot.fragments.base - networktocode.nautobot.fragments.tags - networktocode.nautobot.fragments.custom_fields options: name: description: - Route target name required: true type: str tenant: description: - The tenant that the route target will be assigned to required: false type: raw description: description: - Tag description required: false type: str """ ``` -------------------------------- ### VS Code Workspace Configuration Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/debugging.md This file configures the VS Code workspace for the Nautobot Ansible project. Remove the `.example` suffix to enable local customizations. It is ignored by git. ```json { "folders": [ { "path": "." } ], "settings": { "python.analysis.extraPaths": [ "./collections/ansible_collections/networktocode/nautobot/plugins/modules" ], "ansible.collections.paths": [ "./collections" ] }, "tasks": { "version": "2.0.0", "tasks": [ { "label": "Build Nautobot docker image", "type": "shell", "command": "invoke build" }, { "label": "Start Nautobot and dependencies (detached)", "type": "shell", "command": "invoke start" }, { "label": "Stop Nautobot and dependencies", "type": "shell", "command": "invoke stop" }, { "label": "Build and serve docs locally", "type": "shell", "command": "invoke docs" }, { "label": "Build collection for Galaxy", "type": "shell", "command": "invoke galaxy-build" }, { "label": "Install collection locally from build", "type": "shell", "command": "invoke galaxy-install" }, { "label": "Force build collection for Galaxy", "type": "shell", "command": "invoke galaxy-build --force" }, { "label": "Force install collection locally from build", "type": "shell", "command": "invoke galaxy-install --force" } ] }, "launch": { "version": "0.2.0", "configurations": [ { "name": "Python: Current File", "type": "python", "request": "launch", "program": "${file}", "console": "integratedTerminal", "justMyCode": false, "args": [ "--debug", "--log-level=DEBUG", "--log-file=/tmp/nautobot-ansible-debug.log" ] }, { "name": "Python: Debug Module Args File", "type": "python", "request": "launch", "program": "${file}", "console": "integratedTerminal", "justMyCode": false, "args": [] } ] } } ``` -------------------------------- ### Build Query Parameters and Fetch Object Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/architecture.md Dynamically builds query parameters for an endpoint and attempts to fetch an object from Nautobot using these parameters. This is the standard method for retrieving objects. ```python object_query_params = self._build_query_params( endpoint_name, data, user_query_params ) self.nb_object = self._nb_endpoint_get( nb_endpoint, object_query_params, name ) ``` -------------------------------- ### Connect to Nautobot API Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/architecture.md Establishes a connection to the Nautobot API using provided URL and token, or uses an existing pynautobot client. It also retrieves the Nautobot version. ```python class NautobotModule(object): ... # These should not be required after making connection to Nautobot url = self.module.params["url"] token = self.module.params["token"] ssl_verify = self.module.params["validate_certs"] # Attempt to initiate connection to Nautobot if nb_client is None: self.nb = self._connect_api(url, token, ssl_verify) else: self.nb = nb_client self.version = self.nb.version ``` -------------------------------- ### Add IP Address using Lookup Plugin ID Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/advanced.md This task demonstrates how to add an IP address to Nautobot. It uses the `query` function with a lookup plugin to find an existing IP address's ID, which is then used to populate the `nat_inside` field. Ensure the `networktocode.nautobot.ip_address` module is available and configured with correct URL and token. ```yaml --- ... tasks: - name: "Add ip address to nautobot" networktocode.nautobot.ip_address: url: "http://nautobot.local" token: "thisIsMyToken" data: address: "192.168.10.60/24" vrf: "Test VRF" nat_inside: id: "{{ query('networktocode.nautobot.lookup', 'ip-addresses', api_filter='address=192.168.100.1/24 vrf=1:1', api_endpoint='http://nautobot.local', token='thisIsMyToken', validate_certs=False, raw_data=True) | map(attribute='id') | first }}" state: present ``` -------------------------------- ### Run Specific Integration Tests with Tags Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/testing_locally.md Filter integration tests to run only those matching specific tags, such as 'graphql_info'. Multiple tags can be specified. ```shell # Run only graphql_info integration tests ❯ invoke integration -t graphql_info # Run only graphql_info and graphql_facts tests ❯ invoke integration -t graphql_info -t graphql_facts ``` -------------------------------- ### Update Inventory JSON Files Source: https://github.com/nautobot/nautobot-ansible/blob/develop/tests/integration/targets/inventory/README.md Run the `invoke integration` task with the `--update-inventories` flag to overwrite inventory JSON files with the latest data. Manual verification of the output is required as this process does not perform diffing. ```bash invoke integration --update-inventories ``` -------------------------------- ### List Available Invoke Tasks Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/testing_locally.md Display all available Invoke tasks for managing the Nautobot development environment and running tests. ```shell ❯ invoke --list Available tasks: build Build Nautobot docker image. cli Launch a bash shell inside the running Nautobot container. createsuperuser Create a new Nautobot superuser account (default: "admin"), will prompt for password. debug Start Nautobot and its dependencies in debug mode. destroy Destroy all containers and volumes. docs Build and serve docs locally for development. galaxy-build Build the collection. galaxy-install Install the collection to ./collections. integration Run all tests including integration tests lint Run linting tools makemigrations Perform makemigrations operation in Django. migrate Perform migrate operation in Django. nbshell Launch an interactive nbshell session. post-upgrade Performs Nautobot common post-upgrade operations using a single entrypoint. restart Gracefully restart all containers. start Start Nautobot and its dependencies in detached mode. stop Stop Nautobot and its dependencies. unit Run unit tests ``` -------------------------------- ### Ansible Playbook Execution (Success Output) Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/advanced.md This is the expected output when running the Ansible playbook with custom `query_params`, showing a successful update of the IP address to the specified VRF. ```bash ❯ ansible-playbook nautobot-ip.yml -v No config file found; using defaults [WARNING]: No inventory was parsed, only implicit localhost is available [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [localhost] ********************************************************************************************************************** TASK [Update non-unique IP address] *************************************************************************************************** changed: [localhost] => {"changed": true, "ip_address": {"address": "192.168.100.1/24", "assigned_object": null, "assigned_object_id": null, "assigned_object_type": null, "created": "2021-01-01", "custom_fields": {}, "description": "", "dns_name": "docs.nautobot-modules.com", "family": 4, "id": 15, "last_updated": "2021-01-01T19:16:49.756265Z", "nat_inside": null, "nat_outside": null, "role": null, "status": "active", "tags": [], "tenant": null, "url": "http://192.168.50.10:8000/api/ipam/ip-addresses/15/", "vrf": 2}, "msg": "ip_address 192.168.100.1/24 updated"} PLAY RECAP **************************************************************************************************************************** localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 ``` -------------------------------- ### Checkout and Test Pull Request for Nautobot Ansible Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/installation.md Clone the repository, fetch a specific pull request, and build/install the collection to test changes before merging. ```bash cd nautobot-ansible git fetch origin pull//head: git checkout ansible-galaxy collection build . ansible-galaxy collection install networktocode-nautobot*.tar.gz ``` -------------------------------- ### Integration Test Directory Structure Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/new_module.md Overview of the directory structure for integration tests within the Nautobot Ansible collection. Each target directory corresponds to a command-line argument for running tests. ```bash ❯ tree tests/integration tests/integration ├── integration.cfg ├── nautobot-deploy.py ├── render_config.sh └── targets ├── latest │ └── tasks │ ├── main.yml │ ├── cable.yml ├── regression-latest │ └── tasks │ └── main.yml ├── regression-v2.9 │ └── tasks │ └── main.yml └── v2.9 └── tasks ├── main.yml ├── cable.yml ``` -------------------------------- ### Run Integration Tests Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/testing_locally.md Execute all integration tests against the running Nautobot services. ```shell ❯ invoke integration ``` -------------------------------- ### Set ansible_network_os using Keyed Groups Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/inventory.md Utilize `keyed_groups` to dynamically group devices and set `ansible_network_os` based on platform information. This allows for more organized inventory management. ```yaml --- plugin: networktocode.nautobot.inventory keyed_groups: - key: platform prefix: "network_os" separator: "_" ``` -------------------------------- ### Specify Module with FQCN Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/modules.md Use the Fully Qualified Collection Name (FQCN) for modules directly within tasks. This is the preferred method for clarity and avoiding naming conflicts. ```yaml --- - hosts: "localhost" tasks: - name: "Configure a device in Nautobot" networktocode.nautobot.device: <.. omitted> ``` -------------------------------- ### Run Nautobot EDA Rulebook Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/eda.md Execute an EDA rulebook using the `ansible-rulebook` command. The `--print-events` option is used to display all received events in the terminal. ```bash ansible-rulebook --rulebook networktocode.nautobot.demo_nautobot_rulebook --print-events ``` -------------------------------- ### Associate IP Addresses with an Interface (Simple String) Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/inline_m2m.md Associates an IP address with a device interface using a simple string lookup for the IP address. ```yaml # Simple string -- looks up the IP address by address - name: Associate IP addresses with an interface networktocode.nautobot.device_interface: url: "{{ nautobot_url }}" token: "{{ nautobot_token }}" device: "my-router" name: "GigabitEthernet0/0" ip_addresses: objects: - ip_address: "10.0.0.1/24" state: present ``` -------------------------------- ### Nautobot Ansible Module Directory Structure Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/contributing/modules/architecture.md Illustrates the organization of Ansible modules and utilities within the Nautobot collection, highlighting the `module_utils` directory for application-specific logic. ```bash ├── plugins │ ├── module_utils │ │ ├── circuits.py │ │ ├── dcim.py │ │ ├── extras.py │ │ ├── ipam.py │ │ ├── secrets.py │ │ ├── tenancy.py │ │ ├── utils.py │ │ └── virtualization.py │ └── modules │ ├── device.py │ └── vrf.py 128 directories, 357 files ``` -------------------------------- ### Add IP Address with Basic NAT Inside Source: https://github.com/nautobot/nautobot-ansible/blob/develop/docs/getting_started/how-to-use/advanced.md This task attempts to add an IP address to Nautobot, specifying the IP and VRF, but uses a simple string for 'nat_inside'. This may fail if 'nat_inside' is not unique. ```yaml --- ... tasks: - name: "Add ip address to nautobot" networktocode.nautobot.ip_address: url: "http://nautobot.local" token: "thisIsMyToken" data: address: "192.168.10.60/24" vrf: "Test VRF" nat_inside: "192.168.100.1/24" state: present ```