# =============================================================================
# Kubernetes Event Exporter - Phase O-2.2
# =============================================================================
# 建立者: Claude Code (首席架構師)
# 日期: 2026-04-02 (台北時間)
# 用途: 將 K8s Event 轉為結構化 Log 送往 SigNoz，保留 30 天
# 解決: K8s Event 預設僅保留 ~1 小時的致命盲區
# =============================================================================
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: event-exporter
  namespace: observability
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: event-exporter
rules:
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["get", "watch", "list"]
  - apiGroups: [""]
    resources: ["namespaces"]
    verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: event-exporter
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: event-exporter
subjects:
  - kind: ServiceAccount
    name: event-exporter
    namespace: observability
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: event-exporter-config
  namespace: observability
data:
  config.yaml: |
    # Phase O-2.2: K8s Event → SigNoz (OTLP HTTP)
    logLevel: info
    logFormat: json
    route:
      routes:
        # Warning 和 Error 事件: 全量保留 (RCA 關鍵資料)
        - match:
            - receiver: signoz-warning
          drop:
            - type: "Normal"
              reason: "Scheduled"
            - type: "Normal"
              reason: "Pulling"
            - type: "Normal"
              reason: "Pulled"
            - type: "Normal"
              reason: "Created"
            - type: "Normal"
              reason: "Started"
        # Normal 事件中的關鍵類型: 選擇性保留
        - match:
            - receiver: signoz-normal
          drop:
            - type: "Warning"
    receivers:
      - name: signoz-warning
        webhook:
          endpoint: http://192.168.0.188:24318/v1/logs
          headers:
            Content-Type: application/json
          layout:
            severity: "{{ .Type }}"
            body: "{{ .Message }}"
            attributes:
              k8s.event.reason: "{{ .Reason }}"
              k8s.event.type: "{{ .Type }}"
              k8s.event.action: "{{ .Action }}"
              k8s.event.count: "{{ .Count }}"
              k8s.namespace.name: "{{ .InvolvedObject.Namespace }}"
              k8s.object.kind: "{{ .InvolvedObject.Kind }}"
              k8s.object.name: "{{ .InvolvedObject.Name }}"
              k8s.event.source.component: "{{ .Source.Component }}"
              k8s.event.source.host: "{{ .Source.Host }}"
              k8s.event.first_timestamp: "{{ .FirstTimestamp }}"
              k8s.event.last_timestamp: "{{ .LastTimestamp }}"
      - name: signoz-normal
        webhook:
          endpoint: http://192.168.0.188:24318/v1/logs
          headers:
            Content-Type: application/json
          layout:
            severity: "Normal"
            body: "{{ .Message }}"
            attributes:
              k8s.event.reason: "{{ .Reason }}"
              k8s.event.type: "{{ .Type }}"
              k8s.namespace.name: "{{ .InvolvedObject.Namespace }}"
              k8s.object.kind: "{{ .InvolvedObject.Kind }}"
              k8s.object.name: "{{ .InvolvedObject.Name }}"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: event-exporter
  namespace: observability
  labels:
    app.kubernetes.io/name: event-exporter
    phase: o-2
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: event-exporter
  template:
    metadata:
      labels:
        app.kubernetes.io/name: event-exporter
    spec:
      serviceAccountName: event-exporter
      # PSA restricted 合規
      securityContext:
        runAsNonRoot: true
        runAsUser: 65534
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: event-exporter
          image: ghcr.io/resmoio/kubernetes-event-exporter:v1.7
          args:
            - -conf=/etc/event-exporter/config.yaml
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop: ["ALL"]
          resources:
            requests:
              cpu: 20m
              memory: 32Mi
            limits:
              cpu: 100m
              memory: 64Mi
          volumeMounts:
            - name: config
              mountPath: /etc/event-exporter
              readOnly: true
      volumes:
        - name: config
          configMap:
            name: event-exporter-config
