@saptools/cf-events 0.1.1 → 0.1.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/README.md CHANGED
@@ -1,135 +1,309 @@
1
- # @saptools/cf-events
1
+ <div align="center">
2
2
 
3
- Inspect SAP BTP Cloud Foundry application **audit events** and detect active
4
- **SSH / debug sessions** from the command line. Point it at a
5
- `region/org/space/app` target and it answers questions like "what just happened
6
- to this app?", "is anyone SSH'd into it right now?", and "why did it crash?".
3
+ # ☁️ `@saptools/cf-events`
7
4
 
8
- `cf-events` reuses [`@saptools/cf-sync`](https://github.com/dongitran/saptools/tree/main/packages/cf-sync)
9
- for the synced `region/org/space/app` topology, then calls the Cloud Foundry v3
10
- API (`/v3/audit_events`, process stats, SSH status) through the `cf` CLI.
5
+ **Inspect SAP BTP Cloud Foundry application audit events and detect active SSH/debug sessions from the command line.**
11
6
 
12
- ## Prerequisites
7
+ Point it at a `region/org/space/app` (or a bare app name) and instantly answer: "what just happened?", "is anyone SSH'd in right now?", or "why did it crash?".
13
8
 
14
- - Node.js >= 20.
15
- - The [Cloud Foundry CLI v8+](https://github.com/cloudfoundry/cli) on `PATH`.
16
- - A topology snapshot produced by `cf-sync`. Run `cf-sync sync` (or a targeted
17
- `cf-sync space <region> <org> <space>`) once so `cf-events` can resolve and
18
- validate selectors. The snapshot lives at `~/.saptools/cf-structure.json`.
9
+ [![npm version](https://img.shields.io/npm/v/@saptools/cf-events.svg?style=flat&color=CB3837&logo=npm)](https://www.npmjs.com/package/@saptools/cf-events)
10
+ [![license](https://img.shields.io/npm/l/@saptools/cf-events.svg?style=flat&color=blue)](./LICENSE)
11
+ [![node](https://img.shields.io/node/v/@saptools/cf-events.svg?style=flat&color=339933&logo=node.js&logoColor=white)](https://nodejs.org)
12
+ [![install size](https://packagephobia.com/badge?p=@saptools/cf-events)](https://packagephobia.com/result?p=@saptools/cf-events)
13
+ [![types](https://img.shields.io/npm/types/@saptools/cf-events.svg?style=flat&color=3178C6&logo=typescript&logoColor=white)](https://www.typescriptlang.org)
19
14
 
20
- ## Install
15
+ [Install](#-install) • [Quick Start](#-quick-start) • [CLI](#-cli) • [API](#-programmatic-usage) • [FAQ](#-faq)
16
+
17
+ </div>
18
+
19
+ ---
20
+
21
+ ## ✨ Features
22
+
23
+ - 📜 **Audit event inspection** — list recent `audit.app.*` events (start/stop, scale, restarts, restage, route changes, env views, crashes, SSH authz)
24
+ - 🔐 **SSH & debug session detection** — surface authorized sessions + denied attempts; infer "likely active" ones from recent `ssh-authorized` events (CF has no live session or close events)
25
+ - 💥 **Crash summaries** — count, last crash time/reason/exit code, and per-instance detail
26
+ - ❤️ **One-glance status** — requested state, per-instance CPU/mem/uptime, SSH flag, and the most recent audit event
27
+ - 👀 **Live watch** — poll `/v3/audit_events` on an interval and stream new events (Ctrl+C to stop)
28
+ - 🧭 **Smart selectors** — full `region/org/space/app` or bare app name (resolved via the `cf-sync` snapshot; falls back to current `cf target` for bare names)
29
+ - 🔄 **Reuses cf-sync** — topology snapshot + current-target helpers from [`@saptools/cf-sync`](https://www.npmjs.com/package/@saptools/cf-sync)
30
+ - 🧪 **Isolated sessions** — every invocation uses a fresh ephemeral `CF_HOME`; never touches your interactive login
31
+ - 🧩 **CLI + typed library** — full TypeScript exports for `CfEventsRuntime`, parsers, formatters, and types
32
+ - 🪶 **Zero daemon, tiny deps** — commander + cf-sync only
33
+
34
+ ---
35
+
36
+ ## 📦 Install
21
37
 
22
38
  ```bash
39
+ # Global CLI
23
40
  npm install -g @saptools/cf-events
24
- # or run it on demand
41
+
42
+ # Or use on demand
25
43
  npx @saptools/cf-events --help
44
+
45
+ # As a library
46
+ npm install @saptools/cf-events
47
+ # pnpm add @saptools/cf-events
26
48
  ```
27
49
 
28
- ## Authentication
50
+ > [!NOTE]
51
+ > Requires **Node.js ≥ 20** and the official **Cloud Foundry CLI (v8+)** on `PATH`.
29
52
 
30
- Credentials are read from environment variables (preferred) or flags:
53
+ ---
54
+
55
+ ## 🚀 Quick Start
31
56
 
32
57
  ```bash
33
- export SAP_EMAIL="you@example.com"
34
- export SAP_PASSWORD="your-password"
58
+ # 1. Provide SAP SSO credentials (used only for live CF calls)
59
+ export SAP_EMAIL="you@company.com"
60
+ export SAP_PASSWORD="your-sap-password"
61
+
62
+ # 2. Make sure you have a topology snapshot (or be logged into a CF target)
63
+ cf-sync sync --only ap10 # or cf-sync space ap10 my-org dev
64
+
65
+ # 3. Inspect events
66
+ cf-events events orders-srv
67
+ cf-events events ap10/my-org/dev/orders-srv --limit 100 --since 6h
68
+
69
+ # 4. Check for active SSH/debug sessions
70
+ cf-events ssh-status orders-srv --since 7d
71
+
72
+ # 5. Summarize recent crashes
73
+ cf-events crashes orders-srv
74
+
75
+ # 6. Quick health view
76
+ cf-events status orders-srv
77
+
78
+ # 7. Stream new events live
79
+ cf-events watch orders-srv --type crash
35
80
  ```
36
81
 
37
- Every command also accepts `--email` and `--password`. Credentials are passed
38
- to the `cf` CLI through the environment, never on the command line, and each
39
- invocation runs in an isolated, ephemeral `CF_HOME`.
82
+ After a `cf-sync` snapshot exists, bare app names are resolved automatically (with current `cf target` expansion when no `/` present).
40
83
 
41
- ## Selectors
84
+ ---
42
85
 
43
- Every command takes a single positional selector:
86
+ ## 🧰 CLI
44
87
 
45
- - A full path: `ap10/my-org/dev/orders-srv`.
46
- - A bare app name: `orders-srv` — resolved against the `cf-sync` snapshot. If
47
- the name is ambiguous across spaces, `cf-events` lists the candidates and
48
- asks for a full path.
88
+ All commands accept a single positional **selector**:
49
89
 
50
- ## Commands
90
+ - Full path: `ap10/my-org/dev/orders-srv`
91
+ - Bare app name: `orders-srv` — resolved against the cf-sync snapshot (and current `cf target` when the name is unique within the target scope). Ambiguous names list the candidates and fail.
92
+
93
+ Common credential flags (all commands):
94
+
95
+ | Flag | Description |
96
+ |-----------------|--------------------------------------------------|
97
+ | `--email` | SAP email (falls back to `SAP_EMAIL` env) |
98
+ | `--password` | SAP password (falls back to `SAP_PASSWORD` env) |
99
+ | `--json` | Emit JSON instead of human text |
51
100
 
52
101
  ### `events <selector>`
53
102
 
54
- List recent audit events for an app (deployments, restarts, scaling, crashes,
55
- SSH activity, ...).
103
+ List recent audit events for the app (deployments, restarts, scaling, crashes, SSH, routes, ...).
56
104
 
57
105
  ```bash
58
106
  cf-events events ap10/my-org/dev/orders-srv
59
107
  cf-events events orders-srv --limit 100 --since 6h
60
108
  cf-events events orders-srv --type ssh --json
109
+ cf-events events orders-srv --type audit.app.start,audit.app.stop
61
110
  ```
62
111
 
63
- Options: `--limit <count>` (default 50), `--since <duration>` (e.g. `30m`,
64
- `6h`, `7d`), `--type <types>` (comma-separated CF event types, or the
65
- shorthand `ssh` / `crash`), `--json`.
112
+ | Flag | Description |
113
+ |----------|--------------------------------------------------|
114
+ | `--limit <n>` | Max events (default 50) |
115
+ | `--since <dur>` | Only newer than duration (e.g. `30m`, `6h`, `7d`) |
116
+ | `--type <types>` | Comma list of types or shorthands `ssh` / `crash` |
66
117
 
67
118
  ### `ssh-status <selector>`
68
119
 
69
- Show whether SSH is enabled for the app and surface recent SSH / debug
70
- activity: who opened a session and when, plus any denied attempts.
120
+ Show the SSH-enabled flag for the app + recent SSH / debug activity (who authorized when) and denied attempts. Marks sessions that are "likely active" (within the last 60 minutes of an `ssh-authorized` event).
71
121
 
72
122
  ```bash
73
123
  cf-events ssh-status orders-srv
74
124
  cf-events ssh-status orders-srv --since 7d --json
75
125
  ```
76
126
 
77
- Options: `--since <duration>` (default `24h`), `--json`.
127
+ | Flag | Description |
128
+ |---------------|-----------------------------------------|
129
+ | `--since <dur>` | Look-back window (default `24h`) |
78
130
 
79
- > Cloud Foundry exposes no live-session API and emits no event when an SSH
80
- > session closes. `cf-events` therefore *infers* "likely active" sessions from
81
- > recent `ssh-authorized` audit events — treat it as a strong hint, not proof.
131
+ > [!IMPORTANT]
132
+ > Cloud Foundry does not expose live sessions or emit `ssh-unauthorized` / close events. `cf-events` **infers** likely-active sessions from recent `audit.app.ssh-authorized` records. Treat as a strong signal, not definitive proof.
82
133
 
83
134
  ### `crashes <selector>`
84
135
 
85
- Summarize recent crash events: how many, the most recent one, and the exit
86
- reason.
136
+ Count and detail recent crash events (both `audit.app.crash` and `audit.app.process.crash`).
87
137
 
88
138
  ```bash
89
139
  cf-events crashes orders-srv
90
140
  cf-events crashes orders-srv --since 24h --json
91
141
  ```
92
142
 
93
- Options: `--limit <count>` (default 50), `--since <duration>`, `--json`.
143
+ | Flag | Description |
144
+ |---------------|------------------------------------------|
145
+ | `--limit <n>` | Max crash events to inspect (default 50) |
146
+ | `--since <dur>` | Filter window |
94
147
 
95
148
  ### `status <selector>`
96
149
 
97
- A one-glance health view: requested state, per-instance state / uptime / CPU /
98
- memory, the SSH-enabled flag, and the most recent audit event.
150
+ Compact health snapshot: GUID, requested state, SSH flag, instance table (index / state / uptime / cpu / mem), and the single most recent audit event.
99
151
 
100
152
  ```bash
153
+ cf-events status orders-srv
101
154
  cf-events status orders-srv --json
102
155
  ```
103
156
 
104
157
  ### `watch <selector>`
105
158
 
106
- Poll `/v3/audit_events` on an interval and print new events as they appear.
107
- Press `Ctrl+C` to stop.
159
+ Poll `/v3/audit_events` repeatedly and print (or emit NDJSON) fresh events as they arrive. Press Ctrl+C to stop.
108
160
 
109
161
  ```bash
110
162
  cf-events watch orders-srv
111
- cf-events watch orders-srv --interval 30000 --type crash
163
+ cf-events watch orders-srv --interval 30000 --type crash --lookback 5m
112
164
  ```
113
165
 
114
- Options: `--interval <ms>` (default 15000, minimum 2000), `--lookback
115
- <duration>` (initial window on start, default `2m`), `--type <types>`,
116
- `--json` (line-delimited JSON).
166
+ | Flag | Description |
167
+ |------------------|--------------------------------------------------|
168
+ | `--interval <ms>` | Poll interval (default 15000, min 2000) |
169
+ | `--lookback <dur>` | Initial fetch window on start (default `2m`) |
170
+ | `--type <types>` | Filter (supports `ssh` / `crash` shorthands) |
171
+ | `--json` | Line-delimited JSON output |
117
172
 
118
- ## Programmatic use
173
+ ---
119
174
 
120
- The package also ships a typed library entry:
175
+ ## 🧑‍💻 Programmatic Usage
121
176
 
122
177
  ```ts
123
- import { CfEventsRuntime } from "@saptools/cf-events";
178
+ import {
179
+ CfEventsRuntime,
180
+ // also re-exported for advanced use:
181
+ // fetchAuditEvents, fetchApp, fetchSshEnabled, fetchWebProcessStats,
182
+ // parseTypeFilter, durationToCreatedAfter,
183
+ // formatEventsReport, formatSshStatusReport, formatCrashReport, formatStatusReport,
184
+ // resolveSelector, parseSelector,
185
+ // plus all types
186
+ } from "@saptools/cf-events";
124
187
 
125
188
  const runtime = new CfEventsRuntime();
126
- const events = await runtime.fetchEvents("orders-srv", credentials, {
189
+
190
+ const events = await runtime.fetchEvents("orders-srv", {
191
+ email: process.env.SAP_EMAIL ?? "",
192
+ password: process.env.SAP_PASSWORD ?? "",
193
+ }, {
127
194
  limit: 50,
128
195
  since: "6h",
129
- types: [],
196
+ types: [], // or ["audit.app.crash"] or use parseTypeFilter("crash")
130
197
  });
198
+
199
+ console.log(events.length);
200
+
201
+ // SSH inference + enabled flag
202
+ const ssh = await runtime.getSshStatus("orders-srv", creds, "24h");
203
+
204
+ // Crash summary
205
+ const crashes = await runtime.getCrashes("orders-srv", creds, { limit: 20 });
206
+
207
+ // Health + instances
208
+ const health = await runtime.getStatus("ap10/my-org/dev/orders-srv", creds);
209
+
210
+ // Live polling (call with AbortSignal)
211
+ const ac = new AbortController();
212
+ await runtime.watchEvents("orders-srv", creds, { intervalMs: 15000, lookback: "2m", types: [] }, (ev) => {
213
+ console.log(ev);
214
+ }, ac.signal);
215
+ ```
216
+
217
+ The package is a full barrel; everything under `src/` (parsers, formatters, low-level CF session helpers, types) is exported for power users or custom tooling.
218
+
219
+ ---
220
+
221
+ ## 📁 Prerequisites & Snapshots
222
+
223
+ `cf-events` relies on a `cf-sync` snapshot at `~/.saptools/cf-structure.json` for bare-app-name resolution and validation of explicit paths.
224
+
225
+ - Run `cf-sync sync`, `cf-sync space ...`, or `cf-sync org ...` at least once.
226
+ - When you pass a bare app name, `cf-events` will also consult your current `cf target` (via `cf target` output) to build a full selector before validating against the snapshot.
227
+ - Pure `--json` + explicit full selectors still require the snapshot for safety.
228
+
229
+ All CF operations run inside a throw-away `CF_HOME`. Your interactive `cf` login is never affected.
230
+
231
+ ---
232
+
233
+ ## ❓ FAQ
234
+
235
+ <details>
236
+ <summary><b>Do I need to run cf target first?</b></summary>
237
+
238
+ Not required. Pass a full selector or make sure a cf-sync snapshot exists. Bare names will try to use your current `cf target` output to expand into `region/org/space/app`.
239
+
240
+ </details>
241
+
242
+ <details>
243
+ <summary><b>Why "likely active" instead of real sessions?</b></summary>
244
+
245
+ Cloud Foundry's audit log only records authorization. There is no "session closed" or live-process table exposed via the APIs `cf-events` consumes. The 60-minute window after `ssh-authorized` is a documented heuristic.
246
+
247
+ </details>
248
+
249
+ <details>
250
+ <summary><b>What durations are accepted?</b></summary>
251
+
252
+ `30s`, `5m`, `6h`, `7d` (positive integers + s/m/h/d). Used by `--since` and `--lookback`.
253
+
254
+ </details>
255
+
256
+ <details>
257
+ <summary><b>Can I filter only crashes or only SSH?</b></summary>
258
+
259
+ Yes: `--type crash` or `--type ssh`. You can also pass comma-separated full types: `--type audit.app.crash,audit.app.process.crash`.
260
+
261
+ </details>
262
+
263
+ <details>
264
+ <summary><b>Is the snapshot required even for JSON output?</b></summary>
265
+
266
+ Yes for safety and consistent resolution. The snapshot is the single source of truth for which apps exist in which spaces.
267
+
268
+ </details>
269
+
270
+ ---
271
+
272
+ ## 🛠️ Development
273
+
274
+ From monorepo root:
275
+
276
+ ```bash
277
+ pnpm install
278
+ pnpm --filter @saptools/cf-events build
279
+ pnpm --filter @saptools/cf-events typecheck
280
+ pnpm --filter @saptools/cf-events lint
281
+ pnpm --filter @saptools/cf-events test:unit
282
+ pnpm --filter @saptools/cf-events test:e2e
283
+ pnpm --filter @saptools/cf-events check # cspell + lint + type + unit + e2e
131
284
  ```
132
285
 
133
- ## License
286
+ E2E tests are fully fake-backed (no real CF or credentials needed).
287
+
288
+ ---
289
+
290
+ ## 🌐 Related
291
+
292
+ - 🗺️ [`@saptools/cf-sync`](https://www.npmjs.com/package/@saptools/cf-sync) — the topology snapshot and current-target helpers that power selector resolution
293
+ - 🔐 [`@saptools/cf-xsuaa`](https://www.npmjs.com/package/@saptools/cf-xsuaa)
294
+ - 🐛 [`@saptools/cf-debugger`](https://www.npmjs.com/package/@saptools/cf-debugger)
295
+ - Full toolbox: [saptools monorepo](https://github.com/dongitran/saptools)
296
+
297
+ ---
298
+
299
+ ## 👨‍💻 Author
300
+
301
+ **Dong Tran**
302
+
303
+ ## 📄 License
134
304
 
135
305
  MIT
306
+
307
+ ---
308
+
309
+ Made with ❤️ for SAP BTP CF developers.