# 機能設計書 81-リソース作成（create）

## 概要

本ドキュメントは、kubectlの`create`コマンドによるKubernetesリソース作成機能の設計を記述する。マニフェストファイルまたは標準入力からリソースを作成する命令型のリソース作成処理を定義する。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesクラスターにおいてリソースを新規作成する最も基本的な操作を提供する。`apply`が宣言的なリソース管理であるのに対し、`create`は命令型のリソース作成を行い、既存リソースが存在する場合はエラーとなる。開発・運用者がPod、Deployment、Service等のリソースを迅速に作成するために不可欠な機能である。

**機能の利用シーン**：新規リソースの作成時に利用される。マニフェストファイル（YAML/JSON）を指定してリソースを作成する一般的なケースに加え、`kubectl create deployment`のようなサブコマンドによる簡易作成、`--edit`フラグによる作成前編集、`--raw`フラグによるRaw APIリクエストなど、多様なリソース作成パターンに対応する。

**主要な処理内容**：
1. コマンドライン引数とフラグの解析（Complete）
2. 入力バリデーション（Validate）
3. マニフェストファイルの読み込みとリソースビルダーによるオブジェクト構築
4. アノテーション付与（kubectl.kubernetes.io/last-applied-configuration等）
5. DryRun戦略に基づくAPI ServerへのCREATEリクエスト送信
6. 結果の出力表示

**関連システム・外部連携**：API Serverに対してRESTful CREATEリクエストを送信する。Admission Webhookによる検証・変換が適用される。

**権限による制御**：対象リソースに対するcreate権限（RBAC）が必要。Namespaceスコープのリソースの場合、対象Namespace内でのcreate権限が求められる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | kubectl create | 主機能 | マニフェストファイルまたはstdinからKubernetesリソースを作成する主処理 |

## 機能種別

CRUD操作（Create）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -f / --filename | string[] | Yes（--rawと排他） | リソース定義ファイルのパス（YAML/JSON） | ファイルまたはKustomizeディレクトリが必須 |
| -k / --kustomize | string | No | Kustomizeディレクトリのパス | --filenameと排他 |
| --edit | bool | No | 作成前にエディタで編集する | --rawと排他 |
| --raw | string | No | Raw URI（直接POSTする） | 有効なURLパスである必要がある |
| -l / --selector | string | No | ラベルセレクター | --rawと排他 |
| --dry-run | string | No | DryRun戦略（none/client/server） | none、client、serverのいずれか |
| --field-manager | string | No | フィールドマネージャー名 | デフォルト: kubectl-create |
| --validate | string | No | バリデーション指示 | true/false/strict/warn/ignore |
| -o / --output | string | No | 出力形式 | --rawと排他 |
| --save-config | bool | No | kubectl.kubernetes.io/last-applied-configurationアノテーションを付与 | - |
| -R / --recursive | bool | No | ディレクトリの再帰的処理 | --rawと排他 |

### 入力データソース

- ローカルファイルシステム上のマニフェストファイル（YAML/JSON）
- 標準入力（stdin）からのマニフェストデータ
- URL経由のマニフェストファイル（--rawとは排他）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| リソース情報 | string | 作成されたリソースのタイプと名前（例: pod/nginx created） |
| JSON/YAML出力 | object | -o json/yaml指定時の完全なリソースオブジェクト |

### 出力先

- 標準出力（stdout）：作成結果メッセージまたはリソースオブジェクト
- API Server：リソースオブジェクトの永続化（DryRunClient以外）

## 処理フロー

### 処理シーケンス

```
1. NewCmdCreate: コマンド定義とサブコマンド登録
   └─ cobra.Commandの初期化、フラグバインド、サブコマンド登録（namespace, quota, secret, configmap等）
2. Complete: オプション補完
   └─ DryRun戦略の取得、バリデーション指示の取得、プリンターの初期化
3. Validate: 入力バリデーション
   └─ ファイル名必須チェック、--raw関連の排他チェック
4. RunCreate: リソース作成の実行
   ├─ [--raw指定時] rawhttp.RawPost によるRaw APIリクエスト
   ├─ [--edit指定時] RunEditOnCreate によるエディタ経由の作成
   └─ [通常時]
      ├─ 4a. f.Validator: バリデーターの取得
      ├─ 4b. f.NewBuilder: リソースビルダーの構築
      ├─ 4c. r.Visit: 各リソースに対する処理
      │   ├─ アノテーション付与（CreateOrUpdateAnnotation）
      │   ├─ resource.NewHelper.Create: API ServerへのCREATEリクエスト
      │   └─ PrintObj: 結果出力
      └─ 4d. オブジェクト数が0の場合はエラー
```

### フローチャート

```mermaid
flowchart TD
    A[開始: RunCreate] --> B{--raw指定?}
    B -->|Yes| C[rawhttp.RawPost]
    B -->|No| D{--edit指定?}
    D -->|Yes| E[RunEditOnCreate]
    D -->|No| F[Validatorの取得]
    F --> G[ResourceBuilderの構築]
    G --> H[r.Visit: 各リソースを処理]
    H --> I[アノテーション付与]
    I --> J{DryRunClient?}
    J -->|No| K[resource.Helper.Create]
    J -->|Yes| L[スキップ]
    K --> M[info.Refresh]
    M --> N[PrintObj]
    L --> N
    N --> O{次のリソース?}
    O -->|Yes| H
    O -->|No| P{count == 0?}
    P -->|Yes| Q[エラー: no objects passed]
    P -->|No| R[終了]
    C --> R
    E --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ファイル必須 | --filenameまたは--kustomizeのいずれかが必須 | 常時 |
| BR-02 | raw排他制約 | --rawは--edit、-R、-l、-oと排他 | --raw指定時 |
| BR-03 | rawファイル制約 | --raw使用時はローカルファイル1つまたはstdinのみ | --raw指定時 |
| BR-04 | rawURL制約 | --rawはHTTP(S) URLからの読み込み不可 | --raw指定時 |
| BR-05 | 引数不可 | createコマンドは位置引数を受け付けない | 常時 |
| BR-06 | 既存リソースエラー | 同名リソースが存在する場合はAPI Serverがエラーを返す | 常時 |

### 計算ロジック

特になし。

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| リソース作成 | etcd（API Server経由） | INSERT | 新規リソースオブジェクトの永続化 |

### テーブル別操作詳細

#### etcd（API Server経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | リソースオブジェクト全体 | マニフェストで指定された内容 | API Serverのアドミッション制御後に永続化 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バリデーションエラー | ファイル名未指定 | --filenameまたは--kustomizeを指定 |
| - | バリデーションエラー | --rawと--editの同時指定 | いずれか一方のみを使用 |
| - | バリデーションエラー | --rawで複数ファイル指定 | 単一ファイルまたはstdinを使用 |
| 409 | Conflict | 同名リソースが既に存在 | apply使用またはdelete後にcreate |
| 403 | Forbidden | RBAC権限不足 | 適切な権限を付与 |
| 422 | Unprocessable Entity | リソース定義が無効 | マニフェストを修正 |

### リトライ仕様

クライアント側でのリトライは行わない。エラーはそのままユーザーに返される。

## トランザクション仕様

各リソースは個別にAPI Serverに送信され、個別にトランザクション管理される。複数リソースの一括作成時、途中でエラーが発生した場合はそれ以降のリソースは作成されないが、既に作成されたリソースのロールバックは行わない。

## パフォーマンス要件

- マニフェストファイルの解析はクライアントローカルで実行
- API Server側のレスポンス時間はクラスター性能に依存
- 大量のリソースを作成する場合は複数ファイルの一括処理が可能

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

- RBAC認可：対象リソースに対するcreate動詞の権限が必要
- Admission Webhook：MutatingおよびValidating Admission Webhookが適用される
- kubeconfigに基づく認証情報を使用してAPI Serverに接続
- --dry-run=serverを使用することで事前に権限とバリデーションの確認が可能

## 備考

- `kubectl create`には多数のサブコマンド（namespace, secret, configmap, deployment, service, role, rolebinding, clusterrole, clusterrolebinding, job, cronjob, ingress, token等）が存在し、それぞれがStructuredGeneratorパターンに基づいてリソースを生成する
- `--edit`フラグを使用すると、作成前にエディタでマニフェストを編集可能（内部的にeditorパッケージのEditBeforeCreateModeを使用）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | create.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create.go` | CreateOptions構造体（51-70行目）でコマンドオプションの全体像を把握する |
| 1-2 | create.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create.go` | CreateSubcommandOptions構造体（340-361行目）でサブコマンド共通オプションを把握する |

**読解のコツ**: Goの構造体埋め込み（`genericiooptions.IOStreams`）に注目。kubectlの全コマンドで共通のI/Oストリームパターンを使用している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | create.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create.go` | NewCmdCreate関数（102-154行目）でコマンド定義、フラグバインド、サブコマンド登録を理解する |

**主要処理フロー**:
1. **111-115行目**: Complete -> Validate -> RunCreate のパイプライン
2. **136-152行目**: 17個のサブコマンド（namespace, quota, secret, configmap等）の登録

#### Step 3: バリデーションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create.go` | Validate関数（157-187行目）で--rawフラグの排他制約を理解する |

**主要処理フロー**:
- **158-160行目**: ファイル名またはKustomize必須チェック
- **162-184行目**: --raw指定時の各種排他チェック

#### Step 4: 作成処理の実行を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | create.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create.go` | RunCreate関数（225-301行目）で実際のリソース作成処理を理解する |

**主要処理フロー**:
- **228-233行目**: --raw指定時のRaw APIリクエスト処理
- **236-238行目**: --edit指定時のエディタ経由作成
- **250-258行目**: リソースビルダーによるオブジェクト構築
- **265-293行目**: r.Visit()による各リソースの作成処理（アノテーション付与、API呼び出し、結果出力）

#### Step 5: サブコマンドのパターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | create.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create.go` | CreateSubcommandOptions.Run関数（420-470行目）でサブコマンド共通の作成パターンを理解する |

**主要処理フロー**:
- **421行目**: StructuredGenerator.StructuredGenerate()によるオブジェクト生成
- **430-434行目**: スキーマからGVKとRESTマッピングの取得
- **440-443行目**: Unstructuredオブジェクトへの変換
- **456行目**: DynamicClient.Resource().Create()によるAPI呼び出し

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

```
NewCmdCreate (create.go:102)
    │
    ├─ Complete (create.go:190)
    │      ├─ GetDryRunStrategy
    │      ├─ GetValidationDirective
    │      └─ PrintFlags.ToPrinter
    │
    ├─ Validate (create.go:157)
    │      └─ FilenameOptions.RequireFilenameOrKustomize
    │
    └─ RunCreate (create.go:225)
           │
           ├─ [--raw] rawhttp.RawPost
           │
           ├─ [--edit] RunEditOnCreate (create.go:304)
           │      └─ editor.NewEditOptions → editOptions.Run
           │
           └─ [通常]
                  ├─ f.Validator
                  ├─ f.NewBuilder().Unstructured().Schema()...Do()
                  └─ r.Visit()
                         ├─ util.CreateOrUpdateAnnotation
                         ├─ resource.NewHelper.Create
                         └─ PrintObj
```

### データフロー図

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

マニフェストファイル ──▶ NewBuilder.FilenameParam ──▶ r.Visit()
(YAML/JSON)              │                            │
                         ▼                            ▼
stdin ──────────────▶ リソースオブジェクト構築 ──▶ resource.Helper.Create ──▶ stdout (結果表示)
                                                      │
                                                      ▼
                                               API Server (etcd永続化)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| create.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create.go` | ソース | メインコマンド定義・作成処理 |
| create_deployment.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_deployment.go` | ソース | Deploymentサブコマンド |
| create_namespace.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_namespace.go` | ソース | Namespaceサブコマンド |
| create_configmap.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_configmap.go` | ソース | ConfigMapサブコマンド |
| create_secret.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret.go` | ソース | Secretサブコマンド |
| create_service.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_service.go` | ソース | Serviceサブコマンド |
| create_role.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_role.go` | ソース | Roleサブコマンド |
| create_rolebinding.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_rolebinding.go` | ソース | RoleBindingサブコマンド |
| create_clusterrole.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_clusterrole.go` | ソース | ClusterRoleサブコマンド |
| create_clusterrolebinding.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_clusterrolebinding.go` | ソース | ClusterRoleBindingサブコマンド |
| create_job.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_job.go` | ソース | Jobサブコマンド |
| create_cronjob.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_cronjob.go` | ソース | CronJobサブコマンド |
| create_ingress.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_ingress.go` | ソース | Ingressサブコマンド |
| create_token.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_token.go` | ソース | Tokenサブコマンド |
| create_quota.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_quota.go` | ソース | ResourceQuotaサブコマンド |
| create_pdb.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_pdb.go` | ソース | PodDisruptionBudgetサブコマンド |
| create_priorityclass.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_priorityclass.go` | ソース | PriorityClassサブコマンド |
| create_serviceaccount.go | `staging/src/k8s.io/kubectl/pkg/cmd/create/create_serviceaccount.go` | ソース | ServiceAccountサブコマンド |
