# 機能設計書 27-ClusterRoleAggregationコントローラー

## 概要

本ドキュメントは、KubernetesのClusterRoleAggregationコントローラーの機能設計を記述する。AggregationRuleに基づいてClusterRoleのルールを自動集約する。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesでは複数のClusterRoleのルールを1つのClusterRoleに集約する仕組みが必要である。例えば、admin ClusterRoleは各種リソース操作のルールを個別のClusterRoleから自動的に収集する。これにより、新しいCRDが追加された際にadmin等の集約ロールが自動的に更新される。

**機能の利用シーン**：CRD追加時に、対応するClusterRoleを作成しラベルを付与すると、admin/edit/view等の集約ClusterRoleに自動的にルールが反映される。

**主要な処理内容**：
1. ClusterRoleリソースの変更（作成・更新・削除）を監視する
2. AggregationRuleを持つ全ClusterRoleをキューに投入する（全件再評価）
3. AggregationRule.ClusterRoleSelectorsに基づきマッチするClusterRoleのルールを収集する
4. ルールに変更がある場合、Server-Side Apply（SSA）でClusterRoleを更新する
5. SSA未対応の場合はUpdateにフォールバックする

**関連システム・外部連携**：API Server（ClusterRoleの取得・更新・Apply）

**権限による制御**：system:controller:clusterrole-aggregation-controllerサービスアカウントで動作し、ClusterRoleの読み取り・更新権限を持つ。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本コントローラーに直接関連する画面はない |

## 機能種別

データ集約 / 自動構成（バックグラウンド自動処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| workers | int | Yes | 同時実行ワーカー数 | 正の整数 |

### 入力データソース

- ClusterRole Informer: ClusterRoleのadd/update/deleteイベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ClusterRole.Rules | []rbacv1.PolicyRule | 集約されたルール一覧 |

### 出力先

- API Server: ClusterRoleの更新（SSAまたはUpdate）

## 処理フロー

### 処理シーケンス

```
1. 任意のClusterRoleが変更された場合、AggregationRuleを持つ全ClusterRoleをキューに投入
   └─ enqueue()で全ClusterRoleをリストし、AggregationRule != nilのもののみ投入
2. syncClusterRole()で集約処理を実行する
   └─ ClusterRole取得 → AggregationRule確認 → セレクタでマッチングClusterRole検索
3. マッチしたClusterRoleのルールを名前順にソートして収集する
   └─ 自己参照を除外、重複ルールを排除
4. ルールに変更がある場合のみ更新する
   └─ applyClusterRoles(SSA) → 失敗時 updateClusterRoles(Update)にフォールバック
```

### フローチャート

```mermaid
flowchart TD
    A[ClusterRole変更イベント] --> B[enqueue: AggregationRule持ち全件投入]
    B --> C[syncClusterRole]
    C --> D{AggregationRule あり?}
    D -->|No| E[スキップ]
    D -->|Yes| F[セレクタでClusterRole検索]
    F --> G[名前順ソート]
    G --> H[ルール収集 自己参照除外 重複排除]
    H --> I{ルール変更あり?}
    I -->|No| J[スキップ]
    I -->|Yes| K[applyClusterRoles SSA]
    K --> L{UnsupportedMediaType?}
    L -->|Yes| M[updateClusterRoles fallback]
    L -->|No| N[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-27-01 | 全件再評価 | 任意のClusterRole変更時に、AggregationRuleを持つ全ClusterRoleを再評価する | enqueue時 |
| BR-27-02 | 名前順ソート | マッチしたClusterRoleを名前のアルファベット順にソートしてルール収集する | syncClusterRole内 |
| BR-27-03 | 自己参照除外 | AggregationRule自身のClusterRoleのルールは収集しない | syncClusterRole内 |
| BR-27-04 | 重複排除 | 既に収集済みの同一ルールは追加しない（DeepEqual比較） | syncClusterRole内 |
| BR-27-05 | SSA優先 | Server-Side Applyを優先し、UnsupportedMediaType時にUpdateにフォールバック | applyClusterRoles/updateClusterRoles |
| BR-27-06 | fieldManager | SSA時のfieldManagerは "clusterrole-aggregation-controller"、Force=true | applyClusterRoles |

### 計算ロジック

特段の数値計算なし。ルール集約はセレクタマッチング、ソート、重複排除のロジック。

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ClusterRole一覧 | ClusterRole（etcd） | SELECT（List） | セレクタによるClusterRole検索 |
| ClusterRole更新 | ClusterRole（etcd） | UPDATE（Apply/Update） | 集約ルールの更新 |

### テーブル別操作詳細

#### ClusterRole（etcd経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| APPLY | rules | 集約されたPolicyRule一覧 | SSA: fieldManager=clusterrole-aggregation-controller |
| UPDATE | rules | 集約されたPolicyRule一覧 | フォールバック: DeepCopy後に更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NotFound | API応答 | ClusterRoleが削除済み | 正常終了 |
| UnsupportedMediaType | API応答 | SSA未サポート | updateClusterRolesにフォールバック |
| LabelSelector変換失敗 | 内部 | 不正なセレクタ定義 | エラー返却しリトライ |

### リトライ仕様

- syncHandler失敗時: RateLimitingキューでリトライ
- 成功時: queue.Forget()でバックオフリセット

## トランザクション仕様

SSA(Server-Side Apply)はFieldManagerの管理するフィールドのみを更新する。Force=trueにより競合時も強制適用。Updateフォールバック時はResourceVersionによる楽観的並行性制御。

## パフォーマンス要件

- ClusterRoleの総数は一般的に少ないため（数十～数百）、全件再評価のコストは低い
- 各ClusterRole変更で全AggregationRule付きClusterRoleを再評価するため、頻繁な変更時にはキュー長が増加する可能性がある

## セキュリティ考慮事項

- ClusterRoleのRulesフィールドを更新するため、権限エスカレーションの可能性がある
- AggregationRuleのセレクタが意図しないClusterRoleにマッチしないよう注意が必要
- SSAのForce=trueにより、他のFieldManagerの変更を上書きする可能性がある

## 備考

- admin、edit、viewのClusterRoleはAggregationRuleを使用して自動集約される
- CRD追加時に適切なラベル付きClusterRoleを作成することで、admin/edit/viewロールが自動更新される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | clusterroleaggregation_controller.go | `pkg/controller/clusterroleaggregation/clusterroleaggregation_controller.go` | ClusterRoleAggregationController構造体（46-53行目）。clusterRoleClient、clusterRoleLister、syncHandler、queueを保持 |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | clusterroleaggregation_controller.go | `pkg/controller/clusterroleaggregation/clusterroleaggregation_controller.go` | NewClusterRoleAggregation（56-83行目）。全イベントでenqueue()を呼ぶシンプルなハンドラ登録 |
| 2-2 | clusterroleaggregation_controller.go | `pkg/controller/clusterroleaggregation/clusterroleaggregation_controller.go` | Run（190-213行目）。キャッシュ同期後workers個のワーカー起動 |

**主要処理フロー**:
1. **71-81行目**: Add/Update/Deleteの全てでenqueue()を呼び出し
2. **203-211行目**: workers個のrunWorker goroutine起動

#### Step 3: キュー投入ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | clusterroleaggregation_controller.go | `pkg/controller/clusterroleaggregation/clusterroleaggregation_controller.go` | enqueue（239-260行目）。全ClusterRoleをリストし、AggregationRule != nilのもののみキューに投入 |

#### Step 4: 集約処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | clusterroleaggregation_controller.go | `pkg/controller/clusterroleaggregation/clusterroleaggregation_controller.go` | syncClusterRole（85-141行目）。セレクタマッチング（102-126行目）、ルール変更チェック（128-130行目）、SSA適用（132行目） |
| 4-2 | clusterroleaggregation_controller.go | `pkg/controller/clusterroleaggregation/clusterroleaggregation_controller.go` | applyClusterRoles（143-150行目）。SSAでfieldManager=clusterrole-aggregation-controller、Force=true |
| 4-3 | clusterroleaggregation_controller.go | `pkg/controller/clusterroleaggregation/clusterroleaggregation_controller.go` | updateClusterRoles（152-160行目）。DeepCopy後にUpdate（フォールバック） |

### プログラム呼び出し階層図

```
ClusterRoleAggregationController.Run()
    │
    └─ runWorker()
           └─ processNextWorkItem()
                  └─ syncClusterRole()
                         ├─ clusterRoleLister.Get() ── ClusterRole取得
                         ├─ AggregationRule確認
                         ├─ clusterRoleLister.List(selector) ── マッチングClusterRole検索
                         ├─ sort.Sort(byName) ── 名前順ソート
                         ├─ ruleExists() ── 重複排除
                         ├─ applyClusterRoles() ── SSA更新
                         └─ updateClusterRoles() ── フォールバックUpdate
```

### データフロー図

```
[入力]                          [処理]                              [出力]

ClusterRoleイベント ────▶ enqueue()
(Informer)                 │ AggregationRule持ち全件
                          ▼
                    syncClusterRole()
                          │
                          ├─ セレクタマッチング ──▶ ルール収集
                          │   (名前順ソート、重複排除)
                          │
                          └─▶ API Server Apply/Update ──▶ ClusterRole
                              (集約ルール設定)                Rules更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| clusterroleaggregation_controller.go | `pkg/controller/clusterroleaggregation/clusterroleaggregation_controller.go` | ソース | ClusterRole集約コントローラーの全ロジック |
