Skill: magicczc/k8sskill (version 1.0.1)

--- name: k8sskill description: 诊断Kubernetes集群问题。用户问Pod崩溃、部署失败、服务不可访问等K8s问题时使用。 --- # K8sSkill - Kubernetes智能诊断助手 ## AI执行指南（必读） **执行诊断时遵守以下规则：** **正确做法：** ```powershell cd scripts python -c "from orchestrator import analyze_cluster; print(analyze_cluster('集群有什么问题'))" ``` 指定命名空间： ```powershell cd scripts python -c "from orchestrator import analyze_cluster; print(analyze_cluster('检查Pod问题', namespace='kubesphere-logging-system'))" ``` **禁止做法：** 1. 禁止创建任何额外的Python脚本文件 2. 禁止创建报告输出文件 3. 禁止封装orchestrator.py的功能 --- ## 使用方式 用户用自然语言描述问题，AI自动调用k8sskill执行诊断。 **触发示例：** - "检查Pod为什么崩溃" - "部署失败了怎么回事" - "为什么服务无法访问" - "节点有问题" - "存储绑定失败" - "查看最近事件" - "集群有什么问题" --- ## 支持的查询类型 | 查询类型 | 示例问法 | |---------|---------| | **Pod问题** | "检查Pod为什么崩溃" / "为什么有Pod一直在重启" | | **Deployment问题** | "部署失败了怎么回事" / "deployment rollout卡住了" | | **Service问题** | "为什么服务无法访问" / "访问不了我的服务" | | **节点问题** | "节点有问题" / "检查节点健康状态" | | **存储问题** | "存储绑定失败" / "PVC无法挂载" | | **事件日志** | "查看最近事件" / "集群有什么警告" | | **全量检查** | "集群有什么问题" / "检查所有资源" | --- ## 核心能力 ### 智能资源诊断（21种分析器） **工作负载分析器：** - **PodAnalyzer** - 检测CrashLoopBackOff、OOMKilled、ImagePullBackOff等状态 - **DeploymentAnalyzer** - 检查滚动更新失败、副本不足等问题 - **ServiceAnalyzer** - 诊断端点缺失、负载均衡异常 - **StatefulSetAnalyzer** - 检查Headless Service、StorageClass、Pod就绪状态 - **JobAnalyzer** - 检测Job挂起、执行失败、超时问题 - **CronJobAnalyzer** - 检查Cron表达式格式、调度配置 - **ReplicaSetAnalyzer** - 检查副本创建失败、ReplicaFailure条件 - **HPAAnalyzer** - 检查自动伸缩配置、目标资源存在性、扩容限制 **存储和网络分析器：** - **PVCAnalyzer** - 检测存储绑定失败、ProvisioningFailed错误 - **IngressAnalyzer** - 检查IngressClass配置、后端Service存在性、TLS证书 - **GatewayAnalyzer** - 检查Gateway API配置、GatewayClass存在性、接受状态 - **HTTPRouteAnalyzer** - 检查HTTPRoute引用的Gateway、后端Service存在性 - **NetworkPolicyAnalyzer** - 检查网络策略范围、未应用的策略 **集群分析器：** - **NodeAnalyzer** - 监控节点就绪状态、内存/磁盘/PID压力 - **EventAnalyzer** - 分析最近警告事件、异常事件模式 - **StorageAnalyzer** - 检查StorageClass配置、PV状态、PVC绑定 - **SecurityAnalyzer** - 检查ServiceAccount使用、容器安全上下文、特权模式 - **WebhookAnalyzer** - 检查Validating/Mutating Webhook的后端Service和Pod **配置分析器：** - **ConfigMapAnalyzer** - 检测未使用的ConfigMap、空配置 - **SecretAnalyzer** - 检查未使用的Secret、TLS证书格式、Docker Registry配置 - **PDBAnalyzer** - 检查PodDisruptionBudget中断限制、选择器匹配 ### 自然语言交互 | 用户输入示例 | 执行的分析 | |-------------|-----------| | "检查我的Pod为什么崩溃" | PodAnalyzer - 检查容器状态和事件 | | "为什么服务无法访问" | ServiceAnalyzer + IngressAnalyzer | | "部署失败了怎么回事" | DeploymentAnalyzer + Event分析 | | "存储绑定失败" | PVCAnalyzer - 检查PVC状态 | | "节点有问题" | NodeAnalyzer - 检查节点健康 | | "查看最近事件" | EventAnalyzer - 分析警告事件 | | "集群有什么问题" | 全量分析所有资源 | ### 分析结果展示 - **结构化输出**：清晰的表格和列表展示问题 - **严重程度分级**：Critical/Warning/Info 三级分类 - **修复建议**：基于SRE经验的逐步解决方案 - **相关资源关联**：展示问题资源的上下游依赖 --- ## 使用示例 ```python # 在 scripts/ 目录下执行 from orchestrator import AnalyzerOrchestrator, analyze_cluster # 方式1: 使用编排器 orchestrator = AnalyzerOrchestrator() results = orchestrator.analyze("检查Pod问题", namespace="default") report = orchestrator.format_report(results) print(report) # 方式2: 使用便捷函数 report = analyze_cluster("检查集群问题", namespace="production") print(report) ``` --- ## 配置 ### kubeconfig支持 支持3种配置方式： 1. 项目自带：`config/k8s-Test-admin.conf` 2. 默认位置：`~/.kube/config` 3. 环境变量：`KUBECONFIG=/path/to/config` ### 快速验证配置 ```python # 在 scripts/ 目录下执行 from core import verify_k8s_connection success, message = verify_k8s_connection() print(message) ``` --- ## 参考文档 - [分析器详细说明](references/analyzers.md) - 各分析器的检测逻辑和故障模式 - [故障排查手册](references/troubleshooting.md) - 常见问题的排查步骤 --- ## 依赖要求 - Python 3.8+ - kubernetes-python 客户端 - 有效的kubeconfig文件 --- ## 使用限制 - 本skill为**诊断工具**，不会修改集群资源 - 需要集群的**只读权限**即可运行 - 大型集群（>1000 Pod）分析可能需要等待数秒 - 首次使用前请确保kubeconfig配置正确 --- **版本**: 1.0.0 **最后更新**: 2026-04-03

path: README.md
content: # K8sSkill - Kubernetes智能诊断助手

基于SRE最佳实践的Kubernetes智能诊断工具，支持在IDE内通过自然语言对话执行诊断。

## 快速开始

### 1. 安装依赖

```bash
cd <skill所在目录>
pip install -r requirements.txt
```

例如，如果skill放在某个目录下：
```bash
cd <skill所在目录>
pip install -r requirements.txt
```

### 2. 配置Kubernetes连接

**方式A: 使用项目自带的kubeconfig（已配置）**

项目已在 `config/` 目录下配置了kubeconfig文件：
- `config/k8s-Test-admin.conf`

**方式B: 手动配置到默认位置**
```bash
# 复制kubeconfig到默认位置（Linux/macOS）
cp ~/.kube/config.backup ~/.kube/config.backup 2>/dev/null || true
cp /path/to/your/kubeconfig ~/.kube/config
```

**方式C: 设置环境变量**
```powershell
# 设置KUBECONFIG环境变量指向skill目录下的配置文件（Windows）
$env:KUBECONFIG="<skill目录>\config\k8s-Test-admin.conf"
```

### 3. 在IDE中使用

**无需手动执行任何命令！** 直接在Trae IDE对话中描述你想检查的问题即可。

### 示例对话

**你:** "检查Pod为什么崩溃"

**AI:** 自动调用k8sskill诊断并返回结果

**支持的查询类型:**
- **Pod问题**: "检查Pod为什么崩溃" / "为什么有Pod一直在重启"
- **Deployment问题**: "部署失败了怎么回事" / "deployment rollout卡住了"
- **Service问题**: "为什么服务无法访问" / "访问不了我的服务"
- **节点问题**: "节点有问题" / "检查节点健康状态"
- **存储问题**: "存储绑定失败" / "PVC无法挂载"
- **事件日志**: "查看最近事件" / "集群有什么警告"
- **全量检查**: "集群有什么问题" / "检查所有资源"

### 4. Python API使用（高级）

开发者可以直接在Python中使用k8sskill：

```python
# 在 scripts/ 目录下执行
from orchestrator import AnalyzerOrchestrator, analyze_cluster

# 方式1: 使用编排器
orchestrator = AnalyzerOrchestrator()
results = orchestrator.analyze("检查集群问题")
print(orchestrator.format_report(results))

# 方式2: 使用便捷函数
report = analyze_cluster("检查Pod为什么崩溃", "production")
print(report)
```

---

## 故障排查

### 连接失败

```bash
# 检查kubeconfig是否存在
dir config\

# 手动测试连接
python -c "from kubernetes import config; config.load_kube_config('config/k8s-Test-admin.conf'); print('OK')"
```

### 权限不足

```bash
# 检查kubectl权限
kubectl auth can-i list pods

# 检查当前上下文
kubectl config current-context
```

### 模块导入错误

```python
# 确保在 scripts/ 目录下执行
# 错误方式: from scripts import AnalyzerOrchestrator
# 正确方式: from orchestrator import AnalyzerOrchestrator

# 验证导入是否正常
from orchestrator import AnalyzerOrchestrator
print("导入成功!")
```

---

## 特性

- **21个Kubernetes资源分析器** - 覆盖Pod、Deployment、Service、Node、PVC等核心资源
- 自然语言意图识别 - 直接对话即可诊断集群问题
- 中文和英文支持 - 全中文文档和错误提示
- 结构化诊断报告 - 清晰的故障分类和修复建议
- 模块化设计 - 按需加载，易于扩展
- 纯Python实现 - 基于kubernetes-python客户端
- 自动kubeconfig检测 - 支持环境变量、默认位置和项目配置

---

## 版本历史

- **v1.0.0** - 重大重构：模块化架构升级，提取BaseAnalyzer，新增orchestrator.py编排器（21个分析器）
- **v0.5.2** - 优化错误提示，新增verify_k8s_connection()连接验证函数（21个分析器）
- **v0.4.0** - 添加Secret、Gateway、HTTPRoute、Webhook分析器（21个分析器）
- **v0.3.0** - 添加ReplicaSet、NetworkPolicy、PDB、Storage、Security分析器（17个分析器）
- **v0.2.0** - 添加StatefulSet、Job、CronJob、HPA、ConfigMap、PVC、Node、Ingress、Event分析器（12个分析器）
- **v0.1.0** - 初始版本，Pod、Deployment、Service分析器（3个分析器）

---

## 许可证

基于Kubernetes最佳实践和SRE经验设计


path: README_EN.md
content: # K8sSkill - Kubernetes Intelligent Diagnostic Assistant

Kubernetes intelligent diagnostic tool based on SRE best practices, supports natural language conversation diagnosis within IDE.

## Quick Start

### 1. Install Dependencies

```bash
cd <skill directory>
pip install -r requirements.txt
```

For example, if skill is placed in a directory:
```bash
cd <skill directory>
pip install -r requirements.txt
```

### 2. Configure Kubernetes Connection

**Option A: Use project-included kubeconfig (already configured)**

The project has configured kubeconfig file in `config/` directory:
- `config/k8s-Test-admin.conf`

**Option B: Manually configure to default location**
```bash
# Copy kubeconfig to default location
copy C:\path\to\your\kubeconfig C:\Users\%USERNAME%\.kube\config
```

**Option C: Set environment variable**
```powershell
# Set KUBECONFIG environment variable pointing to skill directory config file
$env:KUBECONFIG="<skill directory>\config\k8s-Test-admin.conf"
```

### 3. Use in IDE

**No need to manually execute any commands!** Just describe the problem you want to check in the Trae IDE conversation.

### Example Conversation

**You:** "Check why my Pod is crashing"

**AI:** Automatically calls k8sskill for diagnosis and returns results

**Supported Query Types:**
- **Pod Issues**: "Check why Pod is crashing" / "Why is Pod restarting"
- **Deployment Issues**: "What happened to deployment" / "deployment rollout stuck"
- **Service Issues**: "Why can't I access service" / "Can't access my service"
- **Node Issues**: "Node has issues" / "Check node health status"
- **Storage Issues**: "Storage binding failed" / "PVC cannot mount"
- **Event Logs**: "View recent events" / "What warnings does cluster have"
- **Full Check**: "What problems does cluster have" / "Check all resources"

### 4. Python API Usage (Advanced)

Developers can directly use k8sskill in Python:

```python
# Execute in scripts/ directory
from orchestrator import AnalyzerOrchestrator, analyze_cluster

# Method 1: Use orchestrator
orchestrator = AnalyzerOrchestrator()
results = orchestrator.analyze("check cluster issues")
print(orchestrator.format_report(results))

# Method 2: Use convenience function
report = analyze_cluster("check why Pod is crashing", "production")
print(report)
```

---

## Troubleshooting

### Connection Failed

```bash
# Check if kubeconfig exists
dir config\

# Manually test connection
python -c "from kubernetes import config; config.load_kube_config('config/k8s-Test-admin.conf'); print('OK')"
```

### Insufficient Permissions

```bash
# Check kubectl permissions
kubectl auth can-i list pods

# Check current context
kubectl config current-context
```

### Module Import Error

```python
# Make sure to execute in scripts/ directory
# Wrong way: from scripts import AnalyzerOrchestrator
# Correct way: from orchestrator import AnalyzerOrchestrator

# Verify if import works
from orchestrator import AnalyzerOrchestrator
print("Import successful!")
```

---

## Features

- **22 Kubernetes Resource Analyzers** - Covers core resources like Pod, Deployment, Service, Node, PVC
- Natural Language Intent Recognition - Diagnose cluster issues directly through conversation
- Chinese and English Support - Full Chinese documentation and error prompts
- Structured Diagnostic Reports - Clear fault classification and fix recommendations
- Modular Design - Load on demand, easy to extend
- Pure Python Implementation - Based on kubernetes-python client
- Automatic kubeconfig Detection - Supports environment variables, default locations, and project configuration

---

## Version History

- **v1.0.0** - Major refactor: Modular architecture upgrade, extracted BaseAnalyzer, added orchestrator.py (21 analyzers)
- **v0.5.2** - Optimized error messages, added verify_k8s_connection() verification function (21 analyzers)
- **v0.4.0** - Added Secret, Gateway, HTTPRoute, Webhook analyzers (21 analyzers)
- **v0.3.0** - Added ReplicaSet, NetworkPolicy, PDB, Storage, Security analyzers (17 analyzers)
- **v0.2.0** - Added StatefulSet, Job, CronJob, HPA, ConfigMap, PVC, Node, Ingress, Event analyzers (12 analyzers)
- **v0.1.0** - Initial version, Pod, Deployment, Service analyzers (3 analyzers)

---

## License

Designed based on Kubernetes best practices and SRE experience


path: requirements.txt
content: # K8sSkill 依赖
kubernetes>=28.0.0
pyyaml>=6.0


path: SKILL_EN.md
content: ---
name: k8sskill
description: Diagnose Kubernetes cluster issues. Use when users ask about Pod crashes, deployment failures, service inaccessibility, or other K8s problems.
---

# K8sSkill - Kubernetes Intelligent Diagnostic Assistant

## AI Execution Guide (Must Read)

**Follow these rules when executing diagnostics:**

**Correct Approach:**
```powershell
cd scripts
python -c "from orchestrator import analyze_cluster; print(analyze_cluster('cluster has issues'))"
```

Specify namespace:
```powershell
cd scripts
python -c "from orchestrator import analyze_cluster; print(analyze_cluster('check Pod issues', namespace='kubesphere-logging-system'))"
```

**Prohibited Actions:**
1. Do not create any additional Python script files
2. Do not create report output files
3. Do not wrap orchestrator.py functionality

---

## Usage

Users describe problems in natural language, AI automatically calls k8sskill for diagnosis.

**Trigger Examples:**
- "Check why my Pod is crashing"
- "What happened to the deployment"
- "Why can't I access the service"
- "Node has issues"
- "Storage binding failed"
- "View recent events"
- "What problems does the cluster have"

---

## Supported Query Types

| Query Type | Example Phrases |
|-------------|----------------|
| **Pod Issues** | "Check why Pod is crashing" / "Why is Pod restarting" |
| **Deployment Issues** | "What happened to the deployment" / "deployment rollout stuck" |
| **Service Issues** | "Why can't I access the service" / "Can't access my service" |
| **Node Issues** | "Node has issues" / "Check node health status" |
| **Storage Issues** | "Storage binding failed" / "PVC cannot mount" |
| **Event Logs** | "View recent events" / "What warnings does the cluster have" |
| **Full Check** | "What problems does the cluster have" / "Check all resources" |

---

## Core Capabilities

### Intelligent Resource Diagnosis (22 Analyzers)

**Workload Analyzers:**
- **PodAnalyzer** - Detects CrashLoopBackOff, OOMKilled, ImagePullBackOff, and other states
- **DeploymentAnalyzer** - Checks rolling update failures, insufficient replicas, and other issues
- **ServiceAnalyzer** - Diagnoses missing endpoints, load balancing anomalies
- **StatefulSetAnalyzer** - Checks Headless Service, StorageClass, Pod readiness status
- **JobAnalyzer** - Detects Job suspension, execution failures, timeout issues
- **CronJobAnalyzer** - Checks Cron expression format, scheduling configuration
- **ReplicaSetAnalyzer** - Checks replica creation failures, ReplicaFailure conditions
- **HPAAnalyzer** - Checks auto-scaling configuration, target resource existence, scaling limits

**Storage and Network Analyzers:**
- **PVCAnalyzer** - Detects storage binding failures, ProvisioningFailed errors
- **IngressAnalyzer** - Checks IngressClass configuration, backend Service existence, TLS certificates
- **GatewayAnalyzer** - Checks Gateway API configuration, GatewayClass existence, acceptance status
- **HTTPRouteAnalyzer** - Checks HTTPRoute-referenced Gateway, backend Service existence
- **NetworkPolicyAnalyzer** - Checks network policy scope, unapplied policies

**Cluster Analyzers:**
- **NodeAnalyzer** - Monitors node readiness status, memory/disk/PID pressure
- **EventAnalyzer** - Analyzes recent warning events, abnormal event patterns
- **StorageAnalyzer** - Checks StorageClass configuration, PV status, PVC binding
- **SecurityAnalyzer** - Checks ServiceAccount usage, container security context, privileged mode
- **WebhookAnalyzer** - Checks Validating/Mutating Webhook backend Service and Pod

**Configuration Analyzers:**
- **ConfigMapAnalyzer** - Detects unused ConfigMaps, empty configurations
- **SecretAnalyzer** - Checks unused Secrets, TLS certificate format, Docker Registry configuration
- **PDBAnalyzer** - Checks PodDisruptionBudget disruption limits, selector matching

### Natural Language Interaction

| User Input Example | Analysis Executed |
|-------------------|------------------|
| "Check why my Pod is crashing" | PodAnalyzer - Check container status and events |
| "Why can't I access the service" | ServiceAnalyzer + IngressAnalyzer |
| "What happened to the deployment" | DeploymentAnalyzer + Event analysis |
| "Storage binding failed" | PVCAnalyzer - Check PVC status |
| "Node has issues" | NodeAnalyzer - Check node health |
| "View recent events" | EventAnalyzer - Analyze warning events |
| "What problems does the cluster have" | Full analysis of all resources |

### Analysis Result Display
- **Structured Output**: Clear tables and lists displaying issues
- **Severity Classification**: Critical/Warning/Info three-level classification
- **Fix Recommendations**: Step-by-step solutions based on SRE experience
- **Related Resource Association**: Display upstream and downstream dependencies of problematic resources

---

## Usage Examples

```python
# Execute in scripts/ directory
from orchestrator import AnalyzerOrchestrator, analyze_cluster

# Method 1: Use orchestrator
orchestrator = AnalyzerOrchestrator()
results = orchestrator.analyze("check Pod issues", namespace="default")
report = orchestrator.format_report(results)
print(report)

# Method 2: Use convenience function
report = analyze_cluster("check cluster issues", namespace="production")
print(report)
```

---

## Configuration

### kubeconfig Support
Supports 3 configuration methods:
1. Project included: `config/k8s-Test-admin.conf`
2. Default location: `~/.kube/config`
3. Environment variable: `KUBECONFIG=/path/to/config`

### Quick Configuration Verification
```python
# Execute in scripts/ directory
from core import verify_k8s_connection
success, message = verify_k8s_connection()
print(message)
```

---

## Reference Documentation

- [Analyzer Detailed Description](references/analyzers.md) - Detection logic and failure patterns of each analyzer
- [Troubleshooting Manual](references/troubleshooting.md) - Troubleshooting steps for common issues

---

## Dependency Requirements

- Python 3.8+
- kubernetes-python client
- Valid kubeconfig file

---

## Usage Limitations

- This skill is a **diagnostic tool** and does not modify cluster resources
- Requires **read-only permissions** on the cluster to run
- Analysis of large clusters (>1000 Pods) may take several seconds
- Ensure kubeconfig is correctly configured before first use

---

**Version**: 1.0.0  
**Last Updated**: 2026-04-03


path: _meta.json
content: {
    "name": "k8sskill",
    "version": "1.0.0",
    "description": "Kubernetes智能诊断助手 - IDE内自然语言诊断工具，支持21种资源分析",
    "author": "chenzc",
    "created_at": "2026-04-02",
    "updated_at": "2026-04-03",
    "source": "基于Kubernetes最佳实践和SRE经验设计",
    "config": {
        "kubeconfig_path": "~/.kube/config",
        "default_namespace": "default",
        "output_format": "markdown"
    },
    "architecture": {
        "description": "模块化分析器架构 - 使用抽象基类和编排器模式",
        "core_module": "core/base.py - 抽象基类、数据模型、工具函数",
        "orchestrator": "orchestrator.py - AnalyzerOrchestrator分析器编排器",
        "analyzers_dir": "analyzers/ - 20个独立分析器模块"
    },
    "analyzers": {
        "workload": [
            "pod",
            "deployment",
            "service",
            "statefulset",
            "job",
            "cronjob",
            "replicaset",
            "hpa"
        ],
        "storage_network": [
            "pvc",
            "ingress",
            "gateway",
            "httproute",
            "networkpolicy"
        ],
        "cluster": [
            "node",
            "event",
            "storage",
            "security",
            "webhook"
        ],
        "config": [
            "configmap",
            "secret",
            "pdb"
        ]
    },
    "scripts": {
        "entry_point": "scripts/__init__.py - 统一入口，导出所有公共API",
        "orchestrator": "scripts/orchestrator.py - 分析器编排器",
        "core": "scripts/core/base.py - 抽象基类和数据模型",
        "analyzers": "scripts/analyzers/*.py - 20个独立分析器"
    },
    "dependencies": [
        "kubernetes>=28.0.0",
        "pyyaml>=6.0"
    ],
    "exports": [
        "AnalyzerOrchestrator",
        "analyze_cluster",
        "BaseAnalyzer",
        "AnalysisResult",
        "Failure",
        "Severity",
        "verify_k8s_connection",
        "PodAnalyzer",
        "DeploymentAnalyzer",
        "ServiceAnalyzer",
        "StatefulSetAnalyzer",
        "JobAnalyzer",
        "CronJobAnalyzer",
        "ReplicaSetAnalyzer",
        "HPAAnalyzer",
        "PVCAnalyzer",
        "NodeAnalyzer",
        "IngressAnalyzer",
        "EventAnalyzer",
        "ConfigMapAnalyzer",
        "SecretAnalyzer",
        "NetworkPolicyAnalyzer",
        "PDBAnalyzer",
        "StorageAnalyzer",
        "SecurityAnalyzer",
        "GatewayAnalyzer",
        "HTTPRouteAnalyzer",
        "WebhookAnalyzer"
    ],
    "usage_examples": {
        "orchestrator": "cd scripts; from orchestrator import AnalyzerOrchestrator; orchestrator = AnalyzerOrchestrator(); results = orchestrator.analyze('检查Pod问题')",
        "quick": "cd scripts; from orchestrator import analyze_cluster; report = analyze_cluster('检查集群问题')",
        "single": "cd scripts; from analyzers import PodAnalyzer; analyzer = PodAnalyzer(); results = analyzer.analyze()",
        "verify": "cd scripts; from core import verify_k8s_connection; success, msg = verify_k8s_connection()"
    },
    "changelog": [
        {
            "version": "0.1.0",
            "date": "2026-04-02",
            "changes": [
                "初始版本发布",
                "实现Pod/Deployment/Service分析器",
                "支持自然语言意图识别",
                "生成Markdown格式诊断报告"
            ]
        },
        {
            "version": "0.2.0",
            "date": "2026-04-02",
            "changes": [
                "添加扩展分析器: PVC, Node, Ingress, Event",
                "添加更多分析器: StatefulSet, Job, CronJob, HPA, ConfigMap",
                "支持12种Kubernetes资源类型诊断",
                "完善意图识别关键词映射",
                "优化报告格式，避免编码问题"
            ]
        },
        {
            "version": "0.3.0",
            "date": "2026-04-02",
            "changes": [
                "添加高级分析器: ReplicaSet, NetworkPolicy, PDB, Storage, Security",
                "支持17种Kubernetes资源类型诊断",
                "新增安全上下文和权限检查",
                "新增存储类和持久卷分析",
                "完善网络策略和驱逐保护检查"
            ]
        },
        {
            "version": "0.4.0",
            "date": "2026-04-02",
            "changes": [
                "添加最终分析器: Secret, Gateway, HTTPRoute, Webhook",
                "支持21种Kubernetes资源类型诊断",
                "新增Gateway API支持（Gateway和HTTPRoute）",
                "新增Secret和Webhook配置检查",
                "完成核心分析器全覆盖"
            ]
        },
        {
            "version": "0.5.0",
            "date": "2026-04-02",
            "changes": [
                "添加最终分析器: Secret, Gateway, HTTPRoute, Webhook",
                "支持21种Kubernetes资源类型诊断",
                "新增Gateway API支持（Gateway和HTTPRoute）",
                "新增Secret和Webhook配置检查",
                "完成核心分析器全覆盖"
            ]
        },
        {
            "version": "0.5.2",
            "date": "2026-04-02",
            "changes": [
                "优化错误提示，增加中文友好提示",
                "新增verify_k8s_connection()连接验证函数",
                "完善文档和使用说明"
            ]
        },
        {
            "version": "1.0.0",
            "date": "2026-04-03",
            "changes": [
                "【重大重构】模块化架构升级",
                "提取抽象基类BaseAnalyzer，统一分析器接口",
                "将5个臃肿文件拆分为21个独立分析器模块",
                "新增core/目录存放基础组件",
                "新增analyzers/目录存放具体分析器",
                "新增orchestrator.py分析器编排器",
                "使用模板方法模式统一分析流程",
                "删除旧的analyzer*.py重复文件",
                "更新SKILL.md文档反映新架构",
                "提升代码可维护性和扩展性"
            ]
        }
    ]
}


path: scripts/orchestrator.py
content: """
文件功能：K8sSkill分析器编排器
主要类/函数：AnalyzerOrchestrator - 协调多个分析器执行诊断
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 使用编排器模式统一管理多个分析器
IMPORTANT: 支持意图识别和动态分析器加载
"""

from typing import List, Dict, Any, Optional, Type
from datetime import datetime
import logging

try:
    # 尝试相对导入（作为包的一部分时）
    from .core import BaseAnalyzer, AnalysisResult, Severity
    from .analyzers import (
        PodAnalyzer, DeploymentAnalyzer, ServiceAnalyzer,
        StatefulSetAnalyzer, JobAnalyzer, CronJobAnalyzer,
        ReplicaSetAnalyzer, HPAAnalyzer, PVCAnalyzer,
        NodeAnalyzer, IngressAnalyzer, EventAnalyzer,
        ConfigMapAnalyzer, SecretAnalyzer, NetworkPolicyAnalyzer,
        PDBAnalyzer, StorageAnalyzer, SecurityAnalyzer,
        GatewayAnalyzer, HTTPRouteAnalyzer, WebhookAnalyzer,
    )
except ImportError:
    # 回退到绝对导入（直接运行时）
    from core import BaseAnalyzer, AnalysisResult, Severity
    from analyzers import (
        PodAnalyzer, DeploymentAnalyzer, ServiceAnalyzer,
        StatefulSetAnalyzer, JobAnalyzer, CronJobAnalyzer,
        ReplicaSetAnalyzer, HPAAnalyzer, PVCAnalyzer,
        NodeAnalyzer, IngressAnalyzer, EventAnalyzer,
        ConfigMapAnalyzer, SecretAnalyzer, NetworkPolicyAnalyzer,
        PDBAnalyzer, StorageAnalyzer, SecurityAnalyzer,
        GatewayAnalyzer, HTTPRouteAnalyzer, WebhookAnalyzer,
    )

logger = logging.getLogger(__name__)


class AnalyzerOrchestrator:
    """
    分析器编排器 - 协调所有分析器执行诊断
    
    功能：
    - 意图识别：将自然语言映射到分析器
    - 协调分析：调用多个分析器执行诊断
    - 结果汇总：整合和格式化分析结果
    
    使用示例：
    >>> orchestrator = AnalyzerOrchestrator()
    >>> 
    >>> # 分析所有资源
    >>> results = orchestrator.analyze("检查集群问题")
    >>> 
    >>> # 仅分析Pod
    >>> results = orchestrator.analyze("Pod为什么崩溃", namespace="default")
    >>> 
    >>> # 打印报告
    >>> print(orchestrator.format_report(results))
    """
    
    # 意图关键词映射表
    INTENT_MAP = {
        "pod": ["pod", "容器", "container", "重启", "crash", "oom", "崩溃"],
        "deployment": ["deployment", "部署", "rollout", "发布", "更新"],
        "service": ["service", "服务", "访问", "连通", "endpoint"],
        "statefulset": ["statefulset", "sts", "有状态", "数据库", "kafka", "redis", "mysql"],
        "job": ["job", "任务", "批处理", "batchjob", "一次性任务"],
        "cronjob": ["cronjob", "定时任务", "定时器", "schedule", "cron"],
        "replicaset": ["replicaset", "rs", "副本集", "副本"],
        "hpa": ["hpa", "自动伸缩", "扩缩容", "autoscale", "horizontal"],
        "pvc": ["pvc", "存储", "volume", "磁盘", "持久化", "storage", "claim"],
        "node": ["node", "节点", "机器", "服务器", "宿主机", "worker", "master"],
        "ingress": ["ingress", "域名", "路由", "gateway", "入口"],
        "event": ["event", "事件", "日志", "警告", "warning", "log"],
        "configmap": ["configmap", "cm", "配置", "配置项", "config"],
        "secret": ["secret", "密钥", "证书", "tls", "docker-registry"],
        "networkpolicy": ["networkpolicy", "网络策略", "防火墙", "网络隔离"],
        "pdb": ["pdb", "poddisruptionbudget", "中断预算", "驱逐保护"],
        "storage": ["storage", "storageclass", "pv", "持久卷", "存储类"],
        "security": ["security", "安全", "特权", "root", "serviceaccount"],
        "gateway": ["gateway", "网关", "gatewayapi"],
        "httproute": ["httproute", "路由", "http路由"],
        "webhook": ["webhook", "准入控制器", "validatingwebhook", "mutatingwebhook"],
        "all": ["所有", "全部", "集群", "cluster", "整体", "问题"]
    }
    
    # 分析器注册表
    ANALYZER_REGISTRY: Dict[str, Type[BaseAnalyzer]] = {
        "pod": PodAnalyzer,
        "deployment": DeploymentAnalyzer,
        "service": ServiceAnalyzer,
        "statefulset": StatefulSetAnalyzer,
        "job": JobAnalyzer,
        "cronjob": CronJobAnalyzer,
        "replicaset": ReplicaSetAnalyzer,
        "hpa": HPAAnalyzer,
        "pvc": PVCAnalyzer,
        "node": NodeAnalyzer,
        "ingress": IngressAnalyzer,
        "event": EventAnalyzer,
        "configmap": ConfigMapAnalyzer,
        "secret": SecretAnalyzer,
        "networkpolicy": NetworkPolicyAnalyzer,
        "pdb": PDBAnalyzer,
        "storage": StorageAnalyzer,
        "security": SecurityAnalyzer,
        "gateway": GatewayAnalyzer,
        "httproute": HTTPRouteAnalyzer,
        "webhook": WebhookAnalyzer,
    }
    
    def __init__(self, analyzer_types: Optional[List[str]] = None):
        """
        初始化编排器
        
        参数说明：
        - analyzer_types: [Optional[List[str]]] 要加载的分析器类型列表，
                         None表示加载所有分析器
        """
        self._logger = logging.getLogger(self.__class__.__name__)
        self._analyzers: Dict[str, BaseAnalyzer] = {}
        
        # 加载分析器
        types_to_load = analyzer_types or list(self.ANALYZER_REGISTRY.keys())
        for analyzer_type in types_to_load:
            self._load_analyzer(analyzer_type)
    
    def _load_analyzer(self, analyzer_type: str):
        """加载指定类型的分析器"""
        if analyzer_type in self._analyzers:
            return
        
        analyzer_class = self.ANALYZER_REGISTRY.get(analyzer_type)
        if not analyzer_class:
            self._logger.warning(f"未知的分析器类型: {analyzer_type}")
            return
        
        try:
            self._analyzers[analyzer_type] = analyzer_class()
            self._logger.info(f"已加载分析器: {analyzer_type}")
        except Exception as e:
            self._logger.error(f"加载分析器 {analyzer_type} 失败: {e}")
    
    def register_analyzer(self, name: str, analyzer: BaseAnalyzer):
        """
        注册自定义分析器
        
        参数说明：
        - name: [str] 分析器名称
        - analyzer: [BaseAnalyzer] 分析器实例
        """
        self._analyzers[name] = analyzer
        self._logger.info(f"已注册分析器: {name}")
    
    def parse_intent(self, query: str) -> List[str]:
        """
        解析用户意图，识别需要执行的分析类型
        
        参数说明：
        - query: [str] 用户自然语言输入
        
        返回说明：
        - [List[str]] 需要执行的分析器类型列表
        
        示例：
        >>> orchestrator.parse_intent("检查Pod为什么崩溃")
        ['pod']
        >>> orchestrator.parse_intent("服务和部署有什么问题")
        ['service', 'deployment']
        """
        query_lower = query.lower()
        detected = []
        
        for analyzer_type, keywords in self.INTENT_MAP.items():
            for keyword in keywords:
                if keyword in query_lower:
                    detected.append(analyzer_type)
                    break
        
        # 默认执行全部分析
        if not detected or "all" in detected:
            return list(self._analyzers.keys())
        
        # 过滤掉未加载的分析器
        return [d for d in detected if d in self._analyzers]
    
    def analyze(
        self,
        query: str,
        namespace: str = "",
        label_selector: str = ""
    ) -> Dict[str, List[AnalysisResult]]:
        """
        执行分析（主入口）
        
        参数说明：
        - query: [str] 用户自然语言查询
        - namespace: [str] 目标命名空间
        - label_selector: [str] 标签选择器
        
        返回说明：
        - [Dict[str, List[AnalysisResult]]] 按分析器分类的结果
        
        示例：
        >>> results = orchestrator.analyze("检查Pod问题", namespace="production")
        >>> for analyzer_type, result_list in results.items():
        ...     print(f"{analyzer_type}: {len(result_list)} issues")
        """
        analyzer_types = self.parse_intent(query)
        results = {}
        errors = {}
        
        for analyzer_type in analyzer_types:
            analyzer = self._analyzers.get(analyzer_type)
            if not analyzer:
                continue
            
            try:
                result_list = analyzer.analyze(namespace, label_selector)
                if result_list:
                    results[analyzer_type] = result_list
            except Exception as e:
                error_msg = f"分析器 {analyzer_type} 执行失败: {e}"
                self._logger.error(error_msg, exc_info=True)
                errors[analyzer_type] = str(e)
        
        if errors:
            results["_errors"] = errors
        
        return results
    
    def format_report(self, results: Dict[str, List[AnalysisResult]], format_type: str = "markdown") -> str:
        """
        格式化分析报告
        
        参数说明：
        - results: [Dict] 分析结果
        - format_type: [str] 输出格式 (markdown/json)
        
        返回说明：
        - [str] 格式化后的报告
        """
        if format_type == "markdown":
            return self._format_markdown(results)
        elif format_type == "json":
            return self._format_json(results)
        else:
            return str(results)
    
    def _format_json(self, results: Dict[str, List[AnalysisResult]]) -> str:
        """格式化为JSON报告"""
        import json
        json_results = {}
        
        for k, v in results.items():
            if k == "_errors":
                json_results["errors"] = v
            elif isinstance(v, list):
                json_results[k] = [
                    {
                        "kind": r.kind,
                        "name": r.name,
                        "namespace": r.namespace,
                        "failures": [
                            {
                                "text": f.text,
                                "severity": f.severity.value,
                                "reason": f.reason,
                                "suggestion": f.suggestion
                            }
                            for f in r.failures
                        ],
                        "details": r.details
                    }
                    for r in v
                ]
        
        return json.dumps(json_results, indent=2, ensure_ascii=False)
    
    def _format_markdown(self, results: Dict[str, List[AnalysisResult]]) -> str:
        """格式化为Markdown报告"""
        lines = []
        lines.append("# K8sSkill 诊断报告\n")
        lines.append(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
        
        errors = results.get("_errors", {})
        if errors:
            lines.append("\n## [ERROR] 分析过程错误\n")
            lines.append("以下分析器执行失败，请检查集群连接或权限：\n")
            for analyzer_type, error_msg in errors.items():
                lines.append(f"- **{analyzer_type}**: {error_msg}\n")
            lines.append("\n---\n")
        
        total_issues = sum(len(r) for r in results.values() if isinstance(r, list))
        if total_issues == 0 and not errors:
            lines.append("\n[OK] **未发现明显问题**\n")
            return "\n".join(lines)
        elif total_issues == 0:
            lines.append("\n[INFO] **未发现资源问题**（但存在分析错误）\n")
            return "\n".join(lines)
        
        lines.append(f"\n## 汇总\n")
        lines.append(f"发现问题资源: **{total_issues}** 个\n")
        
        # 统计严重程度
        critical = 0
        warning = 0
        for key, result_list in results.items():
            if key == "_errors":
                continue
            if not isinstance(result_list, list):
                continue
            for result in result_list:
                critical += result.critical_count
                warning += sum(1 for f in result.failures if f.severity == Severity.WARNING)
        
        if critical > 0:
            lines.append(f"[CRITICAL] 严重: **{critical}**\n")
        if warning > 0:
            lines.append(f"[WARNING] 警告: **{warning}**\n")
        
        lines.append("\n---\n")
        
        # 详细结果
        for analyzer_type, result_list in results.items():
            if analyzer_type == "_errors":
                continue
            if not isinstance(result_list, list) or not result_list:
                continue
            
            lines.append(f"\n## {analyzer_type.upper()} 分析结果\n")
            
            for result in result_list:
                status = "[CRITICAL]" if result.critical_count > 0 else "[WARNING]" if result.has_issues else "[OK]"
                lines.append(f"\n### {status} {result.kind}: `{result.name}`\n")
                lines.append(f"**命名空间:** {result.namespace}\n")
                
                if result.parent_object:
                    lines.append(f"**父资源:** {result.parent_object}\n")
                
                lines.append(f"\n**问题详情:**\n")
                for failure in result.failures:
                    severity_mark = "[CRITICAL]" if failure.severity == Severity.CRITICAL else "[WARNING]" if failure.severity == Severity.WARNING else "[INFO]"
                    lines.append(f"\n{severity_mark} **{failure.reason}**\n")
                    lines.append(f"> {failure.text}\n")
                    if failure.suggestion:
                        lines.append(f"\n**建议:**\n")
                        lines.append(f"```\n{failure.suggestion}\n```\n")
        
        return "\n".join(lines)


# 便捷函数
def analyze_cluster(query: str = "检查集群问题", namespace: str = "") -> str:
    """
    快速分析集群并返回Markdown报告
    
    参数说明：
    - query: [str] 分析查询
    - namespace: [str] 命名空间
    
    返回说明：
    - [str] Markdown格式的分析报告
    
    使用示例：
    >>> report = analyze_cluster("检查Pod为什么崩溃", "production")
    >>> print(report)
    """
    orchestrator = AnalyzerOrchestrator()
    results = orchestrator.analyze(query, namespace)
    return orchestrator.format_report(results, "markdown")


path: scripts/__init__.py
content: """
文件功能：K8sSkill脚本模块包 - 重构后的清晰结构
主要类/函数：
    # 核心基础
    - Severity - 问题严重程度枚举
    - Failure - 故障详情数据类
    - AnalysisResult - 分析结果数据类
    - BaseAnalyzer - 分析器抽象基类
    
    # 分析器编排
    - AnalyzerOrchestrator - 分析器编排器
    - analyze_cluster - 快速分析函数
    
    # 工作负载分析器
    - PodAnalyzer - Pod分析器
    - DeploymentAnalyzer - Deployment分析器
    - ServiceAnalyzer - Service分析器
    - StatefulSetAnalyzer - StatefulSet分析器
    - JobAnalyzer - Job分析器
    - CronJobAnalyzer - CronJob分析器
    - ReplicaSetAnalyzer - ReplicaSet分析器
    - HPAAnalyzer - HPA分析器
    
    # 存储和网络分析器
    - PVCAnalyzer - PVC分析器
    - IngressAnalyzer - Ingress分析器
    - GatewayAnalyzer - Gateway分析器
    - HTTPRouteAnalyzer - HTTPRoute分析器
    - NetworkPolicyAnalyzer - NetworkPolicy分析器
    
    # 集群分析器
    - NodeAnalyzer - Node分析器
    - EventAnalyzer - Event分析器
    - StorageAnalyzer - Storage分析器
    - SecurityAnalyzer - Security分析器
    - WebhookAnalyzer - Webhook分析器
    
    # 配置分析器
    - ConfigMapAnalyzer - ConfigMap分析器
    - SecretAnalyzer - Secret分析器
    - PDBAnalyzer - PDB分析器

作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 重构后的清晰模块化结构
IMPORTANT: 每个分析器独立，通过编排器统一管理

使用示例：
    # 方式1：使用编排器（推荐）
    # 在 scripts/ 目录下执行
    from orchestrator import AnalyzerOrchestrator
    
    orchestrator = AnalyzerOrchestrator()
    results = orchestrator.analyze("检查Pod问题", namespace="default")
    report = orchestrator.format_report(results)
    print(report)
    
    # 方式2：使用便捷函数
    # 在 scripts/ 目录下执行
    from orchestrator import analyze_cluster
    
    report = analyze_cluster("检查集群问题", namespace="production")
    print(report)
    
    # 方式3：单独使用分析器
    # 在 scripts/ 目录下执行
    from analyzers import PodAnalyzer
    
    analyzer = PodAnalyzer()
    results = analyzer.analyze(namespace="default")
    for result in results:
        print(f"{result.name}: {len(result.failures)} issues")
"""

# 核心基础
try:
    from .core import (
        Severity,
        Failure,
        AnalysisResult,
        BaseAnalyzer,
        ResourceCache,
        AnalyzerError,
        K8sConnectionError,
        ResourceNotFoundError,
        AnalysisFailedError,
        get_kubeconfig_path,
        verify_k8s_connection,
        K8S_AVAILABLE,
        PERF_CONFIG,
    )
    from .orchestrator import AnalyzerOrchestrator, analyze_cluster
    from .analyzers import (
        PodAnalyzer,
        DeploymentAnalyzer,
        ServiceAnalyzer,
        StatefulSetAnalyzer,
        JobAnalyzer,
        CronJobAnalyzer,
        ReplicaSetAnalyzer,
        HPAAnalyzer,
        PVCAnalyzer,
        IngressAnalyzer,
        GatewayAnalyzer,
        HTTPRouteAnalyzer,
        NetworkPolicyAnalyzer,
        NodeAnalyzer,
        EventAnalyzer,
        StorageAnalyzer,
        SecurityAnalyzer,
        WebhookAnalyzer,
        ConfigMapAnalyzer,
        SecretAnalyzer,
        PDBAnalyzer,
    )
except ImportError:
    # 直接运行时的回退导入
    from core import (
        Severity,
        Failure,
        AnalysisResult,
        BaseAnalyzer,
        ResourceCache,
        AnalyzerError,
        K8sConnectionError,
        ResourceNotFoundError,
        AnalysisFailedError,
        get_kubeconfig_path,
        verify_k8s_connection,
        K8S_AVAILABLE,
        PERF_CONFIG,
    )
    from orchestrator import AnalyzerOrchestrator, analyze_cluster
    from analyzers import (
        PodAnalyzer,
        DeploymentAnalyzer,
        ServiceAnalyzer,
        StatefulSetAnalyzer,
        JobAnalyzer,
        CronJobAnalyzer,
        ReplicaSetAnalyzer,
        HPAAnalyzer,
        PVCAnalyzer,
        IngressAnalyzer,
        GatewayAnalyzer,
        HTTPRouteAnalyzer,
        NetworkPolicyAnalyzer,
        NodeAnalyzer,
        EventAnalyzer,
        StorageAnalyzer,
        SecurityAnalyzer,
        WebhookAnalyzer,
        ConfigMapAnalyzer,
        SecretAnalyzer,
        PDBAnalyzer,
    )

__version__ = "1.0.0"
__all__ = [
    # 版本
    "__version__",
    
    # 核心基础
    "Severity",
    "Failure",
    "AnalysisResult",
    "BaseAnalyzer",
    "ResourceCache",
    "AnalyzerError",
    "K8sConnectionError",
    "ResourceNotFoundError",
    "AnalysisFailedError",
    "get_kubeconfig_path",
    "verify_k8s_connection",
    "K8S_AVAILABLE",
    "PERF_CONFIG",
    
    # 分析器编排
    "AnalyzerOrchestrator",
    "analyze_cluster",
    
    # 工作负载分析器
    "PodAnalyzer",
    "DeploymentAnalyzer",
    "ServiceAnalyzer",
    "StatefulSetAnalyzer",
    "JobAnalyzer",
    "CronJobAnalyzer",
    "ReplicaSetAnalyzer",
    "HPAAnalyzer",
    
    # 存储和网络分析器
    "PVCAnalyzer",
    "IngressAnalyzer",
    "GatewayAnalyzer",
    "HTTPRouteAnalyzer",
    "NetworkPolicyAnalyzer",
    
    # 集群分析器
    "NodeAnalyzer",
    "EventAnalyzer",
    "StorageAnalyzer",
    "SecurityAnalyzer",
    "WebhookAnalyzer",
    
    # 配置分析器
    "ConfigMapAnalyzer",
    "SecretAnalyzer",
    "PDBAnalyzer",
]


path: scripts/core/base.py
content: """
文件功能：K8sSkill核心基础模块
主要类/函数：
    - Severity - 问题严重程度枚举
    - Failure - 故障详情数据类
    - AnalysisResult - 分析结果数据类
    - AnalyzerError - 分析器错误基类
    - BaseAnalyzer - 分析器抽象基类
    - ResourceCache - 资源缓存管理器
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 抽象基类设计模式，统一分析器接口
IMPORTANT: 所有具体分析器必须继承BaseAnalyzer
NOTE: 使用模板方法模式定义分析流程
"""

from typing import List, Dict, Any, Optional, Callable
from dataclasses import dataclass, field
from enum import Enum
from abc import ABC, abstractmethod
import re
import os
import logging
import time
from datetime import datetime
from functools import wraps
from collections import OrderedDict

# 配置日志
logger = logging.getLogger(__name__)

# ============== 性能配置 ==============
PERF_CONFIG = {
    "page_size": 100,
    "cache_ttl": 300,
    "request_timeout": 30,
    "max_concurrent": 5,
    "retry_count": 3,
    "retry_delay": 1,
    "max_iterations": 1000,
    "max_items": 50000,
}

# 尝试导入kubernetes客户端
try:
    from kubernetes import client, config
    from kubernetes.client.exceptions import ApiException
    K8S_AVAILABLE = True
except ImportError:
    K8S_AVAILABLE = False
    logger.warning("kubernetes库未安装，分析功能不可用")


# ============== 自定义错误类型 ==============

class AnalyzerError(Exception):
    """
    分析器错误基类
    
    所有分析器相关错误的父类
    
    使用示例：
    >>> raise AnalyzerError("无法连接Kubernetes集群")
    """
    pass


class K8sConnectionError(AnalyzerError):
    """Kubernetes连接错误"""
    pass


class ResourceNotFoundError(AnalyzerError):
    """资源未找到错误"""
    pass


class AnalysisFailedError(AnalyzerError):
    """分析过程失败错误"""
    pass


# ============== 性能优化工具 ==============

class ResourceCache:
    """
    资源缓存管理器
    
    功能：
    - 缓存K8s资源查询结果
    - 自动过期清理
    - 内存占用控制
    
    使用示例：
    >>> cache = ResourceCache()
    >>> cache.set("pods:default", pod_list, ttl=300)
    >>> pods = cache.get("pods:default")
    
    LEARNING: 使用TTL缓存避免重复API调用
    IMPORTANT: 缓存时间不宜过长，K8s资源状态变化快
    """
    
    def __init__(self, max_size: int = 1000, default_ttl: int = None):
        """
        初始化缓存
        
        参数说明：
        - max_size: [int] 最大缓存条目数
        - default_ttl: [int] 默认过期时间(秒)
        """
        self._cache: OrderedDict = OrderedDict()
        self._max_size = max_size
        self._default_ttl = default_ttl or PERF_CONFIG["cache_ttl"]
    
    def get(self, key: str) -> Optional[Any]:
        """
        获取缓存值
        
        参数说明：
        - key: [str] 缓存键
        
        返回说明：
        - [Optional[Any]] 缓存值，过期或不存在返回None
        """
        if key not in self._cache:
            return None
        
        value, expire_time = self._cache[key]
        
        if time.time() > expire_time:
            del self._cache[key]
            return None
        
        self._cache.move_to_end(key)
        return value
    
    def set(self, key: str, value: Any, ttl: int = None):
        """
        设置缓存值
        
        参数说明：
        - key: [str] 缓存键
        - value: [Any] 缓存值
        - ttl: [int] 过期时间(秒)
        """
        if key in self._cache:
            self._cache.move_to_end(key)
        
        if len(self._cache) >= self._max_size:
            self._cleanup()
        
        expire_time = time.time() + (ttl or self._default_ttl)
        self._cache[key] = (value, expire_time)
    
    def _cleanup(self):
        """清理过期缓存和最久未使用的条目"""
        now = time.time()
        expired = [k for k, (_, exp) in self._cache.items() if now > exp]
        
        for key in expired:
            del self._cache[key]
        
        while len(self._cache) >= self._max_size:
            self._cache.popitem(last=False)
    
    def clear(self):
        """清空缓存"""
        self._cache.clear()


# 全局缓存实例
_global_cache = ResourceCache()


# ============== 工具函数 ==============

def get_kubeconfig_path() -> Optional[str]:
    """
    获取kubeconfig路径
    
    按优先级查找：
    1. KUBECONFIG环境变量
    2. 默认位置 ~/.kube/config
    3. 项目自带配置 config/k8s-Test-admin.conf
    
    返回说明：
    - [Optional[str]] kubeconfig路径，如果未找到返回None
    """
    # 1. 检查环境变量
    kubeconfig_env = os.environ.get('KUBECONFIG')
    if kubeconfig_env and os.path.exists(kubeconfig_env):
        return kubeconfig_env
    
    # 2. 检查默认位置
    home = os.path.expanduser('~')
    default_config = os.path.join(home, '.kube', 'config')
    if os.path.exists(default_config):
        return default_config
    
    # 3. 检查项目自带配置
    script_dir = os.path.dirname(os.path.abspath(__file__))
    project_config = os.path.join(os.path.dirname(os.path.dirname(script_dir)), 'config', 'k8s-Test-admin.conf')
    if os.path.exists(project_config):
        return project_config
    
    return None


def verify_k8s_connection() -> tuple:
    """
    验证Kubernetes连接是否正常
    
    功能：
    - 检查kubeconfig是否存在
    - 尝试连接集群
    - 返回友好的状态信息
    
    返回说明：
    - [tuple] (success: bool, message: str)
    
    使用示例：
    >>> success, msg = verify_k8s_connection()
    >>> print(msg)
    """
    if not K8S_AVAILABLE:
        return False, "[X] kubernetes库未安装，请运行: pip install kubernetes"
    
    kubeconfig_path = get_kubeconfig_path()
    if not kubeconfig_path:
        return False, "[X] 未找到kubeconfig文件\n   请检查以下位置:\n   1. KUBECONFIG环境变量\n   2. ~/.kube/config\n   3. skill/config/k8s-Test-admin.conf"
    
    try:
        config.load_kube_config(config_file=kubeconfig_path)
        v1 = client.CoreV1Api()
        v1.list_namespace(limit=1, _request_timeout=5)
        return True, f"[OK] 连接成功\n   kubeconfig: {kubeconfig_path}"
    except Exception as e:
        error_msg = str(e)
        if "Unauthorized" in error_msg or "401" in error_msg:
            return False, "[X] 认证失败：kubeconfig中的token或证书已过期"
        elif "Forbidden" in error_msg or "403" in error_msg:
            return False, "[X] 权限不足：当前用户缺少读取集群权限"
        elif "connection refused" in error_msg.lower():
            return False, "[X] 连接失败：无法连接到Kubernetes API Server"
        else:
            return False, f"[X] 连接失败: {e}"


# ============== 数据模型 ==============

class Severity(Enum):
    """
    问题严重程度分级
    
    对应业界标准的错误分类逻辑
    """
    CRITICAL = "critical"
    WARNING = "warning"
    INFO = "info"


@dataclass
class Failure:
    """
    故障详情数据类
    
    参数说明：
    - text: [str] 故障描述文本
    - severity: [Severity] 严重程度
    - reason: [str] 故障原因分类
    - suggestion: [str] 修复建议
    
    示例：
    >>> failure = Failure(
    ...     text="Container crashed with OOMKilled",
    ...     severity=Severity.CRITICAL,
    ...     reason="OOMKilled",
    ...     suggestion="增加内存限制"
    ... )
    """
    text: str
    severity: Severity = Severity.WARNING
    reason: str = ""
    suggestion: str = ""


@dataclass
class AnalysisResult:
    """
    分析结果数据类
    
    参数说明：
    - kind: [str] 资源类型 (Pod/Deployment/Service等)
    - name: [str] 资源名称
    - namespace: [str] 命名空间
    - failures: [List[Failure]] 发现的故障列表
    - details: [Dict[str, Any]] 额外详情信息
    - parent_object: [str] 父级资源（如Deployment拥有Pod）
    
    示例：
    >>> result = AnalysisResult(
    ...     kind="Pod",
    ...     name="api-server-xxx",
    ...     namespace="default",
    ...     failures=[failure1, failure2]
    ... )
    """
    kind: str
    name: str
    namespace: str
    failures: List[Failure] = field(default_factory=list)
    details: Dict[str, Any] = field(default_factory=dict)
    parent_object: str = ""
    
    @property
    def has_issues(self) -> bool:
        """检查是否存在问题"""
        return len(self.failures) > 0
    
    @property
    def critical_count(self) -> int:
        """统计Critical级别问题数量"""
        return sum(1 for f in self.failures if f.severity == Severity.CRITICAL)


# ============== 抽象基类 ==============

class BaseAnalyzer(ABC):
    """
    分析器抽象基类
    
    所有具体分析器的父类，定义统一接口和公共方法。
    使用模板方法模式，子类只需实现特定的抽象方法。
    
    使用示例：
    >>> class MyAnalyzer(BaseAnalyzer):
    ...     @property
    ...     def resource_kind(self) -> str:
    ...         return "MyResource"
    ...     
    ...     def _list_resources(self, namespace: str, label_selector: str):
    ...         # 实现资源列表获取
    ...         pass
    ...     
    ...     def _analyze_resource(self, resource) -> List[Failure]:
    ...         # 实现单个资源分析
    ...         pass
    
    LEARNING: 模板方法模式统一分析流程
    IMPORTANT: 子类必须实现所有抽象方法
    """
    
    def __init__(self, k8s_client=None, use_cache: bool = True):
        """
        初始化分析器
        
        参数说明：
        - k8s_client: [Optional[Any]] Kubernetes客户端实例
        - use_cache: [bool] 是否启用缓存，默认启用
        """
        self.client = k8s_client
        self._logger = logging.getLogger(f"{self.__class__.__module__}.{self.__class__.__name__}")
        self._use_cache = use_cache
        self._cache = _global_cache if use_cache else None
        self._timeout = PERF_CONFIG["request_timeout"]
        
        if self.client is None and K8S_AVAILABLE:
            self._init_k8s_client()
    
    def _init_k8s_client(self):
        """初始化Kubernetes客户端"""
        try:
            kubeconfig_path = get_kubeconfig_path()
            if kubeconfig_path:
                config.load_kube_config(config_file=kubeconfig_path)
                self.client = client
                self._logger.info(f"成功加载kubeconfig: {kubeconfig_path}")
            else:
                self._logger.warning("未找到kubeconfig文件")
                self.client = None
        except Exception as e:
            self._logger.error(f"加载kubeconfig失败: {e}")
            self.client = None
    
    @property
    @abstractmethod
    def resource_kind(self) -> str:
        """
        资源类型标识
        
        返回说明：
        - [str] 资源类型名称，如 "Pod", "Deployment" 等
        """
        pass
    
    @property
    def analyzer_name(self) -> str:
        """
        分析器名称
        
        返回说明：
        - [str] 分析器名称，默认使用类名小写
        """
        return self.__class__.__name__.lower().replace("analyzer", "")
    
    def analyze(self, namespace: str = "", label_selector: str = "") -> List[AnalysisResult]:
        """
        执行分析（模板方法）
        
        分析流程：
        1. 检查K8s客户端可用性
        2. 获取资源列表
        3. 逐个分析资源
        4. 返回分析结果
        
        参数说明：
        - namespace: [str] 目标命名空间，空字符串表示所有命名空间
        - label_selector: [str] 标签选择器，用于过滤资源
        
        返回说明：
        - [List[AnalysisResult]] 分析结果列表
        """
        if not K8S_AVAILABLE or self.client is None:
            self._logger.warning("Kubernetes客户端不可用，跳过分析")
            return []
        
        try:
            return self._do_analyze(namespace, label_selector)
        except Exception as e:
            self._logger.error(f"分析过程出错: {e}", exc_info=True)
            return []
    
    @abstractmethod
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """
        执行具体分析的抽象方法
        
        参数说明：
        - namespace: [str] 命名空间
        - label_selector: [str] 标签选择器
        
        返回说明：
        - [List[AnalysisResult]] 分析结果列表
        
        NOTE: 子类必须实现此方法
        """
        pass
    
    def _create_result(self, resource: Any, failures: List[Failure], **extra_details) -> AnalysisResult:
        """
        创建分析结果对象
        
        参数说明：
        - resource: [Any] K8s资源对象
        - failures: [List[Failure]] 故障列表
        - **extra_details: 额外详情信息
        
        返回说明：
        - [AnalysisResult] 分析结果对象
        """
        metadata = getattr(resource, 'metadata', None)
        return AnalysisResult(
            kind=self.resource_kind,
            name=getattr(metadata, 'name', 'unknown') if metadata else 'unknown',
            namespace=getattr(metadata, 'namespace', '') if metadata else '',
            failures=failures,
            details=extra_details
        )
    
    def _get_cached(self, key: str) -> Optional[Any]:
        """
        获取缓存数据
        
        参数说明：
        - key: [str] 缓存键
        
        返回说明：
        - [Optional[Any]] 缓存数据
        """
        if self._cache:
            return self._cache.get(key)
        return None
    
    def _set_cached(self, key: str, value: Any, ttl: int = None):
        """
        设置缓存数据
        
        参数说明：
        - key: [str] 缓存键
        - value: [Any] 缓存数据
        - ttl: [int] 过期时间(秒)
        """
        if self._cache:
            self._cache.set(key, value, ttl)
    
    def _list_resources_paginated(
        self,
        list_func: Callable,
        cache_key: str,
        namespace: str = "",
        label_selector: str = "",
        limit: int = None
    ) -> List[Any]:
        """
        分页获取资源列表
        
        参数说明：
        - list_func: [Callable] 列表获取函数
        - cache_key: [str] 缓存键前缀
        - namespace: [str] 命名空间
        - label_selector: [str] 标签选择器
        - limit: [int] 最大返回数量，None表示不限制
        
        返回说明：
        - [List[Any]] 资源列表
        
        LEARNING: 分页获取避免内存溢出
        IMPORTANT: 大集群必须使用分页
        """
        limit = limit or PERF_CONFIG["page_size"]
        full_cache_key = f"{cache_key}:{namespace}:{label_selector}"
        
        cached = self._get_cached(full_cache_key)
        if cached is not None:
            self._logger.debug(f"使用缓存数据: {full_cache_key}")
            return cached
        
        all_items = []
        continue_token = None
        total_count = 0
        iteration = 0
        max_iterations = PERF_CONFIG["max_iterations"]
        
        while iteration < max_iterations:
            iteration += 1
            try:
                if continue_token:
                    response = list_func(
                        limit=limit,
                        _continue=continue_token,
                        label_selector=label_selector if label_selector else None,
                        _request_timeout=self._timeout
                    )
                else:
                    response = list_func(
                        limit=limit,
                        label_selector=label_selector if label_selector else None,
                        _request_timeout=self._timeout
                    )
                
                items = response.items if hasattr(response, 'items') else response
                if not isinstance(items, list):
                    items = [items] if items else []
                
                all_items.extend(items)
                total_count += len(items)
                
                if total_count >= PERF_CONFIG["max_items"]:
                    self._logger.warning(f"资源数量达到上限 {PERF_CONFIG['max_items']}")
                    break
                
                continue_token = getattr(getattr(response, 'metadata', None), '_continue', None)
                
                if not continue_token:
                    break
                    
            except Exception as e:
                self._logger.error(f"分页获取资源失败: {e}", exc_info=True)
                break
        
        if iteration >= max_iterations:
            self._logger.warning(f"分页迭代达到上限 {max_iterations}")
        
        self._set_cached(full_cache_key, all_items)
        self._logger.info(f"获取 {total_count} 个资源: {cache_key}")
        
        return all_items


path: scripts/core/__init__.py
content: """
文件功能：K8sSkill核心模块包
主要类/函数：
    - Severity - 问题严重程度枚举
    - Failure - 故障详情数据类
    - AnalysisResult - 分析结果数据类
    - BaseAnalyzer - 分析器抽象基类
    - ResourceCache - 资源缓存管理器
    - 各类错误异常定义
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 使用包结构组织代码，提高可维护性
IMPORTANT: 核心模块提供所有分析器的基础能力
"""

from .base import (
    Severity,
    Failure,
    AnalysisResult,
    BaseAnalyzer,
    ResourceCache,
    AnalyzerError,
    K8sConnectionError,
    ResourceNotFoundError,
    AnalysisFailedError,
    get_kubeconfig_path,
    verify_k8s_connection,
    K8S_AVAILABLE,
    PERF_CONFIG,
)

__all__ = [
    "Severity",
    "Failure",
    "AnalysisResult",
    "BaseAnalyzer",
    "ResourceCache",
    "AnalyzerError",
    "K8sConnectionError",
    "ResourceNotFoundError",
    "AnalysisFailedError",
    "get_kubeconfig_path",
    "verify_k8s_connection",
    "K8S_AVAILABLE",
    "PERF_CONFIG",
]


path: scripts/analyzers/configmap.py
content: """
文件功能：ConfigMap分析器模块
主要类/函数：ConfigMapAnalyzer - 分析ConfigMap使用情况
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 检测未使用的ConfigMap
IMPORTANT: ConfigMap是配置管理，关注资源利用率
"""

from typing import List, Dict, Set
try:
    from ..core import BaseAnalyzer, AnalysisResult, Failure, Severity
except ImportError:
    from core import BaseAnalyzer, AnalysisResult, Failure, Severity


class ConfigMapAnalyzer(BaseAnalyzer):
    """
    ConfigMap分析器 - 基于SRE最佳实践设计
    
    检测能力：
    - 未被任何Pod使用的ConfigMap
    - 空的ConfigMap（无数据）
    
    使用示例：
    >>> analyzer = ConfigMapAnalyzer()
    >>> results = analyzer.analyze(namespace="production")
    """
    
    @property
    def resource_kind(self) -> str:
        return "ConfigMap"
    
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """执行ConfigMap分析"""
        results = []
        v1 = self.client.CoreV1Api()
        
        configmaps = self._list_resources_paginated(
            list_func=v1.list_config_map_for_all_namespaces,
            cache_key="configmaps",
            namespace=namespace,
            label_selector=label_selector
        )
        
        # 获取所有Pod以检查ConfigMap使用情况
        pods = self._list_resources_paginated(
            list_func=v1.list_pod_for_all_namespaces,
            cache_key="pods",
            namespace="",
            label_selector=""
        )
        
        used_configmaps = self._get_used_configmaps(pods)
        
        for cm in configmaps:
            if namespace and cm.metadata.namespace != namespace:
                continue
            
            # 跳过系统ConfigMap
            if cm.metadata.name.startswith("kube-") or cm.metadata.name.startswith("extension-"):
                continue
            
            failures = self._analyze_configmap(cm, used_configmaps)
            if failures:
                result = self._create_result(
                    cm,
                    failures,
                    data_keys=list(getattr(cm, 'data', {}).keys()) if getattr(cm, 'data', None) else []
                )
                results.append(result)
        
        self._logger.info(f"分析完成: {len(results)} 个ConfigMap发现问题")
        return results
    
    def _get_used_configmaps(self, pods) -> Set[str]:
        """获取被使用的ConfigMap集合"""
        used = set()
        
        for pod in pods.items if hasattr(pods, 'items') else pods:
            spec = pod.spec
            if not spec:
                continue
            
            # 检查Volume挂载
            for volume in getattr(spec, 'volumes', []) or []:
                if volume.config_map:
                    name = getattr(getattr(volume, 'config_map', None), 'name', None)
                    if name:
                        used.add(f"{pod.metadata.namespace}/{name}")
            
            # 检查环境变量引用
            for container in getattr(spec, 'containers', []) or []:
                for env_from in getattr(container, 'env_from', []) or []:
                    if env_from.config_map_ref:
                        name = getattr(getattr(env_from, 'config_map_ref', None), 'name', None)
                        if name:
                            used.add(f"{pod.metadata.namespace}/{name}")
                
                for env in getattr(container, 'env', []) or []:
                    if env.value_from and env.value_from.config_map_key_ref:
                        name = getattr(getattr(env.value_from, 'config_map_key_ref', None), 'name', None)
                        if name:
                            used.add(f"{pod.metadata.namespace}/{name}")
        
        return used
    
    def _analyze_configmap(self, cm, used_configmaps: Set[str]) -> List[Failure]:
        """分析单个ConfigMap"""
        failures = []
        
        cm_key = f"{cm.metadata.namespace}/{cm.metadata.name}"
        
        # 检查是否被使用
        if cm_key not in used_configmaps:
            failures.append(Failure(
                text="ConfigMap未被任何Pod使用",
                severity=Severity.INFO,
                reason="UnusedConfigMap",
                suggestion="1. 删除未使用的ConfigMap\n2. 或在Pod中引用此ConfigMap"
            ))
        
        # 检查是否为空
        data = getattr(cm, 'data', None)
        if not data:
            failures.append(Failure(
                text="ConfigMap为空（无数据）",
                severity=Severity.INFO,
                reason="EmptyConfigMap",
                suggestion="删除空的ConfigMap或添加配置数据"
            ))
        
        return failures


path: scripts/analyzers/cronjob.py
content: """
文件功能：CronJob分析器模块
主要类/函数：CronJobAnalyzer - 分析CronJob配置
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 检测Cron表达式格式、调度配置问题
IMPORTANT: CronJob依赖定时调度，关注时间配置
"""

import re
from typing import List
try:
    from ..core import BaseAnalyzer, AnalysisResult, Failure, Severity
except ImportError:
    from core import BaseAnalyzer, AnalysisResult, Failure, Severity


class CronJobAnalyzer(BaseAnalyzer):
    """
    CronJob分析器 - 基于SRE最佳实践设计
    
    检测能力：
    - CronJob被挂起
    - Cron表达式格式无效
    - 负数的startingDeadlineSeconds
    
    使用示例：
    >>> analyzer = CronJobAnalyzer()
    >>> results = analyzer.analyze(namespace="scheduled-tasks")
    """
    
    @property
    def resource_kind(self) -> str:
        return "CronJob"
    
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """执行CronJob分析"""
        results = []
        batch_v1 = self.client.BatchV1Api()
        
        cronjobs = self._list_resources_paginated(
            list_func=batch_v1.list_cron_job_for_all_namespaces,
            cache_key="cronjobs",
            namespace=namespace,
            label_selector=label_selector
        )
        
        for cronjob in cronjobs:
            if namespace and cronjob.metadata.namespace != namespace:
                continue
            
            failures = self._analyze_cronjob(cronjob)
            if failures:
                spec = cronjob.spec
                
                result = self._create_result(
                    cronjob,
                    failures,
                    schedule=getattr(spec, 'schedule', ''),
                    suspend=getattr(spec, 'suspend', False),
                    concurrency_policy=getattr(spec, 'concurrency_policy', '')
                )
                results.append(result)
        
        self._logger.info(f"分析完成: {len(results)} 个CronJob发现问题")
        return results
    
    def _analyze_cronjob(self, cronjob) -> List[Failure]:
        """分析单个CronJob"""
        failures = []
        spec = cronjob.spec
        
        if not spec:
            return failures
        
        # 检查是否被挂起
        if getattr(spec, 'suspend', False):
            failures.append(Failure(
                text="CronJob被挂起",
                severity=Severity.INFO,
                reason="CronJobSuspended",
                suggestion="CronJob当前处于挂起状态，不会按计划执行"
            ))
            return failures
        
        # 检查Cron表达式格式（简化检查）
        schedule = spec.schedule
        if schedule:
            # 基本的Cron格式验证：5-6个字段
            parts = schedule.split()
            if len(parts) < 5 or len(parts) > 6:
                failures.append(Failure(
                    text=f"CronJob的调度表达式格式无效: {schedule}",
                    severity=Severity.WARNING,
                    reason="InvalidCronSchedule",
                    suggestion="1. 检查Cron表达式格式\n2. 参考: https://en.wikipedia.org/wiki/Cron"
                ))
        
        # 检查startingDeadlineSeconds
        deadline = getattr(spec, 'starting_deadline_seconds', None)
        if deadline is not None and deadline < 0:
            failures.append(Failure(
                text="CronJob的startingDeadlineSeconds为负数",
                severity=Severity.WARNING,
                reason="NegativeDeadline",
                suggestion="startingDeadlineSeconds必须是非负数"
            ))
        
        return failures


path: scripts/analyzers/deployment.py
content: """
文件功能：Deployment分析器模块
主要类/函数：DeploymentAnalyzer - 分析Deployment状态
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 检测滚动更新状态、副本可用性
IMPORTANT: 关注ProgressDeadlineExceeded等关键条件
"""

from typing import List
try:
    from ..core import BaseAnalyzer, AnalysisResult, Failure, Severity
except ImportError:
    from core import BaseAnalyzer, AnalysisResult, Failure, Severity


class DeploymentAnalyzer(BaseAnalyzer):
    """
    Deployment分析器 - 基于SRE最佳实践设计
    
    检测能力：
    - 滚动更新状态
    - 副本可用性
    - 资源配额问题
    
    使用示例：
    >>> analyzer = DeploymentAnalyzer()
    >>> results = analyzer.analyze(namespace="production")
    """
    
    @property
    def resource_kind(self) -> str:
        return "Deployment"
    
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """执行Deployment分析"""
        results = []
        apps_v1 = self.client.AppsV1Api()
        
        deployments = self._list_resources_paginated(
            list_func=apps_v1.list_deployment_for_all_namespaces,
            cache_key="deployments",
            namespace=namespace,
            label_selector=label_selector
        )
        
        for deploy in deployments:
            if namespace and deploy.metadata.namespace != namespace:
                continue
            
            failures = self._analyze_deployment(deploy)
            if failures:
                spec = deploy.spec
                status = deploy.status
                
                result = self._create_result(
                    deploy,
                    failures,
                    replicas=getattr(spec, 'replicas', 0) if spec else 0,
                    available_replicas=getattr(status, 'available_replicas', 0) if status else 0,
                    updated_replicas=getattr(status, 'updated_replicas', 0) if status else 0,
                    strategy=getattr(getattr(spec, 'strategy', None), 'type', 'Unknown') if spec else 'Unknown'
                )
                results.append(result)
        
        self._logger.info(f"分析完成: {len(results)} 个Deployment发现问题")
        return results
    
    def _analyze_deployment(self, deploy) -> List[Failure]:
        """分析单个Deployment"""
        failures = []
        spec = deploy.spec
        status = deploy.status
        
        if not spec or not status:
            return failures
        
        desired = getattr(spec, 'replicas', 0) or 0
        available = getattr(status, 'available_replicas', 0) or 0
        updated = getattr(status, 'updated_replicas', 0) or 0
        
        # 检查可用副本不足
        if available < desired:
            failures.append(Failure(
                text=f"可用副本不足: {available}/{desired}",
                severity=Severity.CRITICAL if available == 0 else Severity.WARNING,
                reason="UnavailableReplicas",
                suggestion="1. 检查Pod状态和事件\n2. 查看资源配额\n3. 检查节点资源"
            ))
        
        # 检查滚动更新进度
        strategy = getattr(getattr(spec, 'strategy', None), 'type', None)
        if updated < desired and strategy == "RollingUpdate":
            failures.append(Failure(
                text=f"滚动更新进行中: {updated}/{desired} 已更新",
                severity=Severity.INFO,
                reason="RollingUpdateInProgress",
                suggestion="等待更新完成或检查新Pod启动失败原因"
            ))
        
        # 检查条件
        if status.conditions:
            for condition in status.conditions:
                if condition.type == "Progressing" and condition.status == "False":
                    failures.append(Failure(
                        text=f"部署进度停滞: {condition.message or 'Unknown'}",
                        severity=Severity.WARNING,
                        reason="ProgressDeadlineExceeded",
                        suggestion="检查新ReplicaSet的Pod创建失败原因"
                    ))
        
        return failures


path: scripts/analyzers/event.py
content: """
文件功能：Event分析器模块
主要类/函数：EventAnalyzer - 分析集群事件
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 检测警告事件、异常事件模式
IMPORTANT: 事件是排查问题的重要线索
"""

from typing import List
from datetime import datetime, timedelta
try:
    from ..core import BaseAnalyzer, AnalysisResult, Failure, Severity
except ImportError:
    from core import BaseAnalyzer, AnalysisResult, Failure, Severity


class EventAnalyzer(BaseAnalyzer):
    """
    事件分析器 - 分析集群中的警告和异常事件
    
    检测能力：
    - 最近的警告事件
    - 重复发生的事件
    - 异常事件模式
    
    使用示例：
    >>> analyzer = EventAnalyzer()
    >>> results = analyzer.analyze(namespace="production", hours=1)
    """
    
    # 需要关注的警告事件类型
    WARNING_REASONS = {
        "Failed", "FailedScheduling", "FailedMount", "FailedCreatePodSandBox",
        "Unhealthy", "Killing", "BackOff", "FailedBinding"
    }
    
    @property
    def resource_kind(self) -> str:
        return "Event"
    
    def analyze(self, namespace: str = "", label_selector: str = "", hours: int = 1) -> List[AnalysisResult]:
        """
        分析事件（扩展参数hours）
        
        参数说明：
        - hours: [int] 分析最近几小时的事件，默认1小时
        """
        self._hours = hours
        return super().analyze(namespace, label_selector)
    
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """执行Event分析"""
        results = []
        v1 = self.client.CoreV1Api()
        
        # 计算时间范围
        hours = getattr(self, '_hours', 1)
        since_time = datetime.utcnow() - timedelta(hours=hours)
        since_time_str = since_time.strftime("%Y-%m-%dT%H:%M:%SZ")
        
        try:
            if namespace:
                events = v1.list_namespaced_event(
                    namespace=namespace,
                    field_selector=f"type=Warning,lastTimestamp>={since_time_str}"
                )
            else:
                events = v1.list_event_for_all_namespaces(
                    field_selector=f"type=Warning,lastTimestamp>={since_time_str}"
                )
            
            # 按涉及对象分组
            event_groups = {}
            for event in events.items:
                involved = event.involved_object
                key = f"{involved.kind}/{involved.namespace}/{involved.name}"
                
                if key not in event_groups:
                    event_groups[key] = {
                        "kind": involved.kind,
                        "name": involved.name,
                        "namespace": involved.namespace,
                        "events": []
                    }
                event_groups[key]["events"].append(event)
            
            # 分析每个对象的事件
            for key, group in event_groups.items():
                failures = self._analyze_events(group["events"])
                if failures:
                    result = AnalysisResult(
                        kind=group["kind"],
                        name=group["name"],
                        namespace=group["namespace"],
                        failures=failures,
                        details={"event_count": len(group["events"])}
                    )
                    results.append(result)
        
        except Exception as e:
            self._logger.error(f"分析事件时出错: {e}", exc_info=True)
        
        self._logger.info(f"分析完成: {len(results)} 个对象有警告事件")
        return results
    
    def _analyze_events(self, events: List) -> List[Failure]:
        """分析事件列表"""
        failures = []
        
        # 统计事件原因
        reason_counts = {}
        for event in events:
            reason = event.reason
            reason_counts[reason] = reason_counts.get(reason, 0) + 1
            
            # 关注特定原因
            if reason in self.WARNING_REASONS:
                if reason_counts[reason] == 1:  # 只记录一次
                    severity = Severity.CRITICAL if reason in ["Failed", "FailedScheduling"] else Severity.WARNING
                    failures.append(Failure(
                        text=f"{reason}: {event.message}",
                        severity=severity,
                        reason=reason,
                        suggestion=f"查看相关资源状态和日志，共发生 {reason_counts[reason]} 次"
                    ))
        
        return failures


path: scripts/analyzers/gateway.py
content: """
文件功能：Gateway分析器模块
主要类/函数：GatewayAnalyzer - 分析Gateway API Gateway资源
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 检测GatewayClass引用、Gateway接受状态
IMPORTANT: Gateway API是Ingress的下一代替代方案
NOTE: 需要集群支持Gateway API（CRD已安装）
"""

from typing import List, Dict, Set
from kubernetes.client.exceptions import ApiException
try:
    from ..core import BaseAnalyzer, AnalysisResult, Failure, Severity
except ImportError:
    from core import BaseAnalyzer, AnalysisResult, Failure, Severity


class GatewayAnalyzer(BaseAnalyzer):
    """
    Gateway分析器（Gateway API）- 基于SRE最佳实践设计
    
    检测能力：
    - Gateway引用的GatewayClass不存在
    - Gateway状态未接受（Accepted=False）
    
    使用示例：
    >>> analyzer = GatewayAnalyzer()
    >>> results = analyzer.analyze(namespace="production")
    
    NOTE: 需要集群支持Gateway API（CRD已安装）
    """
    
    @property
    def resource_kind(self) -> str:
        return "Gateway"
    
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """执行Gateway分析"""
        results = []
        custom_api = self.client.CustomObjectsApi()
        
        try:
            # 获取Gateway列表
            if namespace:
                gateway_list = custom_api.list_namespaced_custom_object(
                    group="gateway.networking.k8s.io",
                    version="v1",
                    namespace=namespace,
                    plural="gateways",
                    label_selector=label_selector
                )
            else:
                gateway_list = custom_api.list_cluster_custom_object(
                    group="gateway.networking.k8s.io",
                    version="v1",
                    plural="gateways",
                    label_selector=label_selector
                )
            
            # 获取GatewayClass列表
            try:
                gatewayclass_list = custom_api.list_cluster_custom_object(
                    group="gateway.networking.k8s.io",
                    version="v1",
                    plural="gatewayclasses"
                )
                gatewayclass_names = {gc["metadata"]["name"] for gc in gatewayclass_list.get("items", [])}
            except ApiException:
                gatewayclass_names = set()
            
            # 分析每个Gateway
            for gateway in gateway_list.get("items", []):
                failures = self._analyze_gateway(gateway, gatewayclass_names)
                if failures:
                    metadata = gateway.get("metadata", {})
                    spec = gateway.get("spec", {})
                    
                    result = AnalysisResult(
                        kind="Gateway",
                        name=metadata.get("name", "unknown"),
                        namespace=metadata.get("namespace", ""),
                        failures=failures,
                        details={
                            "gateway_class_name": spec.get("gatewayClassName", ""),
                            "listeners_count": len(spec.get("listeners", []))
                        }
                    )
                    results.append(result)
        
        except ApiException as e:
            if e.status == 404:
                # Gateway API未安装，返回空结果
                self._logger.info("Gateway API未安装，跳过分析")
            else:
                self._logger.error(f"分析Gateway时出错: {e}")
        
        return results
    
    def _analyze_gateway(self, gateway: Dict, gatewayclass_names: Set[str]) -> List[Failure]:
        """分析单个Gateway"""
        failures = []
        
        spec = gateway.get("spec", {})
        status = gateway.get("status", {})
        
        # 检查GatewayClass是否存在
        gateway_class_name = spec.get("gatewayClassName", "")
        if gateway_class_name and gateway_class_name not in gatewayclass_names:
            failures.append(Failure(
                text=f"Gateway使用的GatewayClass '{gateway_class_name}' 不存在",
                severity=Severity.CRITICAL,
                reason="GatewayClassNotFound",
                suggestion="1. 创建GatewayClass\n2. 或更新Gateway的gatewayClassName"
            ))
        
        # 检查Gateway状态
        conditions = status.get("conditions", [])
        accepted_found = False
        
        for condition in conditions:
            if condition.get("type") == "Accepted":
                accepted_found = True
                if condition.get("status") != "True":
                    failures.append(Failure(
                        text=f"Gateway未被接受: {condition.get('message', 'Unknown')}",
                        severity=Severity.CRITICAL,
                        reason="GatewayNotAccepted",
                        suggestion="1. 检查GatewayClass配置\n2. 查看控制器日志"
                    ))
                break
        
        if not accepted_found:
            failures.append(Failure(
                text="Gateway没有Accepted状态条件",
                severity=Severity.WARNING,
                reason="NoAcceptedCondition",
                suggestion="等待Gateway控制器处理"
            ))
        
        return failures


path: scripts/analyzers/hpa.py
content: """
文件功能：HPA分析器模块
主要类/函数：HPAAnalyzer - 分析HorizontalPodAutoscaler状态
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 检测HPA缩放限制、目标引用问题
IMPORTANT: HPA依赖metrics-server，关注指标可用性
"""

from typing import List
from kubernetes.client.exceptions import ApiException
try:
    from ..core import BaseAnalyzer, AnalysisResult, Failure, Severity
except ImportError:
    from core import BaseAnalyzer, AnalysisResult, Failure, Severity


class HPAAnalyzer(BaseAnalyzer):
    """
    HPA分析器 - 基于SRE最佳实践设计
    
    检测能力：
    - ScalingLimited条件为True
    - 其他条件为False
    - ScaleTargetRef指向的资源不存在
    - 目标资源未配置资源限制
    
    使用示例：
    >>> analyzer = HPAAnalyzer()
    >>> results = analyzer.analyze(namespace="production")
    """
    
    @property
    def resource_kind(self) -> str:
        return "HorizontalPodAutoscaler"
    
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """执行HPA分析"""
        results = []
        autoscaling_v2 = self.client.AutoscalingV2Api()
        apps_v1 = self.client.AppsV1Api()
        
        hpas = self._list_resources_paginated(
            list_func=autoscaling_v2.list_horizontal_pod_autoscaler_for_all_namespaces,
            cache_key="hpas",
            namespace=namespace,
            label_selector=label_selector
        )
        
        for hpa in hpas:
            if namespace and hpa.metadata.namespace != namespace:
                continue
            
            failures = self._analyze_hpa(hpa, apps_v1)
            if failures:
                spec = hpa.spec
                status = hpa.status
                
                result = self._create_result(
                    hpa,
                    failures,
                    min_replicas=getattr(spec, 'min_replicas', None),
                    max_replicas=getattr(spec, 'max_replicas', 0),
                    current_replicas=getattr(status, 'current_replicas', 0) if status else 0,
                    desired_replicas=getattr(status, 'desired_replicas', 0) if status else 0
                )
                results.append(result)
        
        self._logger.info(f"分析完成: {len(results)} 个HPA发现问题")
        return results
    
    def _analyze_hpa(self, hpa, apps_v1) -> List[Failure]:
        """分析单个HPA"""
        failures = []
        spec = hpa.spec
        status = hpa.status
        
        if not spec or not spec.scale_target_ref:
            return failures
        
        target_ref = spec.scale_target_ref
        
        # 检查目标资源是否存在
        if target_ref.kind == "Deployment":
            try:
                apps_v1.read_namespaced_deployment(
                    name=target_ref.name,
                    namespace=hpa.metadata.namespace
                )
            except ApiException as e:
                if e.status == 404:
                    failures.append(Failure(
                        text=f"HPA引用的Deployment '{target_ref.name}' 不存在",
                        severity=Severity.CRITICAL,
                        reason="TargetNotFound",
                        suggestion=f"1. 创建Deployment '{target_ref.name}'\n2. 或更正HPA的scaleTargetRef"
                    ))
        
        # 检查HPA条件
        if status and status.conditions:
            for condition in status.conditions:
                if condition.type == "ScalingLimited" and condition.status == "True":
                    failures.append(Failure(
                        text=f"HPA缩放受限: {condition.message}",
                        severity=Severity.WARNING,
                        reason="ScalingLimited",
                        suggestion="1. 检查minReplicas/maxReplicas设置\n2. 验证metrics-server是否运行\n3. 检查资源限制配置"
                    ))
                elif condition.type in ["AbleToScale", "ScalingActive"] and condition.status == "False":
                    failures.append(Failure(
                        text=f"HPA条件异常 {condition.type}: {condition.message}",
                        severity=Severity.WARNING,
                        reason=condition.type,
                        suggestion="检查HPA配置和metrics-server状态"
                    ))
        
        return failures


path: scripts/analyzers/httproute.py
content: """
文件功能：HTTPRoute分析器模块
主要类/函数：HTTPRouteAnalyzer - 分析Gateway API HTTPRoute资源
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 检测HTTPRoute Gateway引用、后端Service问题
IMPORTANT: HTTPRoute是Gateway API的路由资源
NOTE: 需要集群支持Gateway API（CRD已安装）
"""

from typing import List, Dict
from kubernetes.client.exceptions import ApiException
try:
    from ..core import BaseAnalyzer, AnalysisResult, Failure, Severity
except ImportError:
    from core import BaseAnalyzer, AnalysisResult, Failure, Severity


class HTTPRouteAnalyzer(BaseAnalyzer):
    """
    HTTPRoute分析器（Gateway API）- 基于SRE最佳实践设计
    
    检测能力：
    - HTTPRoute引用的Gateway不存在
    - HTTPRoute与Gateway不在允许的命名空间
    - 后端Service不存在
    
    使用示例：
    >>> analyzer = HTTPRouteAnalyzer()
    >>> results = analyzer.analyze(namespace="production")
    
    NOTE: 需要集群支持Gateway API（CRD已安装）
    """
    
    @property
    def resource_kind(self) -> str:
        return "HTTPRoute"
    
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """执行HTTPRoute分析"""
        results = []
        custom_api = self.client.CustomObjectsApi()
        core_v1 = self.client.CoreV1Api()
        
        try:
            # 获取HTTPRoute列表
            if namespace:
                route_list = custom_api.list_namespaced_custom_object(
                    group="gateway.networking.k8s.io",
                    version="v1",
                    namespace=namespace,
                    plural="httproutes",
                    label_selector=label_selector
                )
            else:
                route_list = custom_api.list_cluster_custom_object(
                    group="gateway.networking.k8s.io",
                    version="v1",
                    plural="httproutes",
                    label_selector=label_selector
                )
            
            # 获取所有Gateway
            try:
                gateway_list = custom_api.list_cluster_custom_object(
                    group="gateway.networking.k8s.io",
                    version="v1",
                    plural="gateways"
                )
                gateways = {
                    f"{g['metadata'].get('namespace', '')}/{g['metadata'].get('name', '')}": g
                    for g in gateway_list.get("items", [])
                }
            except ApiException:
                gateways = {}
            
            # 分析每个HTTPRoute
            for route in route_list.get("items", []):
                failures = self._analyze_httproute(route, gateways, core_v1)
                if failures:
                    metadata = route.get("metadata", {})
                    spec = route.get("spec", {})
                    
                    parent_refs = spec.get("parentRefs", [])
                    gateway_names = [ref.get("name", "") for ref in parent_refs]
                    
                    result = AnalysisResult(
                        kind="HTTPRoute",
                        name=metadata.get("name", "unknown"),
                        namespace=metadata.get("namespace", ""),
                        failures=failures,
                        details={
                            "parent_gateways": gateway_names,
                            "hostnames": spec.get("hostnames", [])
                        }
                    )
                    results.append(result)
        
        except ApiException as e:
            if e.status == 404:
                # Gateway API未安装，返回空结果
                self._logger.info("Gateway API未安装，跳过分析")
            else:
                self._logger.error(f"分析HTTPRoute时出错: {e}")
        
        return results
    
    def _analyze_httproute(self, route: Dict, gateways: Dict, core_v1) -> List[Failure]:
        """分析单个HTTPRoute"""
        failures = []
        
        metadata = route.get("metadata", {})
        spec = route.get("spec", {})
        route_namespace = metadata.get("namespace", "")
        
        # 检查ParentRefs（Gateway引用）
        parent_refs = spec.get("parentRefs", [])
        for ref in parent_refs:
            gateway_name = ref.get("name", "")
            gateway_namespace = ref.get("namespace", route_namespace)
            gateway_key = f"{gateway_namespace}/{gateway_name}"
            
            if gateway_key not in gateways:
                failures.append(Failure(
                    text=f"HTTPRoute引用的Gateway '{gateway_name}'（命名空间: {gateway_namespace}）不存在",
                    severity=Severity.CRITICAL,
                    reason="GatewayNotFound",
                    suggestion="1. 创建Gateway\n2. 或更正parentRefs中的gateway名称"
                ))
        
        # 检查后端Service
        rules = spec.get("rules", [])
        for rule in rules:
            backend_refs = rule.get("backendRefs", [])
            for backend in backend_refs:
                if backend.get("kind") == "Service":
                    service_name = backend.get("name", "")
                    service_namespace = backend.get("namespace", route_namespace)
                    
                    try:
                        core_v1.read_namespaced_service(
                            name=service_name,
                            namespace=service_namespace
                        )
                    except ApiException as e:
                        if e.status == 404:
                            failures.append(Failure(
                                text=f"HTTPRoute引用的Service '{service_name}'（命名空间: {service_namespace}）不存在",
                                severity=Severity.CRITICAL,
                                reason="ServiceNotFound",
                                suggestion="1. 创建Service\n2. 或更正backendRefs中的service名称"
                            ))
        
        return failures


path: scripts/analyzers/ingress.py
content: """
文件功能：Ingress分析器模块
主要类/函数：IngressAnalyzer - 分析Ingress配置
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 检测IngressClass、后端Service、TLS证书问题
IMPORTANT: Ingress是入口流量管理，关注配置完整性
"""

from typing import List
from kubernetes.client.exceptions import ApiException
try:
    from ..core import BaseAnalyzer, AnalysisResult, Failure, Severity
except ImportError:
    from core import BaseAnalyzer, AnalysisResult, Failure, Severity


class IngressAnalyzer(BaseAnalyzer):
    """
    Ingress分析器 - 基于SRE最佳实践设计
    
    检测能力：
    - IngressClass未指定或不存在
    - 后端Service不存在
    - TLS证书Secret不存在
    
    使用示例：
    >>> analyzer = IngressAnalyzer()
    >>> results = analyzer.analyze(namespace="production")
    """
    
    @property
    def resource_kind(self) -> str:
        return "Ingress"
    
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """执行Ingress分析"""
        results = []
        networking_v1 = self.client.NetworkingV1Api()
        
        ingresses = self._list_resources_paginated(
            list_func=networking_v1.list_ingress_for_all_namespaces,
            cache_key="ingresses",
            namespace=namespace,
            label_selector=label_selector
        )
        
        for ingress in ingresses:
            if namespace and ingress.metadata.namespace != namespace:
                continue
            
            failures = self._analyze_ingress(ingress)
            if failures:
                spec = ingress.spec
                
                result = self._create_result(
                    ingress,
                    failures,
                    class_name=getattr(spec, 'ingress_class_name', None) if spec else None,
                    rules_count=len(getattr(spec, 'rules', []) or []) if spec else 0,
                    tls_count=len(getattr(spec, 'tls', []) or []) if spec else 0
                )
                results.append(result)
        
        self._logger.info(f"分析完成: {len(results)} 个Ingress发现问题")
        return results
    
    def _analyze_ingress(self, ingress) -> List[Failure]:
        """分析单个Ingress"""
        failures = []
        spec = ingress.spec
        metadata = ingress.metadata
        
        if not spec:
            return failures
        
        networking_v1 = self.client.NetworkingV1Api()
        core_v1 = self.client.CoreV1Api()
        
        # 检查IngressClass
        ingress_class_name = spec.ingress_class_name
        
        # 从注解获取（旧方式）
        if not ingress_class_name and metadata.annotations:
            ingress_class_name = metadata.annotations.get("kubernetes.io/ingress.class")
        
        if not ingress_class_name:
            failures.append(Failure(
                text="Ingress未指定IngressClass",
                severity=Severity.WARNING,
                reason="NoIngressClass",
                suggestion="1. 设置spec.ingressClassName\n2. 或添加注解kubernetes.io/ingress.class"
            ))
        else:
            # 检查IngressClass是否存在
            try:
                networking_v1.read_ingress_class(ingress_class_name)
            except ApiException as e:
                if e.status == 404:
                    failures.append(Failure(
                        text=f"Ingress使用的IngressClass '{ingress_class_name}' 不存在",
                        severity=Severity.CRITICAL,
                        reason="IngressClassNotFound",
                        suggestion=f"1. 创建IngressClass '{ingress_class_name}'\n2. 或更正为存在的IngressClass"
                    ))
        
        # 检查后端Service
        if spec.rules:
            for rule in spec.rules:
                http = getattr(rule, 'http', None)
                if http and http.paths:
                    for path in http.paths:
                        backend = getattr(path, 'backend', None)
                        service = getattr(backend, 'service', None)
                        if service and service.name:
                            try:
                                core_v1.read_namespaced_service(
                                    name=service.name,
                                    namespace=metadata.namespace
                                )
                            except ApiException as e:
                                if e.status == 404:
                                    failures.append(Failure(
                                        text=f"Ingress引用的Service '{service.name}' 不存在",
                                        severity=Severity.CRITICAL,
                                        reason="ServiceNotFound",
                                        suggestion=f"1. 创建Service '{service.name}'\n2. 或更正Ingress中的service名称"
                                    ))
        
        # 检查TLS Secret
        if spec.tls:
            for tls in spec.tls:
                if tls.secret_name:
                    try:
                        core_v1.read_namespaced_secret(
                            name=tls.secret_name,
                            namespace=metadata.namespace
                        )
                    except ApiException as e:
                        if e.status == 404:
                            failures.append(Failure(
                                text=f"Ingress使用的TLS证书Secret '{tls.secret_name}' 不存在",
                                severity=Severity.WARNING,
                                reason="TLSSecretNotFound",
                                suggestion=f"1. 创建Secret '{tls.secret_name}'\n2. 或使用cert-manager自动管理"
                            ))
        
        return failures


path: scripts/analyzers/job.py
content: """
文件功能：Job分析器模块
主要类/函数：JobAnalyzer - 分析Job执行状态
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 检测Job挂起、失败状态
IMPORTANT: Job是一次性任务，关注完成状态
"""

from typing import List
try:
    from ..core import BaseAnalyzer, AnalysisResult, Failure, Severity
except ImportError:
    from core import BaseAnalyzer, AnalysisResult, Failure, Severity


class JobAnalyzer(BaseAnalyzer):
    """
    Job分析器 - 基于SRE最佳实践设计
    
    检测能力：
    - Job被挂起（Suspended）
    - Job执行失败（Failed > 0）
    - 超时未完成
    
    使用示例：
    >>> analyzer = JobAnalyzer()
    >>> results = analyzer.analyze(namespace="batch-jobs")
    """
    
    @property
    def resource_kind(self) -> str:
        return "Job"
    
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """执行Job分析"""
        results = []
        batch_v1 = self.client.BatchV1Api()
        
        jobs = self._list_resources_paginated(
            list_func=batch_v1.list_job_for_all_namespaces,
            cache_key="jobs",
            namespace=namespace,
            label_selector=label_selector
        )
        
        for job in jobs:
            if namespace and job.metadata.namespace != namespace:
                continue
            
            failures = self._analyze_job(job)
            if failures:
                spec = job.spec
                status = job.status
                
                result = self._create_result(
                    job,
                    failures,
                    completions=getattr(spec, 'completions', None),
                    parallelism=getattr(spec, 'parallelism', None),
                    active=getattr(status, 'active', 0) or 0,
                    succeeded=getattr(status, 'succeeded', 0) or 0,
                    failed=getattr(status, 'failed', 0) or 0
                )
                results.append(result)
        
        self._logger.info(f"分析完成: {len(results)} 个Job发现问题")
        return results
    
    def _analyze_job(self, job) -> List[Failure]:
        """分析单个Job"""
        failures = []
        spec = job.spec
        status = job.status
        
        if not spec:
            return failures
        
        # 检查是否被挂起
        if getattr(spec, 'suspend', False):
            failures.append(Failure(
                text="Job被挂起",
                severity=Severity.INFO,
                reason="JobSuspended",
                suggestion="Job当前处于挂起状态，不会执行"
            ))
        
        # 检查失败次数
        failed_count = getattr(status, 'failed', 0) or 0
        if failed_count > 0:
            failures.append(Failure(
                text=f"Job执行失败，失败次数: {failed_count}",
                severity=Severity.CRITICAL,
                reason="JobFailed",
                suggestion=f"1. 查看Job日志: kubectl logs job/{job.metadata.name}\n2. 检查Job配置"
            ))
        
        return failures


path: scripts/analyzers/networkpolicy.py
content: """
文件功能：NetworkPolicy分析器模块
主要类/函数：NetworkPolicyAnalyzer - 分析网络策略配置
作者：chenzc
创建时间：2026-04-03
最后修改：2026-04-03

LEARNING: 检测NetworkPolicy选择器问题、过度宽松策略
IMPORTANT: NetworkPolicy控制Pod间网络流量，关注安全性
"""

from typing import List
try:
    from ..core import BaseAnalyzer, AnalysisResult, Failure, Severity
except ImportError:
    from core import BaseAnalyzer, AnalysisResult, Failure, Severity


class NetworkPolicyAnalyzer(BaseAnalyzer):
    """
    NetworkPolicy分析器 - 基于SRE最佳实践设计
    
    检测能力：
    - NetworkPolicy允许所有Pod的流量（空selector）
    - NetworkPolicy未应用到任何Pod
    
    使用示例：
    >>> analyzer = NetworkPolicyAnalyzer()
    >>> results = analyzer.analyze(namespace="production")
    """
    
    @property
    def resource_kind(self) -> str:
        return "NetworkPolicy"
    
    def _do_analyze(self, namespace: str, label_selector: str) -> List[AnalysisResult]:
        """执行NetworkPolicy分析"""
        results = []
        networking_v1 = self.client.NetworkingV1Api()
        core_v1 = self.client.CoreV1Api()
        
        policies = self._list_resources_paginated(
            list_func=networking_v1.list_network_policy_for_all_namespaces,
            cache_key="networkpolicies",
            namespace=namespace,
            label_selector=label_selector
        )
        
        for policy in policies:
            if namespace and policy.metadata.namespace != namespace:
                continue
            
            failures = self._analyze_networkpolicy(policy, core_v1)
            if failures:
                spec = policy.spec
                
                result = self._create_result(
                    policy,
                    failures,
                    pod_selector=getattr(getattr(spec, 'pod_selector', None), 'match_labels', {}) if spec else {},
                    policy_types=getattr(spec, 'policy_types', []) if spec else []
                )
                results.append(result)
        
        self._logger.info(f"分析完成: {len(results)} 个NetworkPolicy发现问题")
        return results
    
    def _analyze_networkpolicy(self, policy, core_v1) -> List[Failure]:
        """分析单个NetworkPolicy"""
        failures = []
        spec = policy.spec
        
        if not spec:
            return failures
        
        pod_selector = getattr(spec, 'pod_selector', None)
        match_labels = getattr(pod_selector, 'match_labels', None) if pod_selector else None
        
        # 检查是否允许所有Pod的流量（空selector）
        if not match_labels:
            failures.append(Failure(
                text=f"NetworkPolicy '{policy.metadata.name}' 允许所有Pod的流量（未指定podSelector）",
                severity=Severity.WARNING,
                reason="AllowAllPods",
                suggestion="1. 指定podSelector以限制策略范围\n2. 考虑使用更具体的标签选择器"
            ))
        else:
            # 检查是否应用到任何Pod
            try:
                label_selector = ",".join([f"{k}={v}" for k, v in match_labels.items()])
                pod_list = core_v1.list_namespaced_pod(
                    namespace=policy.metadata.namespace,
                    label_selector=label_selector
                )
                
                if not pod_list.items:
                    failures.append(Failure(
                        text=f"NetworkPolicy '{policy.metadata.name}' 未应用到任何Pod",
                        severity=Severity.INFO,
                        reason="NoMatchingPods",
                        suggestion="1. 检查podSelector标签\n2. 确保有Pod匹配该标签"
                    ))
            except Exception:
                pass
        
        return failures


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)