@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 +232 -58
- package/dist/cli.js +137 -109
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +15 -7
- package/dist/index.js +134 -80
- package/dist/index.js.map +1 -1
- package/package.json +11 -12
package/README.md
CHANGED
|
@@ -1,135 +1,309 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/@saptools/cf-events)
|
|
10
|
+
[](./LICENSE)
|
|
11
|
+
[](https://nodejs.org)
|
|
12
|
+
[](https://packagephobia.com/result?p=@saptools/cf-events)
|
|
13
|
+
[](https://www.typescriptlang.org)
|
|
19
14
|
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
50
|
+
> [!NOTE]
|
|
51
|
+
> Requires **Node.js ≥ 20** and the official **Cloud Foundry CLI (v8+)** on `PATH`.
|
|
29
52
|
|
|
30
|
-
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 🚀 Quick Start
|
|
31
56
|
|
|
32
57
|
```bash
|
|
33
|
-
|
|
34
|
-
export
|
|
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
|
-
|
|
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
|
-
|
|
84
|
+
---
|
|
42
85
|
|
|
43
|
-
|
|
86
|
+
## 🧰 CLI
|
|
44
87
|
|
|
45
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
|
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
|
-
|
|
127
|
+
| Flag | Description |
|
|
128
|
+
|---------------|-----------------------------------------|
|
|
129
|
+
| `--since <dur>` | Look-back window (default `24h`) |
|
|
78
130
|
|
|
79
|
-
>
|
|
80
|
-
>
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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`
|
|
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
|
-
|
|
115
|
-
|
|
116
|
-
`--
|
|
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
|
-
|
|
173
|
+
---
|
|
119
174
|
|
|
120
|
-
|
|
175
|
+
## 🧑💻 Programmatic Usage
|
|
121
176
|
|
|
122
177
|
```ts
|
|
123
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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.
|