rds_ssm_connect 1.8.2 → 1.8.3
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/connect.js +40 -2
- package/package.json +1 -1
- package/test/connect.test.js +11 -0
package/connect.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from './configLoader.js'
|
|
15
15
|
|
|
16
16
|
// Package info for version checking
|
|
17
|
-
const packageJson = { name: 'rds_ssm_connect', version: '1.8.
|
|
17
|
+
const packageJson = { name: 'rds_ssm_connect', version: '1.8.3' }
|
|
18
18
|
|
|
19
19
|
const execAsync = promisify(exec)
|
|
20
20
|
|
|
@@ -28,8 +28,9 @@ const RETRY_CONFIG = {
|
|
|
28
28
|
PORT_FORWARDING_MAX_RETRIES: 2,
|
|
29
29
|
SSM_AGENT_READY_WAIT_MS: 10000,
|
|
30
30
|
KEEPALIVE_INTERVAL_MS: 4 * 60 * 1000,
|
|
31
|
-
AUTO_RECONNECT_MAX_RETRIES:
|
|
31
|
+
AUTO_RECONNECT_MAX_RETRIES: 3,
|
|
32
32
|
AUTO_RECONNECT_DELAY_MS: 3000,
|
|
33
|
+
CREDENTIAL_CHECK_TIMEOUT_MS: 60000,
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
// Version check configuration
|
|
@@ -170,6 +171,21 @@ async function sleep(ms) {
|
|
|
170
171
|
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
// Pre-flight credential check. Uses a short timeout so that if aws-vault
|
|
175
|
+
// needs to open a browser for SSO re-auth (which blocks indefinitely), the
|
|
176
|
+
// command is killed before any browser tab appears.
|
|
177
|
+
async function checkCredentialsValid(profile, region) {
|
|
178
|
+
try {
|
|
179
|
+
await execAsync(
|
|
180
|
+
`aws-vault exec ${profile} -- aws sts get-caller-identity --region ${region}`,
|
|
181
|
+
{ timeout: RETRY_CONFIG.CREDENTIAL_CHECK_TIMEOUT_MS },
|
|
182
|
+
)
|
|
183
|
+
return { valid: true }
|
|
184
|
+
} catch (_error) {
|
|
185
|
+
return { valid: false }
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
173
189
|
// Keepalive: periodic TCP ping through the tunnel to prevent SSM idle timeout.
|
|
174
190
|
// Each connection attempt generates traffic on the SSM WebSocket channel,
|
|
175
191
|
// resetting the server-side idle timer (default 20 min).
|
|
@@ -712,6 +728,18 @@ async function connect(projectKey, profile, options = {}) {
|
|
|
712
728
|
|
|
713
729
|
if (manualDisconnect) break
|
|
714
730
|
|
|
731
|
+
// Verify credentials are still valid before retrying.
|
|
732
|
+
// Avoids opening browser SSO tabs when the user is away.
|
|
733
|
+
emit('status', { message: 'Checking credentials...' })
|
|
734
|
+
const credCheck = await checkCredentialsValid(profile, region)
|
|
735
|
+
if (!credCheck.valid) {
|
|
736
|
+
emit('status', {
|
|
737
|
+
message:
|
|
738
|
+
'AWS credentials expired. Please re-authenticate and reconnect.',
|
|
739
|
+
})
|
|
740
|
+
break
|
|
741
|
+
}
|
|
742
|
+
|
|
715
743
|
// Re-discover infrastructure (bastion may have been replaced by ASG)
|
|
716
744
|
emit('status', { message: 'Finding bastion instance...' })
|
|
717
745
|
currentInstanceId = await findBastionInstance(profile, region)
|
|
@@ -744,6 +772,16 @@ async function connect(projectKey, profile, options = {}) {
|
|
|
744
772
|
|
|
745
773
|
if (manualDisconnect) break
|
|
746
774
|
|
|
775
|
+
// Verify credentials before retrying (same check as happy path)
|
|
776
|
+
const credCheckOnError = await checkCredentialsValid(profile, region)
|
|
777
|
+
if (!credCheckOnError.valid) {
|
|
778
|
+
emit('status', {
|
|
779
|
+
message:
|
|
780
|
+
'AWS credentials expired. Please re-authenticate and reconnect.',
|
|
781
|
+
})
|
|
782
|
+
break
|
|
783
|
+
}
|
|
784
|
+
|
|
747
785
|
try {
|
|
748
786
|
currentInstanceId = await findBastionInstance(profile, region)
|
|
749
787
|
currentRdsEndpoint = await getRdsEndpoint(profile, projectConfig)
|
package/package.json
CHANGED
package/test/connect.test.js
CHANGED
|
@@ -180,6 +180,8 @@ describe('Retry Configuration', () => {
|
|
|
180
180
|
BASTION_WAIT_RETRY_DELAY_MS: 15000,
|
|
181
181
|
PORT_FORWARDING_MAX_RETRIES: 2,
|
|
182
182
|
SSM_AGENT_READY_WAIT_MS: 10000,
|
|
183
|
+
AUTO_RECONNECT_MAX_RETRIES: 3,
|
|
184
|
+
CREDENTIAL_CHECK_TIMEOUT_MS: 60000,
|
|
183
185
|
}
|
|
184
186
|
|
|
185
187
|
assert.ok(
|
|
@@ -198,5 +200,14 @@ describe('Retry Configuration', () => {
|
|
|
198
200
|
RETRY_CONFIG.SSM_AGENT_READY_WAIT_MS > 0,
|
|
199
201
|
'SSM wait should be positive',
|
|
200
202
|
)
|
|
203
|
+
assert.ok(
|
|
204
|
+
RETRY_CONFIG.AUTO_RECONNECT_MAX_RETRIES > 0 &&
|
|
205
|
+
RETRY_CONFIG.AUTO_RECONNECT_MAX_RETRIES <= 10,
|
|
206
|
+
'Auto-reconnect retries should be between 1 and 10',
|
|
207
|
+
)
|
|
208
|
+
assert.ok(
|
|
209
|
+
RETRY_CONFIG.CREDENTIAL_CHECK_TIMEOUT_MS >= 5000,
|
|
210
|
+
'Credential check timeout should be at least 5 seconds',
|
|
211
|
+
)
|
|
201
212
|
})
|
|
202
213
|
})
|