Description
Ansible NetBox Collection version
v3.14.0
Ansible version
There appears to be an issue with the cache code inside the fetch_api_docs
function, where if the response from the NetBox server is not able to be written to the filesystem, and then subsequently read back out sucessfully, the logic ends up setting endpoint_url
to be "/api/docs/?format=openapi"
- which is not correct on NetBox server versions > v3.5.0
- because the plugin tries to access that endpoint, which 404's and then the plugin attempts to parse it, fails, and then gives up.
I run a container built by ansible-build
inside ConcourseCI, which appears to lay things out in such a way where the filesystem is not writable, even by the root
user. This appears to include DEFAULT_LOCAL_TMP
.
Fetching: https://netbox.REDACTED.net/api/status
Fetching: https://netbox.REDACTED.net/api/docs/?format=openapi
14 1698248940.41606: auto failed while attempting to parse /tmp/build/a082d71e/code_repo/netbox.yml
14 1698248940.41668: Attempting to use plugin yaml (/usr/local/lib/python3.10/site-packages/ansible/plugins/inventory/yaml.py)
14 1698248940.41696: Loading data from /tmp/build/a082d71e/code_repo/netbox.yml
14 1698248940.41849: /tmp/build/a082d71e/code_repo/netbox.yml was not parsable by yaml
14 1698248940.41868: Attempting to use plugin ini (/usr/local/lib/python3.10/site-packages/ansible/plugins/inventory/ini.py)
14 1698248940.41948: /tmp/build/a082d71e/code_repo/netbox.yml was not parsable by ini
14 1698248940.41966: Attempting to use plugin toml (/usr/local/lib/python3.10/site-packages/ansible/plugins/inventory/toml.py)
toml declined parsing /tmp/build/a082d71e/code_repo/netbox.yml as it did not pass its verify_file() method
[WARNING]: * Failed to parse /tmp/build/a082d71e/code_repo/netbox.yml with auto plugin: <!DOCTYPE html> <html lang="en" data-netbox-url-name="" data-netbox-base-path="" data-netbox-color-mode="unset" > <head> <meta charset="UTF-8" /> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width, viewport-fit=cover" /> <title>Page Not Found | NetBox</title> <script
type="text/javascript" src="/static/setmode.js" onerror="window.location='/media-failure/?filename=setmode.js'"> </script> <script type="text/javascript"> (function () { initMode() })(); window.CSRF_TOKEN = "Sd7d273elhUcOCrLMhSEogOe0zKIp2vEMmhtNztYuGBNtdQN030q0SQeArvSjSe5"; </script> <link rel="stylesheet" href="/static/netbox-external.css?v=3.5.3" onerror="window.location='/media-failure/?filename=netbox-
external.css'" /> <link rel="stylesheet" href="/static/netbox-light.css?v=3.5.3" onerror="window.location='/media-failure/?filename=netbox-light.css'" /> <link rel="stylesheet" href="/static/netbox-dark.css?v=3.5.3" onerror="window.location='/media-failure/?filename=netbox-dark.css'" /> <link rel="stylesheet" media="print" href="/static/netbox-print.css?v=3.5.3" onerror="window.location='/media-
failure/?filename=netbox-print.css'" /> <link rel="icon" type="image/png" href="/static/netbox.ico" /> <link rel="apple-touch-icon" type="image/png" href="/static/netbox_touch-icon-180.png" /> <script type="text/javascript" src="/static/netbox.js?v=3.5.3" onerror="window.location='/media-failure/?filename=netbox.js'"> </script> </head> <body> <script type="text/javascript"> function checkSideNav() { // Check
localStorage to see if the sidebar should be pinned. var sideNavRaw = localStorage.getItem('netbox-sidenav'); // Determine if the device has a small screeen. This media query is equivalent to // bootstrap's media-breakpoint-down(lg) breakpoint mixin, which is what the sidenav's // CSS uses. var isSmallScreen = window.matchMedia('(max-width: 991.98px)').matches; if (typeof sideNavRaw === 'string') { var sideNavState =
JSON.parse(sideNavRaw); if (sideNavState.pinned === true && !isSmallScreen) { // If the sidebar should be pinned and this is not a small screen, set the appropriate // body attributes prior to the rest of the content rendering. This prevents // jumpy/glitchy behavior on page reloads. document.body.setAttribute('data-sidenav-pinned', ''); document.body.setAttribute('data-sidenav-show', '');
document.body.removeAttribute('data-sidenav-hidden'); } else { document.body.removeAttribute('data-sidenav-pinned'); document.body.setAttribute('data-sidenav-hidden', ''); } } } window.addEventListener('resize', function(){ checkSideNav() }); checkSideNav(); </script> <div class="container-fluid px-0"> <main class="layout"> <nav class="sidenav noprint" id="sidenav" data-simplebar> <div
class="sidenav-header"> <a class="sidenav-brand" href="/"> <img src="/static/netbox_logo.svg" height="48" class="sidenav-brand-img" alt="NetBox Logo"> </a> <a class="sidenav-brand-icon" href="/"> <img src="/static/netbox_icon.svg" height="32" class="sidenav-brand-img" alt="NetBox Logo"> </a> <button class="btn btn-sm btn-ghost-primary sidenav-toggle"> <div class="sidenav-toggle-icon"> <i class="mdi mdi-pin"></i> </div>
</button> </div> <div class="sidenav-inner h-100 mb-auto"> <div class="collapse sidenav-collapse pb-4"> <ul class="navbar-nav"> </ul> </div> <div class="profile-button-container"> <div class="btn-group"> <a class="btn btn-primary ws-nowrap" type="button" href="/login/?next=/api/docs/"> <i class="mdi mdi-login-variant"></i> Log In </a> <button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split"
data-bs-toggle="dropdown"> <span class="visually-hidden">Toggle Dropdown</span> </button> <ul class="dropdown-menu dropdown-menu-end"> <li> <button class="dropdown-item color-mode-toggle"> <i class="color-mode-icon mdi mdi-lightbulb"></i> <span class="color-mode-text">Dark Mode</span> </button> </li> </ul> </div> </div> </div> </nav> <div class="content-container" tabindex="-2"> <div
class="p-2 printonly"> <img src="/static/netbox_logo.svg" alt="NetBox logo" width="200px" /> </div> <nav class="navbar navbar-light sticky-top flex-md-nowrap p-1 mb-3 search container-fluid noprint"> <div class="nav-mobile"> <div class="nav-mobile-top"> <a class="sidebar-logo p-2 d-block" href="/"> <img src="/static/netbox_logo.svg" alt="NetBox logo" height="40" /> </a>
<button type="button" aria-label="Toggle Navigation" class="navbar-toggler sidenav-toggle-mobile"> <span class="navbar-toggler-icon"></span> </button> </div> <div class="d-flex my-1 flex-grow-1 justify-content-center w-100"> <form class="input-group" action="/search/" method="get"> <input name="q" type="text" aria-label="Search" placeholder="Search" class="form-control" /> <button class="btn btn-primary"
type="submit"> <i class="mdi mdi-magnify"></i> </button> </form> </div> </div> <div class="row search-container"> <div class="col-3 d-flex flex-grow-1 ps-0"></div> <div class="col-6 d-flex flex-grow-1 justify-content-center"> <form class="input-group" action="/search/" method="get"> <input name="q" type="text" aria-label="Search" placeholder="Search"
class="form-control" /> <button class="btn btn-primary" type="submit"> <i class="mdi mdi-magnify"></i> </button> </form> </div> <div class="col-3 d-flex flex-grow-1 pe-0 justify-content-end"> <div class="btn-group"> <a class="btn btn-primary ws-nowrap" type="button" href="/login/?next=/api/docs/"> <i class="mdi mdi-login-variant"></i> Log In </a> <button type="button" class="btn btn-primary dropdown-toggle
dropdown-toggle-split" data-bs-toggle="dropdown"> <span class="visually-hidden">Toggle Dropdown</span> </button> <ul class="dropdown-menu dropdown-menu-end"> <li> <button class="dropdown-item color-mode-toggle"> <i class="color-mode-icon mdi mdi-lightbulb"></i> <span class="color-mode-text">Dark Mode</span> </button> </li> </ul> </div> </div> </div> </nav>
<div class="title-container px-3 pb-3"> <div id="content-title"> <h1 class="h2 w-100">Page Not Found</h1> </div> </div> <div id="content" class="container-fluid content px-0 m-0"> <div class="px-3"> <div class="row my-5"> <div class="col-6 offset-3"> <div class="card"> <h5
class="card-header text-danger"> /api/docs/ </h5> <div class="card-body"> The requested page does not exist. </div> <div class="card-footer text-end"> <a href="/" class="btn btn-sm btn-primary">Home Page</a> </div> </div> </div> </div> </div> </div> <footer class="footer container-
fluid"> <div class="row align-items-center justify-content-between mx-0"> <div class="col-sm-12 col-md-auto fs-4 noprint"> <nav class="nav justify-content-center justify-content-lg-start"> <a type="button" class="nav-link" href="/static/docs/" target="_blank"> <i title="Docs" class="mdi mdi-book-open-variant text-primary" data-bs-placement="top" data-bs-
toggle="tooltip"></i> </a> <a type="button" class="nav-link" href="/api/" target="_blank"> <i title="REST API" class="mdi mdi-cloud-braces text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> <a type="button" class="nav-link" href="/api/schema/swagger-ui/" target="_blank"> <i title="REST API documentation"
class="mdi mdi-book text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> <a type="button" class="nav-link" href="/graphql/" target="_blank"> <i title="GraphQL API" class="mdi mdi-graphql text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> <a type="button" class="nav-
link" href="/netbox-community/netbox" target="_blank"> <i title="Source Code" class="mdi mdi-github text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> <a type="button" class="nav-link" href="https://netdev.chat/" target="_blank"> <i title="Community" class="mdi mdi-slack text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i>
</a> </nav> </div> <div class="col-sm-12 col-md-auto text-center text-lg-end text-muted"> <span class="d-block d-md-inline"><span title="Oct. 25, 2023 3:49 p.m.">2023-10-25 15:49</span> UTC</span> <span class="ms-md-3 d-block d-md-inline">netbox-as-i1p-248708.sys.comcast.net (v3.5.3)</span> </div> </div> </footer> </div> </main> </div>
<div id="django-messages" class="toast-container"> </div> <div id="netbox-data" style="display: none!important; visibility: hidden!important"> </div> </body> </html>
File "/usr/local/lib/python3.10/site-packages/ansible/inventory/manager.py", line 290, in parse_source
plugin.parse(self._inventory, self._loader, source, cache=cache)
File "/usr/local/lib/python3.10/site-packages/ansible/plugins/inventory/auto.py", line 59, in parse
plugin.parse(inventory, loader, path, cache=cache)
File "/usr/local/lib/python3.10/site-packages/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1895, in parse
self.main()
File "/usr/local/lib/python3.10/site-packages/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1767, in main
self.fetch_api_docs()
File "/usr/local/lib/python3.10/site-packages/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1395, in fetch_api_docs
openapi = self._fetch_information(
File "/usr/local/lib/python3.10/site-packages/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 380, in _fetch_information
raise AnsibleError(to_native(e.fp.read()))
[WARNING]: * Failed to parse /tmp/build/a082d71e/code_repo/netbox.yml with yaml plugin: Plugin configuration YAML file, not YAML inventory
File "/usr/local/lib/python3.10/site-packages/ansible/inventory/manager.py", line 290, in parse_source
plugin.parse(self._inventory, self._loader, source, cache=cache)
File "/usr/local/lib/python3.10/site-packages/ansible/plugins/inventory/yaml.py", line 114, in parse
raise AnsibleParserError('Plugin configuration YAML file, not YAML inventory')
[WARNING]: * Failed to parse /tmp/build/a082d71e/code_repo/netbox.yml with ini plugin: Invalid host pattern 'plugin:' supplied, ending in ':' is not allowed, this character is reserved to provide a port.
File "/usr/local/lib/python3.10/site-packages/ansible/inventory/manager.py", line 290, in parse_source
plugin.parse(self._inventory, self._loader, source, cache=cache)
File "/usr/local/lib/python3.10/site-packages/ansible/plugins/inventory/ini.py", line 136, in parse
raise AnsibleParserError(e)
[WARNING]: Unable to parse /tmp/build/a082d71e/code_repo/netbox.yml as an inventory source
NetBox version
v3.5.3
Python version
3.9
Steps to Reproduce
Run a container with NetBox inventory plugin in a ConcourseCI server install
Expected Behavior
Inventory should have been parsed
Observed Behavior
Inventory did not get parsed