# 通知設計書 63-ExternalExpanding

## 概要

本ドキュメントは、Kubernetesにおける外部拡張器（External Resizer）によるボリューム拡張が開始・実行される際に発行される「ExternalExpanding」イベントの設計を記述する。

### 本通知の処理概要

PVCのリサイズ要求に対して、内蔵のボリュームプラグインではなく外部のCSIドライバやリサイザが処理を担当する場合に、その待機状態をユーザーに通知する。CSIマイグレーション対応のボリュームや、外部プラグインが必要なボリュームに対して発行される。

**業務上の目的・背景**：PVCのリサイズ（Spec.Resources.Requestsの変更）が要求された際、ボリュームの種類によってはKubernetes内蔵のプラグインでは処理できず、外部のCSIドライバがリサイズを実行する必要がある。この場合、ユーザーにはリサイズが「進行中」に見えるが、実際にはKubernetesは外部コントローラの処理を待機している。この通知はその状態をユーザーに正確に伝える。

**通知の送信タイミング**：ExpandController（expand_controller.go）がPVCのリサイズを処理する際、CSIマイグレーション対象のボリューム、または内蔵の拡張可能プラグインが見つからないボリュームに対して発行される。

**通知の受信者**：PVCオブジェクトに対するKubernetes Eventとして記録され、kubectl describe pvc等で確認可能。クラスタ管理者およびストレージ管理者が対象。

**通知内容の概要**：CSIマイグレーション時は「CSI migration enabled for {plugin}; waiting for external resizer to expand the pvc」、外部プラグイン待ち時は「waiting for an external controller to expand this PVC」のメッセージがPVCに対して記録される。エラー発生時はWarningイベントとなる。

**期待されるアクション**：正常時はユーザーの対応は不要（外部リサイザが自動処理）。エラー時はCSIドライバの状態確認、リサイザコントローラのログ確認が必要。

## 通知種別

Kubernetes Event（EventType: Normal または Warning）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ExpandControllerの処理ループ内で発行） |
| 優先度 | 中（Normal時は情報通知、Warning時は注意喚起） |
| リトライ | なし（コントローラの再キュー処理に依存） |

### 送信先決定ロジック

PVCオブジェクトに対するEventとして記録される。recorder.Event()のターゲットとしてpvc（PVC）が指定される。

## 通知テンプレート

### メール通知の場合

本通知はKubernetes Eventとして発行されるため、メール送信は行わない。

### 本文テンプレート

```
# CSIマイグレーション - 正常時
CSI migration enabled for {inTreePluginName}; waiting for external resizer to expand the pvc

# CSIマイグレーション - CSIドライバ名取得エラー時
error getting CSI driver name for pvc {key}, with error {error}

# CSIマイグレーション - リサイザアノテーション設定エラー時
error setting resizer annotation to pvc {key}, with error {error}

# 外部プラグイン待ち
waiting for an external controller to expand this PVC
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| inTreePluginName | in-treeプラグイン名 | csiMigratedPluginManager.GetInTreePluginNameFromSpec | Yes（CSIマイグレーション時） |
| key | PVCのNamespace/Name | PVCのメタデータ | Yes（エラー時） |
| error | エラー詳細 | エラーオブジェクト | Yes（エラー時） |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コントローラ同期 | ExpandControllerによるPVCリサイズ処理 | CSIマイグレーション対象ボリューム | CSIマイグレーション有効時 |
| コントローラ同期 | ExpandControllerによるPVCリサイズ処理 | 内蔵拡張プラグインが見つからない | 外部コントローラ待ち |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 内蔵プラグインで処理可能 | FindExpandablePluginBySpecが有効なプラグインを返す場合 |
| リサイズ不要 | pvcRequestSize <= pvcStatusSizeかつPreResizeCapacityアノテーションなし |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ExpandController同期ループ] --> B[syncHandler - PVCリサイズ処理]
    B --> C[PV取得・バインド確認]
    C --> D{リサイズ必要?}
    D -->|No| E[終了]
    D -->|Yes| F{CSIマイグレーション対象?}
    F -->|Yes| G[ExternalExpanding Normal イベント発行]
    G --> H{CSIドライバ名取得成功?}
    H -->|No| I[ExternalExpanding Warning イベント発行]
    H -->|Yes| J{リサイザアノテーション設定成功?}
    J -->|No| K[ExternalExpanding Warning イベント発行]
    J -->|Yes| L[終了]
    F -->|No| M[FindExpandablePluginBySpec]
    M --> N{プラグイン見つかった?}
    N -->|No| O[ExternalExpanding イベント発行]
    N -->|Yes| P[内蔵プラグインで拡張実行]
    O --> Q[終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| PersistentVolumeClaim | リサイズ要求の確認 | spec.resources.requests |
| PersistentVolume | バインド状態の確認 | spec.claimRef |
| VolumeSpec | プラグイン情報の取得 | NewSpecFromPersistentVolume |

### テーブル別参照項目詳細

#### PersistentVolumeClaim

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| spec.resources.requests[storage] | リクエストサイズ | リサイズ要求の確認 |
| status.capacity[storage] | 現在のサイズ | リサイズ必要性の判定 |

#### PersistentVolume

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| spec.claimRef | PVCとのバインド確認 | Namespace/UID一致 |
| metadata.annotations | PreResizeCapacityアノテーション | リサイズ状態の管理 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| Event | INSERT | Kubernetes Eventオブジェクトの作成 |
| PersistentVolumeClaim | UPDATE | リサイザアノテーションの設定（CSIマイグレーション時） |

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | reason | ExternalExpanding | イベント理由 |
| INSERT | message | 状況に応じた動的メッセージ | 上記テンプレート参照 |
| INSERT | type | Normal / Warning | 状況に応じて変化 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| CSIドライバ名取得失敗 | GetCSINameFromInTreeNameがエラーを返す | Warningイベント発行しエラーを返す |
| リサイザアノテーション設定失敗 | SetClaimResizerがエラーを返す | Warningイベント発行しエラーを返す |
| in-treeプラグイン名取得失敗 | GetInTreePluginNameFromSpecがエラーを返す | エラーを返す |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | ExpandControllerのワークキューによる自動再キュー |
| リトライ間隔 | エクスポネンシャルバックオフ |
| リトライ対象エラー | CSIドライバ名取得エラー、アノテーション設定エラー |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | Kubernetes Eventのデフォルトレート制限に従う |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（コントローラの動作タイミングに依存）

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

通知メッセージにプラグイン名やPVC名が含まれるが、機密情報ではない。エラーメッセージにはエラー詳細が含まれる場合があるが、Kubernetesの標準的な動作範囲内。

## 備考

- CSIマイグレーション機能により、in-treeボリュームプラグインがCSIドライバに置き換えられる過渡期に頻繁に発行される可能性がある
- 外部プラグイン待ちの場合、PVCはワークキューに再キューされない（外部コントローラの処理を待つため）
- RecoverVolumeExpansionFailure機能ゲートが有効な場合、拡張失敗からの回復処理も行われる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.go | `pkg/controller/volume/events/event.go` | ExternalExpanding定数の定義（行34） |

**読解のコツ**: ExternalExpandingはNormalとWarning両方で使用される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | expand_controller.go | `pkg/controller/volume/expand/expand_controller.go` | syncHandlerメソッドがPVCリサイズの起点 |

**主要処理フロー**:
1. **行229-237**: リサイズ必要性の判定（pvcRequestSize vs pvcStatusSize）
2. **行240-243**: CSIマイグレーション対象かの判定
3. **行246-268**: CSIマイグレーション処理とイベント発行
4. **行271-283**: 内蔵プラグイン検索と外部プラグイン待ちイベント発行

#### Step 3: CSIマイグレーション処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | expand_controller.go | `pkg/controller/volume/expand/expand_controller.go` | 行246-268のCSIマイグレーション分岐 |

**主要処理フロー**:
- **行253-254**: 正常時のNormalイベント発行
- **行256-259**: CSIドライバ名取得失敗時のWarningイベント発行
- **行262-266**: リサイザアノテーション設定失敗時のWarningイベント発行

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

```
expandController.syncHandler
    |
    +-- PV取得・バインド確認
    |
    +-- リサイズ必要性判定
    |
    +-- csiMigratedPluginManager.IsMigratable
    |      |
    |      +-- [migratable] GetInTreePluginNameFromSpec
    |      |      +-- recorder.Event (Normal: ExternalExpanding)
    |      |      +-- translator.GetCSINameFromInTreeName
    |      |      +-- util.SetClaimResizer
    |      |
    |      +-- [!migratable] volumePluginMgr.FindExpandablePluginBySpec
    |             +-- recorder.Event (Normal/Warning: ExternalExpanding)
    |
    +-- expand (内蔵プラグインで拡張)
```

### データフロー図

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

PVC (リサイズ要求)  ───> ExpandController                  ───> Kubernetes Event
PV (バインド済み)   ───> CSIマイグレーション判定            (ExternalExpanding)
VolumeSpec         ───> プラグイン検索                      + リサイザアノテーション
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/controller/volume/events/event.go` | ソース | イベント理由定数の定義 |
| expand_controller.go | `pkg/controller/volume/expand/expand_controller.go` | ソース | ExpandController本体 |
