Skip to main content
Version: 0.7.0
OSSEnterprise

Custom Icons

Knodex assigns icons to RGD catalog entries based on resource kind annotations. You can use built-in icons, add custom icons via ConfigMaps, or override defaults.

Icon Resolution Order

When displaying an icon for a catalog entry, Knodex resolves icons in this order:

  1. Built-in icons - Matched by icon slug from the RGD annotation
  2. ConfigMap icons - Custom icons loaded from labeled ConfigMaps (override built-ins)
  3. Fallback - A generic Kubernetes icon if no match is found

Annotation Usage

Assign an icon to an RGD using the knodex.io/icon annotation:

apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
name: webapp
annotations:
knodex.io/catalog: "true"
knodex.io/icon: "web-app"

The annotation value is an icon slug that maps to either a built-in or custom icon.

Built-in Icon Slugs

SlugDescription
api-gatewayAPI gateway / ingress
applicationGeneric application
cacheCaching layer (Redis, Memcached)
certificateTLS certificates
ci-cdCI/CD pipeline
cloudCloud provider
clusterKubernetes cluster
configConfiguration / ConfigMap
containerContainer / Docker
cronjobScheduled job
databaseDatabase (generic)
dnsDNS management
functionServerless function
gpuGPU workload
helmHelm chart
ingressIngress controller
jobBatch job
kafkaKafka / message queue
load-balancerLoad balancer
monitoringMonitoring / observability
namespaceKubernetes namespace
network-policyNetwork policy
nodeKubernetes node
podPod
postgresPostgreSQL database
queueMessage queue (generic)
redisRedis
secretSecret
serviceKubernetes service
storagePersistent storage
web-appWeb application

Adding Custom Icons via ConfigMap

Create a ConfigMap with the knodex.io/icons label to register custom icons:

apiVersion: v1
kind: ConfigMap
metadata:
name: knodex-custom-icons
namespace: knodex
labels:
knodex.io/icon-registry: "true"
data:
# Each key is the icon slug, value is an SVG string
my-service: |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
</svg>
internal-tool: |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<circle cx="12" cy="12" r="10"/>
</svg>

Then reference the custom slug in your RGD:

annotations:
knodex.io/icon: "my-service"

Per-Package Icon ConfigMaps

In addition to the global knodex-custom-icons ConfigMap, you can ship per-package icon registries that activate only when the matching package is included in CATALOG_PACKAGE_FILTER. This mirrors the per-package pattern used by category configs so each package team can bundle its own brand SVGs alongside its RGDs.

A per-package icon ConfigMap carries both labels:

  • knodex.io/icon-registry: "true" — picks it up at registry load time.
  • knodex.io/package: <package-name> — scopes it to the named package.
apiVersion: v1
kind: ConfigMap
metadata:
name: knodex-custom-icons-networking
namespace: knodex
labels:
knodex.io/icon-registry: "true"
knodex.io/package: "networking"
data:
my-loadbalancer: |
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<title>My LoadBalancer</title>
<rect x="4" y="4" width="16" height="16" rx="2"/>
</svg>

When CATALOG_PACKAGE_FILTER is empty (default), every icon ConfigMap is loaded regardless of label. When the filter is non-empty:

  • ConfigMaps without a knodex.io/package label are always loaded (global scope).
  • ConfigMaps with a knodex.io/package label are loaded only when their value (case-insensitive) is in the filter.

The Helm chart exposes this as the catalog.packageCustomIcons map: each top-level key is a package name, and each value is the same slug → SVG map used by catalog.customIcons.

Merge Order and Collision Behavior

When multiple ConfigMaps provide icons:

  • Custom icons take precedence over built-in icons with the same slug
  • If two ConfigMaps define the same slug, the one that is alphabetically first by ConfigMap name wins
  • A warning is logged when a collision is detected

Example: If both knodex-icons-team-a and knodex-icons-team-b define the slug database, the icon from knodex-icons-team-a is used (alphabetical order), and a warning is logged.

Verifying the Icon Registry

Check Registered ConfigMaps

kubectl get configmaps -n knodex -l knodex.io/icon-registry=true

Check a Specific Icon via API

kubectl port-forward svc/knodex 8080:8080 -n knodex
curl http://localhost:8080/api/v1/icons/{slug}

There is no list endpoint; query individual icons by slug (e.g., /api/v1/icons/web-app).

Slug Format Requirements

Icon slugs must follow these rules:

  • Lowercase alphanumeric characters and hyphens only
  • Must start with a letter
  • Must not end with a hyphen
  • Maximum 63 characters (Kubernetes label value constraint)

Valid: web-app, postgres, my-custom-icon Invalid: -web-app, Web_App, my--icon-