Infrahub Inventory Plugin
Relevant source files
The following files were used as context for generating this wiki page:
The Infrahub Inventory Plugin integrates Nornir with Infrahub to transform Infrahub graph nodes into Nornir hosts and groups. It uses the infrahub-sdk to fetch data, providing a dynamic inventory that reflects the current state of infrastructure managed within Infrahub.
This plugin serves as the primary bridge for automation, mapping Infrahub node kinds (such as devices) to Nornir host objects and deriving group memberships from node attributes, relationships, and standard group assignments.
Sources: nornir_infrahub/plugins/inventory/infrahub.py:122-132, dev/knowledge/architecture.md:7-10
Architecture and SDK Integration
The inventory plugin utilizes InfrahubClientSync to communicate with the Infrahub API. It relies on a synchronous execution model because Nornir tasks run synchronously per host. The interaction follows a specific contract where the inventory plugin stores the source Infrahub node inside the Nornir host's data dictionary under the key InfrahubNode.
Data Flow Overview
The following diagram illustrates the flow from Infrahub API data to the Nornir Inventory structure.
The diagram shows how the infrahub-sdk fetches nodes which the plugin then processes into Nornir objects, while also passing the raw node to subsequent tasks.
Sources: dev/knowledge/architecture.md:58-86, dev/knowledge/infrahub-sdk-integration.md:7-14
Configuration and Data Models
The plugin uses Pydantic models to validate configuration inputs during initialization.
Inventory Options
| Option | Type | Default | Description |
|---|---|---|---|
address | str | http://localhost:8000 | The Infrahub API URL. |
token | str | None | API token for authentication. |
branch | str | main | The Infrahub branch to query. |
host_node | dict | (Required) | Defines node kind, filters, include, and exclude. |
schema_mappings | list | [] | Maps host properties to Infrahub attributes/relations. |
group_mappings | list | [] | Infrahub paths used to derive Nornir groups. |
defaults_file | str | defaults.yaml | Path to static defaults YAML. |
group_file | str | group.yaml | Path to static groups YAML. |
Sources: nornir_infrahub/plugins/inventory/infrahub.py:133-149, dev/guides/using-the-inventory-plugin.md:21-45
HostNode Model Validation
The HostNode model ensures that the member_of_groups relationship is always included in the GraphQL query. This allows the plugin to determine group memberships without performing additional API round-trips.
class HostNode(BaseModel):
kind: str
include: List[str] = Field(default_factory=list)
exclude: List[str] = Field(default_factory=list)
filters: Dict[str, Any] = Field(default_factory=dict)
@model_validator(mode="before")
@classmethod
def validate_include(cls, data: Any) -> Any:
if isinstance(data, dict):
if "include" in data and isinstance(data["include"], list):
data["include"].append("member_of_groups")
elif "include" not in data:
data["include"] = ["member_of_groups"]
return data
Sources: nornir_infrahub/plugins/inventory/infrahub.py:100-116, dev/knowledge/inventory-data-model.md:25-33
Mapping and Resolution Logic
The plugin resolves dotted paths from the configuration to extract data from Infrahub nodes.
Relationship Hop Limit
To prevent complex recursive queries, the plugin enforces a maximum relationship hop limit.
- Constant:
MAX_RELATIONSHIP_HOPS = 2. - Constraint: Mappings may contain at most one dot (e.g.,
primary_address.address). Paths spanning more than two segments (two or more dots) raise aValueError.
Sources: nornir_infrahub/plugins/inventory/infrahub.py:26, dev/knowledge/inventory-data-model.md:46-53
The resolve_node_mapping Algorithm
The resolution process follows these steps for each segment in a mapping path:
- Relation Check: If the segment is a relationship name, it advances to the related peer. The plugin only supports relations with
cardinality == "single". - Attribute Check: If the segment is an attribute name, it retrieves the value.
- Value Mapping: The plugin applies specific transformations for certain types. For example,
IPHosttypes are converted to bare IP strings (excluding prefix lengths) viaip_interface_to_ip_string.
Inventory Loading Process
When the load() method is called, the plugin performs the following sequence:
- Load Static Files: Parses
defaults_fileandgroup_fileusingruamel.yaml. - Fetch Resources: Queries the Infrahub API using
client.filters(). The query includes all relationships identified inschema_mappingsandgroup_mappings. - Identify Host Name:
- If a
schema_mappingwithname: "name"exists, it uses the resolved value. - Otherwise, it uses the node's
nameattribute. - If the node lacks a name and no mapping is provided, the node is skipped.
- If a
- Derive Groups:
- Standard Groups: Includes all peers from the
member_of_groupsrelationship that are of typeCoreStandardGroup. - Mapped Groups: Generates groups from
group_mappingsusing the format{prefix}__{slugified-value}.
- Standard Groups: Includes all peers from the
- Construct Inventory: Returns a Nornir
Inventoryobject containing the populatedHosts,Groups, andDefaults.
Sources: nornir_infrahub/plugins/inventory/infrahub.py:233-312, dev/knowledge/inventory-data-model.md:78-106
Summary
The InfrahubInventory plugin provides a robust mechanism for leveraging Infrahub's version-controlled graph data within Nornir automation. By enforcing strict relationship hop limits and providing automated group derivation through member_of_groups and custom mappings, it ensures a structured and efficient mapping from graph nodes to network automation hosts.