# PAM Project KCMインポート

`pam project kcm-import` は、Keeperコネクションマネージャー (Apache Guacamoleとも呼ばれる) のデータベースから接続、ユーザー、グループを直接読み取り、 `kcm_mappings.json` により150以上のKCM接続パラメータをKeeperPAM相当へマッピングしたうえで、内部で `pam project import` (新規プロジェクト) または `pam project extend` (既存プロジェクト) に委譲します。インポート用JSONを手書きする必要はありません。

### 概要

```
pam project kcm-import
  ( --db-host=HOST [--db-port=PORT] [--db-name=DB] [--db-user=USER]
    [--db-password-record=UID] [--db-ssl]
  | --docker-detect [--docker-container=NAME] )
  [--db-type=mysql|postgresql]
  [--name=PROJECT | --config=UID_OR_TITLE]
  [--gateway=UID_OR_NAME]
  [--folder-mode=ksm|exact|flat]
  [--output=FILE | --dry-run]
  [--skip-users]
  [--include-disabled]
```

`--db-host` **または** `--docker-detect` のいずれかが必須です。その他はデフォルト値があります。

### 要件

* 認証済みのコマンダーセッション — 先に `keeper login` を実行してください。
* コマンダーを実行するホストからKCMデータベースへのネットワークアクセス。
* コマンダーを実行するPythonと同じ環境にDBドライバーをインストール。
* **MySQL** → `pymysql`(推奨) または `mysql-connector-python`。インストール: `pip3 install pymysql`
* **PostgreSQL** → `psycopg2-binary`。インストール: `pip3 install psycopg2-binary`
* `--docker-detect` 使用時は `PATH` 上に `docker` CLI。
* PAMプロジェクト、ゲートウェイ、共有フォルダを作成できるKeeperロール。
* `keepercommander/commands/pam_import/kcm_mappings.json` が存在すること。

### コマンドラインオプション

`--db-host` または `--docker-detect` のいずれかが必須です。その他はデフォルト値があります。

#### ソース: KCMの読み取り元

* `--db-host` → KCMデータベースのホスト名またはIP。**`--docker-detect` を使わない場合は必須。**
* `--docker-detect` → `docker inspect` でDockerコンテナの `MYSQL_*`/`POSTGRES_*` 環境変数を読み、ホスト/ポート/DB/ユーザー/パスワードを自動検出。**`--db-host` を使わない場合は必須。**
* `--docker-container` → `--docker-detect` 時にinspectするコンテナ名。デフォルト: `guacamole` 。
* `--db-type` → DBエンジン。選択肢: `mysql` 、 `postgresql` 。デフォルト: `mysql` 。
* `--db-port` → DBのTCPポート。デフォルト: mysqlは `3306` 、postgresqlは `5432` 。
* `--db-name` → データベース名。デフォルト: `guacamole_db` 。
* `--db-user` → DBユーザー名。デフォルト: `guacamole_user` 。読み取り専用の `SELECT` で十分。
* `--db-password-record` → DBパスワードを格納したKeeperレコードのUID。これも `--docker-detect` もない場合、非表示の `getpass` でパスワードをプロンプトします。CLI引数でパスワードは受け付けません。
* `--db-ssl` → DB接続にTLSを要求。ローカル/RFC1918以外のホストへ `--db-ssl` なしで接続すると警告を出します。

#### 宛先: Keeper上の配置先

* `--name` 、 `-n` → 新規インポートのプロジェクト名。デフォルト: `KCM-Import-<YYYYMMDD-HHMMSS>` 。**`--config` と相互排他。**
* `--config` 、 `-c` → 既存のPAM構成UIDまたはタイトル。**拡張モード**に切り替え。**`--name` と相互排他。**
* `--gateway` 、 `-g` → 既存ゲートウェイのUIDまたは名前。省略時はオンラインゲートウェイの対話型ピッカー。**`--config` モードでは無視。**
* `--folder-mode` → KCM接続グループをKeeper共有フォルダへマッピングする方法。選択肢: `ksm` 、 `exact` 、 `flat` 。デフォルト: `ksm` 。

#### 出力モード

以下の3つは相互排他です。フラグなし (デフォルト) はボルトへインポートします。

* `--dry-run` 、 `-d` → 組み立てた `pam_data` JSONを標準出力に表示 (機密フィールドは `[REDACTED]` に置換)。ボルトへの書き込みなし。
* `--output` 、 `-o` → 完全なJSON (平文パスワード) を `0600` ファイルへ書き込み。ボルトへの書き込みなし。
* *(フラグなし)* → デフォルト。新規は `pam project import`、既存構成は `pam project extend` に委譲。

#### フィルタリング

* `--skip-users` → `pamUser` レコードの生成をスキップ。
* `--include-disabled` → 無効化されたKCM接続 (`max_connections == 0`) を含める。

### クイックスタート

```bash
# ローカル Docker 上の KCM、認証情報を自動検出:
pam project kcm-import --docker-detect --docker-container=guacamole \
    --db-type=postgresql --name="My KCM Migration" --dry-run

# リモート KCM DB、パスワードをプロンプト:
pam project kcm-import --db-host=kcm-db.internal --db-type=postgresql \
    --db-name=guacamole_db --db-user=guacamole_user \
    --name="Prod KCM" --dry-run

# Keeper レコードからパスワードを取得:
pam project kcm-import --db-host=kcm-db.internal --db-type=postgresql \
    --db-password-record=<RECORD_UID> --name="Prod KCM" --dry-run
```

{% hint style="info" %}
最初は必ず `--dry-run` で実行し、問題なければフラグを外してプロジェクトを実際に作成してください。
{% endhint %}

### データベース認証情報の3通り

* **Docker自動検出** (`--docker-detect [--docker-container=NAME]`) → コマンダーと同じホスト上のDockerでKCMを実行している場合。
* **ボルトレコード** (`--db-host=H --db-password-record=<UID>`) → 繰り返し実行やスクリプト化された移行向け。
* **対話型プロンプト** (`--db-host=H` でレコードなし) → 一度きりの実行。非表示 `getpass` プロンプト。CLI引数でパスワードは渡せません。

#### 必要なデータベース権限

DBユーザーには、以下のGuacamoleテーブルへの **`SELECT`** が必要です (読み取り専用。コマンドはソースDBへ書き込みません)。

* `guacamole_connection`
* `guacamole_connection_parameter`
* `guacamole_connection_attribute`
* `guacamole_connection_group`
* `guacamole_connection_permission`
* `guacamole_entity`
* `information_schema.tables`

**PostgreSQL — 最小の読み取り専用ロール:**

```sql
CREATE USER keeper_kcm_ro WITH PASSWORD '...';
GRANT CONNECT ON DATABASE guacamole_db TO keeper_kcm_ro;
GRANT USAGE ON SCHEMA public TO keeper_kcm_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO keeper_kcm_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO keeper_kcm_ro;
```

**MySQL — 最小の読み取り専用ロール:**

```sql
CREATE USER 'keeper_kcm_ro'@'%' IDENTIFIED BY '...';
GRANT SELECT ON guacamole_db.* TO 'keeper_kcm_ro'@'%';
FLUSH PRIVILEGES;
```

### フォルダレイアウト — `--folder-mode`

KCMは接続を「接続グループ」のツリーで整理します。このフラグはそのツリーをKeeper共有フォルダへどうマッピングするかを制御します。モードにかかわらず、リソースは `KCM Resources - <root>` 、ユーザーは `KCM Users - <root>` 配下に配置されます。

* `ksm`*(デフォルト)* → KSM構成が付いたグループをルートとし、子孫はその下にネストしたまま残す。
* `exact` → KCMグループ階層を1:1で再現。
* `flat` → 各グループをトップレベルの共有フォルダにする (ネストなし)。

{% hint style="info" %}
グループ名はサニタイズされます — `/` 、 `\` 、 `..` はパストラバーサル防止のため `_` に置換されます。
{% endhint %}

### プロトコル → レコードタイプのマッピング

| KCMプロトコル     | Keeperレコードタイプ      | 注記                                         |
| ------------ | ------------------ | ------------------------------------------ |
| `ssh`        | `pamMachine`       | SFTPサブリソースを自動抽出                            |
| `rdp`        | `pamMachine`       | RDPオプションは `kcm_mappings.json` でマッピング       |
| `vnc`        | `pamMachine`       |                                            |
| `telnet`     | `pamMachine`       | ログイン正規表現パラメータを引き継ぎ                         |
| `kubernetes` | `pamMachine`       | 名前空間/ポッド/コンテナ/証明書フィールドを引き継ぎ                |
| `mysql`      | `pamDatabase`      | `database_type = "mysql"`                  |
| `postgres`   | `pamDatabase`      | KCMでは `postgres` 、KeeperPAMでは `postgresql` |
| `sql-server` | `pamDatabase`      |                                            |
| `http`       | `pamRemoteBrowser` | RBIのみ                                      |
| *その他*        | `pamMachine`       | 未知のプロトコルはフォールバック                           |

無効化されていない各KCM接続は、リソースレコード1件、 `launch_credentials` に接続された `pamUser` レコード1件、および (SFTP付きSSHの場合) 追加のSFTPリソース+ユーザーペアを生成します。

### ボルトに作成されるもの

`--dry-run`/`--output` なしで実行すると、以下の順で作成されます。

1. \*\*`--name`\*\*にちなんだトップレベルのプロジェクトフォルダ。
2. **グループルートごとに2つの共有フォルダ** — `KCM Resources - <root>` と `KCM Users - <root>`。
3. **PAM構成レコード** (拡張モードではスキップ)。
4. **ゲートウェイ** — `--gateway` 指定時は再利用、なければ対話型ピッカー (`[N] Create new`)。
5. **リソースレコード** (`pamMachine` / `pamDatabase` / `pamRemoteBrowser`)。
6. **ユーザーレコード** (`pamUser`)、各リソースの `launch_credentials` に接続。
7. SFTP構成があるSSH接続向けの**SFTPサブリソースとサブユーザー**。

### ゲートウェイの選択

* `--gateway=<UID|name>` → その既存ゲートウェイを再利用 (オンラインであること)。
* `--gateway` なし → 対話プロンプト。番号で再利用、または `N` で新規プロビジョニング。
* オンラインゲートウェイがない → プロンプトなしで「新規作成」へ。
* `--config` モード → ゲートウェイフラグは無視。

### 出力モードの詳細

```bash
# 1. ドライラン: パスワードを [REDACTED] にして JSON を標準出力
pam project kcm-import --db-host=... --dry-run

# 2. 出力ファイル: 完全 JSON (平文パスワード) を 0600 ファイルへ
pam project kcm-import --db-host=... --output=/tmp/kcm-export.json

# 3. デフォルト: ボルトへインポート
pam project kcm-import --db-host=... --name="Prod KCM"
```

### 再実行とクリーンアップ

**同じ `--name` で再実行** — `pam project import` はタイトルでレコードを照合し、既存はスキップします。新しい接続は追加されます。既存接続への変更は自動では取り込まれません。

**既存プロジェクトに新しいKCM接続を追加** — `--name` の代わりに `--config=<UID_OR_TITLE>` を使用してください。

**インポートのロールバック:**

1.ボルトでプロジェクトフォルダを右クリック → **フォルダを削除**。 2.必要に応じて、管理コンソール → 特権アクセス → ゲートウェイからゲートウェイを別途削除。

{% hint style="info" %}
**ベストプラクティス:** まず `--dry-run` 、続けて `--output=/tmp/kcm-preview.json` で平文値を確認し、その後本番インポートを実行してください。
{% endhint %}

### 例

```bash
# 1. スモークテスト — ローカル Docker、PostgreSQL、接続 3 件
pam project kcm-import --db-host=192.168.32.10 --db-type=postgresql \
    --db-user=guacamole_user --db-name=guacamole_db --db-port=5432 \
    --name="Live-Test-Guac" --dry-run

# 2. 大きめの POC — HTTP+SSH 接続 25 件
pam project kcm-import --db-host=172.29.0.3 --db-type=postgresql \
    --db-user=guacamole_user --db-name=guacamole_db --db-port=5432 \
    --name="Live-Test-KCM" --dry-run

# 3. レビュー用に完全 JSON をディスクへ保存
pam project kcm-import --db-host=192.168.32.10 --db-type=postgresql \
    --db-user=guacamole_user --db-name=guacamole_db --db-port=5432 \
    --name="Output-Test" --output=/tmp/kcm-output-test.json

# 4. ユーザーレコードをスキップ
pam project kcm-import --db-host=172.29.0.3 --db-type=postgresql \
    --db-user=guacamole_user --db-name=guacamole_db --db-port=5432 \
    --name="Skip-Users-Test" --skip-users --dry-run

# 5. フラットフォルダモード
pam project kcm-import --db-host=172.29.0.3 --db-type=postgresql \
    --db-user=guacamole_user --db-name=guacamole_db --db-port=5432 \
    --name="Flat-Mode-Test" --folder-mode=flat --dry-run

# 6. Docker 自動検出
pam project kcm-import --docker-detect --docker-container=kcm-setup-guacamole-1 \
    --db-type=postgresql --name="Docker-Detect-Test" --dry-run
```

### よくある落とし穴

* **`Either --db-host or --docker-detect is required`** → 両方省略。いずれか一方が必須。
* **`No PAM configuration found for gateway "X"`** → ゲートウェイにまだPAM構成がない。先に `pam config create` を実行。
* **`Database connection failed: <ErrorType>`** → コマンダーは認証情報漏洩を避けるため詳細メッセージを隠す。デバッグログ (`-d` をシェル起動時に) で完全な例外を確認。
* **リモートDBへ `--db-ssl` なしで接続** → `WARNING` が出る。認証情報は平文で送信される。非ローカルホストでは常に `--db-ssl` を指定。
* **Docker自動検出でコンテナ名が誤り** → デフォルトは `guacamole` 。Composeでは `<project>-guacamole-1` になりがち。 `docker ps --format '{{.Names}}'` で確認。
* **`pam project import` が `kcm_mappings.json` 欠如を報告** → ファイルはコマンダーに同梱。 `git ls-files keepercommander/commands/pam_import/kcm_mappings.json` で確認。欠けていれば上流 `release` から取得。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keeper.io/keeperpam/jp/commander-cli/command-reference/keeperpam-commands/pam-project-kcm-import.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
