# 画面設計書 35-kubectl label

## 概要

本ドキュメントは、Kubernetes CLIツール `kubectl` の `label` コマンドに関する画面設計書である。`kubectl label` は、Kubernetesリソースのラベルを追加・変更・削除するコマンドであり、リソースの分類やセレクタによるフィルタリングの基盤となるメタデータを管理する。

### 本画面の処理概要

**業務上の目的・背景**：Kubernetesにおいてラベルはリソースの組織化と選択の中核メカニズムである。Service、Deployment、NetworkPolicy等のリソースはラベルセレクタによってターゲットリソースを特定する。`kubectl label` は運用中のリソースに対してラベルの動的な追加・更新・削除を行い、リソースのグルーピングやトラフィックルーティング制御を可能にする。

**画面へのアクセス方法**：ターミナルから `kubectl label` コマンドを実行する。リソースの指定はTYPE NAME形式、ファイル指定、またはラベルセレクタで行い、操作するラベルをKEY=VALUE（追加/更新）またはKEY-（削除）形式で指定する。

**主要な操作・処理内容**：
1. ラベルの追加（KEY=VALUE形式）
2. ラベルの更新（--overwrite指定時のKEY=VALUE形式）
3. ラベルの削除（KEY-形式）
4. ラベルの一覧表示（--list指定時）
5. 全リソース一括操作（--all指定時）
6. ローカルモード・DryRunモードでのシミュレーション

**画面遷移**：kubectl labelは単独で完結するコマンドである。ラベル設定後は `kubectl get -l SELECTOR` でラベルによるフィルタリングが可能になる。

**権限による表示制御**：ラベル更新にはRBACにおける対象リソースの `patch` 権限が必要。`--list` 表示のみの場合は `get` 権限で十分。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 95 | ラベル管理（label） | 主機能 | リソースにラベルを追加・変更・削除する主処理 |
| 1 | API Serverコア | API連携 | ラベル更新リクエストをAPI Serverに送信する |

## 画面種別

CLI コマンド（リソースメタデータ更新操作）

## URL/ルーティング

```
kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
```

コマンドエントリーポイント: `staging/src/k8s.io/kubectl/pkg/cmd/label/label.go` の `NewCmdLabel` 関数（行135）

## 入出力項目

### 入力パラメータ（フラグ）

| パラメータ名 | 短縮形 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|--------|-----|------|-------------|------|
| --overwrite | - | bool | No | false | 既存ラベルの上書きを許可 |
| --list | - | bool | No | false | ラベル一覧を表示 |
| --local | - | bool | No | false | API Serverに接続せずローカル実行 |
| --field-selector | - | string | No | "" | フィールドセレクタ |
| --all | - | bool | No | false | 指定リソースタイプの全リソースを対象 |
| -A / --all-namespaces | -A | bool | No | false | 全Namespace対象 |
| --resource-version | - | string | No | "" | 楽観的ロック用リソースバージョン |
| -f / --filename | -f | []string | No | - | リソースを特定するファイル |
| -l / --selector | -l | string | No | "" | ラベルセレクタ |
| --dry-run | - | string | No | "none" | DryRun戦略 |
| --field-manager | - | string | No | "kubectl-label" | フィールドマネージャー名 |
| -o / --output | -o | string | No | "" | 出力形式 |

### 位置引数

| 引数 | 必須 | 説明 |
|------|------|------|
| TYPE | Yes（ファイル未指定時） | リソースタイプ |
| NAME | No | リソース名（--all使用時は不要） |
| KEY=VALUE / KEY- | Yes（--list以外） | 設定/削除するラベル（複数指定可） |

## 表示項目

### 成功時の出力

| 項目 | 形式 | 説明 |
|------|------|------|
| リソース種別/名前 | テキスト | 操作結果（例: `pod/foo labeled`） |
| 操作種別 | テキスト | labeled / unlabeled / modified / not labeled |

### --list 指定時の出力

| 項目 | 形式 | 説明 |
|------|------|------|
| ラベル一覧 | KEY=VALUE | 各ラベルのキーと値（1行1ラベル） |

## イベント仕様

### 1-ラベル追加/更新

1. 引数のパース（リソースとラベルペアの分離）（行194-202）
2. `parseLabels` でKEY=VALUE / KEY-形式のパース（行416-441）
3. `resource.Builder` でリソース情報を構築（行249-263）
4. 各リソースに対するVisitor関数実行（行277-391）
5. `labelFunc` でラベルの追加/削除処理（行443-480）
6. MergePatchの生成とAPI Serverへの送信（行332-356）

### 2-ラベル削除

1. KEY-形式の引数が `removeLabels` にパースされる（行429-430）
2. 対象ラベルが存在するか確認（行316-318）
3. ラベルの削除後、パッチ生成・送信

### 3-ラベル一覧表示（--list）

1. リソースのメタデータからラベルを取得（行363-383）
2. `accessor.GetLabels()` でラベルマップ取得（行378）
3. KEY=VALUE形式で標準出力に表示

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ラベル追加/更新 | etcd（対象リソース） | UPDATE（PATCH） | metadata.labelsフィールドの更新 |
| ラベル削除 | etcd（対象リソース） | UPDATE（PATCH） | metadata.labelsから指定キーを削除 |
| ラベル一覧表示 | etcd（対象リソース） | SELECT | metadata.labelsの読み取りのみ |

### テーブル別更新項目詳細

#### etcd（対象Kubernetesリソース）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| PATCH | metadata.labels | 指定されたKEY=VALUE | MergePatch形式 |
| PATCH | metadata.labels | 指定KEYの削除 | MergePatch形式（値null） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|----------|
| MSG-L01 | 成功 | `{type}/{name} labeled` | ラベルが追加された場合 |
| MSG-L02 | 成功 | `{type}/{name} unlabeled` | ラベルが削除された場合 |
| MSG-L03 | 成功 | `{type}/{name} modified` | ラベルの追加と削除が同時に行われた場合 |
| MSG-L04 | 成功 | `{type}/{name} not labeled` | 実質的な変更がなかった場合 |
| MSG-L05 | 情報 | `label "{key}" not found.` | 削除対象のラベルが存在しない場合 |
| MSG-L06 | エラー | `'{key}' already has a value ({value}), and --overwrite is false` | --overwrite未指定で既存ラベルの上書き |
| MSG-L07 | エラー | `cannot set --all and --selector at the same time` | --allと--selectorの同時指定 |
| MSG-L08 | エラー | `cannot set --all and --field-selector at the same time` | --allと--field-selectorの同時指定 |
| MSG-L09 | エラー | `at least one label update is required` | ラベル操作未指定（--list以外） |
| MSG-L10 | エラー | `can not both modify and remove a label in the same command` | 同一キーの追加と削除を同時指定 |
| MSG-L11 | エラー | `--resource-version may only be used with a single resource` | 複数リソースに--resource-version指定 |
| MSG-L12 | エラー | `--list and --output may not be specified together` | --listと--outputの同時指定 |
| MSG-L13 | エラー | `invalid label spec: {spec}` | 不正なラベル書式 |
| MSG-L14 | エラー | `invalid label value: "{spec}": {errors}` | ラベル値がバリデーション違反 |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|------|----------|----------|
| 上書き拒否 | --overwrite未指定で既存ラベル上書き | エラーメッセージと共に処理中断 |
| リソース未発見 | 指定リソースが存在しない | API Serverからの404エラーを表示 |
| 権限不足 | patch権限がない | API Serverからのforbiddenエラーを表示 |
| ラベル値バリデーション | 値が63文字超過や不正文字含む | バリデーションエラーを表示 |

## 備考

- ラベルキーと値はそれぞれ最大63文字で、英数字・ハイフン・ドット・アンダースコアが使用可能（行98-99）。
- ラベルキーにはDNSサブドメインプレフィックスを付けることができる（例: `example.com/my-app`）。
- `--resource-version` は単一リソースに対してのみ使用可能で、楽観的ロックを実現する。
- パッチの生成には `jsonpatch.CreateMergePatch` が使用され、MergePatchが生成できない場合は `helper.Replace` にフォールバックする（行352-356）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | label.go | `staging/src/k8s.io/kubectl/pkg/cmd/label/label.go` | LabelOptions構造体（行57-92）のフィールド構成 |

**読解のコツ**: `newLabels`（追加ラベル）と `removeLabels`（削除ラベル）が分離して管理される点に注目。操作メッセージの種別定数（行49-54）も確認する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | label.go | `staging/src/k8s.io/kubectl/pkg/cmd/label/label.go` | NewCmdLabel関数（行135-169）のコマンド定義とフラグ登録 |

**主要処理フロー**:
1. **行135**: `NewCmdLabel` - cobraコマンド生成
2. **行145-149**: Run関数 - Complete -> Validate -> RunLabel
3. **行155-166**: フラグ登録

#### Step 3: ラベルパース処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | label.go | `staging/src/k8s.io/kubectl/pkg/cmd/label/label.go` | parseLabels関数（行416-441）のKEY=VALUE / KEY-パース |
| 3-2 | label.go | `staging/src/k8s.io/kubectl/pkg/cmd/label/label.go` | labelFunc関数（行443-480）のラベル操作ロジック |

#### Step 4: RunLabel - メイン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | label.go | `staging/src/k8s.io/kubectl/pkg/cmd/label/label.go` | RunLabel関数（行248-391）のBuilder構築、Visit、パッチ送信 |

**主要処理フロー**:
- **行249-263**: Builder構築（ローカル/リモート分岐）
- **行277**: Visit開始
- **行300-303**: ローカル/DryRunClient/List時の処理
- **行332-356**: サーバーサイド処理（MergePatch生成 + helper.Patch / helper.Replace）
- **行363-383**: --list時のラベル一覧表示

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

```
NewCmdLabel (行135)
    │
    ├─ Complete (行172)
    │      ├─ GetResourcesAndPairs (行194)
    │      └─ parseLabels (行199, 行416)
    │
    ├─ Validate (行219)
    │      └─ パラメータ整合性チェック
    │
    └─ RunLabel (行248)
           ├─ builder.Do() (行249-266)
           └─ r.Visit() (行277)
                  ├─ labelFunc (行300, 行321, 行443)
                  │      ├─ validateNoOverwrites (行406)
                  │      ├─ accessor.GetLabels / SetLabels
                  │      └─ accessor.SetResourceVersion
                  │
                  ├─ jsonpatch.CreateMergePatch (行337)
                  │
                  ├─ helper.Patch (行353)
                  │  or
                  └─ helper.Replace (行355)
```

### データフロー図

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

ラベル引数                ┌──────────────────┐
(KEY=VAL / KEY-) ────────▶│ parseLabels      │
                         │ newLabels /       │
                         │ removeLabels      │
                         └────────┬─────────┘
                                  │
リソース指定              ┌────────▼─────────┐
(TYPE NAME / -f) ────────▶│ resource.Builder  │
                         └────────┬─────────┘
                                  │
                         ┌────────▼─────────┐
                         │ labelFunc         │
                         │ (ラベル追加/削除)  │
                         └────────┬─────────┘
                                  │
                         ┌────────▼─────────┐
                         │ MergePatch生成    │
                         │ → API Server送信  │
                         └────────┬─────────┘
                                  │
                         ┌────────▼─────────┐
                         │ PrintObj / List   │──────▶ 標準出力
                         └──────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| label.go | `staging/src/k8s.io/kubectl/pkg/cmd/label/label.go` | ソース | labelコマンドのメイン実装（481行） |
| validation.go | `staging/src/k8s.io/apimachinery/pkg/util/validation/validation.go` | ソース | ラベル値バリデーション |
| json-patch | `vendor/gopkg.in/evanphx/json-patch.v4/` | ベンダー | MergePatch生成ライブラリ |
| helper.go | `staging/src/k8s.io/cli-runtime/pkg/resource/helper.go` | ソース | API ServerへのPatch/Replaceヘルパー |
| completion.go | `staging/src/k8s.io/kubectl/pkg/util/completion/completion.go` | ソース | リソースタイプ・名前補完 |
