train-k8s-container-mitre 2.1.0 → 2.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a6f31783b24164cc4022cf02eec0f3f9196a33f80be854545585f7d66d16133
4
- data.tar.gz: 05dacf6aadaa5410f138784622bcd76cbe9cc22c5cfede7a15a256072b9b3738
3
+ metadata.gz: 8ef90f67ca076b6179acb73cdf55cbccc46c574353fa6840a9383bf619a12b03
4
+ data.tar.gz: 45a05c0359f9b79f1c80dca78db72bb902b15ba4cf36fa50cdd644d2ac4ca394
5
5
  SHA512:
6
- metadata.gz: 248da653146893b9aafc45e99c2f1d34904649fb8bf4ad349d602d2c9c758f8517e598cb3c7fd96ffac6169a7935e96c2d6b1771a9d36311d89f2ce0ba68459f
7
- data.tar.gz: 4d350da5926144fe048190fd1cb07f45cf7987509ba53022fd64cd7df47e0f2a6470bef1914aa6bd9463cb3a8fa39a6135aa7e67021ff9010994910d95fbf9eb
6
+ metadata.gz: 5ffda135781a1949734ff7e604b8561569687a5787d48508c429df4bb247b99f9de69336aa44b5da243fe63b0838f1cee0a3bebffdb2beb3aeee88f8a6bdbd74
7
+ data.tar.gz: 237d9179ecdd74b3826de69299b07dfdcf6d001c5684f229344613def553832b1453e51ce418f73997c724ac9bf01ec2b8183476a311049340139db62fe9fa5c
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "2.1.0"
2
+ ".": "2.2.0"
3
3
  }
data/ARCHITECTURE.md ADDED
@@ -0,0 +1,546 @@
1
+ # Architecture Overview
2
+
3
+ This document provides a technical overview of the train-k8s-container plugin architecture.
4
+
5
+ ## High-Level Architecture
6
+
7
+ ```
8
+ ┌─────────────────────────────────────────────────────────────────────────────┐
9
+ │ InSpec / Cinc Auditor │
10
+ │ │
11
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
12
+ │ │ Profile │───▶│ Resources │───▶│ Train │───▶│ Transport │ │
13
+ │ │ Controls │ │ (file, user │ │ Framework │ │ Plugin │ │
14
+ │ └─────────────┘ │ package..) │ └─────────────┘ └──────┬──────┘ │
15
+ └──────────────────────────────────────────────────────────────────┼─────────┘
16
+
17
+ ┌────────────────────────────────────┘
18
+
19
+ ┌─────────────────────────────────────────────────────────────────────────────┐
20
+ │ train-k8s-container Plugin │
21
+ │ │
22
+ │ ┌───────────────────────────────────────────────────────────────────────┐ │
23
+ │ │ Connection │ │
24
+ │ │ • URI parsing (k8s-container://namespace/pod/container) │ │
25
+ │ │ • Parameter validation │ │
26
+ │ │ • File operations via Train::File::Remote::Linux │ │
27
+ │ └───────────────────────────────────┬───────────────────────────────────┘ │
28
+ │ │ │
29
+ │ ┌────────────────────────────┼────────────────────────────┐ │
30
+ │ ▼ ▼ ▼ │
31
+ │ ┌─────────────────┐ ┌─────────────────────┐ ┌─────────────────┐ │
32
+ │ │ ShellDetector │ │ KubectlExecClient │ │ Platform │ │
33
+ │ │ │ │ │ │ │ │
34
+ │ │ • OS detection │ │ • Command execution │ │ • Detect+Context│ │
35
+ │ │ • Shell probing │ │ • PTY sessions │ │ • OS families │ │
36
+ │ │ • Linux family │ │ • Retry handling │ │ • Kubernetes │ │
37
+ │ └────────┬────────┘ └──────────┬──────────┘ │ context │ │
38
+ │ │ │ └─────────────────┘ │
39
+ │ │ ┌──────────┴──────────┐ │
40
+ │ │ ▼ ▼ │
41
+ │ │ ┌─────────────────┐ ┌─────────────────┐ │
42
+ │ │ │ SessionManager │ │ ResultProcessor │ │
43
+ │ │ │ (Singleton) │ │ │ │
44
+ │ │ │ │ │ • ANSI cleanup │ │
45
+ │ │ │ • Connection │ │ • Exit codes │ │
46
+ │ │ │ pooling │ │ • Error detect │ │
47
+ │ │ │ • Thread-safe │ └─────────────────┘ │
48
+ │ │ └────────┬────────┘ │
49
+ │ │ │ │
50
+ │ │ ▼ │
51
+ │ │ ┌─────────────────┐ │
52
+ │ │ │ PtySession │ │
53
+ │ │ │ │ │
54
+ │ │ │ • Persistent │ │
55
+ │ │ │ shell session │ │
56
+ │ │ │ • Command queue │ │
57
+ │ │ └─────────────────┘ │
58
+ │ │ │
59
+ │ ┌────────┴──────────────────────────────────────────────────────────┐ │
60
+ │ │ Support Modules │ │
61
+ │ │ │ │
62
+ │ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │
63
+ │ │ │ KubectlCommand │ │ KubernetesName │ │ AnsiSanitizer │ │ │
64
+ │ │ │ Builder │ │ Validator │ │ │ │ │
65
+ │ │ │ │ │ │ │ • CVE-2021-25743 │ │ │
66
+ │ │ │ • Shell escaping │ │ • RFC 1123 │ │ mitigation │ │ │
67
+ │ │ │ • Windows/Unix │ │ • Injection │ │ • ANSI stripping │ │ │
68
+ │ │ └──────────────────┘ │ prevention │ └──────────────────┘ │ │
69
+ │ │ └──────────────────┘ │ │
70
+ │ └────────────────────────────────────────────────────────────────────┘ │
71
+ └─────────────────────────────────────────────────────────────────────────────┘
72
+
73
+
74
+ ┌─────────────────────────────────────────────────────────────────────────────┐
75
+ │ kubectl exec │
76
+ │ │
77
+ │ kubectl exec --stdin <pod> -n <namespace> -c <container> -- <cmd> │
78
+ └─────────────────────────────────────────────────────────────────────────────┘
79
+
80
+
81
+ ┌─────────────────────────────────────────────────────────────────────────────┐
82
+ │ Kubernetes Cluster │
83
+ │ │
84
+ │ ┌─────────────────────────────────────────────────────────────────┐ │
85
+ │ │ Target Pod │ │
86
+ │ │ ┌─────────────────────────────────────────────────────────┐ │ │
87
+ │ │ │ Target Container │ │ │
88
+ │ │ │ │ │ │
89
+ │ │ │ /bin/bash, /bin/sh, /bin/ash ──or── distroless │ │ │
90
+ │ │ │ │ │ │
91
+ │ │ └─────────────────────────────────────────────────────────┘ │ │
92
+ │ └─────────────────────────────────────────────────────────────────┘ │
93
+ └─────────────────────────────────────────────────────────────────────────────┘
94
+ ```
95
+
96
+ ## Command Execution Flow
97
+
98
+ ```
99
+ ┌──────────────────────────────────────────────────────────────────────────────┐
100
+ │ Command Execution Flow │
101
+ └──────────────────────────────────────────────────────────────────────────────┘
102
+
103
+ InSpec Control Plugin Components kubectl
104
+ ───────────── ───────────────── ───────
105
+
106
+ │ command('whoami')
107
+
108
+ ┌─────────┐
109
+ │ Control │
110
+ └────┬────┘
111
+
112
+
113
+ ┌─────────────────┐
114
+ │ Connection │ ─── parse URI, validate params
115
+ └────────┬────────┘
116
+
117
+
118
+ ┌─────────────────┐
119
+ │ KubectlExec │
120
+ │ Client │
121
+ └────────┬────────┘
122
+
123
+ │ Check for existing session
124
+
125
+ ┌─────────────────┐ ┌─────────────────┐
126
+ │ SessionManager │────▶│ PtySession │ (if pooled session exists)
127
+ │ (Singleton) │ │ (persistent) │
128
+ └────────┬────────┘ └────────┬────────┘
129
+ │ │
130
+ │ No session? │ Has session?
131
+ │ Create new │ Reuse
132
+ ▼ ▼
133
+ ┌─────────────────┐ ┌─────────────────┐
134
+ │ KubectlCommand │ │ Send command │
135
+ │ Builder │ │ via PTY pipe │
136
+ └────────┬────────┘ └────────┬────────┘
137
+ │ │
138
+ ▼ ▼
139
+ ┌─────────────────┐ ┌─────────────────┐
140
+ │ Mixlib:: │ │ Read response │
141
+ │ ShellOut │ │ until marker │
142
+ └────────┬────────┘ └────────┬────────┘
143
+ │ │
144
+ ▼ ▼
145
+ ┌───────────────────────────────┐
146
+ │ kubectl exec │ ───▶ Container
147
+ └───────────────┬───────────────┘
148
+
149
+
150
+ ┌─────────────────┐
151
+ │ ResultProcessor │
152
+ │ │
153
+ │ • Parse exit │
154
+ │ code │
155
+ │ • Strip ANSI │
156
+ │ • Detect errors │
157
+ └────────┬────────┘
158
+
159
+
160
+ ┌─────────────────┐
161
+ │ RetryHandler │ ─── Retry on transient errors
162
+ │ │ (exponential backoff)
163
+ └────────┬────────┘
164
+
165
+
166
+ Train::Extras::CommandResult
167
+ (stdout, stderr, exit_code)
168
+ ```
169
+
170
+ ## File Structure
171
+
172
+ ```
173
+ lib/train-k8s-container/
174
+ ├── transport.rb # Train plugin registration
175
+ ├── connection.rb # Main connection class
176
+ ├── kubectl_exec_client.rb # Command execution engine
177
+ ├── platform.rb # OS detection (Detect+Context)
178
+ ├── version.rb # Version constant
179
+
180
+ ├── session_manager.rb # Connection pool (Singleton)
181
+ ├── pty_session.rb # Persistent PTY shell session
182
+
183
+ ├── shell_detector.rb # Shell/OS detection
184
+ ├── kubectl_command_builder.rb # Command string building
185
+ ├── result_processor.rb # Output parsing & validation
186
+ ├── retry_handler.rb # Exponential backoff retry
187
+
188
+ ├── ansi_sanitizer.rb # ANSI escape removal (CVE fix)
189
+ ├── kubernetes_name_validator.rb # RFC 1123 validation
190
+ └── errors.rb # Custom error classes
191
+ ```
192
+
193
+ ## Component Details
194
+
195
+ ### Core Components
196
+
197
+ #### Transport (`transport.rb`)
198
+
199
+ Registers the `k8s-container` transport with Train:
200
+
201
+ ```ruby
202
+ module TrainPlugins::K8sContainer
203
+ class Transport < Train.plugin(1)
204
+ name 'k8s-container'
205
+ # ...
206
+ end
207
+ end
208
+ ```
209
+
210
+ Connection options:
211
+ - `pod` - Target pod name (required)
212
+ - `container_name` - Target container (required)
213
+ - `namespace` - Kubernetes namespace (default: `default`)
214
+ - `kubeconfig` - Path to kubeconfig file
215
+
216
+ #### Connection (`connection.rb`)
217
+
218
+ Main connection handler:
219
+ - Parses URI format: `k8s-container://<namespace>/<pod>/<container>`
220
+ - Validates required parameters (pod, container)
221
+ - Provides `run_command()` for command execution
222
+ - Provides file access via `Train::File::Remote::Linux`
223
+
224
+ #### KubectlExecClient (`kubectl_exec_client.rb`)
225
+
226
+ Command execution engine:
227
+ - Detects available shell via `ShellDetector`
228
+ - Routes commands through `SessionManager` for pooling
229
+ - Falls back to direct execution for distroless containers
230
+ - Integrates `RetryHandler` for transient errors
231
+
232
+ #### Platform (`platform.rb`)
233
+
234
+ OS detection using **Detect+Context** pattern:
235
+
236
+ ```ruby
237
+ def platform
238
+ # 1. Use Train's scanner to detect actual OS
239
+ @platform = Train::Platforms::Detect.scan(self)
240
+
241
+ # 2. Add Kubernetes context families
242
+ add_k8s_families(@platform)
243
+
244
+ @platform
245
+ end
246
+ ```
247
+
248
+ Result: `os.linux?` returns `true` while `platform.families` includes `kubernetes`, `container`.
249
+
250
+ ### Session Management (Connection Pooling)
251
+
252
+ #### SessionManager (`session_manager.rb`)
253
+
254
+ Thread-safe singleton that pools PTY sessions:
255
+
256
+ ```ruby
257
+ class SessionManager
258
+ include Singleton
259
+
260
+ # One session per namespace/pod/container
261
+ def get_session(session_key, kubectl_cmd:, shell:, timeout:, logger:)
262
+ @mutex.synchronize do
263
+ unless @sessions[session_key]&.healthy?
264
+ @sessions[session_key] = PtySession.new(...)
265
+ @sessions[session_key].connect
266
+ end
267
+ @sessions[session_key]
268
+ end
269
+ end
270
+ end
271
+ ```
272
+
273
+ Benefits:
274
+ - Reuses kubectl exec connections across multiple commands
275
+ - Significantly faster for profiles with many controls
276
+ - Automatic cleanup on session failure or process exit
277
+
278
+ #### PtySession (`pty_session.rb`)
279
+
280
+ Persistent PTY-based shell session:
281
+
282
+ ```ruby
283
+ # Instead of spawning kubectl for each command:
284
+ kubectl exec pod -c container -- /bin/sh -c "command1"
285
+ kubectl exec pod -c container -- /bin/sh -c "command2"
286
+ kubectl exec pod -c container -- /bin/sh -c "command3"
287
+
288
+ # Maintains one persistent session:
289
+ kubectl exec pod -c container -- /bin/bash
290
+ > command1
291
+ > command2
292
+ > command3
293
+ ```
294
+
295
+ Features:
296
+ - Uses Ruby's `PTY.spawn` for interactive session
297
+ - Sends commands with exit code markers
298
+ - Parses output and extracts real exit codes
299
+ - Health checking via process status
300
+
301
+ ### Shell & OS Detection
302
+
303
+ #### ShellDetector (`shell_detector.rb`)
304
+
305
+ Detects available shell in container:
306
+
307
+ ```
308
+ Detection Order (Unix):
309
+ 1. /bin/bash - Ubuntu, Debian, RHEL
310
+ 2. /bin/sh - POSIX standard
311
+ 3. /bin/ash - Alpine, BusyBox
312
+ 4. /bin/zsh - Less common
313
+
314
+ Detection Order (Windows):
315
+ 1. cmd.exe - Command prompt
316
+ 2. powershell.exe - PowerShell 5.1
317
+ 3. pwsh.exe - PowerShell Core
318
+ ```
319
+
320
+ Also detects Linux distribution family from `/etc/os-release`:
321
+ - Debian family: ubuntu, debian, linuxmint, kali
322
+ - RedHat family: rhel, centos, fedora, rocky, almalinux
323
+ - Alpine, Arch, SUSE, Gentoo
324
+
325
+ ### Command Building & Processing
326
+
327
+ #### KubectlCommandBuilder (`kubectl_command_builder.rb`)
328
+
329
+ Builds properly escaped kubectl commands:
330
+
331
+ ```ruby
332
+ builder = KubectlCommandBuilder.new(
333
+ kubectl_path: '/usr/bin/kubectl',
334
+ pod: 'my-pod',
335
+ namespace: 'default',
336
+ container_name: 'app'
337
+ )
338
+
339
+ # Unix shell
340
+ builder.with_shell('/bin/bash', 'cat /etc/passwd')
341
+ # => "kubectl exec --stdin my-pod -n default -c app -- /bin/bash -c 'cat /etc/passwd'"
342
+
343
+ # Windows shell
344
+ builder.with_windows_shell('cmd.exe', 'dir')
345
+ # => "kubectl exec --stdin my-pod -n default -c app -- cmd.exe /c 'dir'"
346
+
347
+ # Direct binary (distroless)
348
+ builder.direct_binary('cat /etc/os-release')
349
+ # => "kubectl exec --stdin my-pod -n default -c app -- cat /etc/os-release"
350
+ ```
351
+
352
+ #### ResultProcessor (`result_processor.rb`)
353
+
354
+ Processes command output:
355
+
356
+ 1. **Validation**: Detects connection errors and silent failures
357
+ 2. **Sanitization**: Strips ANSI sequences, normalizes line endings
358
+ 3. **Exit code parsing**: Extracts real exit code from kubectl messages
359
+
360
+ Connection error patterns detected:
361
+ - `error dialing backend`
362
+ - `connection refused`
363
+ - `pods "name" not found`
364
+ - `Error from server`
365
+
366
+ ### Security Components
367
+
368
+ #### AnsiSanitizer (`ansi_sanitizer.rb`)
369
+
370
+ Addresses **CVE-2021-25743** (terminal escape sequence injection):
371
+
372
+ ```ruby
373
+ module AnsiSanitizer
374
+ CSI_REGEX = /\e\[([;\d]+)?[A-Za-z]/ # Colors, cursor
375
+ OSC_REGEX = /\e\][^\a]*\a/ # Terminal title
376
+ CURSOR_REGEX = /\e\[A|\e\[C|\e\[K/ # Movement
377
+
378
+ def self.sanitize(text)
379
+ # Remove all ANSI escape sequences
380
+ end
381
+ end
382
+ ```
383
+
384
+ #### KubernetesNameValidator (`kubernetes_name_validator.rb`)
385
+
386
+ Validates names per **RFC 1123** DNS subdomain rules:
387
+
388
+ ```ruby
389
+ VALID_NAME_REGEX = /\A[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)?\z/
390
+ MAX_NAME_LENGTH = 253
391
+
392
+ def self.validate!(name, resource_type:)
393
+ # Prevents command injection via malformed names
394
+ end
395
+ ```
396
+
397
+ ### Error Handling
398
+
399
+ #### RetryHandler (`retry_handler.rb`)
400
+
401
+ Exponential backoff for transient errors:
402
+
403
+ ```ruby
404
+ RetryHandler.with_retry(max_retries: 3, logger: logger) do
405
+ # Network operation
406
+ end
407
+
408
+ # Retry delays: 1s, 2s, 4s (exponential backoff)
409
+ ```
410
+
411
+ Retryable errors:
412
+ - `NetworkError` - Silent failures, timeouts
413
+ - `ConnectionError` - kubectl connection issues
414
+
415
+ #### Custom Errors (`errors.rb`)
416
+
417
+ ```ruby
418
+ K8sContainerError < Train::TransportError # Base class
419
+ KubectlNotFoundError # kubectl binary not in PATH
420
+ ContainerNotFoundError # Container doesn't exist in pod
421
+ PodNotFoundError # Pod doesn't exist in namespace
422
+ ShellNotAvailableError # Distroless container, no shell
423
+ ```
424
+
425
+ ## Platform Detection Deep Dive
426
+
427
+ ### Why "Detect + Context" Pattern?
428
+
429
+ When connecting to an **operating system** (container, VM, bare metal), Train must detect the actual OS for InSpec resources to work correctly.
430
+
431
+ **Wrong approach** - `force_platform!('k8s-container')`:
432
+ - Platform name becomes `k8s-container` instead of `ubuntu`
433
+ - `os.linux?` returns `false`
434
+ - Resources like `user`, `package`, `service` fail
435
+
436
+ **Correct approach** - Detect + Context:
437
+ - Detect actual OS: `ubuntu`, `alpine`, `centos`
438
+ - Add context families: `kubernetes`, `container`
439
+ - `os.linux?` returns `true` ✓
440
+ - Resources work correctly ✓
441
+
442
+ ### Detection Commands
443
+
444
+ Train's scanner executes these to identify the OS:
445
+
446
+ ```bash
447
+ uname -s # "Linux"
448
+ uname -m # Architecture
449
+ cat /etc/os-release # OS identification
450
+ cat /etc/debian_version # Debian family
451
+ cat /etc/alpine-release # Alpine
452
+ cat /etc/redhat-release # RHEL family
453
+ ```
454
+
455
+ ### Result
456
+
457
+ ```bash
458
+ $ cinc-auditor detect -t k8s-container:///my-pod/my-container
459
+
460
+ Name: ubuntu
461
+ Families: debian, linux, unix, os, kubernetes, container
462
+ Release: 22.04
463
+ Arch: aarch64
464
+ ```
465
+
466
+ ## URI Format
467
+
468
+ ```
469
+ k8s-container://<namespace>/<pod>/<container>
470
+ ```
471
+
472
+ | Component | Required | Default | Example |
473
+ |-----------|----------|---------|---------|
474
+ | namespace | No | `default` | `production` |
475
+ | pod | Yes | - | `web-app-7d4b8c9f-x2k4m` |
476
+ | container | Yes | - | `nginx` |
477
+
478
+ **Examples:**
479
+ ```bash
480
+ # Full URI
481
+ k8s-container://production/web-app/nginx
482
+
483
+ # Default namespace
484
+ k8s-container:///my-pod/my-container
485
+ ```
486
+
487
+ ## Testing Architecture
488
+
489
+ ### Test Structure
490
+
491
+ ```
492
+ spec/
493
+ ├── train-k8s-container/ # Unit tests (mocked)
494
+ │ ├── connection_spec.rb
495
+ │ ├── kubectl_exec_client_spec.rb
496
+ │ ├── platform_spec.rb
497
+ │ ├── shell_detector_spec.rb
498
+ │ ├── session_manager_spec.rb
499
+ │ └── ...
500
+
501
+ └── integration/ # Integration tests (real cluster)
502
+ ├── platform_detection_spec.rb
503
+ ├── command_execution_spec.rb
504
+ └── ...
505
+ ```
506
+
507
+ ### CI Matrix
508
+
509
+ | Test Type | Ruby | Kubernetes | Description |
510
+ |-----------|------|------------|-------------|
511
+ | Unit | 3.1, 3.2, 3.3 | N/A | Mocked, fast |
512
+ | Integration | 3.1, 3.2, 3.3 | 1.29, 1.30, 1.31 | Real kind cluster |
513
+ | Pod-to-Pod | 3.3 | 1.30 | Scanner inside cluster |
514
+
515
+ ## Key Design Decisions
516
+
517
+ 1. **kubectl over Kubernetes Ruby client**
518
+ - Simpler dependency management
519
+ - Leverages user's existing kubeconfig and auth
520
+ - Works with any kubectl-compatible cluster
521
+
522
+ 2. **Connection pooling via PTY sessions**
523
+ - Dramatically improves performance for multi-control profiles
524
+ - Single kubectl process instead of one per command
525
+ - Thread-safe singleton pattern
526
+
527
+ 3. **Detect+Context over force_platform**
528
+ - Ensures InSpec resources work correctly
529
+ - Provides Kubernetes awareness via family tags
530
+ - Compatible with existing profiles
531
+
532
+ 4. **RFC 1123 validation**
533
+ - Prevents command injection via malformed names
534
+ - Enforces Kubernetes naming standards
535
+
536
+ 5. **ANSI sanitization (CVE-2021-25743)**
537
+ - Strips terminal escape sequences
538
+ - Prevents injection attacks via kubectl output
539
+
540
+ 6. **Cinc Auditor in CI**
541
+ - Open-source, license-free InSpec distribution
542
+ - No Chef license required for testing
543
+
544
+ 7. **OIDC trusted publishing**
545
+ - Secure gem publishing without API keys
546
+ - Leverages GitHub Actions identity
data/BEADS-BOARD.md ADDED
@@ -0,0 +1,104 @@
1
+ # train-k8s-container - Project Board
2
+
3
+ **Last Updated:** 2025-12-21
4
+ **Current Version:** 2.0.1
5
+ **RubyGems:** `train-k8s-container-mitre`
6
+ **Branch:** main
7
+
8
+ ---
9
+
10
+ ## Current Status: ✅ Released
11
+
12
+ v2.0.1 published to RubyGems and working correctly.
13
+
14
+ ---
15
+
16
+ ## Quick Start
17
+
18
+ ```bash
19
+ # Resume Claude session
20
+ claude --continue
21
+
22
+ # Install plugin
23
+ cinc-auditor plugin install train-k8s-container-mitre
24
+
25
+ # Test with running pod
26
+ cinc-auditor detect -t k8s-container://default/test-nginx/test-nginx
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Active Tasks
32
+
33
+ | Task | Status | Notes |
34
+ |------|--------|-------|
35
+ | Submit PR: Auto-discover train plugins | ⏳ Pending | Plan at `../inspec/PR-AUTO-DISCOVER-TRAIN-PLUGINS.md` |
36
+ | Submit PR: Dynamic os.kubernetes? | ⏳ Pending | Plan at `../inspec/PR-DYNAMIC-OS-FAMILY-METHODS.md` |
37
+
38
+ ---
39
+
40
+ ## Test Environment
41
+
42
+ ```bash
43
+ # Available test pods (may need recreation if completed)
44
+ kubectl run test-nginx --image=nginx:alpine --restart=Never
45
+ kubectl run test-ubuntu --image=ubuntu:24.04 --restart=Never -- sleep infinity
46
+ kubectl run test-ubi9 --image=registry.access.redhat.com/ubi9/ubi:latest --restart=Never -- sleep infinity
47
+
48
+ # Check pod status
49
+ kubectl get pods
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Key Files
55
+
56
+ | File | Purpose |
57
+ |------|---------|
58
+ | `lib/train-k8s-container/transport.rb` | Train.plugin(1) registration |
59
+ | `lib/train-k8s-container/connection.rb` | kubectl exec connection |
60
+ | `lib/train-k8s-container/platform.rb` | OS detection + k8s families |
61
+ | `lib/train-k8s-container-mitre.rb` | Shim for gem name |
62
+ | `.github/workflows/release-please.yml` | Automated version PRs |
63
+ | `.github/workflows/release-tag.yml` | Publish on tag |
64
+
65
+ ---
66
+
67
+ ## Release Process
68
+
69
+ 1. Commits with conventional prefixes land on `main`
70
+ 2. release-please creates a Release PR
71
+ 3. Merge PR → tag created automatically
72
+ 4. Tag triggers `release-tag.yml` → publishes to RubyGems
73
+
74
+ **Do NOT manually tag** - let release-please handle it.
75
+
76
+ ---
77
+
78
+ ## Session History
79
+
80
+ | Date | Session | Summary |
81
+ |------|---------|---------|
82
+ | 2025-12-21 | SESSION-2025-12-21-008.md | Plugin API clarified, tested on 3 OS types |
83
+ | 2025-12-12 | SESSION-2025-12-12-009.md | Diagrams research |
84
+ | 2025-12-05 | SESSION-2025-12-05-007.md | v2.0.1 released to RubyGems |
85
+ | 2025-12-04 | SESSION-2025-12-04-006.md | CI fixed, release automation |
86
+
87
+ ---
88
+
89
+ ## Known Issues
90
+
91
+ 1. **gem install doesn't show in plugin list** - InSpec bug, PR plan ready
92
+ 2. **Test pods expire** - Recreate with `--restart=Never` + `sleep infinity`
93
+
94
+ ---
95
+
96
+ ## Recovery Prompt
97
+
98
+ ```
99
+ Continue train-k8s-container from BEADS-BOARD.md
100
+
101
+ Status: v2.0.1 released and working
102
+ Pending: Submit 2 PRs to inspec/inspec upstream
103
+ Test pods: test-nginx, test-ubuntu, test-ubi9 (may need recreation)
104
+ ```