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

Integrate NetBox UI with plugins catalog #14731

Closed
jeremystretch opened this issue Jan 8, 2024 · 7 comments
Closed

Integrate NetBox UI with plugins catalog #14731

jeremystretch opened this issue Jan 8, 2024 · 7 comments
Assignees
Labels
complexity: medium Requires a substantial but not unusual amount of effort to implement status: accepted This issue has been accepted for implementation type: feature Introduction of new functionality to the application
Milestone

Comments

@jeremystretch
Copy link
Member

NetBox version

v3.7.0

Feature type

New functionality

Proposed functionality

Provide an interface for users to compare their installed plugins against the public database, and potentially to discover new plugins

Use case

Providing a single interface where NetBox administrators can compare the installed version of each plugin to the latest available greatly simplifies the task of keeping plugins up-to-date.

Database changes

This can probably be done without introducing any new models, as plugin details live in memory. Some caching may be needed.

External dependencies

TBD, but no new dependencies are expected.

@jeremystretch jeremystretch added type: feature Introduction of new functionality to the application status: blocked Another issue or external requirement is preventing implementation labels Jan 8, 2024
@jeremystretch
Copy link
Member Author

jeremystretch commented Jan 8, 2024

Blocked by #14728. We'll also likely need to build out a full API for the plugins database to support this.

@AnythingOverIP
Copy link

Could this be done on client side? In our case (and I'm sure it's the same for many others), the Netbox infrastructure does not have access to internet...

@peteeckel
Copy link
Contributor

For this to work properly (and for plugin authors to know how to make sure the information in the plugin database is correct) it would really be helpful to have some documentation on how the database is created. Additionally, the database needs to be kept in a more current state if it's supposed to be useful.

Example: In the case of NetBox DNS (netbox-plugin-dns), the last version according to the database is 0.18.2, which is almost 9 months old, and the development status is "unknown". The current version is 0.22.1, which was released last week, and the development status is, as far as I'm concerned, "supported" ... on the other hand, the old netbox-dns is still in there, whose status is definitely "abandoned" (the last commit is almost a year old, and there will be no new ones, as the project was forked by me due to the sudden demise of its former maintainers).

@jeffgdotorg jeffgdotorg removed the status: blocked Another issue or external requirement is preventing implementation label May 1, 2024
@jeffgdotorg
Copy link
Contributor

Details of the public plugin catalog endpoint
URL: https://api.netbox.oss.netboxlabs.com//v1/plugins
Allowed methods: GET
Allowed query parameters:

  • page: Page number to fetch
  • per_page: Number of entries per page

At the time of this comment, it appears the endpoint expects an authentication token, which I assume will be removed soon.

Here is a sample of the endpoint's output.

{
  "metadata": {
    "duration": 1,
    "pagination": {
      "current_page": 1,
      "first_page": true,
      "last_page": true,
      "page_size": 50,
      "total_items": 2,
      "total_pages": 1
    }
  },
  "data": [
    {
      "id": "77525ee1-838e-4b99-9d0a-ff3d891a9049",
      "status": "active",
      "title_short": "Netbox plugin for BGP related objects documentation.",
      "title_long": "Model & manage BGP related resources like communities, sessions, routing policies, and IP prefix lists",
      "tag_line": "BGP related objects",
      "description_short": "Netbox plugin for BGP related objects documentation.",
      "slug": "netbox-bgp",
      "author": {
        "name": "Nikolay Yuzefovich",
        "org_id": "org-00000000",
        "url": "https://github.com/netbox-community/netbox-bgp"
      },
      "created_at": "2023-10-24T22:24:59.244147Z",
      "updated_at": "2024-04-17T17:55:16.837377Z",
      "license_type": "Apache 2.0",
      "homepage_url": "https://github.com/netbox-community/netbox-bgp",
      "package_name_pypi": "netbox-bgp",
      "config_name": "netbox_bgp",
      "is_certified": false,
      "release_count": 2,
      "release_latest": {
        "date": "2024-02-26T19:46:31.962084Z",
        "version": "0.12.1",
        "netbox_min_version": "3.7.3",
        "netbox_max_version": "3.7.8",
        "has_model": true,
        "is_certified": true,
        "is_feature": false,
        "is_integration": false,
        "is_netboxlabs_supported": true
      },
      "release_recent_history": [
        {
          "date": "2024-02-26T19:46:31.962084Z",
          "version": "0.12.1",
          "netbox_min_version": "3.7.3",
          "netbox_max_version": "3.7.8",
          "has_model": true,
          "is_certified": true,
          "is_feature": false,
          "is_integration": false,
          "is_netboxlabs_supported": true
        },
        {
          "date": "2024-01-18T15:15:03.870601Z",
          "version": "0.12.0",
          "netbox_min_version": "3.7.0",
          "netbox_max_version": "3.7.2",
          "has_model": true,
          "is_certified": false,
          "is_feature": false,
          "is_integration": false,
          "is_netboxlabs_supported": true
        }
      ]
    },
    {
      "id": "4c107c65-59d8-4197-9a26-9eb2a29a742a",
      "status": "active",
      "title_short": "Automatically discover your network with Slurp’it",
      "title_long": "Automatically discover your network with Slurp’it",
      "tag_line": "Automatically discover your network with Slurp’it",
      "description_short": "Automatically discover your network with Slurp’it",
      "slug": "slurpit_netbox",
      "author": {
        "name": "Pieter van Os",
        "org_id": "org-00000000",
        "url": "https://gitlab.com/slurpit.io/slurpit-netbox"
      },
      "created_at": "2024-01-31T15:31:37.247368Z",
      "updated_at": "2024-04-19T14:23:33.598421Z",
      "license_type": "MIT",
      "homepage_url": "https://gitlab.com/slurpit.io/slurpit-netbox",
      "package_name_pypi": "slurpit_netbox",
      "config_name": "slurpit_netbox",
      "is_certified": true,
      "release_count": 1,
      "release_latest": {
        "date": "2024-04-18T12:15:52.308399Z",
        "version": "0.8.117",
        "netbox_min_version": "3.7.5",
        "netbox_max_version": "3.7.8",
        "has_model": true,
        "is_certified": true,
        "is_feature": false,
        "is_integration": true,
        "is_netboxlabs_supported": false
      },
      "release_recent_history": [
        {
          "date": "2024-04-18T12:15:52.308399Z",
          "version": "0.8.117",
          "netbox_min_version": "3.7.5",
          "netbox_max_version": "3.7.8",
          "has_model": true,
          "is_certified": true,
          "is_feature": false,
          "is_integration": true,
          "is_netboxlabs_supported": false
        }
      ]
    }
  ]
}

@jeremystretch jeremystretch added status: backlog Awaiting selection for work complexity: medium Requires a substantial but not unusual amount of effort to implement labels May 22, 2024
@jeremystretch jeremystretch changed the title Integrate NetBox UI with plugins database Integrate NetBox UI with plugins catalog May 23, 2024
@jeffgdotorg
Copy link
Contributor

jeffgdotorg commented May 29, 2024

Roughed-out Proper pydantic-generated json-schema description for this endpoint:

{
  "$defs": {
    "Author": {
      "description": "Author model.",
      "properties": {
        "name": {
          "description": "Name",
          "title": "Name",
          "type": "string"
        },
        "org_id": {
          "description": "Organization ID",
          "title": "Org Id",
          "type": "string"
        },
        "url": {
          "description": "Author URL",
          "format": "uri",
          "minLength": 1,
          "title": "Url",
          "type": "string"
        }
      },
      "required": [
        "name",
        "org_id",
        "url"
      ],
      "title": "Author",
      "type": "object"
    },
    "LicenseType": {
      "description": "License type model.",
      "enum": [
        "No license",
        "MIT",
        "Apache 2.0",
        "BSD-3-Clause",
        "BSD-2-Clause",
        "CDDL-1.0",
        "LGPLv3",
        "GPLv3",
        "MPL-2.0",
        "EPL-2.0"
      ],
      "title": "LicenseType",
      "type": "string"
    },
    "Metadata": {
      "description": "Metadata model.",
      "properties": {
        "duration": {
          "default": 0,
          "description": "Duration",
          "title": "Duration",
          "type": "integer"
        },
        "pagination": {
          "allOf": [
            {
              "$ref": "#/$defs/Pagination"
            }
          ],
          "description": "Pagination object"
        }
      },
      "required": [
        "pagination"
      ],
      "title": "Metadata",
      "type": "object"
    },
    "Pagination": {
      "description": "Pagination model.",
      "properties": {
        "current_page": {
          "default": 1,
          "description": "Current page",
          "title": "Current Page",
          "type": "integer"
        },
        "first_page": {
          "description": "First page",
          "title": "First Page",
          "type": "boolean"
        },
        "last_page": {
          "description": "Last page",
          "title": "Last Page",
          "type": "boolean"
        },
        "page_size": {
          "description": "Page size",
          "title": "Page Size",
          "type": "integer"
        },
        "total_items": {
          "default": 0,
          "description": "Total items",
          "title": "Total Items",
          "type": "integer"
        },
        "total_pages": {
          "default": 0,
          "description": "Total pages",
          "title": "Total Pages",
          "type": "integer"
        }
      },
      "required": [
        "first_page",
        "last_page",
        "page_size"
      ],
      "title": "Pagination",
      "type": "object"
    },
    "Plugin": {
      "description": "Plugin model.",
      "properties": {
        "id": {
          "description": "Plugin ID",
          "format": "uuid4",
          "title": "Id",
          "type": "string"
        },
        "status": {
          "allOf": [
            {
              "$ref": "#/$defs/PluginStatus"
            }
          ],
          "description": "Plugin status"
        },
        "title_short": {
          "description": "Short title",
          "title": "Title Short",
          "type": "string"
        },
        "title_long": {
          "description": "Long title",
          "title": "Title Long",
          "type": "string"
        },
        "tag_line": {
          "description": "Tag line",
          "title": "Tag Line",
          "type": "string"
        },
        "description_short": {
          "description": "Short description",
          "title": "Description Short",
          "type": "string"
        },
        "slug": {
          "description": "Slug",
          "title": "Slug",
          "type": "string"
        },
        "author": {
          "allOf": [
            {
              "$ref": "#/$defs/Author"
            }
          ],
          "description": "Author"
        },
        "created_at": {
          "description": "Created at",
          "format": "date-time",
          "title": "Created At",
          "type": "string"
        },
        "updated_at": {
          "description": "Updated at",
          "format": "date-time",
          "title": "Updated At",
          "type": "string"
        },
        "license_type": {
          "allOf": [
            {
              "$ref": "#/$defs/LicenseType"
            }
          ],
          "description": "License type"
        },
        "homepage_url": {
          "description": "Homepage URL",
          "format": "uri",
          "minLength": 1,
          "title": "Homepage Url",
          "type": "string"
        },
        "package_name_pypi": {
          "description": "Package name (PyPI)",
          "title": "Package Name Pypi",
          "type": "string"
        },
        "config_name": {
          "description": "Configuration name",
          "title": "Config Name",
          "type": "string"
        },
        "is_certified": {
          "description": "Certified",
          "title": "Is Certified",
          "type": "boolean"
        },
        "release_count": {
          "default": 0,
          "description": "Release count",
          "title": "Release Count",
          "type": "integer"
        },
        "release_latest": {
          "allOf": [
            {
              "$ref": "#/$defs/Release"
            }
          ],
          "default": null,
          "description": "Latest release"
        },
        "release_recent_history": {
          "default": [],
          "description": "Recent releases",
          "items": {
            "$ref": "#/$defs/Release"
          },
          "title": "Release Recent History",
          "type": "array"
        }
      },
      "required": [
        "id",
        "status",
        "title_short",
        "title_long",
        "tag_line",
        "description_short",
        "slug",
        "author",
        "created_at",
        "updated_at",
        "license_type",
        "homepage_url",
        "package_name_pypi",
        "config_name",
        "is_certified"
      ],
      "title": "Plugin",
      "type": "object"
    },
    "PluginStatus": {
      "const": "active",
      "description": "Plugin status model.",
      "enum": [
        "active"
      ],
      "title": "PluginStatus",
      "type": "string"
    },
    "Release": {
      "description": "Release model.",
      "properties": {
        "id": {
          "description": "Release ID",
          "format": "uuid4",
          "title": "Id",
          "type": "string"
        },
        "date": {
          "description": "Date",
          "format": "date-time",
          "title": "Date",
          "type": "string"
        },
        "version": {
          "description": "Version",
          "title": "Version",
          "type": "string"
        },
        "netbox_min_version": {
          "description": "NetBox minimum version",
          "title": "Netbox Min Version",
          "type": "string"
        },
        "netbox_max_version": {
          "description": "NetBox maximum version",
          "title": "Netbox Max Version",
          "type": "string"
        },
        "has_model": {
          "description": "Has model",
          "title": "Has Model",
          "type": "boolean"
        },
        "is_certified": {
          "description": "Is certified",
          "title": "Is Certified",
          "type": "boolean"
        },
        "is_feature": {
          "description": "Is feature",
          "title": "Is Feature",
          "type": "boolean"
        },
        "is_integration": {
          "description": "Is integration",
          "title": "Is Integration",
          "type": "boolean"
        },
        "is_netboxlabs_supported": {
          "description": "Is NetBox Labs supported",
          "title": "Is Netboxlabs Supported",
          "type": "boolean"
        }
      },
      "required": [
        "id",
        "date",
        "version",
        "netbox_min_version",
        "netbox_max_version",
        "has_model",
        "is_certified",
        "is_feature",
        "is_integration",
        "is_netboxlabs_supported"
      ],
      "title": "Release",
      "type": "object"
    }
  },
  "description": "List response model.",
  "properties": {
    "metadata": {
      "allOf": [
        {
          "$ref": "#/$defs/Metadata"
        }
      ],
      "description": "Metadata object"
    },
    "data": {
      "description": "Plugins",
      "items": {
        "$ref": "#/$defs/Plugin"
      },
      "title": "Data",
      "type": "array"
    }
  },
  "required": [
    "metadata",
    "data"
  ],
  "title": "PluginListResponse",
  "type": "object"
}

@jeffgdotorg
Copy link
Contributor

jeffgdotorg commented Jun 27, 2024

Prototype of list view:
Embedded catalog – card list (1)

(edit: Added a made up locally-installed plugin Contrail Sync not listed in the catalog)

@jeffgdotorg
Copy link
Contributor

jeffgdotorg commented Jun 27, 2024

Additional prototypes for per-plugin detail view. I'm having trouble getting clickable prototype sharing to work so I'm just dropping static images here for the time being.

ACLs plugin – certified, not installed
Board_ Embedded catalog – ACLs overview
Board_ Embedded catalog – ACLs version history
Board_ Embedded catalog – ACLs install

Contrail Sync plugin – made up, installed locally, not in catalog
Board_ Embedded catalog – Contrail overview

DNS plugin – certified, installed, new version available (pretend version history tab shows this)
Board_ Embedded catalog – DNS overview
Board_ Embedded catalog – DNS version history
Board_ Embedded catalog – DNS upgrade

@jeremystretch jeremystretch added status: accepted This issue has been accepted for implementation and removed status: backlog Awaiting selection for work labels Jul 24, 2024
jeremystretch added a commit that referenced this issue Jul 30, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
complexity: medium Requires a substantial but not unusual amount of effort to implement status: accepted This issue has been accepted for implementation type: feature Introduction of new functionality to the application
Projects
None yet
Development

No branches or pull requests

5 participants