JSON schema interface

The F5 Analyzer Framework communicates with both built-in and custom analyzer scripts using a standardized JSON interface. Scripts receive a JSON payload via standard input and must return a JSON response via standard output containing the computed weights.

Note: Custom scripts must not write any print() statements or logging to stdout. All non-JSON output (debug, logs, errors) should go to stderr to avoid breaking the framework’s expected input/output.

Request Schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Plugin Request Schema",
  "type": "object",
  "required": ["action"],
  "properties": {
    "action": {
      "type": "string",
      "enum": ["init", "run", "cleanup"]
    },
    "pool_member_ips": {
      "oneOf": [
        {
          "type": "array",
          "items": {
            "type": "string"
          },
          "minItems": 1
        },
        {
          "type": "object",
          "patternProperties": {
            "^[a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?$": {
              "type": "object",
              "properties": {
                "member_ips": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "minItems": 1
                },
                "params": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "required": ["member_ips"],
              "additionalProperties": false
            }
          },
          "additionalProperties": false,
          "minProperties": 1
        }
      ]
    },
    "pod_ip_mapping": {
      "type": "object",
      "description": "Mapping of pod names to their IP addresses",
      "patternProperties": {
        "^[a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?$": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "data_source": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "type": {
          "type": "string"
        },
        "endpoint": {
          "type": "string"
        },
        "username": {
          "type": "string"
        },
        "password": {
          "type": "string"
        }
      },
      "required": ["type", "endpoint"],
      "additionalProperties": false
    },
    "custom_params": {
      "type": "object",
      "description": "custom parameters",
      "additionalProperties": true
    },
    "builtin_metrics_sources": {
      "type": "array",
      "description": "Enabled metric sources for load metric collection",
      "items": {
        "type": "string",
        "enum": ["DCGM", "NIM", "vLLM"]
      },
      "minItems": 1
    },
    "dynamic_capacity_reduction": {
      "type": "object",
      "description": "Dynamic capacity reduction configuration for automatic connection throttling",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "aggressiveness": {
          "type": "string",
          "enum": ["low", "medium", "high"]
        }
      },
      "required": ["enabled"],
      "additionalProperties": false
    },
    "is_external_pool_members": {
      "type": "boolean",
      "description": "Indicates that pool members are external (no pod names available)"
    },
    "state": {
      "type": "object",
      "properties": {
        "last_run_timestamp": {
          "type": "string",
          "format": "date-time"
        },
        "custom_plugin_state": {
          "type": "object",
          "properties": {
            "binary_cache": {
              "type": "string",
              "description": "Base64 encoded binary cache for plugin re-use",
              "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
            }
          },
          "additionalProperties": true
        }
      },
      "additionalProperties": false
    }
  },
  "allOf": [
    {
      "if": { "properties": { "action": { "const": "run" } } },
      "then": { "required": ["pool_member_ips", "pod_ip_mapping", "data_source"] }
    }
  ],
  "additionalProperties": false
}

Request Schema Example (Framework → Script) :

{
  "action": "run",
  "pool_member_ips": ["10.0.0.1", "10.0.0.2", "10.0.0.3"],
  "pod_ip_mapping": {
    "pool-member-1": "10.0.0.1",
    "pool-member-2": "10.0.0.2",
    "pool-member-3": "10.0.0.3"
  },
  "data_source": {
    "name": "prometheus",
    "type": "prometheus",
    "endpoint": "your_prometheus_endpoint",
    "username": "optional_user",
    "password": "optional_pass"
  },
  "custom_params": {
    "custom_param1": "value_param_1",
    "custom_param2": "value_param_2"
  },
  "builtin_metrics_sources": ["NIM", "DCGM"],
  "dynamic_capacity_reduction": {
    "enabled": true,
    "aggressiveness": "high"
  },
  "is_external_pool_members": false,
  "state": {
    "last_run_timestamp": "2025-08-22T10:30:00Z",
    "custom_plugin_state": {
      "binary_cache": "base64_encoded_data"
    }
  }
}

Key Fields (Request):

Field

Description

action

Execution phase. Allowed values:
• init: Initialization step to prepare custom script
• run: Main execution step where the script should calculate updated weights
• cleanup: Finalization step used to clean up any temporary resources or state.

pool_member_ips

Backend IP addresses that require weight calculation (auto-discovered). Accepts either a flat array of IP strings or an object keyed by application name, each with a member_ips array and optional params.

pod_ip_mapping

Kubernetes pod name → IP address mapping (automatically populated).

data_source

Data source configuration (includes name, type, endpoint, and optional authentication).

custom_params

Custom parameters provided by user that can be used to tune the script’s behaviour.

state

Persistent data from previous executions (timestamp + custom plugin state).

builtin_metrics_sources

List of enabled metric sources for load metric collection. Possible values: DCGM, NIM, vLLM.

dynamic_capacity_reduction

Configures automatic connection throttling via dynamic capacity reduction, with a required enabled flag and an aggressiveness level (low, medium, or high).

is_external_pool_members

Indicates that pool members are external and no Kubernetes pod names are available.

Conditional Requirements:

  • When action = run → pool_member_ips, pod_ip_mapping, and data_source are required.

  • When action = init or cleanup → Only action is required

Response Schema (Script → Framework):

{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["status"],
"properties": {
  "status": {
    "type": "string",
    "enum": ["success", "error"]
  },
  "message": {
    "type": "string"
  },
  "weights": {
    "type": "object",
    "patternProperties": {
      ".*": {
        "type": "integer",
        "minimum": 0
      }
    },
    "additionalProperties": false
  },
  "drop_percent": {
    "type": "number",
    "minimum": 0,
    "maximum": 1,
    "description": "Rate limit drop percentage (0.0 to 1.0)"
  },
  "state": {
    "type": "object",
    "properties": {
      "last_run_timestamp": {
        "type": "string",
        "format": "date-time"
      },
      "custom_plugin_state": {
        "type": "object",
        "properties": {
          "binary_cache": {
            "type": "string",
            "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
          }
        },
        "additionalProperties": true
      }
    },
    "required": ["last_run_timestamp"],
    "additionalProperties": false
  },
  "plugin_stderr": {
    "type": "string"
  }
},
"allOf": [
  {
    "if": { "properties": { "status": { "const": "success" } } },
    "then": {
      "required": ["state"],
      "anyOf": [
        { "properties": { "weights": { "type": "object" } } },
        {}
      ]
    }
  },
  {
    "if": { "properties": { "status": { "const": "error" } } },
    "then": { "required": ["message"] }
  }
],
"additionalProperties": false
}

Response Schema (Script → Framework) Example:

{
  "status": "success",
  "message": "Weights calculated successfully",
  "weights": {
    "10.0.0.1": 45,
    "10.0.0.2": 30,
    "10.0.0.3": 25
  },
  "drop_percent": 0.15,
  "state": {
    "last_run_timestamp": "2025-08-22T10:35:00Z"
  },
  "plugin_stderr": "Optional debug information"
}

Key Response Fields:

Field

Description

message

Optional human-readable message describing outcome

plugin_stderr

Optional debugging information

state

Persistent data from previous executions: timestamp + custom plugin state (required)

status

"Success" or "Error" indicating execution result (required)

weights

Mapping of IP addresses to integer weights. These weights determine the proportion of traffic each backend receives. (Weights should sum to 100)

drop_percent

Rate limit drop percentage expressed in decimal value. Allowed range is between 0.0 and 1.0 (For example 0.15 = 15% of requests dropped)

Conditional Requirements:

  • When status = error, the message field is required.

  • When status = success, the state field is required, and weights may also be provided.