How INFINI Console Handles Index Template Management and Dynamic Cluster Registration
INFINI Console uses fasttemplate-rendered .tpl files for index template management and exposes a POST /instance endpoint for dynamic cluster registration, coupling both systems through a global Elastic client registry.
The infinilabs/console repository implements a decoupled architecture for managing Elasticsearch and OpenSearch infrastructure. Index template management operates as a setup-time process that renders DSL templates and pushes them to target clusters, while dynamic cluster registration allows administrators to add new endpoints on-the-fly via REST API calls.
Index Template Management Architecture
Template Initialization Flow
When the Console system cluster starts, main/main.go invokes elastic2.InitTemplate(false) after verifying system-cluster health. This call triggers the template initialization sequence defined in plugin/setup/setup.go.
The InitTemplate() function sets a guard flag cfg1.InitTemplate to prevent duplicate initialization on subsequent runs. If the flag is already set, the process skips rendering and pushing templates, ensuring idempotent startup behavior.
Template Rendering with fasttemplate
The initializeTemplate handler in plugin/setup/setup.go processes SetupRequest payloads containing a template_type field (e.g., template_ilm, rollup, alerting). Based on this type, the system selects the appropriate .tpl file from config/setup/.
Template rendering uses github.com/valyala/fasttemplate to inject runtime values. Tags like $[[SETUP_INDEX_PREFIX]], $[[SETUP_CLUSTER_ID]], and credential variables are replaced with actual cluster configuration. The rendered output produces valid Elasticsearch DSL for index templates, ILM policies, or rollup configurations.
Template Storage and DSL Structure
Template files reside in config/setup/ with distribution-specific subdirectories:
- ILM Templates:
config/setup/opensearch/template_ilm.tpl(withv5andv6variants for legacy versions) - Rollup Templates:
config/setup/easysearch/template_rollup.tplfor Easysearch distributions - Common Templates:
config/setup/common/containsalerting.tpl,insight.tpl,view.tpl, andagent.tplfor alert history, visualization data, UI views, and agent ingest pipelines
The system also renders config/system_config.tpl at startup to generate the system-cluster configuration document consumed by the client factory.
Dynamic Cluster Registration Mechanism
The POST /instance Endpoint
Dynamic cluster registration is handled by the managed-server component in plugin/managed/server/instance.go. The endpoint POST /instance accepts JSON payloads mapping to the model.Instance struct.
The handler registerInstance decodes the request body, populating fields for name, endpoint, authentication credentials, and TLS configuration. This endpoint serves both agent-driven registration and UI-based "Add Cluster" workflows.
Validation and Persistence
Before persistence, the handler validates that the endpoint field is non-empty. It uses uri.Parse to extract host and scheme components, automatically populating missing fields when only a URL is provided.
The validated instance is persisted via orm.Save(nil, obj), which stores the model.Instance document in the internal Elasticsearch-backed datastore. If the instance already exists, the Created timestamp is preserved to maintain historical accuracy.
Global Client Registry Integration
After successful persistence, the new cluster becomes available through the global Elastic client registry. The client factory in infini.sh/framework/core/elastic (referenced via elastic.GetClient) reads persisted instance documents to construct ready-to-use elastic.API clients.
This integration enables any Console plugin—whether index-template initialization, alerting, or insight pipelines—to target the newly registered cluster transparently. The tryConnect function in instance.go performs health checks using client.ClusterHealth to verify reachability before marking the cluster as active.
Integrating Templates with Registered Clusters
Once a cluster is registered, the setup module can push index templates to it on demand. The /setup/init API accepts a SetupRequest with InitializeTemplate set to the desired template type (e.g., template_ilm) and a Cluster object containing connection details.
The initializeTemplate handler renders the appropriate .tpl file using runtime values from the cluster configuration, then pushes the rendered DSL via PUT /_template/<name> using the low-level Elastic client. This decoupled approach allows administrators to register clusters first and provision templates later, or to re-provision templates when upgrading Console versions.
Code Examples
Registering a Cluster via API
curl -X POST http://console.mycompany.com/instance \
-H "Content-Type: application/json" \
-d '{
"name": "prod-es-01",
"endpoint": "https://es-prod.example.com:9200",
"basic_auth": {
"username": "admin",
"password": "s3cr3t"
},
"tls": true,
"hosts": ["es-prod-01.example.com:9200", "es-prod-02.example.com:9200"]
}'
The response contains the generated instance ID:
{
"result": "created",
"_id": "c7b3e1a5-4d8f-48e6-9e2a-f7a5c2d6b9e0"
}
Initializing Templates via Setup API
curl -X POST http://localhost:8080/setup/init \
-H "Content-Type: application/json" \
-d '{
"InitializeTemplate": "template_ilm",
"Cluster": {
"Username": "admin",
"Password": "s3cr3t",
"Schema": "https",
"Endpoint": "https://es-prod.example.com:9200",
"Hosts": ["es-prod-01.example.com:9200", "es-prod-02.example.com:9200"]
},
"BootstrapUsername": "admin"
}'
This triggers the initializeTemplate handler in plugin/setup/setup.go to render the ILM template and push it to the specified cluster.
Managing Templates via REST
Retrieve an existing template:
curl -X GET "http://localhost:8080/elasticsearch/<cluster-id>/_template/metrics-rollover"
Save or update a template:
curl -X PUT "http://localhost:8080/elasticsearch/<cluster-id>/_template/metrics-rollover" \
-H "Content-Type: application/json" \
-d @custom_template.json
These endpoints are implemented in modules/elastic/api/template.go via HandleGetTemplateAction and HandleSaveTemplateAction.
Summary
-
Index template management in INFINI Console operates at setup time using
fasttemplateto render.tplfiles fromconfig/setup/into valid Elasticsearch DSL, which is then pushed to target clusters viaPUT /_template/<name>. -
Dynamic cluster registration exposes a
POST /instanceendpoint that persistsmodel.Instancedocuments, validates endpoints, and integrates new clusters into the global Elastic client registry viaelastic.GetClient. -
Both systems are decoupled: clusters can be registered at any time, and template initialization can be triggered later via the
/setup/initAPI, allowing flexible provisioning of ILM policies, rollup jobs, and alerting indices across heterogeneous Elasticsearch and OpenSearch distributions.
Frequently Asked Questions
How does INFINI Console prevent duplicate template initialization?
The system uses a guard flag cfg1.InitTemplate set inside the InitTemplate() function in plugin/setup/setup.go. When main/main.go invokes elastic2.InitTemplate(false) at startup, the function checks this flag and skips rendering if templates were already initialized. Administrators can force re-initialization by passing true to the function or by calling the /setup/init API directly.
What template types does INFINI Console support?
INFINI Console supports multiple template categories stored under config/setup/: ILM templates (template_ilm.tpl) for index lifecycle management, rollup templates (template_rollup.tpl) for Easysearch distributions, and common templates for alerting (alerting.tpl), insight (insight.tpl), view storage (view.tpl), and agent ingest pipelines (agent.tpl). Distribution-specific variants exist for OpenSearch, Elasticsearch v5, and v6.
How does dynamic cluster registration handle authentication?
The POST /instance handler in plugin/managed/server/instance.go accepts a JSON payload containing optional basic_auth fields (username and password) and TLS configuration flags. These credentials are stored in the model.Instance document persisted via orm.Save. When subsequent operations request a client for that cluster ID, the global Elastic client factory reads these credentials from the persisted document to establish authenticated connections.
Can templates be pushed to existing clusters without restarting?
Yes. While main/main.go automatically initializes templates for the system cluster at startup, administrators can push templates to any registered cluster at runtime using the /setup/init API. By sending a SetupRequest with InitializeTemplate set to the desired type (e.g., template_ilm) and including the target cluster configuration, the initializeTemplate handler in plugin/setup/setup.go renders the template and executes a PUT /_template/<name> request against the specified cluster without requiring a Console restart.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →