# 帳票設計書 68-テーブル出力

## 概要

本ドキュメントは、Kubernetesリソース情報を人間が読みやすいテーブル形式で出力する帳票の設計書である。`kubectl get <resource>` コマンドのデフォルト出力形式であり、HumanReadablePrinterが`metav1.Table`形式のレスポンスをタブ区切りテーブルとしてフォーマットする。

### 本帳票の処理概要

**業務上の目的・背景**：Kubernetesクラスタ管理においてリソースの一覧を素早く確認することは最も基本的な操作である。テーブル出力はkubectlのデフォルト出力形式として、リソースの重要な情報をコンパクトなテーブル形式で表示し、クラスタの状態を一目で把握できるようにする。各リソースタイプごとにサーバサイドでカラム定義が行われ、最も有用な情報が選択的に表示される。

**帳票の利用シーン**：日常的なクラスタ運用でリソース状態を確認する場合、`-o wide`でより多くのカラムを表示する場合、`--show-labels`でラベル情報を付加する場合、`-w`（watch）でリアルタイム監視する場合に利用される。

**主要な出力内容**：
1. リソースタイプ固有のカラム（サーバサイドまたはクライアントサイドで定義）
2. オプションによるNamespace列、Label列の追加
3. Watch時のイベントタイプ（ADDED/MODIFIED/DELETED）列の追加
4. Priority値によるwideモード制御

**帳票の出力タイミング**：`kubectl get <resource>` コマンドのデフォルト実行時に出力される。

**帳票の利用者**：全てのKubernetesユーザ（開発者、管理者、SRE等）。

## 帳票種別

一覧表（汎用テーブル出力エンジン）

## 利用画面

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

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（タブ区切りテーブル） |
| 用紙サイズ | N/A（ターミナル出力） |
| 向き | N/A |
| ファイル名 | N/A（標準出力） |
| 出力方法 | 標準出力（stdout） |
| 文字コード | UTF-8 |

## 帳票レイアウト

### レイアウト概要

tabwriterによるタブ区切り整形テーブル。ヘッダー行のカラム名は大文字表示。Watch時やNamespace指定時には追加カラムが先頭に挿入される。

```
┌──────────────────────────────────────────────────────────────┐
│  [EVENT]  [NAMESPACE]  NAME       READY   STATUS    RESTARTS │
├──────────────────────────────────────────────────────────────┤
│  ADDED    default      nginx-1    1/1     Running   0        │
│  MODIFIED default      nginx-2    1/1     Running   1        │
└──────────────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | 条件 |
|----|-------|------|------|
| 1 | EVENT | イベントタイプ（ADDED/MODIFIED/DELETED/ERROR） | `-w`（Watch）時のみ |
| 2 | NAMESPACE | リソースのネームスペース | `--all-namespaces`または`-A`指定時 |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1-N | リソース固有カラム | metav1.TableのColumnDefinitionsで定義 | metav1.Table.Rows[].Cells[] | 型に応じた文字列表示 | tabwriterで自動調整 |
| N+1 | カスタムラベル列 | `--label-columns`で指定されたラベル値 | metadata.labels | 文字列 | 自動調整 |
| N+2 | LABELS | 全ラベル | metadata.labels | key=value,key=value形式 | `--show-labels`時のみ |

### フッター部

該当なし

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| Wide表示 | `-o wide`で Priority > 0 のカラムも表示 | No |
| ヘッダー非表示 | `--no-headers`でヘッダー行を非表示 | No |
| ラベル表示 | `--show-labels`で全ラベルカラムを追加 | No |
| ラベルカラム | `-L`で特定ラベルのカラムを追加 | No |
| Namespace表示 | `--all-namespaces`でNAMESPACEカラムを追加 | No |
| リソース種別プレフィックス | `--show-kind`でNAMEカラムに種別プレフィックスを付加 | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | APIサーバデフォルト | 昇順（name順） |

### 改ページ条件

改ページなし。Watch時はヘッダーの重複出力制御あり（同じカラム定義の場合はヘッダー省略）。

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| metav1.Table | APIサーバからのテーブル形式レスポンス | Accept: application/json;as=Table;g=meta.k8s.io;v=v1 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| カラムフィルタ | column.Priority == 0 で通常表示、options.Wideの場合は全カラム表示 | N/A | - |
| Namespaceプレフィックス | options.WithNamespaceの場合、行の先頭にmetadata.namespaceを挿入 | N/A | - |
| リソース種別プレフィックス | options.WithKindの場合、NAMEカラムに`<kind>/<name>`形式で表示 | N/A | Format: "name"のカラムに適用 |
| ラベルフォーマット | `labels.FormatLabels(itemLabels)`でkey=value形式に変換 | N/A | - |
| 文字列切り詰め | 改行文字（\f, \n, \r）が含まれる場合、その位置で切り詰めて"..."を付加 | N/A | - |
| Watchイベントタイプ | ADDED→"ADDED   ", MODIFIED→"MODIFIED", DELETED→"DELETED ", ERROR→"ERROR   " | N/A | 固定幅パディング |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[kubectl get resource 実行] --> B[コマンド引数・フラグ解析]
    B --> C[PrintOptions構築]
    C --> D[NewTablePrinter生成]
    D --> E[APIサーバからmetav1.Table取得]
    E --> F[HumanReadablePrinter.PrintObj]
    F --> G{tabwriter.Writer?}
    G -->|No| H[tabwriter.Writerでラップ]
    G -->|Yes| I[そのまま使用]
    H --> J{WatchEvent?}
    I --> J
    J -->|Yes| K[eventType取得しオブジェクト展開]
    J -->|No| L[オブジェクトそのまま]
    K --> M{metav1.Table?}
    L --> M
    M -->|Yes| N[decorateTable + printTable]
    M -->|No| O{metav1.Status?}
    O -->|Yes| P[printStatus]
    O -->|No| Q[printObjectMeta デフォルトハンドラ]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| APIサーバ接続エラー | クラスタに接続できない場合 | `The connection to the server ... was refused` | kubeconfig設定確認 |
| テーブル変換エラー | サーバがテーブル形式で応答できない場合 | printObjectMetaでフォールバック | 正常動作（デフォルトハンドラで処理） |
| セル数不一致 | ColumnDefinitionsよりRowsのCell数が多い場合 | 余分なセルは無視 | サーバ側バグの可能性（k8s.io/66379） |

## パフォーマンス要件

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

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

テーブル出力はリソースの主要フィールドのみを表示するため、JSONやYAML出力と比較して情報漏洩のリスクは低い。ただし、Secretリソースの場合もテーブルに含まれる情報（名前、タイプ、データ数等）は表示される。

## 備考

- HumanReadablePrinterは`cli-runtime/pkg/printers/tableprinter.go`で実装されている
- サーバサイドテーブル変換: APIサーバがAcceptヘッダーに基づいてmetav1.Table形式でレスポンスを返す
- クライアントサイドフォールバック: metav1.Tableでない場合はprintObjectMetaまたはprintStatusでデフォルト出力
- Watch時のヘッダー制御: 同じカラム定義が続く場合はヘッダーを省略（lastColumnsとの比較）
- `github.com/liggitt/tabwriter`パッケージを使用（標準のtabwriterの拡張版）
- WriteEscaped関数でタブ文字等のエスケープ処理を行う

---

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

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

### 推奨読解順序

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

HumanReadablePrinterの構造とPrintOptionsを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | interface.go | `staging/src/k8s.io/cli-runtime/pkg/printers/interface.go` | 40-54行目: PrintOptions構造体（NoHeaders, WithNamespace, Wide, ShowLabels等） |
| 1-2 | tableprinter.go | `staging/src/k8s.io/cli-runtime/pkg/printers/tableprinter.go` | 72-77行目: HumanReadablePrinter構造体（options, lastType, lastColumns, printedHeaders） |

**読解のコツ**: lastTypeとlastColumnsはWatch出力時のヘッダー重複制御に使用される。printedHeadersはテーブルが最低1行のデータを持つ場合にtrueに設定される。

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

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

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

**主要処理フロー**:
1. **97-101行目**: tabwriter.Writerでない場合はラップ
2. **104-107行目**: WatchEventの場合はeventType取得とオブジェクト展開
3. **111-143行目**: metav1.Tableの場合: decorateTable + eventType列追加 + printTable
4. **148-166行目**: テーブルでない場合: statusHandlerEntryまたはdefaultHandlerEntryで処理

#### Step 3: テーブル装飾処理を理解する

decorateTableとprintTableの詳細処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tableprinter.go | `staging/src/k8s.io/cli-runtime/pkg/printers/tableprinter.go` | 309-398行目: decorateTable関数（Namespace列、Label列、種別プレフィックスの追加） |
| 3-2 | tableprinter.go | `staging/src/k8s.io/cli-runtime/pkg/printers/tableprinter.go` | 172-234行目: printTable関数（ヘッダーとデータ行の実際の出力） |

**主要処理フロー**:
- **309行目**: decorateTable: WithNamespace, ColumnLabels, ShowLabels, WithKindに基づいてテーブルを装飾
- **172行目**: printTable: NoHeadersでなければヘッダー出力、Priorityに基づくカラムフィルタ、文字列の改行切り詰め

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

```
kubectl get <resource>
    |
    +-- NewTablePrinter(options) [tableprinter.go:80]
    |
    +-- HumanReadablePrinter.PrintObj() [tableprinter.go:95]
            |
            +-- tabwriter.Writer ラップ [97行目]
            |
            +-- WatchEvent 展開 [104行目]
            |
            +-- metav1.Table 判定 [111行目]
            |       |
            |       +-- decorateTable() [tableprinter.go:309]
            |       |       |
            |       |       +-- Namespace列追加
            |       |       +-- Label列追加
            |       |       +-- 種別プレフィックス付与
            |       |
            |       +-- addColumns() (EVENT列) [tableprinter.go:245]
            |       |
            |       +-- printTable() [tableprinter.go:172]
            |               |
            |               +-- ヘッダー出力 (大文字化)
            |               +-- データ行出力 (改行切り詰め)
            |
            +-- デフォルトハンドラ [148行目]
                    |
                    +-- printStatus() or printObjectMeta()
```

### データフロー図

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

APIサーバレスポンス       -->  HumanReadablePrinter.PrintObj   -->  標準出力
(metav1.Table)                 |                                    (テーブル形式テキスト)
                               +-- decorateTable
PrintOptions             -->  |   (列追加・装飾)
(Wide, ShowLabels等)           +-- printTable
                                   (tabwriter整形)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| tableprinter.go | `staging/src/k8s.io/cli-runtime/pkg/printers/tableprinter.go` | ソース | HumanReadablePrinter実装（メインファイル） |
| interface.go | `staging/src/k8s.io/cli-runtime/pkg/printers/interface.go` | ソース | ResourcePrinterインターフェースとPrintOptions定義 |
| printers.go | `pkg/printers/internalversion/printers.go` | ソース | 各リソースタイプのカラム定義とテーブル行生成関数（サーバサイド） |
| tabwriter.go | `staging/src/k8s.io/cli-runtime/pkg/printers/tabwriter.go` | ソース | GetNewTabWriter関数（tabwriterファクトリ） |
