legion-settings 1.3.5 → 1.3.7
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/CHANGELOG.md +11 -0
- data/CLAUDE.md +14 -2
- data/README.md +1 -1
- data/lib/legion/settings/loader.rb +29 -9
- data/lib/legion/settings/version.rb +1 -1
- data/lib/legion/settings.rb +8 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0646cd4b6cfc444c7a7468206df6a2ebb4148c82f561a6f8df47e663199cc776
|
|
4
|
+
data.tar.gz: 9eb1f3e56f4af70ba7df5dd8a494998ad9e3e1ace96bf2141eae8dbbaed60afb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bca6f0949cf3e29992894d3b2d05a9f41283df50d8f4cf1f2d911048c5de95f66d3dbf76bca2eda9cc4c2124a888808c73ca3a4477499c22fec2a428a9a0b525
|
|
7
|
+
data.tar.gz: b55b543a2f387c813703d5276ff4975237c93dbe66b8281ecb05d4991645d793c0d413c1d929cc7497f63aae6d90975921444a6d1eba8159f3ab56cacd60fcb6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Legion::Settings Changelog
|
|
2
2
|
|
|
3
|
+
## [1.3.7] - 2026-03-20
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `enterprise_privacy?` class method: returns true when `LEGION_ENTERPRISE_PRIVACY=true` env var or `enterprise_data_privacy` setting is set
|
|
7
|
+
- `LEGION_ENTERPRISE_PRIVACY` env var loaded into settings via `Loader#load_privacy_env`
|
|
8
|
+
|
|
9
|
+
## [1.3.6] - 2026-03-20
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Guard all `Legion::Logging` calls in loader with `defined?` check to prevent `NameError` when legion-logging is not loaded (fixes CI for downstream gems like legion-transport)
|
|
13
|
+
|
|
3
14
|
## [1.3.5] - 2026-03-19
|
|
4
15
|
|
|
5
16
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
Hash-like configuration store for the LegionIO framework. Loads settings from JSON files, directories, and environment variables. Provides a unified `Legion::Settings[:key]` accessor used by all other Legion gems. Includes schema-based validation with type inference, enum constraints, and cross-module checks.
|
|
9
9
|
|
|
10
10
|
**GitHub**: https://github.com/LegionIO/legion-settings
|
|
11
|
-
**Version**: 1.3.
|
|
11
|
+
**Version**: 1.3.5
|
|
12
12
|
**License**: Apache-2.0
|
|
13
13
|
|
|
14
14
|
## Architecture
|
|
@@ -27,11 +27,19 @@ Legion::Settings (singleton module)
|
|
|
27
27
|
│
|
|
28
28
|
├── Loader # Core: loads env vars, files, directories, merges settings
|
|
29
29
|
│ ├── .load_env # Load environment variables (LEGION_API_PORT)
|
|
30
|
+
│ ├── .load_dns_bootstrap # DNS-based corporate config discovery (baseline defaults)
|
|
30
31
|
│ ├── .load_file # Load single JSON file
|
|
31
32
|
│ ├── .load_directory # Load all JSON files from directory
|
|
32
33
|
│ ├── .load_module_settings # Merge with module priority
|
|
33
34
|
│ └── .load_module_default # Merge with default priority
|
|
34
35
|
│
|
|
36
|
+
├── DnsBootstrap # DNS-based corporate config auto-discovery
|
|
37
|
+
│ ├── .resolve? # Check if legion-bootstrap.<domain> resolves
|
|
38
|
+
│ ├── .fetch # HTTPS GET /legion/bootstrap.json
|
|
39
|
+
│ ├── .write_cache # Atomic write to ~/.legionio/settings/_dns_bootstrap.json
|
|
40
|
+
│ ├── .read_cache # Read + strip metadata, delete if corrupted
|
|
41
|
+
│ └── .cache_exists? # Check for cached config
|
|
42
|
+
│
|
|
35
43
|
├── Schema # Type inference, validation, unknown key detection
|
|
36
44
|
│ ├── .register # Infer types from defaults
|
|
37
45
|
│ ├── .define_override # Add enum/required/type constraints
|
|
@@ -46,7 +54,9 @@ Legion::Settings (singleton module)
|
|
|
46
54
|
### Key Design Patterns
|
|
47
55
|
|
|
48
56
|
- **Auto-Load on Access**: `Legion::Settings[:key]` auto-loads if not initialized
|
|
57
|
+
- **DNS Bootstrap Discovery**: On load, resolves `legion-bootstrap.<search-domain>` to fetch corporate baseline config. First boot blocks; subsequent boots use cache + async refresh. Disabled via `LEGION_DNS_BOOTSTRAP=false`
|
|
49
58
|
- **Directory-Based Config**: Loads all `.json` files from config directories (default paths: `/etc/legionio`, `~/legionio`, `./settings`)
|
|
59
|
+
- **Load Priority** (lowest to highest): hardcoded defaults < DNS bootstrap < local JSON files < CLI flags < secret resolution
|
|
50
60
|
- **Module Merging**: Each Legion module registers its defaults via `merge_settings` during startup
|
|
51
61
|
- **Schema Inference**: Types are inferred from default values — no manual schema definitions needed
|
|
52
62
|
- **Two-Pass Validation**: Per-module on merge (catches type mismatches immediately) + cross-module on `validate!` (catches dependency conflicts)
|
|
@@ -70,13 +80,15 @@ Legion::Settings (singleton module)
|
|
|
70
80
|
| `lib/legion/settings/validation_error.rb` | Error collection and formatted reporting |
|
|
71
81
|
| `lib/legion/settings/os.rb` | OS detection helpers |
|
|
72
82
|
| `lib/legion/settings/resolver.rb` | Secret resolution: `vault://` and `env://` URI references, fallback chains |
|
|
83
|
+
| `lib/legion/settings/dns_bootstrap.rb` | DNS-based corporate config discovery, caching, background refresh |
|
|
73
84
|
| `lib/legion/settings/version.rb` | VERSION constant |
|
|
74
85
|
| `spec/legion/settings_spec.rb` | Core settings module tests |
|
|
75
86
|
| `spec/legion/settings_module_spec.rb` | Module-level accessor and merge tests |
|
|
76
87
|
| `spec/legion/loader_spec.rb` | Loader: env/file/directory loading tests |
|
|
77
88
|
| `spec/legion/settings/schema_spec.rb` | Schema validation tests |
|
|
78
89
|
| `spec/legion/settings/validation_error_spec.rb` | Error formatting tests |
|
|
79
|
-
| `spec/legion/settings/integration_spec.rb` | End-to-end validation tests |
|
|
90
|
+
| `spec/legion/settings/integration_spec.rb` | End-to-end validation + DNS bootstrap override tests |
|
|
91
|
+
| `spec/legion/settings/dns_bootstrap_spec.rb` | DnsBootstrap class tests (resolve, fetch, cache) |
|
|
80
92
|
| `spec/legion/settings/role_defaults_spec.rb` | Role profile default settings tests |
|
|
81
93
|
| `spec/legion/settings/resolver_spec.rb` | Secret resolver tests (env://, vault://, lease://, fallback chains) |
|
|
82
94
|
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Configuration management module for the [LegionIO](https://github.com/LegionIO/LegionIO) framework. Loads settings from JSON files, directories, and environment variables. Provides a unified `Legion::Settings[:key]` accessor used by all other Legion gems.
|
|
4
4
|
|
|
5
|
-
**Version**: 1.3.
|
|
5
|
+
**Version**: 1.3.5
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -128,6 +128,7 @@ module Legion
|
|
|
128
128
|
|
|
129
129
|
def load_env
|
|
130
130
|
load_api_env
|
|
131
|
+
load_privacy_env
|
|
131
132
|
end
|
|
132
133
|
|
|
133
134
|
def load_dns_bootstrap(cache_dir: nil)
|
|
@@ -162,7 +163,7 @@ module Legion
|
|
|
162
163
|
end
|
|
163
164
|
|
|
164
165
|
def load_file(file)
|
|
165
|
-
|
|
166
|
+
log_debug("Trying to load file #{file}")
|
|
166
167
|
if File.file?(file) && File.readable?(file)
|
|
167
168
|
begin
|
|
168
169
|
contents = read_config_file(file)
|
|
@@ -173,11 +174,11 @@ module Legion
|
|
|
173
174
|
# @indifferent_access = false
|
|
174
175
|
@loaded_files << file
|
|
175
176
|
rescue Legion::JSON::ParseError => e
|
|
176
|
-
|
|
177
|
-
|
|
177
|
+
log_error("config file must be valid json: #{file}")
|
|
178
|
+
log_error(" parse error: #{e.message}")
|
|
178
179
|
end
|
|
179
180
|
else
|
|
180
|
-
|
|
181
|
+
log_warn("Config file does not exist or is not readable file:#{file}")
|
|
181
182
|
end
|
|
182
183
|
end
|
|
183
184
|
|
|
@@ -199,7 +200,7 @@ module Legion
|
|
|
199
200
|
@settings[:client][:subscriptions].uniq!
|
|
200
201
|
@indifferent_access = false
|
|
201
202
|
else
|
|
202
|
-
|
|
203
|
+
log_warn('unable to apply legion client overrides, reason: client subscriptions is not an array')
|
|
203
204
|
end
|
|
204
205
|
end
|
|
205
206
|
|
|
@@ -226,7 +227,7 @@ module Legion
|
|
|
226
227
|
end
|
|
227
228
|
|
|
228
229
|
def load_dns_first_boot(bootstrap)
|
|
229
|
-
|
|
230
|
+
log_debug("DNS bootstrap: first boot, fetching from #{bootstrap.url}")
|
|
230
231
|
config = bootstrap.fetch
|
|
231
232
|
bootstrap.write_cache(config) if config
|
|
232
233
|
config
|
|
@@ -285,7 +286,14 @@ module Legion
|
|
|
285
286
|
|
|
286
287
|
@settings[:api] ||= {}
|
|
287
288
|
@settings[:api][:port] = ENV['LEGION_API_PORT'].to_i
|
|
288
|
-
|
|
289
|
+
log_warn("using api port environment variable, api: #{@settings[:api]}")
|
|
290
|
+
@indifferent_access = false
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def load_privacy_env
|
|
294
|
+
return unless ENV['LEGION_ENTERPRISE_PRIVACY'] == 'true'
|
|
295
|
+
|
|
296
|
+
@settings[:enterprise_data_privacy] = true
|
|
289
297
|
@indifferent_access = false
|
|
290
298
|
end
|
|
291
299
|
|
|
@@ -355,18 +363,30 @@ module Legion
|
|
|
355
363
|
'unknown'
|
|
356
364
|
end
|
|
357
365
|
|
|
366
|
+
def log_debug(message)
|
|
367
|
+
Legion::Logging.debug(message) if defined?(Legion::Logging)
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
def log_warn(message)
|
|
371
|
+
defined?(Legion::Logging) ? Legion::Logging.warn(message) : warn(message)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
def log_error(message)
|
|
375
|
+
defined?(Legion::Logging) ? Legion::Logging.error(message) : warn(message)
|
|
376
|
+
end
|
|
377
|
+
|
|
358
378
|
def warning(message, data = {})
|
|
359
379
|
@warnings << {
|
|
360
380
|
message: message
|
|
361
381
|
}.merge(data)
|
|
362
|
-
|
|
382
|
+
log_warn(message)
|
|
363
383
|
end
|
|
364
384
|
|
|
365
385
|
def load_error(message, data = {})
|
|
366
386
|
@errors << {
|
|
367
387
|
message: message
|
|
368
388
|
}.merge(data)
|
|
369
|
-
|
|
389
|
+
log_error(message)
|
|
370
390
|
raise(Error, message)
|
|
371
391
|
end
|
|
372
392
|
|
data/lib/legion/settings.rb
CHANGED
|
@@ -75,6 +75,14 @@ module Legion
|
|
|
75
75
|
false
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
+
def enterprise_privacy?
|
|
79
|
+
return true if ENV['LEGION_ENTERPRISE_PRIVACY'] == 'true'
|
|
80
|
+
|
|
81
|
+
Legion::Settings[:enterprise_data_privacy] ? true : false
|
|
82
|
+
rescue StandardError
|
|
83
|
+
false
|
|
84
|
+
end
|
|
85
|
+
|
|
78
86
|
def validate!
|
|
79
87
|
@loader = load if @loader.nil?
|
|
80
88
|
revalidate_all_modules
|