# 画面設計書 36-kubectl annotate

## 概要

本ドキュメントは、Kubernetes CLIツール `kubectl` の `annotate` コマンドに関する画面設計書である。`kubectl annotate` は、Kubernetesリソースのアノテーションを追加・変更・削除するコマンドであり、ツールやシステム拡張が利用する任意のメタデータを管理する。

### 本画面の処理概要

**業務上の目的・背景**：Kubernetesのアノテーションは、ラベルとは異なりセレクタには使用されないが、任意のキー/値ペアを格納できるメタデータ機構である。構造化JSONデータの格納、ツール間の情報共有、デプロイメント履歴の記録など幅広い用途で使用される。`kubectl annotate` はこれらのアノテーションの運用時の動的な管理を可能にする。

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

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

**画面遷移**：kubectl annotateは単独で完結するコマンドである。アノテーションは `kubectl describe` でも確認でき、Ingress Controller等のコントローラーがアノテーションに基づいて動作する場合がある。

**権限による表示制御**：アノテーション更新にはRBACにおける対象リソースの `patch` 権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 96 | アノテーション管理（annotate） | 主機能 | リソースにアノテーションを追加・変更・削除する主処理 |
| 1 | API Serverコア | API連携 | アノテーション更新リクエストをAPI Serverに送信する |

## 画面種別

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

## URL/ルーティング

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

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

## 入出力項目

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

| パラメータ名 | 短縮形 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|--------|-----|------|-------------|------|
| --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-annotate" | フィールドマネージャー名 |
| -o / --output | -o | string | No | "" | 出力形式 |

### 位置引数

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

## 表示項目

### 成功時の出力

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

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

| 項目 | 形式 | 説明 |
|------|------|------|
| アノテーション一覧 | KEY=VALUE | 各アノテーションのキーと値（1行1アノテーション） |

## イベント仕様

### 1-アノテーション追加/更新

1. `ToOptions` でフラグからオプション変換（行193-285）
2. `parseAnnotations` でKEY=VALUE / KEY-形式のパース（行413-415）
3. `resource.Builder` でリソース情報を構築（行289-303）
4. 各リソースに対するVisitor関数実行（行321-409）
5. `updateAnnotations` でアノテーションの追加/削除処理（行457-485）
6. MergePatchの生成とAPI Serverへの送信（行361-383）

### 2-アノテーション一覧表示（--list）

1. リソースのメタデータからアノテーションを取得（行386-406）
2. `accessor.GetAnnotations()` でアノテーションマップ取得（行401）
3. KEY=VALUE形式で標準出力に表示

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

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

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

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

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|----------|
| MSG-A01 | 成功 | `{type}/{name} annotated` | アノテーションが更新された場合 |
| MSG-A02 | エラー | `--overwrite is false but found the following declared annotation(s): '{key}' already has a value ({value})` | --overwrite未指定で既存アノテーションの上書き |
| MSG-A03 | エラー | `cannot set --all and --selector at the same time` | --allと--selectorの同時指定 |
| MSG-A04 | エラー | `cannot set --all and --field-selector at the same time` | --allと--field-selectorの同時指定 |
| MSG-A05 | エラー | `at least one annotation update is required` | アノテーション操作未指定（--list以外） |
| MSG-A06 | エラー | `can not both modify and remove the following annotation(s) in the same command: {keys}` | 同一キーの追加と削除を同時指定 |
| MSG-A07 | エラー | `--resource-version may only be used with a single resource` | 複数リソースに--resource-version指定 |
| MSG-A08 | エラー | `--list and --output may not be specified together` | --listと--outputの同時指定 |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|------|----------|----------|
| 上書き拒否 | --overwrite未指定で既存アノテーション上書き | エラーメッセージと共に処理中断 |
| リソース未発見 | 指定リソースが存在しない | API Serverからの404エラーを表示 |
| 権限不足 | patch権限がない | API Serverからのforbiddenエラーを表示 |

## 備考

- アノテーションにはラベルのような値の長さ制限がなく、構造化JSONデータなど任意の文字列値を格納できる。
- `change-cause` アノテーション（`kubernetes.io/change-cause`）は特別扱いされ、--overwrite未指定でも常に上書きが許可される（行440-441）。
- パッチの生成には `jsonpatch.CreateMergePatch` が使用され、MergePatchが生成できない場合は `helper.Replace` にフォールバックする（行376-380）。
- annotateコマンドの構造はlabelコマンドと非常に似ており、Flags -> Options変換パターンを採用している。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | annotate.go | `staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go` | AnnotateFlags構造体（行52-70）とAnnotateOptions構造体（行82-111）の2段階変換パターン |

**読解のコツ**: AnnotateFlagsはCLI入力を直接反映し、AnnotateOptionsはランタイムで必要な情報を保持する。`ToOptions` メソッドでフラグからオプションへの変換が行われる。

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

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

**主要処理フロー**:
1. **行149**: `NewCmdAnnotate` - cobraコマンド生成
2. **行159-163**: Run関数 - ToOptions -> RunAnnotate
3. **行166**: AddFlags呼び出し

#### Step 3: ToOptions - 入力変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | annotate.go | `staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go` | ToOptions関数（行193-285）のバリデーションを含む変換処理 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | annotate.go | `staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go` | RunAnnotate関数（行288-410）のBuilder構築、Visit、パッチ送信 |
| 4-2 | annotate.go | `staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go` | updateAnnotations関数（行457-485）のアノテーション操作ロジック |
| 4-3 | annotate.go | `staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go` | validateNoAnnotationOverwrites関数（行436-454）の上書きチェック |

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

```
NewCmdAnnotate (行149)
    │
    ├─ AnnotateFlags.ToOptions (行193)
    │      ├─ RecordFlags.ToRecorder
    │      ├─ GetDryRunStrategy
    │      ├─ GetResourcesAndPairs (行240)
    │      ├─ parseAnnotations (行245, 行413)
    │      └─ validateAnnotations (行279, 行418)
    │
    └─ RunAnnotate (行288)
           ├─ builder.Do() (行289-305)
           └─ r.Visit() (行321)
                  ├─ updateAnnotations (行330/354, 行457)
                  │      ├─ validateNoAnnotationOverwrites (行436)
                  │      └─ accessor.SetAnnotations
                  │
                  ├─ jsonpatch.CreateMergePatch (行361)
                  │
                  ├─ helper.Patch (行377)
                  │  or
                  └─ helper.Replace (行379)
```

### データフロー図

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

アノテーション引数          ┌──────────────────┐
(KEY=VAL / KEY-) ──────────▶│ parseAnnotations │
                           │ + validate       │
                           └────────┬─────────┘
                                    │
リソース指定                ┌────────▼─────────┐
(TYPE NAME / -f) ──────────▶│ resource.Builder  │
                           └────────┬─────────┘
                                    │
                           ┌────────▼─────────┐
                           │ updateAnnotations │
                           │ (追加/削除)        │
                           └────────┬─────────┘
                                    │
                           ┌────────▼─────────┐
                           │ MergePatch生成    │
                           │ → API Server送信  │
                           └────────┬─────────┘
                                    │
                           ┌────────▼─────────┐
                           │ PrintObj / List   │──────▶ 標準出力
                           └──────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| annotate.go | `staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go` | ソース | annotateコマンドのメイン実装（486行） |
| polymorphichelpers.go | `staging/src/k8s.io/kubectl/pkg/polymorphichelpers/` | ソース | ChangeCauseAnnotation定数の定義 |
| 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` | ソース | リソースタイプ・名前補完 |
