@saptools/cf-hana 0.5.0 → 0.5.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,52 @@
2
2
 
3
3
  <!-- cspell:words VARCHAR -->
4
4
 
5
+ ## 0.5.1 - 2026-07-25
6
+
7
+ - **Security fix:** a `WITH`-prefixed write (e.g. `WITH x AS (...) DELETE
8
+ FROM ...`) and a bare `CALL <procedure>()` both previously slipped past
9
+ the `--read-only` and destructive-statement guards entirely — the former
10
+ was always classified as a harmless `SELECT` regardless of what it
11
+ actually did, and the latter was never classified as destructive at all,
12
+ so it ran with no `--allow-destructive` confirmation even in the default
13
+ (non-read-only) mode. Both are now correctly classified and guarded.
14
+ Anyone relying on `--read-only` or the destructive-statement guard as a
15
+ hard trust boundary should treat this as the release that closes that gap.
16
+ The automatic pre-write backup now also correctly recognizes and protects
17
+ a `WITH`-prefixed `UPDATE`/`DELETE`/`UPSERT`/`MERGE`, matching what a
18
+ non-`WITH` equivalent write already produced.
19
+ - Disable SAP HANA Cloud's reactive mid-auth redirect on every connection
20
+ (direct and tunneled): on a genuine multi-node HANA Cloud instance, the
21
+ server can redirect an already-established connection to an internal
22
+ per-node hostname that isn't reachable outside SAP's own network, which
23
+ previously defeated the SSH-tunnel fallback by silently abandoning the
24
+ tunnel for a fresh, untunneled connection that failed the same way the
25
+ original direct connection did.
26
+ - Fix the SSH-tunnel fallback's candidate discovery calling `cf apps`
27
+ (measured at up to ~20s against a large space) before ever trying the
28
+ already-known target app or a cached "last worked" app, which could
29
+ starve the entire shared fallback budget before a working candidate got a
30
+ chance. Known candidates are now always tried first; `cf apps` is only
31
+ called if none of them work, and is bounded to whatever budget remains
32
+ rather than retried on its own separate timeout/retry policy.
33
+ - Cap the direct-connect attempt's own timeout to the tunnel fallback's
34
+ per-candidate ceiling whenever a fallback is available, so a silently
35
+ hanging (rather than actively refused) direct connection can no longer
36
+ consume its full configured timeout before the tunnel path gets a chance
37
+ — lowering the documented worst-case latency from ~85s to ~40s.
38
+ - Fix `--refresh-tunnel` leaking the SSH process it superseded; the old
39
+ tunnel is now terminated instead of running until its keepalive elapses.
40
+ - Surface a failed tunnel candidate's actual stderr (e.g. "SSH disabled for
41
+ this app") via the existing connectivity status output on stderr, instead
42
+ of discarding it silently.
43
+ - Fix a freshly-established or reused tunnel being cached as usable even
44
+ when its own post-connect setup failed in a way that looked like a
45
+ dropped connection rather than a genuine, actionable HANA rejection.
46
+ - Bound how long a process waits for another concurrent invocation to
47
+ finish establishing the same host's tunnel, so the entire shared deadline
48
+ can no longer be spent waiting on a leader whose owning process has
49
+ already died.
50
+
5
51
  ## 0.5.0 - 2026-07-25
6
52
 
7
53
  - Add an SSH-tunnel fallback for HANA Cloud hosts unreachable directly (e.g.
package/README.md CHANGED
@@ -389,9 +389,57 @@ unattended live SSH path open just because its keepalive has not lapsed.
389
389
 
390
390
  In the worst case (a silently-dropping network path, so the direct attempt
391
391
  runs its full connect timeout, and no candidate app works either), `auto`
392
- mode takes roughly 60s (direct) + 25s (tunnel budget) before surfacing a
393
- final error bounded and predictable, not open-ended. Use `--tunnel` to skip
394
- the 60s direct cost for a host you already know is unreachable.
392
+ mode takes roughly 15s (direct, capped once a tunnel fallback is available
393
+ see below) + 25s (tunnel budget) 40s before surfacing a final error —
394
+ bounded and predictable, not open-ended. Use `--tunnel` to skip the direct
395
+ cost entirely for a host you already know is unreachable.
396
+
397
+ Whenever a tunnel fallback is available at all (`auto` mode, the default),
398
+ the direct attempt's own timeout is capped at the tunnel side's own
399
+ per-candidate ceiling (15s by default) even if a longer timeout is
400
+ configured — a silently-hanging (rather than actively refused) direct
401
+ connection would otherwise consume its entire configured timeout before the
402
+ tunnel path got a chance at all. This only ever shortens an
403
+ otherwise-hanging attempt; it never affects a host that refuses quickly, or
404
+ a configured timeout that is already shorter.
405
+
406
+ `cf-hana` also disables SAP HANA Cloud's reactive mid-auth redirect (used
407
+ for per-node/pod locality routing) on every connection, direct or tunneled:
408
+ without this, a multi-node HANA Cloud instance can redirect an
409
+ already-established connection to a different internal hostname that isn't
410
+ reachable outside SAP's own network, silently abandoning a working SSH
411
+ tunnel for a fresh, untunneled connection that fails for the same reason the
412
+ original direct connection did. The original bound host is always a real,
413
+ working endpoint for your binding, so this has no effect on which schema,
414
+ user, or data you reach.
415
+
416
+ ### Known limitations
417
+
418
+ - **Cross-org reaper and concurrent processes.** Every connection attempt
419
+ closes any cached tunnel tagged for a different Cloud Foundry org than the
420
+ current target, regardless of remaining lifetime — intentional hygiene so
421
+ switching orgs never leaves a stale tunnel open. On a shared machine, this
422
+ can also close another, unrelated, concurrently-running invocation's
423
+ active tunnel to a different org; there is no portable, low-cost way to
424
+ detect "is this port actively in use by someone else" from outside that
425
+ TCP session.
426
+ - **Stale-tunnel reaping trusts the recorded pid.** The reaper terminates a
427
+ dead or expired tunnel's process by its recorded pid, with no additional
428
+ identity check (e.g. confirming the pid still refers to a `cf ssh`
429
+ process). On a long-uptime machine, pid reuse could in principle target an
430
+ unrelated process; this is a narrow race not worth a platform-specific
431
+ check for.
432
+ - **Programmatic (non-CLI) pool usage can strand idle connections.** The
433
+ connection pool reuses the most-recently-released idle connection first
434
+ (LIFO); a long-lived process that opens a burst of connections and then
435
+ settles into serial one-at-a-time use can leave earlier connections
436
+ idle-but-unreaped for the pool's lifetime. The CLI itself always drains
437
+ its pool at the end of every command, so this only affects long-lived
438
+ programmatic use of the library.
439
+ - **Pre-write backups are never pruned.** Unlike SQL history (5-day
440
+ retention) and saved query results (TTL plus `result prune`/`result
441
+ clear`), files under `~/.saptools/cf-hana/backups/` accumulate
442
+ indefinitely with no retention policy or cleanup command.
395
443
 
396
444
  ## Requirements
397
445