# 機能設計書 111-プラグイン管理（plugin）

## 概要

本ドキュメントは、kubectlのプラグイン管理機能（`kubectl plugin`コマンド）の設計を記述する。PATH上の実行可能ファイルを検索・検証し、kubectlの機能を拡張するプラグインの一覧表示と補完機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：kubectlはKubernetesの主要なCLIツールであるが、すべてのユースケースをカバーすることはできない。プラグイン機構により、ユーザーやサードパーティが独自のサブコマンドを追加でき、kubectlの拡張性を担保する。krew等のプラグインマネージャーとの連携により、エコシステム全体の利便性を向上させる。

**機能の利用シーン**：ユーザーがインストール済みのkubectlプラグインを確認したい場合に`kubectl plugin list`を実行する。また、シェル補完においてプラグインコマンドの候補を動的に提供する際にも内部的に使用される。

**主要な処理内容**：
1. `kubectl plugin list` - PATH上の`kubectl-`プレフィックスを持つ実行可能ファイルを検索し一覧表示する
2. プラグインの検証（実行権限の確認、既存コマンドとの名前衝突チェック、重複プラグインの検出）
3. シェル補完（bash/zsh/fish/powershell）におけるプラグインコマンドの動的登録
4. プラグイン補完実行ファイル（`kubectl_complete-<plugin>`）を通じたプラグイン引数の補完

**関連システム・外部連携**：OS のファイルシステム（PATH環境変数に基づく実行ファイル検索）、krew（推奨されるプラグインマネージャー）

**権限による制御**：特になし（ローカルファイルシステムの読み取り権限のみ必要）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 39 | kubectl plugin | 主機能 | kubectlプラグインの検出と実行を管理する主処理 |

## 機能種別

ファイルシステム検索 / 一覧表示 / シェル補完

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --name-only | bool | No | バイナリ名のみ表示（パスなし） | - |

### 入力データソース

- PATH環境変数で指定されたディレクトリ群
- kubectlコマンドツリー（名前衝突チェック用）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| プラグインパス | string | プラグイン実行ファイルのフルパスまたはバイナリ名 |
| 警告メッセージ | string | 実行権限なし、名前衝突等の警告 |

### 出力先

標準出力（プラグイン一覧）、標準エラー出力（警告・エラー）

## 処理フロー

### 処理シーケンス

```
1. PATHの取得と重複排除
   └─ uniquePathsList()でPATHを重複なしリストに変換
2. 各ディレクトリのスキャン
   └─ os.ReadDir()でファイル一覧を取得
3. プラグインの抽出
   └─ hasValidPrefix()で"kubectl-"プレフィックスを持つファイルを抽出
4. プラグインの検証
   └─ CommandOverrideVerifier.Verify()で各プラグインを検証
      ├─ isExecutable()で実行権限の確認
      ├─ 重複プラグインの検出
      └─ 既存コマンドとの名前衝突チェック
5. 結果の出力
   └─ --name-onlyフラグに応じてパスまたはバイナリ名を出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始: kubectl plugin list] --> B[PATH環境変数を取得]
    B --> C[重複パスを排除]
    C --> D{各ディレクトリをスキャン}
    D --> E[ディレクトリ内のファイルを列挙]
    E --> F{"kubectl-"プレフィックス?}
    F -->|Yes| G[プラグインリストに追加]
    F -->|No| D
    G --> D
    D -->|全ディレクトリ完了| H[各プラグインを検証]
    H --> I[実行権限チェック]
    I --> J[重複チェック]
    J --> K[既存コマンド衝突チェック]
    K --> L[結果出力]
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-111-01 | プラグイン命名規則 | `kubectl-`プレフィックスで始まる実行可能ファイルがプラグインとして認識される | 常時 |
| BR-111-02 | 名前変換規則 | ファイル名のハイフン区切りがサブコマンド階層に、アンダースコアがハイフンに変換される | 補完登録時 |
| BR-111-03 | 補完実行ファイル | `kubectl_complete-<plugin>`という名前の実行ファイルがあれば補完を委譲する | シェル補完時 |
| BR-111-04 | Windows実行権限 | Windowsでは.bat/.cmd/.com/.exe/.ps1拡張子を実行可能と判定する | runtime.GOOS == "windows" |

### 計算ロジック

特になし

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

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

該当なし（データベースを使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | PathError | PATHディレクトリが読み取れない | 警告を出力してスキップ |
| - | 実行権限なし | プラグインファイルに実行権限がない | 警告メッセージを表示 |
| - | 名前衝突 | プラグインが既存のkubectlコマンドを上書きする | 警告メッセージを表示 |
| - | 重複プラグイン | 同名のプラグインが複数のPATHに存在する | 先に見つかったものが優先、警告を表示 |
| - | プラグイン未検出 | PATH上にプラグインが見つからない | エラーメッセージを表示 |

### リトライ仕様

リトライなし

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

該当なし

## パフォーマンス要件

ファイルシステムのディレクトリスキャンに依存する。PATH上のディレクトリ数とファイル数に比例した処理時間がかかる。

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

- プラグインは任意の実行可能ファイルであるため、信頼できるソースからのみインストールすること
- 実行権限のチェックはセキュリティのためではなく、ユーザーへの通知目的
- 補完実行ファイルの呼び出し時には環境変数がそのまま引き継がれる

## 備考

- krewプラグインマネージャーの使用が推奨されている
- プラグインの実行自体はkubectlのメインコマンドハンドラーで処理され、本機能はプラグインの検出・一覧表示のみを担当する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | plugin.go | `staging/src/k8s.io/kubectl/pkg/cmd/plugin/plugin.go` | PluginListOptions構造体（82-89行目）、PathVerifierインターフェース（201-204行目）、CommandOverrideVerifier構造体（206-209行目） |

**読解のコツ**: PluginListOptionsがCLIフラグの値を保持し、PathVerifierが検証ロジックを抽象化するインターフェースパターンに注目。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | plugin.go | `staging/src/k8s.io/kubectl/pkg/cmd/plugin/plugin.go` | NewCmdPlugin関数（66-80行目）でCobraコマンドを構築、NewCmdPluginList関数（92-110行目）でlistサブコマンドを構築 |

**主要処理フロー**:
1. **66-80行目**: NewCmdPluginでpluginコマンドを作成し、listサブコマンドを追加
2. **92-110行目**: NewCmdPluginListでlistコマンドを作成、Complete -> Run の流れ
3. **112-120行目**: CompleteでVerifierとPluginPathsを初期化
4. **122-162行目**: RunでListPluginsを呼び出し結果を表示

#### Step 3: プラグイン検索ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | plugin.go | `staging/src/k8s.io/kubectl/pkg/cmd/plugin/plugin.go` | ListPlugins関数（165-198行目）でPATH上のプラグインを検索 |

**主要処理フロー**:
- **169行目**: uniquePathsListでPATHの重複を除去
- **174行目**: os.ReadDirで各ディレクトリのファイルを列挙
- **189行目**: hasValidPrefixで"kubectl-"プレフィックスを確認
- **193行目**: マッチしたファイルをプラグインリストに追加

#### Step 4: プラグイン検証ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | plugin.go | `staging/src/k8s.io/kubectl/pkg/cmd/plugin/plugin.go` | Verify関数（214-248行目）で各プラグインの妥当性を検証 |

**主要処理フロー**:
- **231行目**: isExecutableで実行権限をチェック
- **237行目**: seenPluginsマップで重複を検出
- **243行目**: cmd.Root().Findで既存コマンドとの衝突を検出

#### Step 5: シェル補完ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | plugin_completion.go | `staging/src/k8s.io/kubectl/pkg/cmd/plugin/plugin_completion.go` | SetupPluginCompletion（46-89行目）とpluginCompletion（188-201行目）で補完を処理 |

**主要処理フロー**:
- **46行目**: SetupPluginCompletionで引数に応じたプラグインコマンド登録
- **93行目**: registerPluginCommandsでプラグインをCobraコマンドツリーに登録
- **188行目**: pluginCompletionで外部補完実行ファイルに委譲

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

```
NewCmdPlugin()
    │
    └─ NewCmdPluginList()
           │
           ├─ Complete()
           │      ├─ CommandOverrideVerifier初期化
           │      └─ filepath.SplitList(PATH)
           │
           └─ Run()
                  ├─ ListPlugins()
                  │      ├─ uniquePathsList()
                  │      ├─ os.ReadDir()
                  │      └─ hasValidPrefix()
                  │
                  └─ Verifier.Verify()
                         ├─ isExecutable()
                         ├─ seenPlugins重複チェック
                         └─ root.Find()既存コマンド衝突チェック

SetupPluginCompletion()
    └─ registerPluginCommands()
           ├─ PluginListOptions.ListPlugins()
           └─ pluginCompletion()
                  ├─ lookupCompletionExec()
                  └─ getPluginCompletions()
```

### データフロー図

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

PATH環境変数 ───────▶ uniquePathsList()
                         │
                    ディレクトリスキャン
                         │
                    hasValidPrefix()フィルタ
                         │
                    Verify()検証
                         │
                    ├─ プラグイン一覧 ─────▶ stdout
                    └─ 警告メッセージ ─────▶ stderr
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| plugin.go | `staging/src/k8s.io/kubectl/pkg/cmd/plugin/plugin.go` | ソース | プラグイン一覧表示の主要ロジック |
| plugin_completion.go | `staging/src/k8s.io/kubectl/pkg/cmd/plugin/plugin_completion.go` | ソース | シェル補完でのプラグイン登録と補完委譲 |
| plugin_test.go | `staging/src/k8s.io/kubectl/pkg/cmd/plugin/plugin_test.go` | テスト | プラグイン機能のユニットテスト |
