train-k8s-container-mitre 2.1.0 → 2.1.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.
- checksums.yaml +4 -4
- data/.release-please-manifest.json +1 -1
- data/ARCHITECTURE.md +546 -0
- data/CHANGELOG.md +15 -0
- data/CONTRIBUTING.md +125 -36
- data/DEVELOPMENT.md +32 -34
- data/README.md +16 -4
- data/lib/train-k8s-container/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6255dfedd08c1ccc04f6c69fdd56f530f927ece9876c248813ceabe38ab93134
|
|
4
|
+
data.tar.gz: 4976598e8fec6ae7274a468be4aedda447251dc66c59acf10c0af924b47b1be2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0959c3bbc96a96c717f0f4129ef6612ac874e599920bfd399179423e7884745accee2d9415473fa0e0dc7d50061aae01db81343be7dd4883e55465019716d9bc'
|
|
7
|
+
data.tar.gz: 3085e763b733098b172a3c73e9eb06698dd54f1632d65a0fe6b2545c7ea4dd5056a5ad49bc38cf37e469d19beb3a88dd7629b7243a8d9d848fc57a0e106153d8
|
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/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.1.1](https://github.com/mitre/train-k8s-container/compare/v2.1.0...v2.1.1) (2025-12-12)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* Parse PR number from JSON in auto-merge step ([09a3667](https://github.com/mitre/train-k8s-container/commit/09a3667cb67010c58837d3ff1ddcf5b197dc3d0d))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Documentation
|
|
17
|
+
|
|
18
|
+
* Add ARCHITECTURE.md with technical overview ([acfe73a](https://github.com/mitre/train-k8s-container/commit/acfe73a5ad16faa9b481d0c7802d2a8f6f64efb9))
|
|
19
|
+
* Enhance ARCHITECTURE.md with comprehensive technical details ([519675d](https://github.com/mitre/train-k8s-container/commit/519675db04d3766ac3d00575989e748da738a7ea))
|
|
20
|
+
* Fix inaccurate claims in README acknowledgments ([fa2e53c](https://github.com/mitre/train-k8s-container/commit/fa2e53c0eee41638edfa04a583bdcea4fd7eb272))
|
|
21
|
+
* Update release process documentation for automated workflow ([23d1fcf](https://github.com/mitre/train-k8s-container/commit/23d1fcfb38b1415c12029564b92dbcb9df34715d))
|
|
22
|
+
|
|
8
23
|
## [2.1.0](https://github.com/mitre/train-k8s-container/compare/v2.0.3...v2.1.0) (2025-12-12)
|
|
9
24
|
|
|
10
25
|
|
data/CONTRIBUTING.md
CHANGED
|
@@ -135,60 +135,149 @@ open coverage/index.html
|
|
|
135
135
|
5. **CI Passing**: All GitHub Actions checks must pass
|
|
136
136
|
6. **Merge**: Maintainers will merge approved PRs
|
|
137
137
|
|
|
138
|
-
##
|
|
138
|
+
## Versioning and Commit Messages
|
|
139
|
+
|
|
140
|
+
This project uses [Conventional Commits](https://www.conventionalcommits.org/) and [Semantic Versioning](https://semver.org/). Your commit message prefix determines how the version number changes.
|
|
141
|
+
|
|
142
|
+
**Official References:**
|
|
143
|
+
- [Conventional Commits Specification](https://www.conventionalcommits.org/en/v1.0.0/)
|
|
144
|
+
- [Angular Commit Message Guidelines](https://github.com/angular/angular/blob/main/CONTRIBUTING.md#-commit-message-format) (original source)
|
|
145
|
+
- [Semantic Versioning](https://semver.org/)
|
|
146
|
+
|
|
147
|
+
### Commit Prefix → Version Bump
|
|
148
|
+
|
|
149
|
+
| Commit Prefix | Version Change | When to Use |
|
|
150
|
+
|---------------|----------------|-------------|
|
|
151
|
+
| `feat:` | **Minor** (2.0.0 → 2.1.0) | New features, capabilities, or enhancements |
|
|
152
|
+
| `fix:` | **Patch** (2.0.0 → 2.0.1) | Bug fixes, corrections, error handling |
|
|
153
|
+
| `docs:` | **Patch** | Documentation changes only |
|
|
154
|
+
| `style:` | **Patch** | Code style, formatting (no logic change) |
|
|
155
|
+
| `refactor:` | **Patch** | Code restructuring (no behavior change) |
|
|
156
|
+
| `perf:` | **Patch** | Performance improvements |
|
|
157
|
+
| `test:` | **Patch** | Adding or updating tests |
|
|
158
|
+
| `chore:` | **Patch** | Maintenance, dependencies, tooling |
|
|
159
|
+
| `ci:` | **Patch** | CI/CD pipeline changes |
|
|
160
|
+
| `build:` | **Patch** | Build system changes |
|
|
161
|
+
| `revert:` | **Patch** | Reverting a previous commit |
|
|
162
|
+
| `feat!:` | **Major** (2.0.0 → 3.0.0) | Breaking changes (note the `!`) |
|
|
163
|
+
| `fix!:` | **Major** | Breaking bug fix |
|
|
164
|
+
| `BREAKING CHANGE:` | **Major** | In commit body, forces major bump |
|
|
165
|
+
|
|
166
|
+
### Type Descriptions
|
|
167
|
+
|
|
168
|
+
- **feat**: A new feature for the user (not a build script feature)
|
|
169
|
+
- **fix**: A bug fix for the user (not a build script fix)
|
|
170
|
+
- **docs**: Documentation only changes (README, CONTRIBUTING, inline docs)
|
|
171
|
+
- **style**: Changes that don't affect code meaning (whitespace, formatting, semicolons)
|
|
172
|
+
- **refactor**: Code change that neither fixes a bug nor adds a feature
|
|
173
|
+
- **perf**: Code change that improves performance
|
|
174
|
+
- **test**: Adding missing tests or correcting existing tests
|
|
175
|
+
- **chore**: Changes to build process, auxiliary tools, libraries
|
|
176
|
+
- **ci**: Changes to CI configuration files and scripts
|
|
177
|
+
- **build**: Changes that affect the build system or external dependencies
|
|
178
|
+
- **revert**: Reverts a previous commit (include reverted commit SHA in body)
|
|
179
|
+
|
|
180
|
+
### Examples
|
|
139
181
|
|
|
140
|
-
|
|
182
|
+
```bash
|
|
183
|
+
# Patch version bump (2.1.0 → 2.1.1)
|
|
184
|
+
git commit -m "fix: handle nil response in platform detection"
|
|
185
|
+
git commit -m "docs: update installation instructions"
|
|
186
|
+
git commit -m "chore: update rubocop dependency"
|
|
187
|
+
git commit -m "test: add integration tests for Alpine containers"
|
|
141
188
|
|
|
142
|
-
|
|
189
|
+
# Minor version bump (2.1.0 → 2.2.0)
|
|
190
|
+
git commit -m "feat: add support for Windows containers"
|
|
191
|
+
git commit -m "feat: add retry logic for transient kubectl failures"
|
|
143
192
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
193
|
+
# Major version bump (2.1.0 → 3.0.0)
|
|
194
|
+
git commit -m "feat!: change URI format to k8s://namespace/pod/container"
|
|
195
|
+
git commit -m "fix!: remove deprecated connection options"
|
|
196
|
+
```
|
|
148
197
|
|
|
149
|
-
|
|
150
|
-
- Bumps the version in `VERSION` file
|
|
151
|
-
- Updates `CHANGELOG.md` with commit messages
|
|
152
|
-
- Shows the proposed version change
|
|
198
|
+
### Commit Message Format
|
|
153
199
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
- GitHub Actions builds and publishes the gem to RubyGems.org
|
|
157
|
-
- A GitHub Release is created with auto-generated notes
|
|
200
|
+
```
|
|
201
|
+
<type>(<optional scope>): <description>
|
|
158
202
|
|
|
159
|
-
|
|
203
|
+
[optional body]
|
|
160
204
|
|
|
205
|
+
[optional footer(s)]
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Examples:**
|
|
161
209
|
```bash
|
|
162
|
-
#
|
|
163
|
-
git commit -m "
|
|
164
|
-
git push origin main
|
|
210
|
+
# Simple
|
|
211
|
+
git commit -m "fix: handle empty shell response"
|
|
165
212
|
|
|
166
|
-
#
|
|
167
|
-
|
|
213
|
+
# With scope
|
|
214
|
+
git commit -m "feat(platform): add FreeBSD detection"
|
|
168
215
|
|
|
169
|
-
#
|
|
170
|
-
|
|
171
|
-
|
|
216
|
+
# With body
|
|
217
|
+
git commit -m "feat: add Windows container support
|
|
218
|
+
|
|
219
|
+
This adds support for Windows containers running in Kubernetes.
|
|
220
|
+
Tested with Windows Server 2022 and Windows Server Core images."
|
|
221
|
+
|
|
222
|
+
# Breaking change with body
|
|
223
|
+
git commit -m "feat!: require Ruby 3.1+
|
|
224
|
+
|
|
225
|
+
BREAKING CHANGE: Ruby 2.7 and 3.0 are no longer supported.
|
|
226
|
+
This allows us to use pattern matching and other Ruby 3.1 features."
|
|
172
227
|
```
|
|
173
228
|
|
|
174
|
-
|
|
229
|
+
## Release Process
|
|
175
230
|
|
|
176
|
-
|
|
231
|
+
Releases are **fully automated** using [release-please](https://github.com/googleapis/release-please) with auto-merge enabled.
|
|
177
232
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
233
|
+
### How It Works
|
|
234
|
+
|
|
235
|
+
1. **Release PR Created Automatically**: When commits are pushed to `main`, release-please creates/updates a Release PR with auto-merge enabled that:
|
|
236
|
+
- Bumps the version in `lib/train-k8s-container/version.rb`
|
|
237
|
+
- Updates `CHANGELOG.md` with commit messages
|
|
238
|
+
- Shows the proposed version change
|
|
239
|
+
|
|
240
|
+
2. **Auto-Merge When CI Passes**: The Release PR automatically merges once all CI checks pass:
|
|
241
|
+
- Unit tests (Ruby 3.1, 3.2, 3.3)
|
|
242
|
+
- Integration tests (Kubernetes 1.29, 1.30, 1.31)
|
|
243
|
+
- Security audit
|
|
244
|
+
- Branch protection enforces all checks must pass
|
|
245
|
+
|
|
246
|
+
3. **Automatic Publishing**: After merge, release-please creates a GitHub Release which triggers:
|
|
247
|
+
- Gem build
|
|
248
|
+
- Publish to RubyGems.org (via OIDC trusted publishing)
|
|
249
|
+
- Gem artifact attached to GitHub Release
|
|
250
|
+
|
|
251
|
+
### Complete Automated Flow
|
|
181
252
|
|
|
182
|
-
|
|
253
|
+
```
|
|
254
|
+
Push commit → CI runs → Release PR created (auto-merge enabled)
|
|
255
|
+
↓
|
|
256
|
+
CI passes on PR
|
|
257
|
+
↓
|
|
258
|
+
PR auto-merges
|
|
259
|
+
↓
|
|
260
|
+
GitHub Release created
|
|
261
|
+
↓
|
|
262
|
+
Gem published to RubyGems
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Example
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# Make changes with conventional commit messages
|
|
269
|
+
git commit -m "feat: add support for Windows containers"
|
|
270
|
+
git push origin main
|
|
183
271
|
|
|
184
|
-
#
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
272
|
+
# Everything else is automatic:
|
|
273
|
+
# 1. release-please creates PR: "chore(main): release 2.2.0"
|
|
274
|
+
# 2. CI runs on the PR
|
|
275
|
+
# 3. PR auto-merges when CI passes
|
|
276
|
+
# 4. Tag v2.2.0 is created
|
|
277
|
+
# 5. Gem is published to RubyGems.org
|
|
189
278
|
```
|
|
190
279
|
|
|
191
|
-
|
|
280
|
+
No manual intervention required for releases.
|
|
192
281
|
|
|
193
282
|
## Getting Help
|
|
194
283
|
|
data/DEVELOPMENT.md
CHANGED
|
@@ -295,29 +295,24 @@ See `.github/workflows/ci.yml` for details.
|
|
|
295
295
|
|
|
296
296
|
## Releasing
|
|
297
297
|
|
|
298
|
-
Releases are automated using [release-please](https://github.com/googleapis/release-please).
|
|
298
|
+
Releases are **fully automated** using [release-please](https://github.com/googleapis/release-please) with auto-merge enabled. No manual intervention required.
|
|
299
299
|
|
|
300
|
-
###
|
|
300
|
+
### How It Works
|
|
301
301
|
|
|
302
|
-
1. **
|
|
302
|
+
1. **Push commits with Conventional Commits format**:
|
|
303
303
|
```bash
|
|
304
304
|
git commit -m "feat: add Windows container support"
|
|
305
305
|
git commit -m "fix: handle empty shell response"
|
|
306
|
-
git commit -m "docs: update installation instructions"
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
2. **Push to main** - release-please will automatically create a Release PR:
|
|
310
|
-
```bash
|
|
311
306
|
git push origin main
|
|
312
|
-
# release-please creates PR: "chore(main): release 2.1.0"
|
|
313
307
|
```
|
|
314
308
|
|
|
315
|
-
|
|
316
|
-
-
|
|
317
|
-
-
|
|
318
|
-
-
|
|
319
|
-
-
|
|
320
|
-
- GitHub Release
|
|
309
|
+
2. **Automatic flow**:
|
|
310
|
+
- Release-please creates/updates a Release PR with auto-merge enabled
|
|
311
|
+
- CI runs on the PR (unit tests, integration tests, security audit)
|
|
312
|
+
- Branch protection requires all checks to pass
|
|
313
|
+
- PR auto-merges when CI is green
|
|
314
|
+
- Release-please creates a GitHub Release
|
|
315
|
+
- `release-tag.yml` triggers and publishes gem to RubyGems.org
|
|
321
316
|
|
|
322
317
|
### Conventional Commits Cheat Sheet
|
|
323
318
|
|
|
@@ -329,25 +324,28 @@ Releases are automated using [release-please](https://github.com/googleapis/rele
|
|
|
329
324
|
| `chore:` | Patch | `chore: update dependencies` |
|
|
330
325
|
| `feat!:` | Major (2.0.0 → 3.0.0) | `feat!: change URI format` |
|
|
331
326
|
|
|
332
|
-
###
|
|
333
|
-
|
|
334
|
-
For hotfixes that can't wait for the release-please flow:
|
|
335
|
-
|
|
336
|
-
```bash
|
|
337
|
-
# Update VERSION file
|
|
338
|
-
echo "2.0.2" > VERSION
|
|
339
|
-
|
|
340
|
-
# Update CHANGELOG.md manually
|
|
327
|
+
### Complete Flow Diagram
|
|
341
328
|
|
|
342
|
-
# Commit and tag
|
|
343
|
-
git add VERSION CHANGELOG.md
|
|
344
|
-
git commit -m "chore: release v2.0.2"
|
|
345
|
-
git tag v2.0.2
|
|
346
|
-
git push origin main --tags
|
|
347
329
|
```
|
|
330
|
+
Push commit → CI runs on main → Release-please creates PR (auto-merge on)
|
|
331
|
+
↓
|
|
332
|
+
CI runs on PR
|
|
333
|
+
↓
|
|
334
|
+
PR auto-merges when green
|
|
335
|
+
↓
|
|
336
|
+
GitHub Release created (v2.x.x)
|
|
337
|
+
↓
|
|
338
|
+
release-tag.yml triggers
|
|
339
|
+
↓
|
|
340
|
+
Gem published to RubyGems.org
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Key Files
|
|
348
344
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
345
|
+
| File | Purpose |
|
|
346
|
+
|------|---------|
|
|
347
|
+
| `lib/train-k8s-container/version.rb` | VERSION constant (updated by release-please) |
|
|
348
|
+
| `release-please-config.json` | Release-please configuration |
|
|
349
|
+
| `.release-please-manifest.json` | Current version tracking |
|
|
350
|
+
| `.github/workflows/release-please.yml` | Creates PRs with auto-merge |
|
|
351
|
+
| `.github/workflows/release-tag.yml` | Publishes gem on release |
|
data/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A Train transport plugin that enables Chef InSpec and Cinc Auditor to execute compliance checks against containers running in Kubernetes clusters via kubectl exec.
|
|
4
4
|
|
|
5
|
+
[](https://badge.fury.io/rb/train-k8s-container-mitre)
|
|
5
6
|
[](https://github.com/mitre/train-k8s-container/actions/workflows/ci.yml)
|
|
6
7
|
[](https://github.com/mitre/train-k8s-container/actions/workflows/security.yml)
|
|
7
8
|
|
|
@@ -29,7 +30,7 @@ This plugin allows InSpec/Cinc Auditor to scan containers running in Kubernetes
|
|
|
29
30
|
**Important:** Always install Train plugins using `inspec plugin install` or `cinc-auditor plugin install`. Do NOT use `gem install` directly, as this can cause issues with plugin discovery and management.
|
|
30
31
|
|
|
31
32
|
```bash
|
|
32
|
-
# Using Cinc Auditor (
|
|
33
|
+
# Using Cinc Auditor (open source, license-free)
|
|
33
34
|
cinc-auditor plugin install train-k8s-container-mitre
|
|
34
35
|
|
|
35
36
|
# Or using Chef InSpec
|
|
@@ -204,6 +205,18 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
|
204
205
|
4. Run `bundle exec rspec && bundle exec rake style`
|
|
205
206
|
5. Submit a pull request
|
|
206
207
|
|
|
208
|
+
### Versioning
|
|
209
|
+
|
|
210
|
+
This project uses [Conventional Commits](https://www.conventionalcommits.org/) for automated releases:
|
|
211
|
+
|
|
212
|
+
| Commit Prefix | Version Bump | Example |
|
|
213
|
+
|---------------|--------------|---------|
|
|
214
|
+
| `feat:` | Minor (2.1.0) | New features |
|
|
215
|
+
| `fix:` | Patch (2.0.1) | Bug fixes |
|
|
216
|
+
| `feat!:` | Major (3.0.0) | Breaking changes |
|
|
217
|
+
|
|
218
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md#versioning-and-commit-messages) for full details.
|
|
219
|
+
|
|
207
220
|
## Security
|
|
208
221
|
|
|
209
222
|
See [SECURITY.md](SECURITY.md) for security policy and reporting vulnerabilities.
|
|
@@ -224,13 +237,12 @@ This project is maintained by the MITRE SAF (Security Automation Framework) team
|
|
|
224
237
|
|
|
225
238
|
## Acknowledgments
|
|
226
239
|
|
|
227
|
-
This project is a fork of [inspec/train-k8s-container](https://github.com/inspec/train-k8s-container),
|
|
240
|
+
This project is a fork of [inspec/train-k8s-container](https://github.com/inspec/train-k8s-container), enhanced with:
|
|
228
241
|
|
|
229
242
|
- Train v2 plugin architecture
|
|
230
243
|
- Detect+Context platform detection pattern
|
|
231
244
|
- Comprehensive CI/CD with pod-to-pod testing
|
|
232
|
-
-
|
|
233
|
-
- MITRE SAF ecosystem integration
|
|
245
|
+
- Automated releases via release-please
|
|
234
246
|
|
|
235
247
|
---
|
|
236
248
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: train-k8s-container-mitre
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.1.
|
|
4
|
+
version: 2.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- MITRE SAF Team
|
|
@@ -49,6 +49,7 @@ files:
|
|
|
49
49
|
- ".release-please-manifest.json"
|
|
50
50
|
- ".rspec"
|
|
51
51
|
- ".rubocop.yml"
|
|
52
|
+
- ARCHITECTURE.md
|
|
52
53
|
- CHANGELOG.md
|
|
53
54
|
- CODE_OF_CONDUCT.md
|
|
54
55
|
- CONTRIBUTING.md
|