# 機能設計書 123-CSIマイグレーション

## 概要

本ドキュメントは、CSIマイグレーション機能の設計を記述する。CSIマイグレーションは、Kubernetesのin-treeストレージプラグイン（AWS EBS、GCE PD、Azure Disk/File、Cinder、vSphere、Portworx）を対応するCSIドライバーに透過的に移行する機能である。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesのコアコードベースからストレージプラグインの実装を分離し、メンテナンス性とリリースサイクルの独立性を向上させる。ユーザーは既存のin-tree Volume定義を変更することなく、CSIドライバー経由でストレージを利用できる。

**機能の利用シーン**：kubelet/kube-controller-managerがin-treeプラグインを参照するボリュームスペックを処理する際に、自動的にCSIドライバーへの変換を行う。ユーザーの操作は不要（透過的移行）。

**主要な処理内容**：
1. PluginManager: in-treeプラグイン名からCSIドライバー名へのマッピング管理
2. IsMigrationEnabledForPlugin: プラグインごとのマイグレーション有効化状態判定
3. IsMigrationCompleteForPlugin: プラグインごとのマイグレーション完了状態判定
4. IsMigratable: ボリュームスペックがマイグレーション対象か判定
5. TranslateInTreeSpecToCSI: in-treeスペックからCSIスペックへの変換

**関連システム・外部連携**：csi-translation-lib（スペック変換ライブラリ）、各CSIドライバー（ebs-csi-driver、pd-csi-driver等）。

**権限による制御**：フィーチャーゲートで制御される。各プラグインの移行はGA済みでデフォルト有効。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CSIマイグレーションはCLI画面を持たない内部処理 |

## 機能種別

ストレージマイグレーション / 互換性レイヤー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| spec | *volume.Spec | Yes | ボリュームスペック（PVまたはインラインボリューム） | nilチェック |
| pluginName | string | Yes | in-treeプラグイン名 | マイグレーション対象プラグインとの照合 |
| podNamespace | string | Conditional | Pod名前空間（インラインボリューム変換時） | インラインボリューム時は必須 |

### 入力データソース

- ボリュームスペック（PersistentVolume.Spec / Volume.VolumeSource）
- csi-translation-lib のプラグイン名定数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| マイグレーション可否 | bool | IsMigratable判定結果 |
| CSI PV | *v1.PersistentVolume | 変換されたCSI PVスペック |
| マイグレーション済みSpec | *volume.Spec | Migrated=trueフラグ付きスペック |

## 処理フロー

### 処理シーケンス

```
1. PluginManager.IsMigratable(spec)
   ├─ GetInTreePluginNameFromSpec(pv, vol)  [プラグイン名特定]
   └─ IsMigrationEnabledForPlugin(pluginName)  [マイグレーション有効化確認]
2. TranslateInTreeSpecToCSI(spec, podNamespace, translator)
   ├─ [PV] translator.TranslateInTreePVToCSI(pv)
   └─ [Inline] translator.TranslateInTreeInlineVolumeToCSI(vol, namespace)
3. 結果: Migrated=true, CSI PVスペック
```

### フローチャート

```mermaid
flowchart TD
    A[ボリュームスペック受信] --> B[GetInTreePluginNameFromSpec]
    B --> C{プラグイン名取得成功?}
    C -->|No| D[非マイグレーション対象]
    C -->|Yes| E[IsMigrationEnabledForPlugin]
    E --> F{マイグレーション有効?}
    F -->|No| G[in-treeプラグインで処理]
    F -->|Yes| H[TranslateInTreeSpecToCSI]
    H --> I{PV or Inline?}
    I -->|PV| J[TranslateInTreePVToCSI]
    I -->|Inline| K[TranslateInTreeInlineVolumeToCSI]
    J --> L[CSI Specを返却 Migrated=true]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-123-1 | GA済みプラグイン | AWS EBS、GCE PD、Azure File/Disk、Cinder、vSphere、Portworxはデフォルトで移行有効 | 常時 |
| BR-123-2 | マイグレーション完了判定 | IsMigrationEnabledForPluginがtrueの場合のみ完了判定可能 | IsMigrationCompleteForPlugin呼び出し時 |
| BR-123-3 | スペック変換のフラグ設定 | 変換後のSpecにMigrated=trueを設定 | TranslateInTreeSpecToCSI時 |
| BR-123-4 | インラインボリューム識別 | InlineVolumeSpecForCSIMigration=trueを設定 | インラインボリューム変換時 |
| BR-123-5 | ReadOnly保持 | 変換後もReadOnlyフラグを保持する | 全変換時 |

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

本機能はデータベースを直接操作しない。KubernetesリソースはCSI変換後のスペックで通常通り操作される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | nilスペック | specがnil | "volume spec is nil"エラーを返却 |
| - | 変換エラー | in-tree → CSI変換失敗 | "failed to translate in-tree pv to CSI"エラーを返却 |
| - | 無効スペック | PVもVolumeもnilのスペック | "not a valid volume spec"エラーを返却 |

### リトライ仕様

本機能自体にリトライ機構はない。呼び出し元のvolume managerの再試行に依存する。

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

本機能は純粋な変換処理であり、トランザクションの概念は存在しない。

## パフォーマンス要件

スペック変換は純粋なメモリ内処理であり、外部I/Oを伴わないため、パフォーマンスへの影響は無視できる程度。

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

- マイグレーション後のCSIドライバーは元のin-treeプラグインと同等のセキュリティポリシーを継承する
- フィーチャーゲートによる制御は既にGA済みのため、無効化は推奨されない

## 備考

- csi-translation-libは別リポジトリ（k8s.io/csi-translation-lib）で管理されている
- in-treeプラグインの完全な削除はKubernetes本体から段階的に行われる

---

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

### 推奨読解順序

#### Step 1: PluginManager構造体の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | plugin_manager.go | `pkg/volume/csimigration/plugin_manager.go` | PluginNameMapperインターフェース（31-34行目）: プラグイン名解決の抽象 |
| 1-2 | plugin_manager.go | `pkg/volume/csimigration/plugin_manager.go` | PluginManager構造体（37-39行目）: PluginNameMapperを埋め込み |
| 1-3 | plugin_manager.go | `pkg/volume/csimigration/plugin_manager.go` | NewPluginManager()（42-46行目）: コンストラクタ |

#### Step 2: マイグレーション判定ロジック

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | plugin_manager.go | `pkg/volume/csimigration/plugin_manager.go` | IsMigrationEnabledForPlugin()（81-103行目）: プラグイン別の有効化判定（全て`return true`） |
| 2-2 | plugin_manager.go | `pkg/volume/csimigration/plugin_manager.go` | IsMigrationCompleteForPlugin()（52-77行目）: 完了判定（IsMigrationEnabled確認後、全て`return true`） |
| 2-3 | plugin_manager.go | `pkg/volume/csimigration/plugin_manager.go` | IsMigratable()（107-118行目）: specからプラグイン名を取得し判定 |

**読解のコツ**: 現在はAWS EBS、GCE PD、Azure File/Disk、Cinder、vSphere、PortworxがGA済みのため、IsMigrationEnabledForPluginもIsMigrationCompleteForPluginもこれらに対してはすべてtrueを返す。switch文のcase句が対応プラグインの一覧を示している。

#### Step 3: スペック変換ロジック

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | plugin_manager.go | `pkg/volume/csimigration/plugin_manager.go` | InTreeToCSITranslatorインターフェース（122-125行目）: 変換の抽象 |
| 3-2 | plugin_manager.go | `pkg/volume/csimigration/plugin_manager.go` | TranslateInTreeSpecToCSI()（129-150行目）: PV/インラインの分岐変換 |

**主要処理フロー**:
- **133-137行目**: PVの場合はTranslateInTreePVToCSI、Volumeの場合はTranslateInTreeInlineVolumeToCSIを呼び出し
- **144-149行目**: 変換結果にMigrated=true、ReadOnly保持、インラインフラグを設定

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

```
kubelet volume manager / kube-controller-manager
    |
    ├─ PluginManager.IsMigratable(spec)
    |      ├─ GetInTreePluginNameFromSpec(pv, vol)
    |      └─ IsMigrationEnabledForPlugin(pluginName)
    |             └─ switch pluginName (GA済みプラグイン判定)
    |
    ├─ PluginManager.IsMigrationCompleteForPlugin(pluginName)
    |      └─ IsMigrationEnabledForPlugin(pluginName)
    |
    └─ TranslateInTreeSpecToCSI(spec, namespace, translator)
           ├─ [PV] translator.TranslateInTreePVToCSI(pv)
           └─ [Inline] translator.TranslateInTreeInlineVolumeToCSI(vol, ns)
```

### データフロー図

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

in-tree Volume Spec ──────▶ IsMigratable() ─────────▶ bool (マイグレーション可否)
                                 |
                                 ▼
                          TranslateInTreeSpecToCSI()
                                 |
                                 ├──▶ volume.Spec{Migrated: true}
                                 └──▶ CSI PersistentVolume
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| plugin_manager.go | `pkg/volume/csimigration/plugin_manager.go` | ソース | マイグレーション判定・管理 |
| plugins/ | `k8s.io/csi-translation-lib/plugins/` | 外部依存 | 各in-treeプラグインのCSI変換実装 |
| csi_plugin.go | `pkg/volume/csi/csi_plugin.go` | ソース | CSIプラグイン（マイグレーション先） |
