Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 70 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -426,65 +426,82 @@ In case multi-cluster support is enabled (default) and you have access to multip

<summary>kiali</summary>

- **kiali_mesh_graph** - Returns the topology of a specific namespaces, health, status of the mesh and namespaces. Includes a mesh health summary overview with aggregated counts of healthy, degraded, and failing apps, workloads, and services. Use this for high-level overviews
- `graphType` (`string`) - Optional type of graph to return: 'versionedApp', 'app', 'service', 'workload', 'mesh'
- `namespace` (`string`) - Optional single namespace to include in the graph (alternative to namespaces)
- `namespaces` (`string`) - Optional comma-separated list of namespaces to include in the graph
- `rateInterval` (`string`) - Optional rate interval for fetching (e.g., '10m', '5m', '1h').

- **kiali_manage_istio_config_read** - Lists or gets Istio configuration objects (Gateways, VirtualServices, etc.)
- `action` (`string`) **(required)** - Action to perform: list or get
- `group` (`string`) - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
- `kind` (`string`) - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
- `name` (`string`) - Name of the Istio object
- `namespace` (`string`) - Namespace containing the Istio object
- `version` (`string`) - API version of the Istio object (e.g., 'v1', 'v1beta1')

- **kiali_manage_istio_config** - Creates, patches, or deletes Istio configuration objects (Gateways, VirtualServices, etc.)
- `action` (`string`) **(required)** - Action to perform: create, patch, or delete
- `group` (`string`) - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
- `json_data` (`string`) - JSON data to apply or create the object
- `kind` (`string`) - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
- `name` (`string`) - Name of the Istio object
- `namespace` (`string`) - Namespace containing the Istio object
- `version` (`string`) - API version of the Istio object (e.g., 'v1', 'v1beta1')

- **kiali_get_resource_details** - Gets lists or detailed info for Kubernetes resources (services, workloads) within the mesh
- `namespaces` (`string`) - Comma-separated list of namespaces to get services from (e.g. 'bookinfo' or 'bookinfo,default'). If not provided, will list services from all accessible namespaces
- `resource_name` (`string`) - Name of the resource to get details for (optional string - if provided, gets details; if empty, lists all).
- `resource_type` (`string`) - Type of resource to get details for (service, workload)

- **kiali_get_metrics** - Gets lists or detailed info for Kubernetes resources (services, workloads) within the mesh
- **kiali_get_mesh_traffic_graph** - Returns service-to-service traffic topology, dependencies, and network metrics (throughput, response time, mTLS) for the specified namespaces. Use this to diagnose routing issues, latency, or find upstream/downstream dependencies.
- `clusterName` (`string`) - Optional cluster name to include in the graph. Default is the cluster name in the Kiali configuration (KubeConfig).
- `graphType` (`string`) - Granularity of the graph. 'app' aggregates by app name, 'versionedApp' separates by versions, 'workload' maps specific pods/deployments. Default: versionedApp.
- `namespaces` (`string`) **(required)** - Comma-separated list of namespaces to map

- **kiali_get_mesh_status** - Retrieves the high-level health, topology, and environment details of the Istio service mesh. Returns multi-cluster control plane status (istiod), data plane namespace health (including ambient mesh status), observability stack health (Prometheus, Grafana...), and component connectivity. Use this tool as the first step to diagnose mesh-wide issues, verify Istio/Kiali versions, or check overall health before drilling into specific workloads.

- **kiali_manage_istio_config_read** - Read-only Istio config: list or get objects. For action 'list', returns an array of objects with {name, namespace, type, validation}. For create, patch, or delete use manage_istio_config.
- `action` (`string`) **(required)** - Action to perform (read-only)
- `clusterName` (`string`) - Optional cluster name. Defaults to the cluster name in the Kiali configuration.
- `group` (`string`) - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io'). Required for 'get' action.
- `kind` (`string`) - Kind of the Istio object (e.g., 'VirtualService', 'DestinationRule'). Required for 'get' action.
- `namespace` (`string`) - Namespace containing the Istio object. For 'list', if not provided, returns objects across all namespaces. For 'get', required.
- `object` (`string`) - Name of the Istio object. Required for 'get' action.
- `serviceName` (`string`) - Filter Istio configurations (VirtualServices, DestinationRules, and their referenced Gateways) that affect a specific service. Only applicable for 'list' action
- `version` (`string`) - API version. Use 'v1' for VirtualService, DestinationRule, and Gateway. Required for 'get' action.

- **kiali_manage_istio_config** - Create, patch, or delete Istio config. For list and get (read-only) use manage_istio_config_read.
- `action` (`string`) **(required)** - Action to perform (write)
- `clusterName` (`string`) - Optional cluster name. Defaults to the cluster name in the Kiali configuration.
- `confirmed` (`boolean`) - CRITICAL: If 'true', the destructive action (create/patch/delete) is executed. If 'false' (or omitted) for create/patch, the tool returns a YAML PREVIEW. Display it to the user and ask for confirmation before calling again with confirmed=true.
- `data` (`string`) - Complete JSON or YAML data to apply or create the object. Required for create and patch actions. You MUST provide a COMPLETE and VALID manifest with ALL required fields for the resource type. Arrays (like servers, http, etc.) are REPLACED entirely, so you must include ALL required fields within each array element.
- `group` (`string`) **(required)** - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io').
- `kind` (`string`) **(required)** - Kind of the Istio object (e.g., 'VirtualService', 'DestinationRule').
- `namespace` (`string`) **(required)** - Namespace containing the Istio object
- `object` (`string`) **(required)** - Name of the Istio object
- `version` (`string`) **(required)** - API version. Use 'v1' for VirtualService, DestinationRule, and Gateway.

- **kiali_get_resource_details** - Fetches a list of resources OR retrieves detailed data for a specific resource. If 'resourceName' is omitted, it returns a list. If 'resourceName' is provided, it returns details for that specific resource.
- `clusterName` (`string`) - Optional. Name of the cluster to get resources from. If not provided, will use the default cluster name in the Kiali KubeConfig
- `namespaces` (`string`) - Comma-separated list of namespaces to query (e.g., 'bookinfo' or 'bookinfo,default'). If not provided, it will query across all accessible namespaces.
- `resourceName` (`string`) - Optional. The specific name of the resource. If left empty, the tool returns a list of all resources of the specified type. If provided, the tool returns deep details for this specific resource.
- `resourceType` (`string`) **(required)** - The type of resource to query.

- **kiali_get_pod_performance** - Returns a human-readable text summary with current Pod CPU/memory usage (from Prometheus) compared to Kubernetes requests/limits (from the Pod spec). Useful to answer questions like 'Is this workload using too much memory?'
- `clusterName` (`string`) - Optional. Name of the cluster to get resources from. If not provided, will use the default cluster name in the Kiali KubeConfig
- `namespace` (`string`) **(required)** - Kubernetes namespace of the Pod.
- `podName` (`string`) - Kubernetes Pod name. If workloadName is provided, the tool will attempt to resolve a Pod from that workload first.
- `queryTime` (`string`) - Optional end timestamp (RFC3339) for the query. Defaults to now.
- `timeRange` (`string`) - Time window used to compute CPU rate (Prometheus duration like '5m', '10m', '1h', '1d'). Defaults to '10m'.
- `workloadName` (`string`) - Kubernetes Workload name (e.g. Deployment/StatefulSet/etc). Tool will look up the workload and pick one of its Pods. If not found, it will fall back to treating this value as a podName.

- **kiali_get_traces** - Fetches a distributed trace (Jaeger/Tempo) by trace_id or searches by service_name (optionally only error traces) and summarizes bottlenecks and error spans.
- `clusterName` (`string`) - Optional cluster name. Defaults to the cluster name in the Kiali configuration.
- `errorOnly` (`boolean`) - If true, only consider traces that contain errors (e.g. error=true / non-200 status). Default false.
- `limit` (`integer`) - Max number of traces to consider when searching by service_name. Default 10.
- `lookbackSeconds` (`integer`) - How far back to search when using service_name. Default 600 (10m).
- `maxSpans` (`integer`) - Max number of spans to return in each summary section (bottlenecks, errors, roots). Default 7.
- `namespace` (`string`) - Kubernetes namespace of the service (required when trace_id is not provided).
- `serviceName` (`string`) - Service name to search traces for (required when trace_id is not provided).
- `traceId` (`string`) - Trace ID to fetch and summarize. If provided, namespace/service_name are ignored.

- **kiali_get_logs** - Get the logs of a Kubernetes Pod (or workload name that will be resolved to a pod) in a namespace. Output is plain text, matching kubernetes-mcp-server pods_log.
- `clusterName` (`string`) - Optional. Name of the cluster to get the logs from. If not provided, will use the default cluster name in the Kiali KubeConfig
- `container` (`string`) - Optional. Name of the Pod container to get the logs fro
- `format` (`string`) - Output formatting for chat. 'codeblock' wraps logs in ~~~ fences (recommended). 'plain' returns raw text like kubernetes-mcp-server pods_log.
- `name` (`string`) **(required)** - Name of the Pod to get the logs from. If it does not exist, it will be treated as a workload name and a running pod will be selected.
- `namespace` (`string`) **(required)** - Namespace to get the Pod logs from
- `previous` (`boolean`) - Optional. Return previous terminated container logs
- `severity` (`string`) - Optional severity filter applied client-side. Accepts 'ERROR', 'WARN' or combinations like 'ERROR,WARN'.
- `tail` (`integer`) - Number of lines to retrieve from the end of the logs (Optional, defaults to 50). Cannot exceed 200 lines.
- `workload` (`string`) - Optional. Workload name override (used when name lookup fails).

- **kiali_get_metrics** - Returns metrics for the given resource type, namespaces and resource name.
- `byLabels` (`string`) - Comma-separated list of labels to group metrics by (e.g., 'source_workload,destination_service'). Optional
- `direction` (`string`) - Traffic direction: 'inbound' or 'outbound'. Optional, defaults to 'outbound'
- `namespace` (`string`) **(required)** - Namespace to get resources from
- `clusterName` (`string`) - Cluster name to get metrics from. Optional, defaults to the cluster name in the Kiali configuration (KubeConfig)
- `direction` (`string`) - Traffic direction. Optional, defaults to 'outbound'
- `namespace` (`string`) **(required)** - Namespace to get metrics from
- `quantiles` (`string`) - Comma-separated list of quantiles for histogram metrics (e.g., '0.5,0.95,0.99'). Optional
- `rateInterval` (`string`) - Rate interval for metrics (e.g., '1m', '5m'). Optional, defaults to '10m'
- `reporter` (`string`) - Metrics reporter: 'source', 'destination', or 'both'. Optional, defaults to 'source'
- `reporter` (`string`) - Metrics reporter. Optional, defaults to 'source'
- `requestProtocol` (`string`) - Filter by request protocol (e.g., 'http', 'grpc', 'tcp'). Optional
- `resource_name` (`string`) **(required)** - Name of the resource to get details for (optional string - if provided, gets details; if empty, lists all).
- `resource_type` (`string`) **(required)** - Type of resource to get details for (service, workload)
- `resourceName` (`string`) **(required)** - Name of the resource to get metrics for
- `resourceType` (`string`) **(required)** - Type of resource to get metrics
- `step` (`string`) - Step between data points in seconds (e.g., '15'). Optional, defaults to 15 seconds

- **kiali_workload_logs** - Get logs for a specific workload's pods in a namespace. Only requires namespace and workload name - automatically discovers pods and containers. Optionally filter by container name, time range, and other parameters. Container is auto-detected if not specified.
- `container` (`string`) - Optional container name to filter logs. If not provided, automatically detects and uses the main application container (excludes istio-proxy and istio-init)
- `namespace` (`string`) **(required)** - Namespace containing the workload
- `since` (`string`) - Time duration to fetch logs from (e.g., '5m', '1h', '30s'). If not provided, returns recent logs
- `tail` (`integer`) - Number of lines to retrieve from the end of logs (default: 100)
- `workload` (`string`) **(required)** - Name of the workload to get logs for

- **kiali_get_traces** - Gets traces for a specific resource (app, service, workload) in a namespace, or gets detailed information for a specific trace by its ID. If traceId is provided, it returns detailed trace information and other parameters are not required.
- `clusterName` (`string`) - Cluster name for multi-cluster environments (optional, only used when traceId is not provided)
- `endMicros` (`string`) - End time for traces in microseconds since epoch (optional, defaults to 10 minutes after startMicros if not provided, only used when traceId is not provided)
- `limit` (`integer`) - Maximum number of traces to return (default: 100, only used when traceId is not provided)
- `minDuration` (`integer`) - Minimum trace duration in microseconds (optional, only used when traceId is not provided)
- `namespace` (`string`) - Namespace to get resources from. Required if traceId is not provided.
- `resource_name` (`string`) - Name of the resource to get traces for. Required if traceId is not provided.
- `resource_type` (`string`) - Type of resource to get traces for (app, service, workload). Required if traceId is not provided.
- `startMicros` (`string`) - Start time for traces in microseconds since epoch (optional, defaults to 10 minutes before current time if not provided, only used when traceId is not provided)
- `tags` (`string`) - JSON string of tags to filter traces (optional, only used when traceId is not provided)
- `traceId` (`string`) - Unique identifier of the trace to retrieve detailed information for. If provided, this will return detailed trace information and other parameters (resource_type, namespace, resource_name) are not required.

</details>

<details>
Expand Down
2 changes: 1 addition & 1 deletion build/kiali.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
ISTIOCTL = $(shell pwd)/_output/tools/bin/istioctl
ISTIO_ADDONS_DIR = $(shell pwd)/_output/istio-addons
ISTIO_VERSION = 1.28.0
KIALI_VERSION = v2.22.0
KIALI_VERSION = v2.24.0
# Release version without patch (e.g. 1.28.0 -> 1.28)

# Download and install istioctl (also copies samples/addons for install-istio)
Expand Down
4 changes: 2 additions & 2 deletions evals/claude-code/eval.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ config:
minToolCalls: 1
maxToolCalls: 20
# Kiali tasks
- glob: ../tasks/*/*/*.yaml
- glob: ../tasks/kiali/*/*.yaml
labelSelector:
suite: kiali
assertions:
toolsUsed:
- server: kubernetes
toolPattern: ".*"
minToolCalls: 1
maxToolCalls: 40
maxToolCalls: 20
# Tekton tasks
- glob: ../tasks/tekton/*/*.yaml
labelSelector:
Expand Down
4 changes: 2 additions & 2 deletions evals/openai-agent/eval.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ config:
minToolCalls: 1
maxToolCalls: 20
# Kiali tasks
- glob: ../tasks/*/*/*.yaml
- glob: ../tasks/kiali/*/*.yaml
labelSelector:
suite: kiali
assertions:
toolsUsed:
- server: kubernetes
toolPattern: ".*"
minToolCalls: 1
maxToolCalls: 40
maxToolCalls: 20
# Tekton tasks
- glob: ../tasks/tekton/*/*.yaml
labelSelector:
Expand Down
73 changes: 73 additions & 0 deletions pkg/kiali/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,79 @@ func (s *ConfigSuite) TestConfigParser_AllowsSecureWithRequireTLS() {
s.False(kcfg.Insecure)
}

func (s *ConfigSuite) TestValidate() {
s.Run("nil config returns error", func() {
var cfg *Config
err := cfg.Validate()
s.Error(err, "Expected error for nil config")
s.ErrorContains(err, "kiali config is nil")
})
s.Run("empty URL returns error", func() {
cfg := &Config{}
err := cfg.Validate()
s.Error(err, "Expected error for empty URL")
s.ErrorContains(err, "url is required")
})
s.Run("invalid URL returns error", func() {
cfg := &Config{Url: "://bad-url"}
err := cfg.Validate()
s.Error(err, "Expected error for invalid URL")
s.ErrorContains(err, "url must be a valid URL")
})
s.Run("URL without scheme returns error", func() {
cfg := &Config{Url: "just-a-hostname"}
err := cfg.Validate()
s.Error(err, "Expected error for URL without scheme")
s.ErrorContains(err, "url must be a valid URL")
})
s.Run("HTTP URL does not require certificate_authority", func() {
cfg := &Config{Url: "http://kiali.example/"}
err := cfg.Validate()
s.NoError(err, "HTTP URL should not require certificate_authority")
})
s.Run("HTTPS with insecure=true does not require certificate_authority", func() {
cfg := &Config{Url: "https://kiali.example/", Insecure: true}
err := cfg.Validate()
s.NoError(err, "HTTPS with insecure=true should not require certificate_authority")
})
s.Run("HTTPS with insecure=false requires certificate_authority", func() {
cfg := &Config{Url: "https://kiali.example/", Insecure: false}
err := cfg.Validate()
s.Error(err, "Expected error for HTTPS without cert when not insecure")
s.ErrorContains(err, "certificate_authority is required for https when insecure is false")
})
s.Run("HTTPS with insecure=false and valid certificate_authority passes", func() {
cfg := &Config{
Url: "https://kiali.example/",
CertificateAuthority: s.caFile,
}
err := cfg.Validate()
s.NoError(err, "HTTPS with valid certificate_authority should pass validation")
})
}

func (s *ConfigSuite) TestConfigParser_HTTPUrl_NoCertRequired() {
cfg, err := config.ReadToml([]byte(`
[toolset_configs.kiali]
url = "http://kiali.example/"
`))
s.NoError(err, "HTTP URL should not require certificate_authority")
s.NotNil(cfg, "Config should not be nil for valid HTTP URL")
}

func (s *ConfigSuite) TestConfigParser_NoCertificateAuthority() {
cfg := test.Must(config.ReadToml([]byte(`
[toolset_configs.kiali]
url = "http://kiali.example/"
`)))

kialiCfg, ok := cfg.GetToolsetConfig("kiali")
s.Require().True(ok, "Kiali config should be present")
kcfg, ok := kialiCfg.(*Config)
s.Require().True(ok, "Kiali config should be of type *Config")
s.Empty(kcfg.CertificateAuthority, "certificate_authority should be empty when not provided")
}

func TestConfig(t *testing.T) {
suite.Run(t, new(ConfigSuite))
}
Loading