# 通知設計書 48-SuccessfulAttachVolume

## 概要

本ドキュメントは、Kubernetesにおけるボリュームのアタッチ成功時に発行されるイベント通知「SuccessfulAttachVolume」の設計を記述する。ボリュームがノードに正常にアタッチされた際に、Normalイベントとして記録される。

### 本通知の処理概要

本通知は、ボリュームのアタッチ操作（AttachVolume.Attach）が成功した際に発行されるKubernetesイベントである。クラウドプロバイダーのストレージサービスやCSIドライバーを通じてボリュームがノードにアタッチされ、デバイスパスが確定した時点で発行される。

**業務上の目的・背景**：ボリュームのアタッチはPodの起動における重要なステップであり、その成功をユーザーに通知することでデバッグや運用監視を支援する。特にアタッチに時間がかかる場合や、失敗後のリトライで成功した場合に有用な情報となる。

**通知の送信タイミング**：GenerateAttachVolumeFuncで生成されたattachVolumeFunc内で、volumeAttacher.Attach()が成功し、actualStateOfWorldにMarkVolumeAsAttachedが完了した後に発行される。

**通知の受信者**：ボリュームをスケジュールされた全てのPodオブジェクトに対してイベントが記録される。volumeToAttach.ScheduledPodsに含まれる各Podにイベントが発行される。

**通知内容の概要**：「AttachVolume.Attach succeeded for volume ... (UniqueName: ...) ...」という成功メッセージが含まれる。

**期待されるアクション**：特別なアクションは不要。アタッチ成功の確認として利用する。後続のマウント処理の進捗を確認する。

## 通知種別

Kubernetesイベント（Event API リソース）- EventType: Normal

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（EventRecorder経由） |
| 優先度 | 中（Normal） |
| リトライ | EventRecorderの内部リトライ機構に依存 |

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

volumeToAttach.ScheduledPodsに含まれる全てのPodオブジェクトに対してイベントが記録される。ループにより各Podに個別にイベントが発行される（304-306行目）。

## 通知テンプレート

### メール通知の場合

該当なし（Kubernetesネイティブイベント）

### 本文テンプレート

```
"AttachVolume.Attach succeeded for volume %q (UniqueName: %q) ..."
```

GenerateMsg関数により生成される。第2引数は空文字列。

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| ボリューム名 | VolumeSpecの名前 | volumeToAttach.VolumeSpec | Yes |
| ユニーク名 | ボリュームの一意識別子 | volumeToAttach.VolumeName | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部処理 | AttachVolume操作 | Attach成功かつMarkVolumeAsAttached成功 | operation_generator.go 302-306行目 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| Attach失敗 | FailedAttachVolumeが発行される |
| MarkVolumeAsAttached失敗 | エラーが返却される（イベント発行なし） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[GenerateAttachVolumeFunc] --> B[attachVolumeFunc実行]
    B --> C[FindAttachablePluginBySpec]
    C --> D[NewAttacher]
    D --> E[Attach実行]
    E -->|失敗| F[FailedAttachVolume]
    E -->|成功| G[MarkVolumeAsAttached]
    G -->|失敗| H[エラー返却]
    G -->|成功| I[ScheduledPods ループ]
    I --> J[SuccessfulAttachVolume イベント発行（各Pod）]
    J --> K[終了]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| VolumeToAttach | アタッチ対象情報 | VolumeSpec, NodeName, ScheduledPods |

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

#### VolumeToAttach

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| VolumeSpec | ボリューム仕様 | 対象ボリューム |
| NodeName | アタッチ先ノード | 対象ボリューム |
| ScheduledPods | イベント発行対象Pod一覧 | 対象ボリューム |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| ActualStateOfWorld | UPDATE | MarkVolumeAsAttached |
| Event | INSERT | SuccessfulAttachVolumeイベント作成（Pod数分） |

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

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | Event.Reason | "SuccessfulAttachVolume" | Normalイベント |
| INSERT | Event.Message | simpleMsg | 成功メッセージ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 該当なし | 本イベントは成功時のみ発行 | - |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 該当なし（成功イベント） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | EventRecorderのデフォルト設定に従う |
| 1日あたり上限 | 制限なし（同一イベントは集約される） |

### 配信時間帯

制限なし（24時間365日）

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

イベントメッセージにはボリューム名が含まれるが、機密情報は含まれない。

## 備考

- SuccessfulAttachVolumeは、ScheduledPodsの全Podに対して個別にイベントが発行される点が特徴的である
- DanglingAttachErrorが発生した場合、uncertainNodeとして別ノードが記録されるが、イベントは発行されない（エラーパス）
- アタッチ失敗時はeventRecorderFuncにより、同様にScheduledPodsの全PodにFailedAttachVolumeが発行される（312-317行目）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.go | `pkg/kubelet/events/event.go` | 72行目: SuccessfulAttachVolume定数定義 |

**読解のコツ**: SuccessfulAttachVolumeはScheduledPods全てに対してイベントが発行される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | operation_generator.go | `pkg/volume/util/operationexecutor/operation_generator.go` | 240-319行目: GenerateAttachVolumeFunc - アタッチ操作全体 |

**主要処理フロー**:
1. **252行目**: FindAttachablePluginBySpec呼び出し
2. **264行目**: NewAttacher呼び出し
3. **271-272行目**: volumeAttacher.Attach実行
4. **294-295行目**: MarkVolumeAsAttached呼び出し
5. **303行目**: GenerateMsgで成功メッセージ生成
6. **304-306行目**: ScheduledPodsループでSuccessfulAttachVolumeイベント発行

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

```
operationGenerator.GenerateAttachVolumeFunc()
    |
    +-- attachVolumeFunc()
    |       +-- FindAttachablePluginBySpec()
    |       +-- NewAttacher()
    |       +-- volumeAttacher.Attach()
    |       +-- actualStateOfWorld.MarkVolumeAsAttached()
    |       +-- for pod in ScheduledPods:
    |               og.recorder.Eventf(pod, Normal, SuccessfulAttachVolume, ...)
    |
    +-- eventRecorderFunc() [失敗時]
            +-- for pod in ScheduledPods:
                    og.recorder.Eventf(pod, Warning, FailedAttachVolume, ...)
```

### データフロー図

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

VolumeToAttach            operationGenerator                 Kubernetes Event API
(VolumeSpec,         --> .GenerateAttachVolumeFunc()    --> Event(Normal,
 NodeName,               volumeAttacher.Attach()            SuccessfulAttachVolume)
 ScheduledPods)          MarkVolumeAsAttached()              x ScheduledPods数
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/kubelet/events/event.go` | ソース | SuccessfulAttachVolume定数定義（72行目） |
| operation_generator.go | `pkg/volume/util/operationexecutor/operation_generator.go` | ソース | GenerateAttachVolumeFunc実装（240-319行目） |
