# 画面設計書 12-kubectl certificate

## 概要

本ドキュメントは、Kubernetes CLIツール `kubectl certificate` コマンドの画面設計書である。CertificateSigningRequest（CSR）リソースの承認（approve）および拒否（deny）を行うクラスタ管理コマンドの仕様を記載する。

### 本画面の処理概要

`kubectl certificate` コマンドは、クラスタ内で発行されたCSR（証明書署名要求）を承認または拒否するためのサブコマンドを提供する。クラスタ管理者がCSRの内容を確認した上で、証明書の発行可否を制御するための重要なセキュリティ管理機能である。

**業務上の目的・背景**：Kubernetesクラスタ内では、ノード参加時やユーザー認証のためにTLS証明書が必要となる。CSRはクラスタメンバーが証明書を要求する仕組みであり、クラスタ管理者がCSRを承認することでCertificate署名コントローラーが証明書を発行する。不正なCSRを拒否する機能もセキュリティ上不可欠である。

**画面へのアクセス方法**：ターミナル上で `kubectl certificate approve <CSR名>` または `kubectl certificate deny <CSR名>` を実行する。CSR名はCSRリソース名またはファイル指定（-f）で与える。

**主要な操作・処理内容**：
1. `kubectl certificate approve` - 指定されたCSRを承認し、証明書の発行を許可する
2. `kubectl certificate deny` - 指定されたCSRを拒否し、証明書の発行を拒否する
3. `--force` フラグにより、既に承認/拒否済みのCSRを強制的に更新可能

**画面遷移**：本コマンドは単独実行のCLIコマンドである。CSRの承認後、Certificate署名コントローラーが証明書を自動発行する。

**権限による表示制御**：CSRの承認/拒否にはcertificates.k8s.io APIグループに対するupdate権限（UpdateApproval）が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 105 | 証明書管理（certificates） | 主機能 | CSR（CertificateSigningRequest）の承認・拒否を行う主処理 |
| 26 | Certificate署名コントローラー | API連携 | CSR承認後にCertificate署名コントローラーが証明書を署名する |

## 画面種別

CLI コマンド（リソース更新 - サブコマンド構成）

## URL/ルーティング

```
kubectl certificate approve (-f FILENAME | NAME)
kubectl certificate deny (-f FILENAME | NAME)
```

## 入出力項目

### 入力項目（コマンドライン引数・フラグ）

| 項目名 | フラグ | 型 | 必須 | デフォルト | 説明 |
|--------|--------|------|------|-----------|------|
| CSR名 | 位置引数 | string[] | Yes(*) | - | 承認/拒否するCSRリソースの名前（複数指定可） |
| ファイル指定 | -f, --filename | string[] | Yes(*) | - | CSRリソースを特定するファイルパス |
| 強制更新 | --force | bool | No | false | 既に承認/拒否済みのCSRを強制的に更新する |
| 出力形式 | -o, --output | string | No | "" | 出力フォーマット（json/yaml等） |

(*) CSR名またはファイル指定のいずれかが必須

### 出力項目

| 項目名 | 説明 |
|--------|------|
| 処理結果メッセージ | 承認時「`certificatesigningrequest.certificates.k8s.io/<name> approved`」、拒否時「`certificatesigningrequest.certificates.k8s.io/<name> denied`」 |

## 表示項目

| 項目 | 形式 | 説明 |
|------|------|------|
| リソース種別/名前 | `certificatesigningrequest.certificates.k8s.io/<name>` | 処理対象のCSRリソース |
| 操作結果 | `approved` / `denied` | 実行された操作 |

## イベント仕様

### 1-certificate approve実行

1. コマンドライン引数を解析し、CertificateOptionsを初期化する（`Complete`、L86-112）
2. CSR名が1つ以上指定されていることを検証する（`Validate`、L115-120）
3. Builderを使用してCSRリソースを取得する（`modifyCertificateCondition`、L213-277）
4. certificates/v1 APIでCSRオブジェクトを取得する（L238）
5. CSRに承認条件を追加する（`addConditionIfNeeded`、L279-306）
   - 既にDenied状態の場合はエラー（`--force`なしの場合）
   - 条件タイプ: `Approved`、理由: `KubectlApprove`
6. UpdateApproval APIを呼び出してCSRを更新する（L252）
7. コンフリクト発生時は最大10回リトライする（L257-262）

### 2-certificate deny実行

1. approveと同様の流れだが、条件タイプが`Denied`、理由が`KubectlDeny`となる
2. 既にApproved状態の場合はエラー

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

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

| 操作（イベント） | 対象リソース | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| certificate approve | CertificateSigningRequest | UPDATE | CSRのstatus.conditionsにApproved条件を追加 |
| certificate deny | CertificateSigningRequest | UPDATE | CSRのstatus.conditionsにDenied条件を追加 |

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

#### CertificateSigningRequest（certificates.k8s.io/v1）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| UPDATE (approve) | status.conditions[].type | `Approved` | 新しいConditionとして追加 |
| UPDATE (approve) | status.conditions[].status | `True` | |
| UPDATE (approve) | status.conditions[].reason | `KubectlApprove` | |
| UPDATE (approve) | status.conditions[].message | `This CSR was approved by kubectl certificate approve.` | |
| UPDATE (approve) | status.conditions[].lastUpdateTime | 現在時刻 | |
| UPDATE (deny) | status.conditions[].type | `Denied` | 新しいConditionとして追加 |
| UPDATE (deny) | status.conditions[].status | `True` | |
| UPDATE (deny) | status.conditions[].reason | `KubectlDeny` | |
| UPDATE (deny) | status.conditions[].message | `This CSR was denied by kubectl certificate deny.` | |
| UPDATE (deny) | status.conditions[].lastUpdateTime | 現在時刻 | |

## メッセージ仕様

| 種別 | メッセージ | 条件 |
|------|-----------|------|
| 成功（approve） | `certificatesigningrequest.certificates.k8s.io/<name> approved` | CSR承認成功時 |
| 成功（deny） | `certificatesigningrequest.certificates.k8s.io/<name> denied` | CSR拒否成功時 |
| エラー | `one or more CSRs must be specified as <name> or -f <filename>` | CSR名未指定 |
| エラー | `certificate signing request "<name>" is already Denied` | 承認試行時にDenied済み |
| エラー | `certificate signing request "<name>" is already Approved` | 拒否試行時にApproved済み |
| エラー | `could not find v1 version of <name>: <error>` | v1 CSRが見つからない |
| 情報 | `No resources found` | 対象CSRが0件 |

## 例外処理

| 例外条件 | 動作 |
|---------|------|
| CSR名が指定されていない | バリデーションエラーを表示して終了 |
| 指定されたCSRが存在しない | NotFoundエラーを表示して終了 |
| 既にApproved/Denied済み（--forceなし） | エラーメッセージを表示して終了 |
| API Serverとのコンフリクト | 最大10回リトライ後にエラーを返す |
| 権限不足 | 403 Forbiddenエラーを表示して終了 |

## 備考

- `kubectl certificate`自体はサブコマンドヘルプを表示するのみで、`approve`または`deny`サブコマンドの指定が必要（L50-52）
- CSRの承認はセキュリティ上重要な操作であり、コマンドのLong descriptionにセキュリティ警告が含まれる（L137-141）
- コンフリクトリトライは最大10回（L257）で、各回でCSRを最新版に再取得してから条件を再適用する
- certificates/v1 APIのみサポートし、v1beta1はサポートしない

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | certificates.go | `staging/src/k8s.io/kubectl/pkg/cmd/certificates/certificates.go` | CertificateOptions構造体（L62-75）：コマンドオプション定義 |
| 1-2 | types.go（certificates/v1） | `staging/src/k8s.io/api/certificates/v1/types.go` | CertificateSigningRequest/CertificateSigningRequestCondition型 |

**読解のコツ**: CertificateOptionsのcertificatesV1Clientフィールドが、CSRの取得・更新に使用されるAPIクライアント。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | certificates.go | `staging/src/k8s.io/kubectl/pkg/cmd/certificates/certificates.go` | NewCmdCertificate関数（L44-59）：親コマンド登録とサブコマンド追加 |
| 2-2 | certificates.go | `staging/src/k8s.io/kubectl/pkg/cmd/certificates/certificates.go` | NewCmdCertificateApprove関数（L123-159）：approveサブコマンド定義 |
| 2-3 | certificates.go | `staging/src/k8s.io/kubectl/pkg/cmd/certificates/certificates.go` | NewCmdCertificateDeny関数（L171-202）：denyサブコマンド定義 |

**主要処理フロー**:
1. **L44-59**: 親コマンド`certificate`を作成し、approve/denyサブコマンドを追加
2. **L146-150**: approve実行時のComplete -> Validate -> RunCertificateApprove呼び出しチェーン
3. **L189-193**: deny実行時の同様のチェーン

#### Step 3: コア処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | certificates.go | `staging/src/k8s.io/kubectl/pkg/cmd/certificates/certificates.go` | modifyCertificateCondition（L213-277）：CSR更新のメインループ |
| 3-2 | certificates.go | `staging/src/k8s.io/kubectl/pkg/cmd/certificates/certificates.go` | addConditionIfNeeded（L279-306）：条件追加ロジック |

**主要処理フロー**:
- **L215-223**: Builderでcertificatesigningrequestsリソースを検索
- **L228-267**: リトライループ内でCSR取得→条件追加→UpdateApproval
- **L238**: v1 APIでCSRオブジェクトを再取得（型付きオブジェクトとして）
- **L252**: UpdateApproval APIで条件付きCSRを更新
- **L281-305**: 既存条件チェックと新条件追加のロジック

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

```
NewCmdCertificate (L44)
    |
    +-- NewCmdCertificateApprove (L123)
    |       +-- Complete (L86)
    |       |       +-- PrintFlags.ToPrinter()
    |       |       +-- resource.NewBuilder()
    |       |       +-- v1.NewForConfig()
    |       +-- Validate (L115)
    |       +-- RunCertificateApprove (L162)
    |               +-- modifyCertificateCondition (L213)
    |                       +-- builder.Do().Visit()
    |                       +-- certificatesV1Client.Get()
    |                       +-- addConditionIfNeeded (L279)
    |                       +-- certificatesV1Client.UpdateApproval()
    |
    +-- NewCmdCertificateDeny (L171)
            +-- Complete (L86)
            +-- Validate (L115)
            +-- RunCertificateDeny (L205)
                    +-- modifyCertificateCondition (L213)
                            +-- addConditionIfNeeded (L279)
```

### データフロー図

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

CSR名 / -f ファイル     Complete()
                       --> クライアント初期化 --------+
                                                     |
                       Validate()                    |
                       --> CSR名検証 ----------------+
                                                     |
                       modifyCertificateCondition()  |
                       --> Builder.Do() ------------>|
                       --> v1Client.Get() ---------->+---> API Server
                       --> addConditionIfNeeded() -->|     (CSR取得)
                       --> UpdateApproval() -------->|
                                                     |     CSR更新結果
                       [コンフリクト時]               +---> stdout
                       --> リトライ（最大10回）--->|     "approved/denied"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| certificates.go | `staging/src/k8s.io/kubectl/pkg/cmd/certificates/certificates.go` | ソース | certificateコマンドのメイン実装 |
| certificates_test.go | `staging/src/k8s.io/kubectl/pkg/cmd/certificates/certificates_test.go` | テスト | certificateコマンドのユニットテスト |
| types.go | `staging/src/k8s.io/api/certificates/v1/types.go` | ソース | CSRリソース型定義 |
| builder.go | `staging/src/k8s.io/cli-runtime/pkg/resource/builder.go` | ソース | リソースBuilderパターン実装 |
