rds_ssm_connect 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +92 -41
- package/README.md +90 -70
- package/connect.js +1 -1
- package/package.json +1 -1
- package/src/App.svelte +1 -30
- package/src-tauri/Cargo.lock +1 -1
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/src/lib.rs +0 -131
- package/src-tauri/tauri.conf.json +1 -1
- package/RESEARCH-AWS-TOOLS-INTEGRATION.md +0 -538
- package/src/lib/PrerequisitesCheck.svelte +0 -253
package/CLAUDE.md
CHANGED
|
@@ -4,34 +4,67 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
4
4
|
|
|
5
5
|
## Project Overview
|
|
6
6
|
|
|
7
|
-
**rds_ssm_connect** is a Node.js CLI tool that enables secure connections to AWS RDS databases through AWS Systems Manager (SSM) port forwarding via bastion hosts.
|
|
7
|
+
**rds_ssm_connect** is a Node.js CLI tool and Tauri desktop app that enables secure connections to AWS RDS databases through AWS Systems Manager (SSM) port forwarding via bastion hosts. Projects are user-configurable — the tool reads AWS profiles from `~/.aws/config`, loads project definitions from `~/.rds-ssm-connect/projects.json`, retrieves database credentials from AWS Secrets Manager, and sets up port forwarding through a bastion instance.
|
|
8
8
|
|
|
9
9
|
## Key Architecture
|
|
10
10
|
|
|
11
11
|
### Entry Point
|
|
12
12
|
- `connect.js` - Main executable (shebang: `#!/usr/bin/env node`)
|
|
13
13
|
- Reads AWS profiles from `~/.aws/config`
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
14
|
+
- Loads project configs from `~/.rds-ssm-connect/projects.json` via `configLoader.js`
|
|
15
|
+
- Uses `inquirer` for interactive project/environment selection
|
|
16
|
+
- Includes first-run wizard when no projects are configured
|
|
17
|
+
- Uses AWS SDK v3 directly (STS, EC2, RDS, SSM, Secrets Manager, SSO OIDC)
|
|
18
|
+
- Ensures SSO session is valid before connecting (via `src/sso-login.js`)
|
|
19
|
+
- Establishes SSM port forwarding session with keepalive and auto-reconnect
|
|
17
20
|
|
|
18
21
|
### Configuration
|
|
19
|
-
- `
|
|
20
|
-
- `
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
- `configLoader.js` - Project config CRUD for `~/.rds-ssm-connect/projects.json`
|
|
23
|
+
- `loadProjectConfigs()` / `saveProjectConfig()` / `deleteProjectConfig()`
|
|
24
|
+
- `validateProjectConfig()` - validates required fields, region format, port format, shell-safe patterns
|
|
25
|
+
- Each project defines: name, region, database, secretPrefix, rdsType, engine, rdsPattern, profileFilter, envPortMapping, defaultPort
|
|
26
|
+
|
|
27
|
+
### GUI Adapter
|
|
28
|
+
- `gui-adapter.js` - JSON stdin/stdout IPC bridge for Tauri sidecar
|
|
29
|
+
- Commands: `list-projects`, `list-profiles`, `connect`, `disconnect`, `disconnect-all`, `status`, `list-project-configs`, `save-project-config`, `delete-project-config`, `sso-login`, `ping`
|
|
30
|
+
- Manages multiple simultaneous connections with strict port availability checks
|
|
31
|
+
- SSO pre-flight validation before connecting
|
|
32
|
+
|
|
33
|
+
### Backend Modules (src/)
|
|
34
|
+
- `aws-clients.js` - AWS SDK client factory (STS, EC2, RDS, SSM, Secrets Manager)
|
|
35
|
+
- `aws-operations.js` - AWS operations (find bastion, get endpoint, get credentials, start session, etc.)
|
|
36
|
+
- `credential-resolver.js` - AWS credential chain resolution (SSO, profiles)
|
|
37
|
+
- `sso-login.js` - AWS SSO OIDC device authorization flow
|
|
38
|
+
- `plugin-resolver.js` - Locates session-manager-plugin binary
|
|
39
|
+
|
|
40
|
+
### Tauri Desktop App
|
|
41
|
+
- `src-tauri/src/lib.rs` - Tauri commands (connect, disconnect, saved connections CRUD, project config CRUD, AWS profile CRUD, updates)
|
|
42
|
+
- `src-tauri/tauri.conf.json` - App config, plugins, window settings, bundling
|
|
43
|
+
- Session Manager Plugin is bundled as an external binary
|
|
44
|
+
|
|
45
|
+
### Frontend (src/)
|
|
46
|
+
- `App.svelte` - Main app shell (Svelte 5 with runes)
|
|
47
|
+
- `lib/ConnectionForm.svelte` - Project/environment selector + connect button
|
|
48
|
+
- `lib/ActiveConnections.svelte` - Live connection panels with credentials
|
|
49
|
+
- `lib/SavedConnections.svelte` - Bookmarked connections list
|
|
50
|
+
- `lib/Settings.svelte` - Project management + AWS profile CRUD + raw config editor
|
|
51
|
+
- `lib/SessionStatus.svelte` - Connection status indicator
|
|
52
|
+
- `lib/UpdateBanner.svelte` - In-app update notification
|
|
53
|
+
- `lib/CopyButton.svelte` - Reusable copy-to-clipboard with feedback
|
|
54
|
+
- `lib/ConfirmDialog.svelte` - Reusable confirmation modal
|
|
55
|
+
- `lib/utils.js` - Shared utilities (clipboard, timeout, focus trap)
|
|
25
56
|
|
|
26
57
|
### Core Flow
|
|
27
58
|
1. Read AWS profiles from `~/.aws/config`
|
|
28
|
-
2.
|
|
29
|
-
3.
|
|
30
|
-
4.
|
|
31
|
-
5.
|
|
32
|
-
6.
|
|
33
|
-
7.
|
|
34
|
-
8.
|
|
59
|
+
2. Load project configs from `~/.rds-ssm-connect/projects.json`
|
|
60
|
+
3. Prompt user to select project (filtered by available profiles)
|
|
61
|
+
4. Filter and prompt for environment (AWS profile) based on project's `profileFilter`
|
|
62
|
+
5. Ensure SSO session is valid (OIDC device authorization if needed)
|
|
63
|
+
6. Query Secrets Manager for RDS credentials (project-specific `secretPrefix`)
|
|
64
|
+
7. Find running bastion instance (tagged with `Name=*bastion*`)
|
|
65
|
+
8. Get RDS endpoint (cluster or instance based on project's `rdsType`)
|
|
66
|
+
9. Start SSM port forwarding session with correct local/remote ports
|
|
67
|
+
10. Display connection details for database client
|
|
35
68
|
|
|
36
69
|
## Development Commands
|
|
37
70
|
|
|
@@ -45,16 +78,24 @@ npm install
|
|
|
45
78
|
npm test
|
|
46
79
|
```
|
|
47
80
|
Tests cover:
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
81
|
+
- Project config loading, validation, and CRUD (`configLoader.test.js`)
|
|
82
|
+
- AWS operations (`aws-operations.test.js`)
|
|
83
|
+
- Credential resolution (`credential-resolver.test.js`)
|
|
84
|
+
- SSO login flow (`sso-login.test.js`)
|
|
85
|
+
- Plugin resolution (`plugin-resolver.test.js`)
|
|
86
|
+
- Port mapping and config parsing (`connect.test.js`)
|
|
52
87
|
|
|
53
88
|
### Local Testing
|
|
54
89
|
```bash
|
|
55
90
|
node connect.js
|
|
56
91
|
```
|
|
57
92
|
|
|
93
|
+
### Desktop App Development
|
|
94
|
+
```bash
|
|
95
|
+
npm run dev:gui # Tauri dev mode (full app)
|
|
96
|
+
npm run build:gui # Build Tauri desktop app
|
|
97
|
+
```
|
|
98
|
+
|
|
58
99
|
### Global Installation (for testing as installed package)
|
|
59
100
|
```bash
|
|
60
101
|
npm install -g .
|
|
@@ -62,38 +103,34 @@ rds_ssm_connect
|
|
|
62
103
|
```
|
|
63
104
|
|
|
64
105
|
### Publishing
|
|
65
|
-
|
|
106
|
+
- **npm**: Published via GitHub Actions workflow (`.github/workflows/npm-publish.yml`) when a release is created
|
|
107
|
+
- **Desktop**: Multi-platform builds (macOS ARM64/x64, Linux ARM64/x64, Windows x64) via `tauri-action` on git tags
|
|
66
108
|
|
|
67
109
|
## Prerequisites for Running
|
|
68
110
|
|
|
69
|
-
- `aws-vault` - Required for AWS credential management
|
|
70
|
-
- AWS CLI - Required for AWS API calls
|
|
71
111
|
- Node.js (ES modules enabled via `"type": "module"` in package.json)
|
|
72
112
|
- Properly configured `~/.aws/config` with named profiles
|
|
113
|
+
- Session Manager Plugin (bundled in desktop app; CLI requires separate install)
|
|
114
|
+
|
|
115
|
+
Note: aws-vault and AWS CLI are **not required** — the app uses AWS SDK v3 natively for all API calls and credential resolution.
|
|
73
116
|
|
|
74
117
|
## AWS Resource Naming Conventions
|
|
75
118
|
|
|
76
|
-
The application relies on
|
|
119
|
+
The application relies on AWS resource naming patterns defined per project in `~/.rds-ssm-connect/projects.json`:
|
|
77
120
|
|
|
78
|
-
**
|
|
79
|
-
- **Secrets**: Must start with `rds!cluster`
|
|
121
|
+
- **Secrets**: Must start with the project's `secretPrefix` (e.g., `rds!cluster`, `rds!db`)
|
|
80
122
|
- **Bastion instances**: Must be tagged with `Name=*bastion*` and in `running` state
|
|
81
|
-
- **RDS clusters**: DBClusterIdentifier must
|
|
82
|
-
- **
|
|
83
|
-
|
|
84
|
-
**Covered Project:**
|
|
85
|
-
- **Secrets**: Must start with `rds!db`
|
|
86
|
-
- **Bastion instances**: Must be tagged with `Name=*bastion*` and in `running` state
|
|
87
|
-
- **RDS instances**: DBInstanceIdentifier must contain `covered-db` and be in `available` state
|
|
88
|
-
- **Region**: us-west-1
|
|
89
|
-
- **AWS Profiles**: Must start with `covered` (e.g., `covered`, `covered-staging`)
|
|
123
|
+
- **RDS clusters**: DBClusterIdentifier must match the project's `rdsPattern` and be `available` (when `rdsType` is `cluster`)
|
|
124
|
+
- **RDS instances**: DBInstanceIdentifier must match the project's `rdsPattern` and be `available` (when `rdsType` is `instance`)
|
|
90
125
|
|
|
91
126
|
## Important Notes
|
|
92
127
|
|
|
93
|
-
-
|
|
128
|
+
- Projects are user-configurable via `~/.rds-ssm-connect/projects.json` (no hardcoded defaults)
|
|
129
|
+
- Port assignment is based on project-specific `envPortMapping` with `defaultPort` fallback
|
|
94
130
|
- The tool keeps the SSM session running until Ctrl+C is pressed
|
|
95
|
-
-
|
|
96
|
-
-
|
|
131
|
+
- AWS region is determined by the selected project's `region` field
|
|
132
|
+
- SSO sessions are validated before connecting; browser opens automatically if needed
|
|
133
|
+
- Desktop app bundles Session Manager Plugin as an external binary
|
|
97
134
|
|
|
98
135
|
## Error Handling & Recovery
|
|
99
136
|
|
|
@@ -106,12 +143,26 @@ The application automatically handles the race condition where a bastion instanc
|
|
|
106
143
|
4. Verifies SSM agent is online using `describe-instance-information`
|
|
107
144
|
5. Retries port forwarding with new instance (max 2 retries)
|
|
108
145
|
|
|
146
|
+
### Auto-Reconnect
|
|
147
|
+
When an established session drops unexpectedly (idle timeout, network issue):
|
|
148
|
+
|
|
149
|
+
1. Verifies AWS credentials are still valid (avoids opening SSO tabs when user is away)
|
|
150
|
+
2. Re-discovers infrastructure (bastion may have been replaced by ASG)
|
|
151
|
+
3. Reconnects on the same local port (up to 3 attempts with 3s delay)
|
|
152
|
+
|
|
153
|
+
### Keepalive
|
|
154
|
+
Periodic TCP pings every 4 minutes prevent SSM from timing out idle connections.
|
|
155
|
+
|
|
109
156
|
### Configuration Constants
|
|
110
|
-
All retry/timeout values are configurable in `RETRY_CONFIG
|
|
157
|
+
All retry/timeout values are configurable in `RETRY_CONFIG` (`connect.js`):
|
|
111
158
|
- `BASTION_WAIT_MAX_RETRIES`: 20 (time to wait for new instance)
|
|
112
159
|
- `BASTION_WAIT_RETRY_DELAY_MS`: 15000 (delay between instance checks)
|
|
113
160
|
- `PORT_FORWARDING_MAX_RETRIES`: 2 (connection retry attempts)
|
|
114
161
|
- `SSM_AGENT_READY_WAIT_MS`: 10000 (stabilization time after agent online)
|
|
162
|
+
- `KEEPALIVE_INTERVAL_MS`: 240000 (TCP ping interval, 4 minutes)
|
|
163
|
+
- `AUTO_RECONNECT_MAX_RETRIES`: 3 (auto-reconnect attempts)
|
|
164
|
+
- `AUTO_RECONNECT_DELAY_MS`: 3000 (delay between reconnect attempts)
|
|
165
|
+
- `CREDENTIAL_CHECK_TIMEOUT_MS`: 60000 (credential validation timeout)
|
|
115
166
|
|
|
116
167
|
### Process Cleanup
|
|
117
|
-
The application registers handlers for `SIGINT`, `SIGTERM`, and `exit` events to properly clean up child processes (SSM sessions) to prevent zombie processes.
|
|
168
|
+
The application registers handlers for `SIGINT`, `SIGTERM`, and `exit` events to properly clean up child processes (SSM sessions) using a three-strategy kill approach (process group, individual SIGTERM, SIGKILL) to prevent zombie processes.
|
package/README.md
CHANGED
|
@@ -4,21 +4,22 @@ Secure database tunneling to AWS RDS through SSM port forwarding via bastion hos
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **Multiple simultaneous connections** with
|
|
7
|
+
- **User-configurable projects** — define any number of RDS projects (Aurora clusters or RDS instances, PostgreSQL or MySQL)
|
|
8
|
+
- **Multiple simultaneous connections** with strict port availability checks
|
|
9
9
|
- **Saved connections** — bookmark frequently used profiles with one-click connect
|
|
10
|
-
- **Auto-reconnect** —
|
|
10
|
+
- **Auto-reconnect** — transparently reconnects on the same port if the session drops unexpectedly
|
|
11
|
+
- **TargetNotConnected recovery** — cycles bastion instances via ASG when the SSM agent is disconnected
|
|
12
|
+
- **SSO support** — handles AWS SSO (OIDC device authorization) with automatic browser launch
|
|
13
|
+
- **Keepalive** — periodic TCP pings prevent SSM idle timeout
|
|
11
14
|
- **In-app updates** — checks GitHub releases, downloads and installs signed updates
|
|
12
|
-
- **Prerequisites validation** — detects missing `aws-vault` and AWS CLI on launch
|
|
13
15
|
- **Keyboard shortcuts** — `Cmd/Ctrl + ,` for settings
|
|
14
16
|
- **Accessible** — ARIA labels, focus trapping, keyboard navigation, screen reader support
|
|
15
17
|
|
|
16
18
|
## Prerequisites
|
|
17
19
|
|
|
18
|
-
- [aws-vault](https://github.com/99designs/aws-vault) — AWS credential management
|
|
19
|
-
- [AWS CLI](https://aws.amazon.com/cli/) — AWS API access
|
|
20
20
|
- [Node.js](https://nodejs.org/) 22+ (CLI only)
|
|
21
21
|
- AWS profiles configured in `~/.aws/config`
|
|
22
|
+
- [Session Manager Plugin](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html) (bundled with desktop app; CLI requires separate install)
|
|
22
23
|
|
|
23
24
|
## Installation
|
|
24
25
|
|
|
@@ -29,12 +30,6 @@ brew tap yarka-guru/tap
|
|
|
29
30
|
brew install --cask rds-ssm-connect
|
|
30
31
|
```
|
|
31
32
|
|
|
32
|
-
This installs the desktop app along with `aws-vault` and `awscli` dependencies. You also need the [Session Manager Plugin](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html):
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
brew install --cask session-manager-plugin
|
|
36
|
-
```
|
|
37
|
-
|
|
38
33
|
Or download the `.dmg` directly from [GitHub Releases](https://github.com/yarka-guru/connection_app/releases).
|
|
39
34
|
|
|
40
35
|
### Linux
|
|
@@ -47,15 +42,10 @@ Or download the `.dmg` directly from [GitHub Releases](https://github.com/yarka-
|
|
|
47
42
|
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.bashrc
|
|
48
43
|
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
|
|
49
44
|
|
|
50
|
-
# Install the app
|
|
45
|
+
# Install the app
|
|
51
46
|
brew tap yarka-guru/tap
|
|
52
47
|
brew install yarka-guru/tap/rds-ssm-connect
|
|
53
48
|
|
|
54
|
-
# Install Session Manager Plugin (ARM64)
|
|
55
|
-
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_arm64/session-manager-plugin.deb" -o session-manager-plugin.deb
|
|
56
|
-
sudo dpkg -i session-manager-plugin.deb
|
|
57
|
-
# For x86_64, replace ubuntu_arm64 with ubuntu_64bit
|
|
58
|
-
|
|
59
49
|
# Make brew tools visible to the desktop app
|
|
60
50
|
echo 'export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"' | sudo tee /etc/profile.d/linuxbrew.sh
|
|
61
51
|
# Log out and back in for this to take effect
|
|
@@ -64,41 +54,20 @@ echo 'export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"' | sudo tee /etc/profil
|
|
|
64
54
|
#### Option B: Direct .deb install
|
|
65
55
|
|
|
66
56
|
```bash
|
|
67
|
-
#
|
|
68
|
-
# ARM64:
|
|
69
|
-
wget https://github.com/yarka-guru/connection_app/releases/latest/download/RDS.SSM.Connect_1.7.5_arm64.deb
|
|
70
|
-
sudo dpkg -i RDS.SSM.Connect_1.7.5_arm64.deb
|
|
71
|
-
# x86_64:
|
|
72
|
-
# wget https://github.com/yarka-guru/connection_app/releases/latest/download/RDS.SSM.Connect_1.7.5_amd64.deb
|
|
73
|
-
# sudo dpkg -i RDS.SSM.Connect_1.7.5_amd64.deb
|
|
74
|
-
|
|
75
|
-
# 2. Install aws-vault
|
|
76
|
-
# ARM64:
|
|
77
|
-
wget https://github.com/99designs/aws-vault/releases/latest/download/aws-vault-linux-arm64 -O aws-vault
|
|
78
|
-
# x86_64:
|
|
79
|
-
# wget https://github.com/99designs/aws-vault/releases/latest/download/aws-vault-linux-amd64 -O aws-vault
|
|
80
|
-
chmod +x aws-vault && sudo mv aws-vault /usr/local/bin/
|
|
81
|
-
|
|
82
|
-
# 3. Install AWS CLI
|
|
83
|
-
# ARM64:
|
|
84
|
-
curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o awscliv2.zip
|
|
85
|
-
# x86_64:
|
|
86
|
-
# curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o awscliv2.zip
|
|
87
|
-
unzip awscliv2.zip && sudo ./aws/install
|
|
88
|
-
|
|
89
|
-
# 4. Install Session Manager Plugin
|
|
57
|
+
# Download and install the app (check GitHub Releases for the latest version)
|
|
90
58
|
# ARM64:
|
|
91
|
-
|
|
59
|
+
wget https://github.com/yarka-guru/connection_app/releases/latest/download/RDS.SSM.Connect_2.0.2_arm64.deb
|
|
60
|
+
sudo dpkg -i RDS.SSM.Connect_2.0.2_arm64.deb
|
|
92
61
|
# x86_64:
|
|
93
|
-
#
|
|
94
|
-
sudo dpkg -i
|
|
62
|
+
# wget https://github.com/yarka-guru/connection_app/releases/latest/download/RDS.SSM.Connect_2.0.2_amd64.deb
|
|
63
|
+
# sudo dpkg -i RDS.SSM.Connect_2.0.2_amd64.deb
|
|
95
64
|
```
|
|
96
65
|
|
|
97
66
|
### Windows
|
|
98
67
|
|
|
99
68
|
Download the `.msi` or `.exe` installer from [GitHub Releases](https://github.com/yarka-guru/connection_app/releases).
|
|
100
69
|
|
|
101
|
-
|
|
70
|
+
No additional prerequisites — the app uses AWS SDK v3 natively.
|
|
102
71
|
|
|
103
72
|
### CLI (all platforms)
|
|
104
73
|
|
|
@@ -106,55 +75,100 @@ Prerequisites must be installed separately: [aws-vault](https://github.com/99des
|
|
|
106
75
|
npm install -g rds_ssm_connect
|
|
107
76
|
```
|
|
108
77
|
|
|
78
|
+
The CLI requires the [Session Manager Plugin](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html) to be installed separately.
|
|
79
|
+
|
|
109
80
|
## Usage
|
|
110
81
|
|
|
111
82
|
### Desktop App
|
|
112
83
|
|
|
113
84
|
Launch the app, select a project and environment, then click **Connect**. Connection credentials are displayed inline with one-click copy buttons. Save connections for quick access later.
|
|
114
85
|
|
|
86
|
+
Manage projects and AWS profiles in **Settings** (`Cmd/Ctrl + ,`).
|
|
87
|
+
|
|
115
88
|
### CLI
|
|
116
89
|
|
|
117
90
|
```bash
|
|
118
91
|
rds_ssm_connect
|
|
119
92
|
```
|
|
120
93
|
|
|
121
|
-
1.
|
|
122
|
-
2. Select
|
|
123
|
-
3.
|
|
124
|
-
4.
|
|
94
|
+
1. On first run with no projects configured, an interactive wizard walks you through creating one
|
|
95
|
+
2. Select a project
|
|
96
|
+
3. Select an environment (AWS profile)
|
|
97
|
+
4. SSO session is validated automatically (opens browser if needed)
|
|
98
|
+
5. The tool retrieves credentials from Secrets Manager, finds a bastion instance, and starts SSM port forwarding
|
|
99
|
+
6. Use the displayed connection details with your database client (`psql`, `mysql`, pgAdmin, DBeaver, etc.)
|
|
125
100
|
|
|
126
101
|
The tunnel stays open until you press `Ctrl+C`.
|
|
127
102
|
|
|
128
103
|
## How It Works
|
|
129
104
|
|
|
130
105
|
1. Reads AWS profiles from `~/.aws/config`
|
|
131
|
-
2.
|
|
132
|
-
3.
|
|
133
|
-
4.
|
|
134
|
-
5.
|
|
135
|
-
6.
|
|
136
|
-
7.
|
|
106
|
+
2. Loads project configurations from `~/.rds-ssm-connect/projects.json`
|
|
107
|
+
3. Filters profiles based on the selected project's `profileFilter`
|
|
108
|
+
4. Ensures AWS SSO session is valid (OIDC device authorization if needed)
|
|
109
|
+
5. Queries AWS Secrets Manager for RDS credentials (project-specific `secretPrefix`)
|
|
110
|
+
6. Finds a running bastion instance (tagged `Name=*bastion*`)
|
|
111
|
+
7. Gets the RDS endpoint (cluster or instance depending on project `rdsType`)
|
|
112
|
+
8. Starts an SSM port forwarding session with the correct local/remote ports
|
|
113
|
+
9. Displays connection details (host, port, username, password, database)
|
|
137
114
|
|
|
138
115
|
### Error Recovery
|
|
139
116
|
|
|
140
|
-
|
|
117
|
+
**TargetNotConnected** — when a bastion instance appears running but SSM agent is disconnected (exit code 254):
|
|
141
118
|
|
|
142
119
|
1. Terminates the disconnected instance
|
|
143
120
|
2. Waits for ASG to launch a replacement (up to 20 retries, 15s intervals)
|
|
144
121
|
3. Verifies the SSM agent is online
|
|
145
122
|
4. Retries port forwarding (up to 2 attempts)
|
|
146
123
|
|
|
124
|
+
**Auto-reconnect** — when an established session drops unexpectedly (idle timeout, network issue):
|
|
125
|
+
|
|
126
|
+
1. Verifies AWS credentials are still valid (avoids opening SSO tabs when user is away)
|
|
127
|
+
2. Re-discovers infrastructure (bastion may have been replaced by ASG)
|
|
128
|
+
3. Reconnects on the same local port (up to 3 attempts with 3s delay)
|
|
129
|
+
|
|
130
|
+
**Keepalive** — periodic TCP pings every 4 minutes prevent SSM from timing out idle connections.
|
|
131
|
+
|
|
147
132
|
## Project Configuration
|
|
148
133
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
| Database | emr | covered_db |
|
|
153
|
-
| RDS type | Aurora cluster | RDS instance |
|
|
154
|
-
| Secret prefix | `rds!cluster` | `rds!db` |
|
|
155
|
-
| Port range | 5432–5452 | 5460–5461 |
|
|
134
|
+
Projects are stored in `~/.rds-ssm-connect/projects.json` and can be managed through the desktop app's Settings UI or the CLI's first-run wizard.
|
|
135
|
+
|
|
136
|
+
Each project defines:
|
|
156
137
|
|
|
157
|
-
|
|
138
|
+
| Field | Description | Example |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| `name` | Display name | `"My Project"` |
|
|
141
|
+
| `region` | AWS region | `"us-east-2"` |
|
|
142
|
+
| `database` | Database name | `"mydb"` |
|
|
143
|
+
| `secretPrefix` | Secrets Manager prefix | `"rds!cluster"` |
|
|
144
|
+
| `rdsType` | `"cluster"` or `"instance"` | `"cluster"` |
|
|
145
|
+
| `engine` | `"postgres"` or `"mysql"` | `"postgres"` |
|
|
146
|
+
| `rdsPattern` | RDS identifier pattern | `"my-app-rds-aurora"` |
|
|
147
|
+
| `profileFilter` | AWS profile prefix filter (optional) | `"my-app"` |
|
|
148
|
+
| `envPortMapping` | Environment suffix to local port mapping | `{"-staging": "5433"}` |
|
|
149
|
+
| `defaultPort` | Fallback local port | `"5432"` |
|
|
150
|
+
|
|
151
|
+
Example `projects.json`:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"my-project": {
|
|
156
|
+
"name": "My Project",
|
|
157
|
+
"region": "us-east-2",
|
|
158
|
+
"database": "mydb",
|
|
159
|
+
"secretPrefix": "rds!cluster",
|
|
160
|
+
"rdsType": "cluster",
|
|
161
|
+
"engine": "postgres",
|
|
162
|
+
"rdsPattern": "my-app-rds-aurora",
|
|
163
|
+
"profileFilter": null,
|
|
164
|
+
"envPortMapping": {
|
|
165
|
+
"-prod": "5432",
|
|
166
|
+
"-staging": "5433"
|
|
167
|
+
},
|
|
168
|
+
"defaultPort": "5432"
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
158
172
|
|
|
159
173
|
## Development
|
|
160
174
|
|
|
@@ -177,11 +191,18 @@ npm run build:gui # Build Tauri desktop app
|
|
|
177
191
|
### Architecture
|
|
178
192
|
|
|
179
193
|
```
|
|
180
|
-
connect.js CLI entry point
|
|
194
|
+
connect.js CLI entry point + core connection logic
|
|
181
195
|
gui-adapter.js IPC bridge — JSON stdin/stdout protocol for Tauri sidecar
|
|
182
|
-
|
|
196
|
+
configLoader.js Project config CRUD (~/.rds-ssm-connect/projects.json)
|
|
197
|
+
src/
|
|
198
|
+
aws-clients.js AWS SDK client factory (STS, EC2, RDS, SSM, Secrets Manager)
|
|
199
|
+
aws-operations.js AWS operations (find bastion, get endpoint, get credentials, etc.)
|
|
200
|
+
credential-resolver.js AWS credential chain resolution (SSO, profiles)
|
|
201
|
+
sso-login.js AWS SSO OIDC device authorization flow
|
|
202
|
+
plugin-resolver.js Locates session-manager-plugin binary
|
|
183
203
|
src-tauri/
|
|
184
|
-
src/lib.rs Tauri commands (connect, disconnect,
|
|
204
|
+
src/lib.rs Tauri commands (connect, disconnect, saved connections, project
|
|
205
|
+
config CRUD, AWS profile CRUD, updates, prerequisites check)
|
|
185
206
|
tauri.conf.json App config, plugins, window settings, bundling
|
|
186
207
|
src/
|
|
187
208
|
App.svelte Main app shell (Svelte 5 with runes)
|
|
@@ -193,8 +214,7 @@ src/
|
|
|
193
214
|
SavedConnections.svelte Bookmarked connections list
|
|
194
215
|
ActiveConnections.svelte Live connection panels with credentials
|
|
195
216
|
SessionStatus.svelte Connection status indicator
|
|
196
|
-
Settings.svelte AWS profile
|
|
197
|
-
PrerequisitesCheck.svelte Missing dependency warnings
|
|
217
|
+
Settings.svelte Project management + AWS profile CRUD + raw config editor
|
|
198
218
|
UpdateBanner.svelte In-app update notification
|
|
199
219
|
```
|
|
200
220
|
|
|
@@ -203,7 +223,7 @@ src/
|
|
|
203
223
|
- **Frontend**: Svelte 5 (runes), Vite
|
|
204
224
|
- **Desktop**: Tauri v2 (Rust)
|
|
205
225
|
- **Backend**: Node.js sidecar bundled with esbuild + pkg
|
|
206
|
-
- **AWS SDK**: v3 (EC2, RDS, SSM, Secrets Manager)
|
|
226
|
+
- **AWS SDK**: v3 (STS, EC2, RDS, SSM, Secrets Manager, SSO OIDC)
|
|
207
227
|
- **Linter**: Biome
|
|
208
228
|
|
|
209
229
|
## Publishing
|
package/connect.js
CHANGED
|
@@ -17,7 +17,7 @@ import { findPluginBinary, spawnPlugin } from './src/plugin-resolver.js'
|
|
|
17
17
|
import { ensureSsoSession } from './src/sso-login.js'
|
|
18
18
|
|
|
19
19
|
// Package info for version checking
|
|
20
|
-
const packageJson = { name: 'rds_ssm_connect', version: '2.0.
|
|
20
|
+
const packageJson = { name: 'rds_ssm_connect', version: '2.0.2' }
|
|
21
21
|
|
|
22
22
|
// Event emitter for IPC communication
|
|
23
23
|
const ipcEmitter = new EventEmitter()
|
package/package.json
CHANGED
package/src/App.svelte
CHANGED
|
@@ -5,7 +5,6 @@ import SavedConnections from './lib/SavedConnections.svelte'
|
|
|
5
5
|
import ConnectionForm from './lib/ConnectionForm.svelte'
|
|
6
6
|
import SessionStatus from './lib/SessionStatus.svelte'
|
|
7
7
|
import UpdateBanner from './lib/UpdateBanner.svelte'
|
|
8
|
-
import PrerequisitesCheck from './lib/PrerequisitesCheck.svelte'
|
|
9
8
|
import Settings from './lib/Settings.svelte'
|
|
10
9
|
import ConfirmDialog from './lib/ConfirmDialog.svelte'
|
|
11
10
|
|
|
@@ -36,9 +35,6 @@ let showCloseConfirm = $state(false)
|
|
|
36
35
|
let isCheckingUpdates = $state(false)
|
|
37
36
|
let updateCheckMessage = $state('')
|
|
38
37
|
|
|
39
|
-
// Prerequisites and Settings
|
|
40
|
-
let showPrerequisites = $state(false)
|
|
41
|
-
let prerequisitesData = $state([])
|
|
42
38
|
let showSettings = $state(false)
|
|
43
39
|
|
|
44
40
|
let invoke = null
|
|
@@ -185,9 +181,8 @@ async function initApp() {
|
|
|
185
181
|
loadingProjects = false
|
|
186
182
|
}
|
|
187
183
|
|
|
188
|
-
// Non-blocking
|
|
184
|
+
// Non-blocking update check
|
|
189
185
|
checkForUpdates()
|
|
190
|
-
checkPrerequisites()
|
|
191
186
|
}
|
|
192
187
|
|
|
193
188
|
function retryInit() {
|
|
@@ -245,22 +240,6 @@ async function checkForUpdates() {
|
|
|
245
240
|
}
|
|
246
241
|
}
|
|
247
242
|
|
|
248
|
-
async function checkPrerequisites() {
|
|
249
|
-
try {
|
|
250
|
-
const result = await invoke('check_prerequisites')
|
|
251
|
-
if (!result.allInstalled) {
|
|
252
|
-
prerequisitesData = result.prerequisites
|
|
253
|
-
showPrerequisites = true
|
|
254
|
-
}
|
|
255
|
-
} catch (_err) {}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
async function openUrl(url) {
|
|
259
|
-
try {
|
|
260
|
-
await invoke('open_url', { url })
|
|
261
|
-
} catch (_err) {}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
243
|
async function loadProfiles() {
|
|
265
244
|
if (!selectedProject) return
|
|
266
245
|
try {
|
|
@@ -667,14 +646,6 @@ const isAlreadySaved = $derived(
|
|
|
667
646
|
/>
|
|
668
647
|
{/if}
|
|
669
648
|
|
|
670
|
-
{#if showPrerequisites}
|
|
671
|
-
<PrerequisitesCheck
|
|
672
|
-
prerequisites={prerequisitesData}
|
|
673
|
-
onDismiss={() => showPrerequisites = false}
|
|
674
|
-
onOpenUrl={openUrl}
|
|
675
|
-
/>
|
|
676
|
-
{/if}
|
|
677
|
-
|
|
678
649
|
{#if showSettings}
|
|
679
650
|
<Settings
|
|
680
651
|
onClose={() => showSettings = false}
|
package/src-tauri/Cargo.lock
CHANGED