Menu customization
Infrahub lets you control the menu on the left side of the web interface.
The menu has two sections. The bottom section is fixed — it lists navigation for built-in Infrahub features. The top section is user-controlled: organize your schema's node types in the order that makes sense for your use case, with custom groupings and icons.
By default, nodes without a menu placement are grouped under Other.
Prerequisites​
- A running Infrahub instance
Schema used in this guide
The examples on this page use the following schema nodes. Adapt the type names to match your own schema.
---
version: "1.0"
generics:
- name: Generic
namespace: Location
include_in_menu: false
hierarchical: true
attributes:
- name: name
kind: Text
optional: false
unique: true
nodes:
- name: Country
namespace: Location
inherit_from:
- LocationGeneric
parent: ""
children: LocationSite
- name: Site
namespace: Location
inherit_from:
- LocationGeneric
parent: LocationCountry
children: ""
relationships:
- name: devices
kind: Generic
peer: NetworkDevice
cardinality: many
optional: true
- name: Device
namespace: Network
attributes:
- name: name
kind: Text
optional: false
unique: true
relationships:
- name: site
kind: Attribute
cardinality: one
optional: true
peer: LocationSite
- name: interfaces
kind: Component
cardinality: many
optional: true
peer: NetworkInterface
- name: Interface
namespace: Network
attributes:
- name: name
kind: Text
optional: false
relationships:
- name: device
kind: Parent
optional: false
cardinality: one
peer: NetworkDevice
Define a menu file​
A menu file is a YAML file with a defined structure. See the menu file reference for the full schema.
Icons support any entry from the Material Design Icons library on iconify.design.
An Infrahub skill called /infrahub-menu-creator can generate this file for you. For production-grade examples, see the menus in infrahub-demo-dc and infrahub-solution-ai-dc.
The following example defines two top-level sections — Location and Infrastructure. Adjust namespaces and kinds to match your schema:
# yaml-language-server: $schema=https://schema.infrahub.app/infrahub/menu/latest.json
---
apiVersion: infrahub.app/v1
kind: Menu
spec:
data:
- namespace: Location
name: Mainmenu
label: Location
icon: "mingcute:location-line"
children:
data:
- namespace: Location
name: Country
label: Countries
kind: LocationCountry
icon: "gis:search-country"
- namespace: Location
name: Site
label: Sites
kind: LocationSite
icon: "ri:building-line"
- namespace: Infrastructure
name: Mainmenu
label: Infrastructure
icon: "mdi:domain"
children:
data:
- namespace: Network
name: Device
label: Devices
kind: NetworkDevice
icon: "mdi:router"
- namespace: Network
name: Interface
label: Interface
kind: NetworkInterface
icon: "mdi:ethernet"
For complex schemas, split menu definitions across multiple files — the same pattern used for schema files. By convention, keep them in a menus/ folder; you can then pass the folder path to infrahubctl menu load to load all files at once.
Load a menu file​
Use infrahubctl for development and testing. The git integration option is better suited for production.
- infrahubctl
- Git integration
infrahubctl menu load menus/menu.yml
See the infrahubctl menu documentation for details.
Add the menu file to .infrahub.yml:
---
menus:
- menus/menu.yml
See the infrahub.yml documentation for details.
When you load a menu file, Infrahub creates the items that do not exist yet and updates the ones that do, matching each item on its namespace and name. infrahubctl menu load never deletes an item: if you remove an entry from the file and load the file again, the item stays in the menu and the command still reports success. To remove an item from the menu, see Remove menu items.
Remove menu items​
How you remove a menu item depends on how it was loaded. An item loaded with infrahubctl stays until you delete it with infrahubctl, GraphQL, or the Python SDK. For an item loaded from a repository's .infrahub.yml, Infrahub deletes it on the next import after you remove it from the menu file.
Menu items exist per branch. Delete an item on the branch where you loaded it. If that branch has since been merged, the item also exists on the branch it was merged into, so delete it there too.
Menu files have no state key. state: absent applies to schema files only. Loading a menu file that sets state on an item fails with state is not a valid attribute or relationship for CoreMenuItem.
- infrahubctl
- GraphQL
- Python SDK
- Git integration
The infrahubctl object get and infrahubctl object delete commands require infrahubctl 1.20 or later.
-
List the menu items on the branch:
infrahubctl object get CoreMenuItem --branch <branch> -
Find the item to remove. Each item is identified by its namespace and name, the same two values as in the menu file.
-
Delete the item, passing the namespace and name separated by
/:infrahubctl object delete CoreMenuItem Location/Mainmenu --branch <branch>The command asks for confirmation. Add
--yesto skip the prompt. -
Delete the item's children as well. When you delete a parent item, Infrahub does not delete its children: they stay without a parent, and the web interface shows each of them as a top-level item in the menu. Run the delete command once for each child, for example
Location/CountryandLocation/Site. -
Reload the web interface and check that the items are gone from the menu.
See Manage objects from the command line for the other infrahubctl object options.
Delete an item with the CoreMenuItemDelete mutation, identifying it by namespace and name:
mutation {
CoreMenuItemDelete(data: { hfid: ["Location", "Mainmenu"] }) {
ok
}
}
Run the mutation on the branch where the item exists. As with infrahubctl, children of the deleted item are not deleted, so run the mutation for each child as well. Infrahub refuses to delete protected items, which are the built-in items in the Builtin namespace.
Fetch the item by namespace and name, then delete it:
item = client.get(kind="CoreMenuItem", hfid=["Location", "Mainmenu"], branch="<branch>")
item.delete()
Children of the deleted item are not deleted, so repeat this for each child.
Remove the item from the menu file, commit the change, and push it to the remote repository. On the next import, Infrahub deletes the items that this repository loaded earlier and that are no longer in any of its menu files.
When the next import runs depends on the repository type:
- For a read-write repository, Infrahub imports the repository again when its background sync pulls a new commit from the remote.
- For a read-only repository, Infrahub imports the repository again only when you change its commit or ref, or run Import latest commit.
Infrahub only deletes items that the repository itself loaded. An item loaded with infrahubctl stays until you delete it with the steps in the infrahubctl tab.
If the menu files no longer contain any items at all, for example after you remove the last entry or the whole menus list, Infrahub deletes nothing on that import and the items stay. Delete them with infrahubctl, GraphQL, or the Python SDK.
Good practices​
Disable schema-driven menu entries​
The schema's include_in_menu flag provides basic menu control. When you introduce a custom menu file, set it to false on every node and generic — otherwise the schema and the menu file both drive the same entries, which can produce unexpected behavior.
nodes:
- name: Node
namespace: Example
include_in_menu: false
The IPAM section is built in​
If your schema includes nodes that inherit from BuiltinIPPrefix or BuiltinIPAddress, Infrahub automatically adds an IPAM section to the menu. You do not need to define it in your menu file.
Search anywhere​
Beyond the menu, you can jump directly to any object, schema, or page from a single search dialog.
Press Cmd+K (macOS) or Ctrl+K (Windows and Linux) anywhere in the web interface to open it, then start typing. The dialog searches across objects, attributes, schemas, menu items, and documentation. You can also open it from the Search button at the top of the left menu, which shows the keyboard shortcut.