Add a new resource type
This guide walks through adding a new resource type to a running Kessel instance. By the end, you will have a working resource type that you can report and delete through the API.
If you are new to Kessel, start with the Getting started tutorial which covers the full setup including schema compilation and local installation. This guide assumes you already have a Kessel instance running.
Prerequisites
Section titled “Prerequisites”- A running Kessel Inventory API instance (see Run locally with Docker Compose)
- Familiarity with resources and representations and how schema drives validation in Kessel
Plan your resource type
Section titled “Plan your resource type”Before creating files, decide on:
- Type name: A lowercase, underscore-separated identifier (e.g.,
host,k8s_cluster,database_instance). This must be unique within your Kessel instance. - Reporters: Which services will report this resource type. Each reporter gets its own representation schema.
- Common attributes: Properties shared across all reporters (e.g.,
workspace_id). - Reporter-specific attributes: Properties unique to each reporter’s view of the resource.
This guide uses a host resource type reported by a discovery reporter as an example. Replace these with your own names and attributes.
Create the configuration files
Section titled “Create the configuration files”Resource types are defined by a set of JSON Schema and YAML files in a specific directory structure under data/schema/resources/ in the Inventory API.
-
Create the directory structure
data/schema/resources/└── host/├── common_representation.json├── config.yaml└── reporters/└── discovery/├── config.yaml└── host.jsonTerminal window mkdir -p data/schema/resources/host/reporters/discovery -
Define the resource type configuration
Create
host/config.yaml. This tells Kessel which reporters are allowed to report this resource type.resource_type: hostresource_reporters:- DISCOVERYIf multiple services will report the same resource type, list them all here (e.g.,
DISCOVERY,MONITORING,CMDB). -
Define the common representation schema
Create
host/common_representation.json. Common attributes are shared across all reporters. Theworkspace_idfield is required to place the resource in a workspace for access control.{"$schema": "http://json-schema.org/draft-07/schema#","type": "object","properties": {"workspace_id": { "type": "string" }},"required": ["workspace_id"]} -
Define the reporter configuration
Create
reporters/discovery/config.yaml. This registers the reporter and links it to the resource type.resource_type: hostreporter_name: discoverynamespace: discovery -
Define the reporter-specific representation schema
Create
reporters/discovery/host.json. This schema validates the attributes that only this reporter provides.{"$schema": "http://json-schema.org/draft-07/schema#","type": "object","properties": {"hostname": { "type": "string" },"cpu_count": {"type": "integer","minimum": 1},"os": { "type": "string" },"ip_address": { "type": "string" }},"required": ["hostname","os"]}
Load the schema
Section titled “Load the schema”Kessel loads resource type schemas at startup. There are two loading methods:
Filesystem loading (default): Point the Inventory API at the schema directory. No extra steps needed if your files are under data/schema/resources/.
resources: schemaPath: "data/schema/resources"Schema caching: For production deployments, you can precompile schemas into a cache file for faster startup. Regenerate the cache after any schema change:
go build -o inventory-api main.go./inventory-api preload-schemaThen configure the Inventory API to use the cache:
resources: use_cache: trueAfter loading, restart the Inventory API to pick up the new resource type.
Test the new resource type
Section titled “Test the new resource type”Once the Inventory API has restarted with your schema loaded, test it using gRPC.
Report a resource
Section titled “Report a resource”grpcurl -plaintext -d '{ "resource": { "type": "host", "reporter_type": "DISCOVERY", "reporter_instance_id": "discovery-instance-001", "representations": { "metadata": { "local_resource_id": "host-001", "api_href": "http://localhost:8000/api/hosts/host-001", "console_href": "http://localhost:3000/hosts/host-001", "reporter_version": "1.0.0" }, "common": { "workspace_id": "d3bd1a4d-d792-48b2-8e9a-17cab4798df8" }, "reporter": { "hostname": "web-server-01.example.com", "cpu_count": 4, "os": "RHEL 9.4", "ip_address": "192.168.1.100" } } }}' localhost:9000 kessel.inventory.v1beta2.KesselInventoryService.ReportResourceDelete a resource
Section titled “Delete a resource”grpcurl -plaintext -d '{ "reference": { "resource_type": "host", "resource_id": "host-001", "reporter": { "type": "DISCOVERY" } }}' localhost:9000 kessel.inventory.v1beta2.KesselInventoryService.DeleteResourceIf the report succeeds, your resource type is correctly configured. If you get a validation error, check that your JSON data matches the schema you defined.