{
  "repo": "tidbcloud/cluster-service-ng",
  "binary": "autoscale_stub",
  "binary_path": "cmd/autoscale_stub/main.go",
  "dependencies": {
    "CustomMetricsAdapter.GetMetric": {
      "infrastructure": {
        "k8s_api": {
          "conditions": ["Always"],
          "operations": [
            "GET/LIST TiDBGroup, TiKVWorkerGroup, Deployment, Service, Secret",
            "GET/LIST HorizontalPodAutoscaler"
          ]
        },
        "k8s_metrics_api": {
          "conditions": [
            "When serving cpu/memory-based custom metrics",
            "When evaluating ext_cpu_scaled_ratio"
          ],
          "operations": ["LIST PodMetrics"]
        },
        "k8s_scale_subresource": {
          "conditions": ["When evaluating ext_cpu_scaled_ratio"],
          "operations": ["GET scale target replicas"]
        },
        "tls_material": {
          "conditions": ["When serving dxf_hscale_* worker hint metrics"],
          "operations": ["LOAD CA/cert/key from in-cluster Secret"]
        }
      },
      "services": [
        {
          "name": "dxf-worker-endpoint",
          "target_interface": "GET /dxf/schedule/status",
          "operation_type": "https_get",
          "conditions": [
            "When metric is dxf_hscale_tidb_worker_hint",
            "When metric is dxf_hscale_tikv_worker_hint",
            "When metric is dxf_hscale_tikv_worker_hint_v2"
          ],
          "operations": [
            "query worker scheduling status over mutual TLS"
          ]
        }
      ]
    },
    "AutoscaleApp.Run": {
      "infrastructure": {
        "local_config": {
          "conditions": ["When /etc/ng_autoscaler/config.yaml exists and clusterScalers is not empty"],
          "operations": ["LOAD autoscale inputs, outputs, scalers, and cluster scaler routes"]
        },
        "k8s_api": {
          "conditions": [
            "When using InputK8sV1",
            "When using OutputDirectHPAV1"
          ],
          "operations": [
            "LIST workload objects by labels",
            "LIST/UPDATE HorizontalPodAutoscaler"
          ]
        },
        "k8s_metrics_api": {
          "conditions": ["When using InputK8sV1"],
          "operations": ["LIST PodMetrics"]
        }
      },
      "services": [
        {
          "name": "auth0",
          "target_interface": "POST token endpoint",
          "operation_type": "https_post",
          "conditions": ["When using InputO11yMetricsV1"],
          "operations": [
            "exchange client credentials for bearer token"
          ]
        },
        {
          "name": "o11y-api",
          "target_interface": "GET /api/v1/clusters and GET /prometheus/{clusterUUID}/api/v1/query_range",
          "operation_type": "https_get",
          "conditions": ["When using InputO11yMetricsV1"],
          "operations": [
            "resolve cluster UUID by applicationID",
            "query range metrics from O11y Prometheus API"
          ]
        }
      ]
    }
  },
  "scaling_routes": [
    {
      "name": "ScalingRouteK8s2HPAByResourceUsageBased",
      "description": "Scale based on K8s resource usage via HPA",
      "input_provider": "input_k8s_v1",
      "output_provider": "output_direct_hpa_v1",
      "scaler": "scaler_o11y_res_based_v1"
    },
    {
      "name": "ScalingRouteK8s2HPAByCPUUsageBased",
      "description": "Scale based on K8s CPU usage via HPA",
      "input_provider": "input_k8s_v1",
      "output_provider": "output_direct_hpa_v1",
      "scaler": "scaler_k8s_v1"
    },
    {
      "name": "ScalingRouteO11y2HPAByResourceUsageBased",
      "description": "Scale based on O11y metrics via HPA",
      "input_provider": "input_o11y_metrics_v1",
      "output_provider": "output_direct_hpa_v1",
      "scaler": "scaler_o11y_res_based_v1"
    },
    {
      "name": "ScalingRouteK8s2BlackholeByResourceUsageBased",
      "description": "Scale based on K8s resource usage (dry run)",
      "input_provider": "input_k8s_v1",
      "output_provider": "output_blackhole",
      "scaler": "scaler_o11y_res_based_v1"
    },
    {
      "name": "ScalingRouteK8s2BlackholeByCPUUsageBased",
      "description": "Scale based on K8s CPU usage (dry run)",
      "input_provider": "input_k8s_v1",
      "output_provider": "output_blackhole",
      "scaler": "scaler_k8s_v1"
    },
    {
      "name": "ScalingRouteO11y2BlackholeByResourceUsageBased",
      "description": "Scale based on O11y metrics (dry run)",
      "input_provider": "input_o11y_metrics_v1",
      "output_provider": "output_blackhole",
      "scaler": "scaler_o11y_res_based_v1"
    }
  ],
  "components": {
    "input_providers": [
      {
        "name": "input_k8s_v1",
        "description": "Collects in-cluster workload metrics via K8s API and metrics.k8s.io.",
        "dependencies": {
          "infrastructure": {
            "k8s_api": {
              "operations": ["LIST workload objects by labels"]
            },
            "k8s_metrics_api": {
              "operations": ["LIST PodMetrics"]
            }
          }
        }
      },
      {
        "name": "input_o11y_metrics_v1",
        "description": "Fetches cluster metadata and Prometheus range metrics from O11y APIs.",
        "dependencies": {
          "services": [
            {
              "name": "auth0",
              "target_interface": "POST token endpoint",
              "operation_type": "https_post"
            },
            {
              "name": "o11y-api",
              "target_interface": "GET /api/v1/clusters and GET /prometheus/{clusterUUID}/api/v1/query_range",
              "operation_type": "https_get"
            }
          ]
        }
      }
    ],
    "output_providers": [
      {
        "name": "output_direct_hpa_v1",
        "description": "Updates in-cluster HPA objects directly.",
        "dependencies": {
          "infrastructure": {
            "k8s_api": {
              "operations": ["LIST HPA", "UPDATE HPA"]
            }
          }
        }
      },
      {
        "name": "output_blackhole",
        "description": "Discards output for dry-run routes.",
        "dependencies": {}
      }
    ],
    "scalers": [
      {
        "name": "scaler_k8s_v1",
        "description": "CPU-based scaling using K8s input metrics.",
        "dependencies": {}
      },
      {
        "name": "scaler_o11y_res_based_v1",
        "description": "Resource-usage-based scaling driven by either K8s or O11y inputs.",
        "dependencies": {}
      }
    ]
  },
  "dependency_summary": {
    "infrastructure": [
      "k8s api",
      "metrics.k8s.io",
      "k8s scale subresource",
      "in-cluster TLS secrets",
      "local autoscale config"
    ],
    "services": [
      "DXF worker endpoints",
      "Auth0",
      "O11y API"
    ],
    "notes": [
      "The foreground adapter serves custom.metrics.k8s.io and external.metrics.k8s.io requests.",
      "DXF worker hint metrics use mutual-TLS HTTPS calls to /dxf/schedule/status on in-cluster worker endpoints.",
      "The background autoscale goroutine only runs when /etc/ng_autoscaler/config.yaml contains clusterScalers.",
      "O11y dependencies are config-driven through InputO11yMetricsV1 and are not required for every deployment."
    ]
  }
}
