# 帳票設計書 64-JSON出力

## 概要

本ドキュメントは、Kubernetesリソース情報をJSON形式で出力する帳票の設計書である。`kubectl get <resource> -o json` コマンド実行時に、リソースの完全な構造化データをJSONフォーマットで標準出力に出力する。

### 本帳票の処理概要

**業務上の目的・背景**：Kubernetesリソースの詳細情報をプログラムから処理可能な構造化データとして取得する必要がある。JSON出力はCI/CDパイプライン、自動化スクリプト、モニタリングツールとの統合において標準的なデータ交換フォーマットとして広く利用される。テーブル形式では表示されない詳細フィールドも全て含まれるため、デバッグや詳細分析にも不可欠である。

**帳票の利用シーン**：スクリプトやツールからKubernetesリソース情報を解析する場合、リソースの完全なマニフェストをバックアップ・複製する場合、jqなどのツールと組み合わせて特定フィールドを抽出する場合、他のシステムとのデータ連携を行う場合に利用される。

**主要な出力内容**：
1. リソースの全フィールド（apiVersion, kind, metadata, spec, status等）をJSON形式で出力
2. 単一リソースの場合はオブジェクト形式、複数リソースの場合はList形式で出力
3. 4スペースインデントによる整形済みJSON

**帳票の出力タイミング**：`kubectl get <resource> -o json` コマンド実行時、またはAPIサーバへのRESTリクエストでAcceptヘッダーにapplication/jsonを指定した場合に出力される。

**帳票の利用者**：DevOpsエンジニア、SRE、アプリケーション開発者、CI/CDパイプライン。

## 帳票種別

データ出力（構造化データ）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | CLI（ターミナル） | - | `kubectl get <resource> -o json` コマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JSON |
| 用紙サイズ | N/A（ターミナル出力） |
| 向き | N/A |
| ファイル名 | N/A（標準出力。リダイレクトで任意のファイルに保存可能） |
| 出力方法 | 標準出力（stdout） |
| 文字コード | UTF-8 |

## 帳票レイアウト

### レイアウト概要

4スペースインデントで整形されたJSON形式で出力される。単一リソースの場合はオブジェクト、複数リソースの場合はkind: "List"のオブジェクトとして出力される。

```
{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "name": "example-pod",
        "namespace": "default",
        ...
    },
    "spec": { ... },
    "status": { ... }
}
```

### ヘッダー部

該当なし（JSON構造の一部としてapiVersion, kind等が含まれる）

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | apiVersion | APIバージョン | runtime.Object.GroupVersionKind() | 文字列 |
| 2 | kind | リソース種別 | runtime.Object.GroupVersionKind() | 文字列 |
| 3 | metadata | メタデータ | runtime.Object全体 | JSONオブジェクト |
| 4 | spec | リソース仕様 | runtime.Object全体 | JSONオブジェクト |
| 5 | status | リソース状態 | runtime.Object全体 | JSONオブジェクト |

### フッター部

該当なし

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 出力フォーマット指定 | `-o json` オプション | Yes |
| リソース種別 | 任意のKubernetesリソース | Yes |

### ソート順

APIサーバが返すデフォルト順序に従う。

### 改ページ条件

改ページなし（全データを一括出力）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| etcd: /registry/<resource>/ | 各リソースの永続化ストア | APIサーバ経由でRESTアクセス |

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

対象リソースの全フィールドがJSON形式でシリアライズされる。

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| JSON出力 | `json.MarshalIndent(obj, "", "    ")` | N/A | 4スペースインデント |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[kubectl get resource -o json 実行] --> B[コマンド引数・フラグ解析]
    B --> C[出力フォーマット判定: JSON]
    C --> D[JSONPrinter生成]
    D --> E[APIサーバからリソース取得]
    E --> F{オブジェクト種別判定}
    F -->|WatchEvent| G[json.Marshal でシリアライズ + 改行]
    F -->|runtime.Unknown| H[json.Indent で整形]
    F -->|通常オブジェクト| I[GVK空チェック]
    I -->|空| J[エラー: missing apiVersion or kind]
    I -->|あり| K[json.MarshalIndent で整形出力]
    G --> L[Writer に書き込み]
    H --> L
    K --> L
    L --> M[標準出力に表示]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 内部オブジェクトエラー | 内部表現のオブジェクトが渡された場合 | `InternalObjectPrinterErr` | 外部バージョンへの変換が必要 |
| GVK未設定エラー | apiVersionまたはkindが空の場合 | `missing apiVersion or kind; try GetObjectKind().SetGroupVersionKind() if you know the type` | SetGroupVersionKindを呼び出す |
| JSONシリアライズエラー | オブジェクトがJSON化できない場合 | json.Marshalのエラーメッセージ | オブジェクト構造の確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1件〜数千件（リソース種別に依存） |
| 目標出力時間 | データサイズに依存（通常1秒以内） |
| 同時出力数上限 | N/A（CLI単発実行） |

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

JSON出力にはリソースの全フィールドが含まれるため、Secretリソースのdataフィールド（base64エンコードされた機密情報）なども出力される。出力先のアクセス制御やログへの記録に注意が必要である。InternalObjectPreventerにより、内部表現のオブジェクトが外部に漏洩することを防止している。

## 備考

- JSONPrinterは`cli-runtime/pkg/printers/json.go`で実装されている
- WatchEvent(-w オプション)の場合は改行区切りのJSON Lines形式で出力される
- runtime.Unknown型（サーバからの生データ）の場合はjson.Indentで再整形される
- `reflect.Indirect`を使用してポインタから実値を取得し、パッケージパスによる内部オブジェクト判定を行う

---

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

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

### 推奨読解順序

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

JSONPrinterの構造とResourcePrinterインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | interface.go | `staging/src/k8s.io/cli-runtime/pkg/printers/interface.go` | 34-38行目: ResourcePrinterインターフェースのPrintObj(runtime.Object, io.Writer)メソッド |
| 1-2 | json.go | `staging/src/k8s.io/cli-runtime/pkg/printers/json.go` | 32行目: JSONPrinter構造体（フィールドなしの空構造体） |

**読解のコツ**: JSONPrinterはステートレスな構造体であり、全ての処理はPrintObjメソッド内で完結する。

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

PrintObjメソッドの分岐処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | json.go | `staging/src/k8s.io/cli-runtime/pkg/printers/json.go` | 35-80行目: PrintObj関数 |

**主要処理フロー**:
1. **39行目**: `InternalObjectPreventer.IsForbidden`で内部オブジェクトチェック
2. **43-57行目**: `*metav1.WatchEvent`の場合: `json.Marshal`でシリアライズし改行を追加
3. **58-67行目**: `*runtime.Unknown`の場合: `json.Indent`で生JSONデータを再整形
4. **69-70行目**: GVK（GroupVersionKind）が空の場合はエラー返却
5. **73-79行目**: 通常オブジェクト: `json.MarshalIndent`で4スペースインデント整形、改行追加、Writerに書き込み

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

```
kubectl get <resource> -o json
    |
    +-- PrintFlags.ToPrinter() (出力形式判定)
    |       |
    |       +-- JSONPrinter 生成
    |
    +-- JSONPrinter.PrintObj() [json.go:35]
            |
            +-- InternalObjectPreventer.IsForbidden() [内部オブジェクトチェック]
            |
            +-- switch obj.(type)
                    |
                    +-- *metav1.WatchEvent: json.Marshal()
                    |
                    +-- *runtime.Unknown: json.Indent()
                    |
                    +-- default: json.MarshalIndent(obj, "", "    ")
```

### データフロー図

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

runtime.Object     -->  JSONPrinter.PrintObj            -->  標準出力
(APIサーバから取得)        |                                    (JSON形式テキスト)
                         +-- 内部オブジェクトチェック
                         +-- 型別分岐処理
                         +-- json.MarshalIndent
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| json.go | `staging/src/k8s.io/cli-runtime/pkg/printers/json.go` | ソース | JSONPrinter実装 |
| interface.go | `staging/src/k8s.io/cli-runtime/pkg/printers/interface.go` | ソース | ResourcePrinterインターフェース定義 |
| json_test.go | `staging/src/k8s.io/cli-runtime/pkg/printers/json_test.go` | テスト | JSONPrinterのテストケース |
| printers.go | `staging/src/k8s.io/cli-runtime/pkg/printers/printers.go` | ソース | InternalObjectPreventer定義 |
