2025-05-03 18:26:12 +03:00

13 KiB

MiniDiscovery API Documentation

This document describes the HTTP API endpoints provided by MiniDiscovery.

Authentication

Most API endpoints require authentication using an API token. Tokens must be passed in the X-API-Token HTTP header.

GET /v1/catalog/services HTTP/1.1
Host: your-minidiscovery-host:8500
X-API-Token: your_secret_api_token

Tokens have associated permissions:

  • read: Allows reading service information (catalog, health).
  • write: Allows registering and deregistering services.
  • admin: Allows all read and write operations, plus managing ACL tokens.

The initial admin token is set using the MINIDISCOVERY_ADMIN_TOKEN environment variable on the first run when the database is empty. Subsequent tokens are managed via the API.

Data Models

ServiceInstance

This model represents a single instance of a registered service.

{
  "id": "web-instance-1",
  "name": "web",
  "address": "192.168.1.100",
  "port": 80,
  "tags": ["frontend", "nginx"],
  "metadata": {
    "version": "1.2.3",
    "region": "us-east-1"
  },
  "health": "passing",
  "last_updated": 1678886400.123456
}
  • id (string, required): Unique identifier for this specific instance.
  • name (string, required): Logical name of the service (e.g., 'web', 'api', 'db').
  • address (string, required): IP address or resolvable hostname where the service listens.
  • port (integer, required): Port number (1-65535).
  • tags (array of strings, optional): List of tags for filtering/grouping. Defaults to [].
  • metadata (object, optional): Key-value string pairs for arbitrary metadata. Defaults to {}.
  • health (string, optional): Current health status ('passing', 'failing', 'unknown'). Defaults to 'passing' on registration. Automatically updated by the health checker.
  • last_updated (float, internal): Unix timestamp of the last update (set automatically).

Endpoints

Agent Endpoints

These endpoints interact with the local agent state (registering/deregistering services).

Register Service

  • POST /v1/agent/service/register
  • Description: Registers a new service instance or updates an existing one with the same id. This operation is idempotent based on the service id.
  • Authentication: Requires write permission.
  • Request Body: ServiceInstance JSON object. The health and last_updated fields in the request body are ignored; health is managed internally, and last_updated is set automatically.
  • Success Response: 200 OK
    {
      "status": "registered",
      "service_id": "web-instance-1"
    }
    
  • Error Responses:
    • 400 Bad Request: Invalid request body format.
    • 401 Unauthorized: Missing X-API-Token.
    • 403 Forbidden: Invalid token or insufficient permissions.
    • 500 Internal Server Error: Database error during registration.
  • curl Example:
    curl -X POST http://localhost:8500/v1/agent/service/register \
      -H "X-API-Token: your_write_token" \
      -H "Content-Type: application/json" \
      -d '{
        "id": "api-instance-01",
        "name": "api",
        "address": "10.0.1.5",
        "port": 8080,
        "tags": ["backend", "v2"],
        "metadata": {"git_sha": "a1b2c3d"}
      }'
    

Deregister Service

  • PUT /v1/agent/service/deregister/{service_id} (Note: Consul uses PUT here, although DELETE might feel more intuitive)
  • Description: Removes a service instance by its ID.
  • Authentication: Requires write permission.
  • Path Parameters:
    • service_id (string): The unique ID of the service instance to deregister.
  • Success Response: 200 OK
    {
      "status": "deregistered",
      "service_id": "api-instance-01"
    }
    
  • Error Responses:
    • 401 Unauthorized: Missing X-API-Token.
    • 403 Forbidden: Invalid token or insufficient permissions.
    • 404 Not Found: Service with the given service_id does not exist.
  • curl Example:
    curl -X PUT http://localhost:8500/v1/agent/service/deregister/api-instance-01 \
      -H "X-API-Token: your_write_token"
    

Catalog Endpoints

These endpoints provide information about registered services across the system.

List Services

  • GET /v1/catalog/services
  • Description: Returns a map of all registered service names to a list of unique tags associated with instances of that service.
  • Authentication: Requires read permission.
  • Success Response: 200 OK
    {
      "web": ["frontend", "nginx"],
      "api": ["backend", "v2"],
      "db": []
    }
    
  • Error Responses:
    • 401 Unauthorized: Missing X-API-Token.
    • 403 Forbidden: Invalid token or insufficient permissions.
  • curl Example:
    curl http://localhost:8500/v1/catalog/services \
      -H "X-API-Token: your_read_token"
    

List Service Instances

  • GET /v1/catalog/service/{service_name}
  • Description: Returns a list of all registered instances for a given service name.
  • Authentication: Requires read permission.
  • Path Parameters:
    • service_name (string): The name of the service (e.g., 'web', 'api').
  • Query Parameters:
    • tag (string, optional): Filter instances by tag. Only instances with this tag will be returned.
  • Success Response: 200 OK (Returns an array of ServiceInstance objects)
    [
      {
        "id": "web-instance-1",
        "name": "web",
        "address": "192.168.1.100",
        "port": 80,
        "tags": ["frontend", "nginx"],
        "metadata": {"version": "1.2.3"},
        "health": "passing",
        "last_updated": 1678886400.123
      },
      {
        "id": "web-instance-2",
        "name": "web",
        "address": "192.168.1.101",
        "port": 80,
        "tags": ["frontend"],
        "metadata": {"version": "1.2.4"},
        "health": "failing",
        "last_updated": 1678886405.456
      }
    ]
    
    • Returns [] if the service name is not found.
  • Error Responses:
    • 401 Unauthorized: Missing X-API-Token.
    • 403 Forbidden: Invalid token or insufficient permissions.
  • curl Examples:
    # Get all 'web' instances
    curl http://localhost:8500/v1/catalog/service/web \
      -H "X-API-Token: your_read_token"
    
    # Get 'web' instances tagged with 'nginx'
    curl http://localhost:8500/v1/catalog/service/web?tag=nginx \
      -H "X-API-Token: your_read_token"
    

Health Endpoints

These endpoints provide service discovery filtered by health status.

List Healthy Service Instances

  • GET /v1/health/service/{service_name}
  • Description: Returns a list of service instances, similar to the catalog endpoint, but allows filtering by health status.
  • Authentication: Requires read permission.
  • Path Parameters:
    • service_name (string): The name of the service.
  • Query Parameters:
    • tag (string, optional): Filter instances by tag.
    • passing (boolean, optional): If true, only return instances with a passing health status. Defaults to false (returns all instances regardless of health).
  • Success Response: 200 OK (Returns an array of ServiceInstance objects)
    • Response format is identical to /v1/catalog/service/{service_name} but filtered according to query parameters.
  • Error Responses:
    • 401 Unauthorized: Missing X-API-Token.
    • 403 Forbidden: Invalid token or insufficient permissions.
  • curl Examples:
    # Get all 'api' instances (healthy or not)
    curl http://localhost:8500/v1/health/service/api \
      -H "X-API-Token: your_read_token"
    
    # Get only healthy ('passing') 'api' instances
    curl http://localhost:8500/v1/health/service/api?passing=true \
      -H "X-API-Token: your_read_token"
    
    # Get only healthy 'api' instances tagged 'v2'
    curl 'http://localhost:8500/v1/health/service/api?passing=true&tag=v2' \
      -H "X-API-Token: your_read_token"
    

ACL Token Endpoints

These endpoints manage API access tokens.

Create Token

  • POST /v1/acl/token
  • Description: Creates a new API token with specified permissions.
  • Authentication: Requires admin permission.
  • Request Body:
    {
      "name": "my-app-token",
      "permissions": ["read", "write"]
    }
    
    • name (string, required): A unique descriptive name for the token.
    • permissions (array of strings, optional): List of permissions (read, write, admin). Defaults to ["read", "write"].
  • Success Response: 201 Created
    {
      "token": "YOUR_NEW_SECRET_TOKEN_VALUE",
      "name": "my-app-token",
      "permissions": ["read", "write"]
    }
    
    • IMPORTANT: The token value is the actual secret token. It is only shown once in this response. Store it securely immediately.
  • Error Responses:
    • 400 Bad Request: Invalid request body or token name already exists.
    • 401 Unauthorized: Missing X-API-Token.
    • 403 Forbidden: Invalid token or insufficient permissions (not admin).
    • 500 Internal Server Error: Database error during token creation.
  • curl Example:
    curl -X POST http://localhost:8500/v1/acl/token \
      -H "X-API-Token: your_admin_token" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "read-only-dashboard",
        "permissions": ["read"]
      }'
    

Revoke Token

  • DELETE /v1/acl/token/{token_to_revoke}
  • Description: Revokes (deletes) an existing API token.
  • Authentication: Requires admin permission.
  • Path Parameters:
    • token_to_revoke (string): The actual secret token value of the token you want to revoke.
  • Success Response: 200 OK
    {
      "status": "revoked",
      "token_info": "Token revoked successfully"
    }
    
  • Error Responses:
    • 401 Unauthorized: Missing X-API-Token.
    • 403 Forbidden: Invalid token or insufficient permissions (not admin).
    • 404 Not Found: The token specified in the path does not exist or was already revoked.
  • curl Example:
    # Replace YOUR_OLD_SECRET_TOKEN_VALUE with the token to be deleted
    curl -X DELETE http://localhost:8500/v1/acl/token/YOUR_OLD_SECRET_TOKEN_VALUE \
      -H "X-API-Token: your_admin_token"
    

DNS over HTTPS (DoH)

  • GET /dns-query
  • Description: Provides a simplified DNS-over-HTTPS interface (RFC 8484 GET format) for querying service addresses and SRV records. Primarily intended for simple DNS clients or scripts. Note: Requires service names to end with the configured DNS suffix (default: .laiska.local).
  • Authentication: None (typically).
  • Query Parameters:
    • name (string, required): The DNS query name (e.g., web.laiska.local, _frontend._tcp.web.laiska.local).
    • type (string, optional): The DNS record type (e.g., A, SRV, TXT). Defaults to A. Case-insensitive.
  • Success Response: 200 OK (JSON object following RFC 8484 structure)
    • Example (A query for web.laiska.local):
      {
        "Status": 0, "TC": false, "RD": true, "RA": false, "AD": false, "CD": false,
        "Question": [{"name": "web.laiska.local.", "type": 1}],
        "Answer": [
          {"name": "web.laiska.local.", "type": 1, "TTL": 60, "data": "192.168.1.100"},
          {"name": "web.laiska.local.", "type": 1, "TTL": 60, "data": "192.168.1.101"}
        ]
      }
      
    • Example (SRV query for _frontend._tcp.web.laiska.local):
      {
        "Status": 0, "TC": false, "RD": true, "RA": false, "AD": false, "CD": false,
        "Question": [{"name": "_frontend._tcp.web.laiska.local.", "type": 33}],
        "Answer": [
          {"name": "_frontend._tcp.web.laiska.local.", "type": 33, "TTL": 60, "data": "0 10 80 web-instance-1.laiska.local."},
          {"name": "_frontend._tcp.web.laiska.local.", "type": 33, "TTL": 60, "data": "0 10 80 web-instance-2.laiska.local."}
        ],
        "Additional": [ // Note: MiniDiscovery doesn't currently populate Additional well for DoH
           // Ideally A records for targets would be here
        ]
      }
      
  • Error/NXDOMAIN Response: Returns JSON with "Status" other than 0 (e.g., 2 for NXDOMAIN, 4 for Not Implemented type).
  • curl Example:
    # Query for A records
    curl "http://localhost:8500/dns-query?name=web.laiska.local&type=A"
    
    # Query for SRV records
    curl "http://localhost:8500/dns-query?name=_frontend._tcp.web.laiska.local&type=SRV"
    

Other Endpoints

Root

  • GET /
  • Description: Provides a basic entry point. Redirects browsers to /status. API clients receive a simple JSON message.
  • Authentication: None.
  • Response (Browser): HTTP 307 Redirect to /status.
  • Response (API Client): 200 OK
    {
      "message": "MiniDiscovery API Root. See /status for HTML view or /docs for API documentation."
    }
    

Status Page

  • GET /status
  • Description: Serves a simple HTML status page showing node health based on registered services. Useful for a quick visual overview. Automatically refreshes.
  • Authentication: None.
  • Response: 200 OK with Content-Type: text/html.