# 画面設計書 111-セキュア設定リロード

## 概要

本ドキュメントは、OpenSearchのセキュア設定リロードAPI（`POST /_nodes/reload_secure_settings`）の画面設計書である。本APIは、OpenSearch keystoreに保存されたセキュア設定を再読み込みし、ReloadablePluginインターフェースを実装するプラグインに新しい設定を反映する。

### 本画面の処理概要

本APIは、OpenSearchクラスタのノードに対してセキュア設定（keystore）のリロードを指示するREST APIエンドポイントである。

**業務上の目的・背景**：OpenSearchでは、パスワードや認証情報などの機密設定をkeystoreに暗号化して保存する。これらの設定を変更した場合、ノードを再起動することなく設定を反映するためにこのAPIが必要となる。例えば、外部認証プロバイダのパスワード変更時に、ダウンタイムなしで新しい認証情報を適用する運用シナリオで利用される。

**画面へのアクセス方法**：HTTPクライアント（curl等）から `POST /_nodes/reload_secure_settings` または `POST /_nodes/{node_id}/reload_secure_settings` にリクエストを送信する。オプションでリクエストボディにkeystoreのパスワードを含めることができる。

**主要な操作・処理内容**：
1. クライアントからPOSTリクエストを受信し、対象ノードIDとkeystoreパスワードをパースする
2. TLS未有効の場合にパスワード付きリクエストのクラスタ全体配信を拒否するセキュリティチェックを実行する
3. 各ノードでkeystoreファイルを再読み込みし、パスワードで復号する
4. ReloadablePluginを実装する全プラグインに対して新しい設定をブロードキャストする
5. 各ノードの処理結果（成功/失敗）を集約してレスポンスを返す

**画面遷移**：本APIは単独で動作する。ノード情報API（`GET /_nodes`）でノードIDを確認した後に呼び出されることが一般的である。

**権限による表示制御**：クラスタ管理権限が必要。TLSが有効でない環境では、`_local`フィルタを使用してノード単位でのリロードのみが許可される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 49 | ノード情報・統計 | 主機能 | セキュア設定をリロードする処理 |
| 83 | 暗号化・復号化 | 補助機能 | 暗号化されたセキュア設定の復号処理 |

## 画面種別

実行（ノード操作）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| POST | `/_nodes/reload_secure_settings` | 全ノードのセキュア設定をリロード |
| POST | `/_nodes/{node_id}/reload_secure_settings` | 指定ノードのセキュア設定をリロード |

## 入出力項目

### パスパラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| node_id | list | いいえ | カンマ区切りのノードIDリスト。空の場合は全ノードが対象 |

### クエリパラメータ

| 項目名 | 型 | 必須 | デフォルト | 説明 |
|--------|-----|------|-----------|------|
| timeout | time | いいえ | - | 明示的な操作タイムアウト |

### リクエストボディ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| secure_settings_password | string | いいえ | OpenSearch keystoreのパスワード |

## 表示項目

### レスポンス

| 項目名 | 型 | 説明 |
|--------|-----|------|
| _nodes.total | integer | リクエスト対象の総ノード数 |
| _nodes.successful | integer | 成功したノード数 |
| _nodes.failed | integer | 失敗したノード数 |
| cluster_name | string | クラスタ名 |
| nodes | object | ノードごとの結果（ノードID -> リロード結果） |

## イベント仕様

### 1-セキュア設定リロードリクエスト送信

1. クライアントがPOSTリクエストを送信する
2. `RestReloadSecureSettingsAction`がリクエストを受信し、ノードIDとkeystoreパスワードをパースする（行番号94-106）
3. `TransportNodesReloadSecureSettingsAction.doExecute`でTLSチェックが実行される（行番号121-143）
4. 各ノードの`nodeOperation`でkeystoreの再読み込み・復号・プラグインへのブロードキャストが実行される（行番号146-184）
5. 全ノードの結果が集約され、JSON形式のレスポンスが返される

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| セキュア設定リロード | なし（ファイルシステム） | READ | keystoreファイルの再読み込み |

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

本APIはデータベースを使用しない。keystoreファイル（ファイルシステム上）を読み取り専用でアクセスし、インメモリのプラグイン設定を更新する。

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 条件 |
|-------------|------|----------|------|
| - | 成功 | HTTP 200 OK + ノードごとの結果 | 正常にリロード完了 |
| - | エラー | "Secure settings cannot be updated cluster wide when TLS for the transport layer is not enabled." | TLS未有効でパスワード付きクラスタ全体リクエスト |
| - | エラー | "Keystore is missing" | keystoreファイルが存在しない |
| - | エラー | "Reload failed for plugin [{plugin}]" | プラグインのリロード失敗（ログ出力） |

## 例外処理

| 例外条件 | HTTPステータス | 処理内容 |
|---------|--------------|---------|
| TLS未有効でクラスタ全体リクエスト | 500 | OpenSearchExceptionがスローされ、`_local`フィルタ使用を推奨 |
| keystoreファイル不在 | 200 | ノード単位のエラーとしてレスポンスに含まれる |
| keystoreパスワード不正 | 200 | ノード単位のエラーとしてレスポンスに含まれる |
| プラグインリロード失敗 | 200 | 例外が集約され、ノード単位のエラーとして返される |

## 備考

- `secure_settings_password`フィールドはログ出力時にフィルタリングされ、監査ログに記録されない（`RestRequestFilter`実装）
- パスワードは処理完了後に明示的にクリアされる（`closePassword`メソッド）
- CircuitBreakerをトリップしない設計（`canTripCircuitBreaker`が`false`を返す）

---

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

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

### 推奨読解順序

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

まず、リクエスト・レスポンスのデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | nodes.reload_secure_settings.json | `rest-api-spec/src/main/resources/rest-api-spec/api/nodes.reload_secure_settings.json` | APIのURL、パラメータ、ボディの定義を確認 |
| 1-2 | NodesReloadSecureSettingsRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/reload/NodesReloadSecureSettingsRequest.java` | リクエストオブジェクトの構造とSecureStringの管理方法 |
| 1-3 | NodesReloadSecureSettingsResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/reload/NodesReloadSecureSettingsResponse.java` | レスポンスオブジェクトの構造とNodeResponseの内容 |

**読解のコツ**: `SecureString`はパスワードを安全に扱うためのクラスで、使用後にメモリからクリアされる点に注意。

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

処理の起点となるRESTハンドラを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestReloadSecureSettingsAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestReloadSecureSettingsAction.java` | RESTリクエストの受付とパラメータ解析 |

**主要処理フロー**:
1. **行番号88-90**: ルート定義（POST /_nodes/reload_secure_settings, POST /_nodes/{nodeId}/reload_secure_settings）
2. **行番号94-106**: リクエストパース処理 - ノードIDとkeystoreパスワードの抽出
3. **行番号69-79**: ObjectParserによる`secure_settings_password`フィールドのパース定義
4. **行番号108-119**: レスポンスビルダーの定義 - NodesHeader + cluster_name + ノード結果

#### Step 3: Transport層の処理を理解する

ノード間通信とセキュア設定リロードの実際の処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportNodesReloadSecureSettingsAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/reload/TransportNodesReloadSecureSettingsAction.java` | ノード間のリロード処理とTLSチェック |

**主要処理フロー**:
- **行番号121-143**: `doExecute` - TLSチェックとパスワードクリーンアップ
- **行番号146-184**: `nodeOperation` - keystoreの読み込み、復号、プラグインへのブロードキャスト
- **行番号152-153**: KeyStoreWrapperの読み込みとnullチェック
- **行番号161**: keystoreの復号
- **行番号166-176**: ReloadablePluginへの設定ブロードキャスト

#### Step 4: キーストア管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | KeyStoreWrapper.java | `server/src/main/java/org/opensearch/common/settings/KeyStoreWrapper.java` | keystoreの読み込みと復号メカニズム |
| 4-2 | ReloadablePlugin.java | `server/src/main/java/org/opensearch/plugins/ReloadablePlugin.java` | プラグインのリロードインターフェース |

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

```
RestReloadSecureSettingsAction.prepareRequest (行番号94)
    |
    +-- PARSER.parse (行番号103) -- secure_settings_password解析
    |
    +-- NodesReloadSecureSettingsRequestBuilder.execute (行番号108)
            |
            +-- TransportNodesReloadSecureSettingsAction.doExecute (行番号121)
                    |
                    +-- isNodeTransportTLSEnabled (行番号214) -- TLSチェック
                    |
                    +-- super.doExecute -- ノード分散実行
                            |
                            +-- nodeOperation (行番号146)
                                    |
                                    +-- KeyStoreWrapper.load (行番号152)
                                    +-- keystore.decrypt (行番号161)
                                    +-- Settings.builder().setSecureSettings (行番号163)
                                    +-- pluginsService.filterPlugins(ReloadablePlugin.class)
                                        .forEach(p -> p.reload(settings)) (行番号166)
```

### データフロー図

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

POST リクエスト         RestReloadSecureSettingsAction       JSON レスポンス
  node_id (path)  ------>  パラメータ解析                     _nodes (成功/失敗数)
  timeout (query)          |                                  cluster_name
  password (body)          v                                  nodes (ノード別結果)
                    TransportNodesReloadSecureSettingsAction
                           |
                           v (各ノードで実行)
                    KeyStoreWrapper.load()
                           |
                           v
                    keystore.decrypt(password)
                           |
                           v
                    ReloadablePlugin.reload(settings) -----> プラグイン設定更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| nodes.reload_secure_settings.json | `rest-api-spec/src/main/resources/rest-api-spec/api/nodes.reload_secure_settings.json` | API定義 | REST APIスペック定義 |
| RestReloadSecureSettingsAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestReloadSecureSettingsAction.java` | ソース | RESTリクエストハンドラ |
| TransportNodesReloadSecureSettingsAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/reload/TransportNodesReloadSecureSettingsAction.java` | ソース | Transport層のリロード処理 |
| NodesReloadSecureSettingsAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/reload/NodesReloadSecureSettingsAction.java` | ソース | アクション定義 |
| NodesReloadSecureSettingsRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/reload/NodesReloadSecureSettingsRequest.java` | ソース | リクエストモデル |
| NodesReloadSecureSettingsResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/reload/NodesReloadSecureSettingsResponse.java` | ソース | レスポンスモデル |
| KeyStoreWrapper.java | `server/src/main/java/org/opensearch/common/settings/KeyStoreWrapper.java` | ソース | keystore管理 |
| ReloadablePlugin.java | `server/src/main/java/org/opensearch/plugins/ReloadablePlugin.java` | ソース | プラグインリロードインターフェース |
