# 画面設計書 90-Kubernetesエージェント

## 概要

本ドキュメントは、GitLabのKubernetesエージェント詳細画面の設計仕様を定義するものである。

### 本画面の処理概要

Kubernetesエージェント詳細画面は、GitLab Agent for Kubernetes（agentk）の詳細情報を表示し、管理するための画面である。エージェントの接続状態、アクセストークン、アクティビティログ、設定情報などを確認できる。

**業務上の目的・背景**：GitLab Agent for Kubernetesは、GitLabとKubernetesクラスターを安全に接続するためのコンポーネントである。従来のクラスター証明書ベースの接続に代わり、エージェントベースのGitOpsワークフローやクラスター管理を実現する。この画面では、エージェントの状態監視、アクセストークンの管理、アクティビティの確認が可能。

**画面へのアクセス方法**：Kubernetesクラスター一覧画面から特定のエージェントを選択、またはURL直接アクセス。URLパターンは `/:namespace/:project/-/cluster_agents/:name` となる。

**主要な操作・処理内容**：
1. エージェント接続状態の確認
2. アクセストークンの表示・作成・削除
3. アクティビティログの確認
4. インストールコマンドの表示
5. 設定情報の確認

**画面遷移**：
- 遷移元：Kubernetesクラスター一覧画面
- 遷移先：トークン作成モーダル

**権限による表示制御**：
- `read_cluster_agent`権限がない場合はアクセス不可
- `admin_cluster`権限を持つユーザーのみトークン作成・削除が可能

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | Kubernetesエージェント管理 | 主機能 | エージェントの詳細表示・管理 |

## 画面種別

詳細

## URL/ルーティング

```
GET /:namespace/:project/-/cluster_agents/:name
POST /api/graphql (GraphQL Query: clusterAgent)
POST /api/graphql (GraphQL Mutation: clusterAgentTokenCreate)
POST /api/graphql (GraphQL Mutation: clusterAgentTokenRevoke)
```

## 入出力項目

### パスパラメータ

| 項目名 | データ型 | 必須 | 説明 |
|--------|----------|------|------|
| name | String | 必須 | エージェント名 |

## 表示項目

### エージェント基本情報

| 項目名 | データ型 | 説明 | ソース |
|--------|----------|------|--------|
| エージェント名 | String | エージェントの識別名 | clusterAgent.name |
| 接続状態 | String | 接続中/切断中 | clusterAgent.tokens[].lastUsedAt |
| 作成日時 | DateTime | エージェント作成日時 | clusterAgent.createdAt |
| 作成者 | User | エージェントを作成したユーザー | clusterAgent.createdByUser |

### アクセストークン一覧

| 項目名 | データ型 | 説明 | ソース |
|--------|----------|------|--------|
| トークン名 | String | トークンの識別名 | token.name |
| 最終使用日時 | DateTime | トークンの最終使用日時 | token.lastUsedAt |
| ステータス | String | アクティブ/非アクティブ | token.status |
| 作成日時 | DateTime | トークン作成日時 | token.createdAt |

### アクティビティログ

| 項目名 | データ型 | 説明 | ソース |
|--------|----------|------|--------|
| 日時 | DateTime | アクティビティ発生日時 | activity.recordedAt |
| 種別 | String | アクティビティの種類 | activity.kind |
| ユーザー | User | 操作を行ったユーザー | activity.user |
| 詳細 | String | アクティビティの詳細 | activity.details |

### インストール情報

| 項目名 | データ型 | 説明 | ソース |
|--------|----------|------|--------|
| KAS URL | String | GitLab Agent Server URL | Gitlab::Kas.external_url |
| インストールバージョン | String | 推奨バージョン情報 | Gitlab::Kas.install_version_info |
| Helmコマンド | String | インストールコマンド例 | 動的生成 |

## イベント仕様

### 1-アクセストークン作成

**トリガー**: 「Create token」ボタン押下

**前提条件**:
- `admin_cluster`権限を持つ

**処理フロー**:
1. トークン作成モーダルを表示
2. トークン名を入力
3. GraphQL Mutation `clusterAgentTokenCreate`を実行
4. 成功時：トークン値を表示（一度のみ）
5. トークン一覧を更新

**遷移先**: モーダル表示 → 同一画面

### 2-アクセストークン削除

**トリガー**: トークンの削除ボタン押下

**前提条件**:
- `admin_cluster`権限を持つ

**処理フロー**:
1. 確認ダイアログを表示
2. GraphQL Mutation `clusterAgentTokenRevoke`を実行
3. 成功時：トークン一覧を更新
4. 失敗時：エラーメッセージを表示

**遷移先**: 同一画面（一覧更新）

### 3-インストールコマンドコピー

**トリガー**: コピーボタン押下

**処理フロー**: Helmインストールコマンドをクリップボードにコピー

**遷移先**: 画面内操作

### 4-アクティビティ更新

**トリガー**: 定期更新/手動更新

**処理フロー**:
1. GraphQLクエリでアクティビティログを取得
2. 表示を更新

**遷移先**: 同一画面（データ更新）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | cluster_agents | SELECT | エージェント情報の取得 |
| 画面表示 | cluster_agent_tokens | SELECT | トークン一覧の取得 |
| 画面表示 | cluster_agent_activity_events | SELECT | アクティビティログの取得 |
| トークン作成 | cluster_agent_tokens | INSERT | 新規トークンの作成 |
| トークン作成 | cluster_agent_activity_events | INSERT | アクティビティログ記録 |
| トークン削除 | cluster_agent_tokens | UPDATE | トークンの無効化（revoked_at設定） |

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

#### cluster_agents

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, project_id, created_at, created_by_user_id | project_id = プロジェクトID, name = パスパラメータ | |

#### cluster_agent_tokens

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, status, last_used_at, created_at, created_by_user_id | agent_id = エージェントID, revoked_at IS NULL | |
| INSERT | agent_id, name, token_encrypted, status, created_by_user_id | 新規トークン | トークン値は暗号化保存 |
| UPDATE | revoked_at, revoked_by_user_id | NOW(), 現在のユーザーID | 削除時（論理削除） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | 情報 | Connected | エージェント接続中 |
| MSG-002 | 警告 | Not connected | エージェント未接続 |
| MSG-003 | 情報 | Token created | トークン作成成功時 |
| MSG-004 | 警告 | Make sure you save it - you won't be able to access it again | トークン表示時の警告 |
| MSG-005 | エラー | Something went wrong | エラー発生時 |
| MSG-006 | 情報 | Activity | アクティビティセクションタイトル |

## 例外処理

| 例外 | 原因 | 対処 |
|------|------|------|
| 404 Not Found | 指定されたエージェントが存在しない | エラーページ表示 |
| 403 Forbidden | read_cluster_agent権限がない | アクセス拒否画面へリダイレクト |
| 422 Unprocessable Entity | トークン作成時のバリデーションエラー | エラーメッセージを表示 |

## 備考

- エージェントの接続状態はトークンの最終使用日時から判定（1時間以内で接続中）
- トークン値は作成時に一度だけ表示される（再表示不可）
- KAS（Kubernetes Agent Server）との通信はgRPC over WebSocketで行われる
- アクティビティログは最新200件まで保持される
- エージェント設定は`.gitlab/agents/{agent_name}/config.yaml`で管理
- CI/CDアクセス、ユーザーアクセスの認可設定が可能（EE機能含む）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | agent.rb | `app/models/clusters/agent.rb` | Clusters::Agentモデルの属性、アソシエーションを確認 |

**読解のコツ**:
- `name`でプロジェクト内一意識別
- `agent_tokens`で複数のアクセストークンを管理
- `active_agent_tokens`スコープでアクティブなトークンのみ取得
- `connected?`メソッドで接続状態を判定
- `INACTIVE_AFTER`（1時間）で非アクティブ判定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cluster_agents_controller.rb | `app/controllers/projects/cluster_agents_controller.rb` | showアクション、認可処理 |
| 2-2 | show.html.haml | `app/views/projects/cluster_agents/show.html.haml` | Vueマウントポイント |
| 2-3 | cluster_agents_helper.rb | `app/helpers/projects/cluster_agents_helper.rb` | js_cluster_agent_details_data |

**主要処理フロー**:
1. **6行目** (controller): `authorize_read_cluster_agent!`で読み取り権限チェック
2. **7行目** (controller): `set_kas_cookie`でKAS認証Cookie設定
3. **12-13行目** (controller): `show`アクションでエージェント名取得
4. **4-15行目** (helper): `js_cluster_agent_details_data`でVueにデータ渡し

#### Step 3: フロントエンド（Vue.js + GraphQL）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.vue | `app/assets/javascripts/clusters/agents/components/show.vue` | メインコンポーネント |

**主要処理フロー**:
- GraphQLクエリ`clusterAgent`でエージェント情報を取得
- トークン作成/削除はGraphQL Mutationを使用

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

```
[ブラウザ]
    │
    ├─ GET /cluster_agents/:name (HTML)
    │      └─ ClusterAgentsController#show
    │             ├─ authorize_read_cluster_agent!
    │             ├─ set_kas_cookie (if logged in)
    │             ├─ @agent_name = params[:name]
    │             └─ HTML response (Vue mount point)
    │                    └─ js_cluster_agent_details_data
    │
    ├─ POST /api/graphql (clusterAgent Query)
    │      └─ Resolvers::Clusters::AgentsResolver
    │             └─ Clusters::Agent.with_name
    │
    ├─ POST /api/graphql (clusterAgentTokenCreate Mutation)
    │      └─ Mutations::Clusters::AgentTokens::Create
    │             └─ Clusters::AgentTokens::CreateService
    │
    └─ POST /api/graphql (clusterAgentTokenRevoke Mutation)
           └─ Mutations::Clusters::AgentTokens::Revoke
                  └─ Clusters::AgentTokens::RevokeService
```

### データフロー図

```
[エージェントデータ取得]
    │
    └─ GraphQL clusterAgent クエリ
           └─ Clusters::Agent
                  ├─ name
                  ├─ createdAt
                  ├─ createdByUser
                  ├─ tokens[]
                  │      ├─ name
                  │      ├─ status
                  │      ├─ lastUsedAt
                  │      └─ createdAt
                  └─ activityEvents[]
                         ├─ kind
                         ├─ recordedAt
                         ├─ user
                         └─ details

[KAS設定情報]
    │
    └─ js_cluster_agent_details_data
           ├─ kas_address (Gitlab::Kas.external_url)
           ├─ kas_install_version (Gitlab::Kas.install_version_info)
           ├─ can_admin_cluster
           └─ can_admin_vulnerability
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| agent.rb | `app/models/clusters/agent.rb` | モデル | Clusters::Agentモデル定義 |
| agent_token.rb | `app/models/clusters/agent_token.rb` | モデル | トークンモデル定義 |
| cluster_agents_controller.rb | `app/controllers/projects/cluster_agents_controller.rb` | コントローラー | HTTPリクエスト処理 |
| show.html.haml | `app/views/projects/cluster_agents/show.html.haml` | ビュー | HTMLテンプレート |
| cluster_agents_helper.rb | `app/helpers/projects/cluster_agents_helper.rb` | ヘルパー | ビューデータ生成 |
| show.vue | `app/assets/javascripts/clusters/agents/components/show.vue` | Vueコンポーネント | 詳細画面 |
| create_service.rb | `app/services/clusters/agent_tokens/create_service.rb` | サービス | トークン作成 |
| revoke_service.rb | `app/services/clusters/agent_tokens/revoke_service.rb` | サービス | トークン削除 |
