mcp-proxy-adapter 6.4.44__py3-none-any.whl → 6.4.46__py3-none-any.whl

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.
Files changed (29) hide show
  1. mcp_proxy_adapter/core/proxy_registration.py +100 -68
  2. mcp_proxy_adapter/custom_openapi.py +294 -2
  3. mcp_proxy_adapter/examples/bugfix_certificate_config.py +284 -0
  4. mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
  5. mcp_proxy_adapter/examples/config_builder.py +574 -0
  6. mcp_proxy_adapter/examples/config_cli.py +283 -0
  7. mcp_proxy_adapter/examples/create_test_configs.py +169 -266
  8. mcp_proxy_adapter/examples/generate_certificates_bugfix.py +374 -0
  9. mcp_proxy_adapter/examples/generate_certificates_cli.py +406 -0
  10. mcp_proxy_adapter/examples/generate_certificates_fixed.py +313 -0
  11. mcp_proxy_adapter/examples/generate_certificates_framework.py +366 -0
  12. mcp_proxy_adapter/examples/generate_certificates_openssl.py +391 -0
  13. mcp_proxy_adapter/examples/required_certificates.py +210 -0
  14. mcp_proxy_adapter/examples/run_full_test_suite.py +117 -13
  15. mcp_proxy_adapter/examples/run_security_tests_fixed.py +42 -26
  16. mcp_proxy_adapter/examples/security_test_client.py +332 -85
  17. mcp_proxy_adapter/examples/test_config_builder.py +450 -0
  18. mcp_proxy_adapter/examples/update_config_certificates.py +136 -0
  19. mcp_proxy_adapter/schemas/base_schema.json +114 -0
  20. mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
  21. mcp_proxy_adapter/schemas/roles.json +37 -0
  22. mcp_proxy_adapter/schemas/roles_schema.json +162 -0
  23. mcp_proxy_adapter/version.py +1 -1
  24. {mcp_proxy_adapter-6.4.44.dist-info → mcp_proxy_adapter-6.4.46.dist-info}/METADATA +81 -1
  25. {mcp_proxy_adapter-6.4.44.dist-info → mcp_proxy_adapter-6.4.46.dist-info}/RECORD +28 -12
  26. mcp_proxy_adapter-6.4.46.dist-info/entry_points.txt +12 -0
  27. mcp_proxy_adapter-6.4.44.dist-info/entry_points.txt +0 -2
  28. {mcp_proxy_adapter-6.4.44.dist-info → mcp_proxy_adapter-6.4.46.dist-info}/WHEEL +0 -0
  29. {mcp_proxy_adapter-6.4.44.dist-info → mcp_proxy_adapter-6.4.46.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,450 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Comprehensive Tests for Configuration Builder
4
+ Tests all combinations of protocols, authentication methods, and other parameters.
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
9
+ import json
10
+ import tempfile
11
+ from pathlib import Path
12
+ from typing import Dict, Any
13
+
14
+ from config_builder import ConfigBuilder, ConfigFactory, Protocol, AuthMethod
15
+
16
+
17
+ class TestConfigBuilder:
18
+ """Test cases for ConfigBuilder class."""
19
+
20
+ def test_default_configuration(self):
21
+ """Test default configuration structure."""
22
+ builder = ConfigBuilder()
23
+ config = builder.build()
24
+
25
+ # Check required fields
26
+ assert "uuid" in config
27
+ assert "server" in config
28
+ assert "ssl" in config
29
+ assert "security" in config
30
+ assert "protocols" in config
31
+
32
+ # Check default values
33
+ assert config["server"]["host"] == "0.0.0.0"
34
+ assert config["server"]["port"] == 8000
35
+ assert config["ssl"]["enabled"] is False
36
+ assert config["security"]["enabled"] is False
37
+
38
+ def test_set_server(self):
39
+ """Test server configuration setting."""
40
+ builder = ConfigBuilder()
41
+ config = builder.set_server(host="127.0.0.1", port=9000, debug=True, log_level="DEBUG").build()
42
+
43
+ assert config["server"]["host"] == "127.0.0.1"
44
+ assert config["server"]["port"] == 9000
45
+ assert config["server"]["debug"] is True
46
+ assert config["server"]["log_level"] == "DEBUG"
47
+
48
+ def test_set_logging(self):
49
+ """Test logging configuration setting."""
50
+ builder = ConfigBuilder()
51
+ config = builder.set_logging(log_dir="/tmp/logs", level="WARNING", console_output=False).build()
52
+
53
+ assert config["logging"]["log_dir"] == "/tmp/logs"
54
+ assert config["logging"]["level"] == "WARNING"
55
+ assert config["logging"]["console_output"] is False
56
+
57
+ def test_set_protocol_http(self):
58
+ """Test HTTP protocol configuration."""
59
+ builder = ConfigBuilder()
60
+ config = builder.set_protocol(Protocol.HTTP).build()
61
+
62
+ assert config["ssl"]["enabled"] is False
63
+ assert config["security"]["ssl"]["enabled"] is False
64
+ assert config["protocols"]["allowed_protocols"] == ["http"]
65
+ assert config["protocols"]["default_protocol"] == "http"
66
+ assert config["protocols"]["protocol_handlers"]["http"]["enabled"] is True
67
+ assert config["protocols"]["protocol_handlers"]["https"]["enabled"] is False
68
+ assert config["protocols"]["protocol_handlers"]["mtls"]["enabled"] is False
69
+
70
+ def test_set_protocol_https(self):
71
+ """Test HTTPS protocol configuration."""
72
+ builder = ConfigBuilder()
73
+ config = builder.set_protocol(Protocol.HTTPS, cert_dir="/tmp/certs", key_dir="/tmp/keys").build()
74
+
75
+ assert config["ssl"]["enabled"] is True
76
+ assert config["ssl"]["cert_file"] == "/tmp/certs/server_cert.pem"
77
+ assert config["ssl"]["key_file"] == "/tmp/keys/server_key.pem"
78
+ assert config["ssl"]["ca_cert"] == "/tmp/certs/ca_cert.pem"
79
+
80
+ assert config["security"]["ssl"]["enabled"] is True
81
+ assert config["security"]["ssl"]["cert_file"] == "/tmp/certs/server_cert.pem"
82
+ assert config["security"]["ssl"]["key_file"] == "/tmp/keys/server_key.pem"
83
+ assert config["security"]["ssl"]["ca_cert_file"] == "/tmp/certs/ca_cert.pem"
84
+
85
+ assert config["protocols"]["allowed_protocols"] == ["https"]
86
+ assert config["protocols"]["default_protocol"] == "https"
87
+ assert config["protocols"]["protocol_handlers"]["http"]["enabled"] is False
88
+ assert config["protocols"]["protocol_handlers"]["https"]["enabled"] is True
89
+ assert config["protocols"]["protocol_handlers"]["mtls"]["enabled"] is False
90
+
91
+ def test_set_protocol_mtls(self):
92
+ """Test mTLS protocol configuration."""
93
+ builder = ConfigBuilder()
94
+ config = builder.set_protocol(Protocol.MTLS, cert_dir="/tmp/certs", key_dir="/tmp/keys").build()
95
+
96
+ assert config["ssl"]["enabled"] is True
97
+ assert config["ssl"]["verify_client"] is True
98
+ assert config["ssl"]["client_cert_required"] is True
99
+
100
+ assert config["security"]["ssl"]["enabled"] is True
101
+ assert config["security"]["ssl"]["client_cert_file"] == "/tmp/certs/admin_cert.pem"
102
+ assert config["security"]["ssl"]["client_key_file"] == "/tmp/keys/admin_key.pem"
103
+ assert config["security"]["ssl"]["verify_mode"] == "CERT_REQUIRED"
104
+
105
+ assert config["protocols"]["allowed_protocols"] == ["mtls"]
106
+ assert config["protocols"]["default_protocol"] == "mtls"
107
+ assert config["protocols"]["protocol_handlers"]["http"]["enabled"] is False
108
+ assert config["protocols"]["protocol_handlers"]["https"]["enabled"] is False
109
+ assert config["protocols"]["protocol_handlers"]["mtls"]["enabled"] is True
110
+ assert config["protocols"]["protocol_handlers"]["mtls"]["client_cert_required"] is True
111
+
112
+ def test_set_auth_none(self):
113
+ """Test no authentication configuration."""
114
+ builder = ConfigBuilder()
115
+ config = builder.set_auth(AuthMethod.NONE).build()
116
+
117
+ assert config["security"]["enabled"] is False
118
+ assert config["security"]["auth"]["enabled"] is False
119
+
120
+ def test_set_auth_token(self):
121
+ """Test token authentication configuration."""
122
+ api_keys = {"admin": "admin-key", "user": "user-key"}
123
+ builder = ConfigBuilder()
124
+ config = builder.set_auth(AuthMethod.TOKEN, api_keys=api_keys).build()
125
+
126
+ assert config["security"]["enabled"] is True
127
+ assert config["security"]["auth"]["enabled"] is True
128
+ assert config["security"]["auth"]["methods"] == ["api_key"]
129
+ assert config["security"]["auth"]["api_keys"] == api_keys
130
+
131
+ def test_set_auth_basic(self):
132
+ """Test basic authentication configuration."""
133
+ builder = ConfigBuilder()
134
+ config = builder.set_auth(AuthMethod.BASIC).build()
135
+
136
+ assert config["security"]["enabled"] is True
137
+ assert config["security"]["auth"]["enabled"] is True
138
+ assert config["security"]["auth"]["methods"] == ["basic_auth"]
139
+ assert config["security"]["auth"]["basic_auth"] is True
140
+
141
+ def test_set_auth_with_roles(self):
142
+ """Test authentication with roles configuration."""
143
+ roles = {"admin": ["read", "write"], "user": ["read"]}
144
+ builder = ConfigBuilder()
145
+ config = builder.set_auth(AuthMethod.TOKEN, roles=roles).build()
146
+
147
+ assert config["security"]["auth"]["user_roles"] == roles
148
+ assert config["roles"]["enabled"] is True
149
+ assert config["security"]["permissions"]["enabled"] is True
150
+
151
+ def test_set_proxy_registration(self):
152
+ """Test proxy registration configuration."""
153
+ builder = ConfigBuilder()
154
+ config = builder.set_proxy_registration(
155
+ enabled=True,
156
+ proxy_url="https://proxy.example.com:8080",
157
+ server_id="test_server",
158
+ cert_dir="/tmp/certs"
159
+ ).build()
160
+
161
+ assert config["proxy_registration"]["enabled"] is True
162
+ assert config["proxy_registration"]["server_url"] == "https://proxy.example.com:8080/register"
163
+ assert config["proxy_registration"]["proxy_url"] == "https://proxy.example.com:8080"
164
+ assert config["proxy_registration"]["fallback_proxy_url"] == "http://proxy.example.com:8080"
165
+ assert config["proxy_registration"]["ssl"]["ca_cert"] == "/tmp/certs/ca_cert.pem"
166
+ assert config["proxy_registration"]["server_id"] == "test_server"
167
+ assert config["proxy_registration"]["server_name"] == "Test_Server Server"
168
+ assert config["proxy_registration"]["description"] == "Test server for test_server"
169
+
170
+ def test_set_debug(self):
171
+ """Test debug configuration."""
172
+ builder = ConfigBuilder()
173
+ config = builder.set_debug(enabled=True, log_level="DEBUG").build()
174
+
175
+ assert config["debug"]["enabled"] is True
176
+ assert config["debug"]["log_level"] == "DEBUG"
177
+ assert config["logging"]["level"] == "DEBUG"
178
+
179
+ def test_set_commands(self):
180
+ """Test commands configuration."""
181
+ enabled = ["health", "echo", "test"]
182
+ disabled = ["admin", "debug"]
183
+ builder = ConfigBuilder()
184
+ config = builder.set_commands(enabled_commands=enabled, disabled_commands=disabled).build()
185
+
186
+ assert config["commands"]["enabled_commands"] == enabled
187
+ assert config["commands"]["disabled_commands"] == disabled
188
+
189
+ def test_save_configuration(self):
190
+ """Test saving configuration to file."""
191
+ with tempfile.TemporaryDirectory() as temp_dir:
192
+ builder = ConfigBuilder()
193
+ builder.set_server(port=9000)
194
+ config_path = builder.save(Path(temp_dir) / "test_config.json")
195
+
196
+ assert config_path.exists()
197
+
198
+ with open(config_path, 'r') as f:
199
+ saved_config = json.load(f)
200
+
201
+ assert saved_config["server"]["port"] == 9000
202
+
203
+ def test_reset_configuration(self):
204
+ """Test configuration reset."""
205
+ builder = ConfigBuilder()
206
+ builder.set_server(port=9000)
207
+ builder.set_auth(AuthMethod.TOKEN)
208
+
209
+ config1 = builder.build()
210
+ assert config1["server"]["port"] == 9000
211
+ assert config1["security"]["enabled"] is True
212
+
213
+ builder.reset()
214
+ config2 = builder.build()
215
+ assert config2["server"]["port"] == 8000 # Default value
216
+ assert config2["security"]["enabled"] is False # Default value
217
+
218
+
219
+ class TestConfigFactory:
220
+ """Test cases for ConfigFactory class."""
221
+
222
+ def test_create_http_simple(self):
223
+ """Test HTTP simple configuration creation."""
224
+ config = ConfigFactory.create_http_simple(host="127.0.0.1", port=9000, log_dir="/tmp/logs")
225
+
226
+ assert config["server"]["host"] == "127.0.0.1"
227
+ assert config["server"]["port"] == 9000
228
+ assert config["logging"]["log_dir"] == "/tmp/logs"
229
+ assert config["ssl"]["enabled"] is False
230
+ assert config["security"]["enabled"] is False
231
+ assert config["protocols"]["allowed_protocols"] == ["http"]
232
+ assert config["proxy_registration"]["enabled"] is False
233
+
234
+ def test_create_http_token(self):
235
+ """Test HTTP token configuration creation."""
236
+ api_keys = {"admin": "admin-key", "user": "user-key"}
237
+ config = ConfigFactory.create_http_token(api_keys=api_keys)
238
+
239
+ assert config["ssl"]["enabled"] is False
240
+ assert config["security"]["enabled"] is True
241
+ assert config["security"]["auth"]["enabled"] is True
242
+ assert config["security"]["auth"]["methods"] == ["api_key"]
243
+ assert config["security"]["auth"]["api_keys"] == api_keys
244
+
245
+ def test_create_https_simple(self):
246
+ """Test HTTPS simple configuration creation."""
247
+ config = ConfigFactory.create_https_simple(cert_dir="/tmp/certs", key_dir="/tmp/keys")
248
+
249
+ assert config["ssl"]["enabled"] is True
250
+ assert config["ssl"]["cert_file"] == "/tmp/certs/server_cert.pem"
251
+ assert config["ssl"]["key_file"] == "/tmp/keys/server_key.pem"
252
+ assert config["protocols"]["allowed_protocols"] == ["https"]
253
+ assert config["security"]["ssl"]["enabled"] is True
254
+
255
+ def test_create_https_token(self):
256
+ """Test HTTPS token configuration creation."""
257
+ api_keys = {"admin": "admin-key"}
258
+ config = ConfigFactory.create_https_token(api_keys=api_keys)
259
+
260
+ assert config["ssl"]["enabled"] is True
261
+ assert config["security"]["enabled"] is True
262
+ assert config["security"]["auth"]["enabled"] is True
263
+ assert config["security"]["auth"]["api_keys"] == api_keys
264
+ assert config["protocols"]["allowed_protocols"] == ["https"]
265
+
266
+ def test_create_mtls_simple(self):
267
+ """Test mTLS simple configuration creation."""
268
+ config = ConfigFactory.create_mtls_simple()
269
+
270
+ assert config["ssl"]["enabled"] is True
271
+ assert config["ssl"]["verify_client"] is True
272
+ assert config["ssl"]["client_cert_required"] is True
273
+ assert config["protocols"]["allowed_protocols"] == ["mtls"]
274
+ assert config["security"]["ssl"]["verify_mode"] == "CERT_REQUIRED"
275
+
276
+ def test_create_mtls_with_roles(self):
277
+ """Test mTLS with roles configuration creation."""
278
+ roles = {"admin": ["read", "write"], "user": ["read"]}
279
+ config = ConfigFactory.create_mtls_with_roles(roles=roles)
280
+
281
+ assert config["ssl"]["enabled"] is True
282
+ assert config["protocols"]["allowed_protocols"] == ["mtls"]
283
+ assert config["security"]["auth"]["user_roles"] == roles
284
+ assert config["roles"]["enabled"] is True
285
+ assert config["security"]["permissions"]["enabled"] is True
286
+
287
+ def test_create_mtls_with_proxy(self):
288
+ """Test mTLS with proxy configuration creation."""
289
+ config = ConfigFactory.create_mtls_with_proxy(
290
+ proxy_url="https://proxy.example.com:8080",
291
+ server_id="test_server"
292
+ )
293
+
294
+ assert config["ssl"]["enabled"] is True
295
+ assert config["protocols"]["allowed_protocols"] == ["mtls"]
296
+ assert config["proxy_registration"]["enabled"] is True
297
+ assert config["proxy_registration"]["proxy_url"] == "https://proxy.example.com:8080"
298
+ assert config["proxy_registration"]["server_id"] == "test_server"
299
+
300
+ def test_create_full_featured(self):
301
+ """Test full-featured configuration creation."""
302
+ config = ConfigFactory.create_full_featured()
303
+
304
+ assert config["ssl"]["enabled"] is True
305
+ assert config["protocols"]["allowed_protocols"] == ["mtls"]
306
+ assert config["security"]["enabled"] is True
307
+ assert config["security"]["auth"]["enabled"] is True
308
+ assert config["proxy_registration"]["enabled"] is True
309
+ assert config["debug"]["enabled"] is True
310
+ assert config["roles"]["enabled"] is True
311
+ assert config["security"]["permissions"]["enabled"] is True
312
+
313
+
314
+ class TestConfigurationCombinations:
315
+ """Test all possible combinations of configuration parameters."""
316
+
317
+ def test_all_protocol_auth_combinations(self):
318
+ """Test all combinations of protocols and authentication methods."""
319
+ protocols = [Protocol.HTTP, Protocol.HTTPS, Protocol.MTLS]
320
+ auth_methods = [AuthMethod.NONE, AuthMethod.TOKEN, AuthMethod.BASIC]
321
+
322
+ for protocol in protocols:
323
+ for auth_method in auth_methods:
324
+ builder = ConfigBuilder()
325
+ config = (builder
326
+ .set_protocol(protocol)
327
+ .set_auth(auth_method)
328
+ .build())
329
+
330
+ # Verify protocol settings
331
+ if protocol == Protocol.HTTP:
332
+ assert config["ssl"]["enabled"] is False
333
+ assert config["protocols"]["allowed_protocols"] == ["http"]
334
+ elif protocol == Protocol.HTTPS:
335
+ assert config["ssl"]["enabled"] is True
336
+ assert config["protocols"]["allowed_protocols"] == ["https"]
337
+ elif protocol == Protocol.MTLS:
338
+ assert config["ssl"]["enabled"] is True
339
+ assert config["ssl"]["verify_client"] is True
340
+ assert config["protocols"]["allowed_protocols"] == ["mtls"]
341
+
342
+ # Verify auth settings
343
+ if auth_method == AuthMethod.NONE:
344
+ assert config["security"]["enabled"] is False
345
+ else:
346
+ assert config["security"]["enabled"] is True
347
+ assert config["security"]["auth"]["enabled"] is True
348
+
349
+ def test_proxy_registration_with_all_protocols(self):
350
+ """Test proxy registration with all protocols."""
351
+ protocols = [Protocol.HTTP, Protocol.HTTPS, Protocol.MTLS]
352
+
353
+ for protocol in protocols:
354
+ builder = ConfigBuilder()
355
+ config = (builder
356
+ .set_protocol(protocol)
357
+ .set_proxy_registration(enabled=True, proxy_url="https://proxy.test:8080")
358
+ .build())
359
+
360
+ assert config["proxy_registration"]["enabled"] is True
361
+ assert config["proxy_registration"]["proxy_url"] == "https://proxy.test:8080"
362
+ assert config["proxy_registration"]["server_url"] == "https://proxy.test:8080/register"
363
+
364
+ def test_roles_with_all_auth_methods(self):
365
+ """Test roles configuration with all authentication methods."""
366
+ auth_methods = [AuthMethod.TOKEN, AuthMethod.BASIC]
367
+ roles = {"admin": ["read", "write"], "user": ["read"]}
368
+
369
+ for auth_method in auth_methods:
370
+ builder = ConfigBuilder()
371
+ config = (builder
372
+ .set_auth(auth_method, roles=roles)
373
+ .build())
374
+
375
+ assert config["security"]["auth"]["user_roles"] == roles
376
+ assert config["roles"]["enabled"] is True
377
+ assert config["security"]["permissions"]["enabled"] is True
378
+
379
+ def test_debug_with_all_combinations(self):
380
+ """Test debug configuration with various combinations."""
381
+ builder = ConfigBuilder()
382
+ config = (builder
383
+ .set_protocol(Protocol.HTTPS)
384
+ .set_auth(AuthMethod.TOKEN)
385
+ .set_proxy_registration(enabled=True)
386
+ .set_debug(enabled=True)
387
+ .build())
388
+
389
+ assert config["debug"]["enabled"] is True
390
+ assert config["debug"]["log_level"] == "DEBUG"
391
+ assert config["logging"]["level"] == "DEBUG"
392
+ assert config["ssl"]["enabled"] is True
393
+ assert config["security"]["enabled"] is True
394
+ assert config["proxy_registration"]["enabled"] is True
395
+
396
+
397
+ def run_comprehensive_tests():
398
+ """Run comprehensive tests and generate report."""
399
+ print("🧪 Running Comprehensive Configuration Builder Tests")
400
+ print("=" * 60)
401
+
402
+ test_classes = [
403
+ TestConfigBuilder,
404
+ TestConfigFactory,
405
+ TestConfigurationCombinations
406
+ ]
407
+
408
+ total_tests = 0
409
+ passed_tests = 0
410
+ failed_tests = []
411
+
412
+ for test_class in test_classes:
413
+ print(f"\n📋 Testing {test_class.__name__}")
414
+ print("-" * 40)
415
+
416
+ test_instance = test_class()
417
+ test_methods = [method for method in dir(test_instance) if method.startswith('test_')]
418
+
419
+ for test_method in test_methods:
420
+ total_tests += 1
421
+ try:
422
+ getattr(test_instance, test_method)()
423
+ print(f"✅ {test_method}")
424
+ passed_tests += 1
425
+ except Exception as e:
426
+ print(f"❌ {test_method}: {e}")
427
+ failed_tests.append(f"{test_class.__name__}.{test_method}: {e}")
428
+
429
+ # Print summary
430
+ print(f"\n{'=' * 60}")
431
+ print("📊 TEST SUMMARY")
432
+ print(f"{'=' * 60}")
433
+ print(f"Total tests: {total_tests}")
434
+ print(f"Passed: {passed_tests}")
435
+ print(f"Failed: {len(failed_tests)}")
436
+ print(f"Success rate: {(passed_tests/total_tests)*100:.1f}%")
437
+
438
+ if failed_tests:
439
+ print(f"\n❌ Failed tests:")
440
+ for failure in failed_tests:
441
+ print(f" • {failure}")
442
+ else:
443
+ print(f"\n🎉 All tests passed!")
444
+
445
+ return len(failed_tests) == 0
446
+
447
+
448
+ if __name__ == "__main__":
449
+ success = run_comprehensive_tests()
450
+ exit(0 if success else 1)
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Update Configuration Files with Correct Certificate Paths
4
+ This script updates all configuration files to use the correct certificate paths.
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
9
+ import json
10
+ import os
11
+ from pathlib import Path
12
+ from typing import Dict, Any
13
+
14
+ from required_certificates import CONFIG_CERTIFICATE_MAPPINGS
15
+
16
+
17
+ class ConfigUpdater:
18
+ """Updates configuration files with correct certificate paths."""
19
+
20
+ def __init__(self):
21
+ """Initialize the config updater."""
22
+ self.working_dir = Path.cwd()
23
+ self.configs_dir = self.working_dir / "configs"
24
+
25
+ def print_step(self, step: str, description: str):
26
+ """Print a formatted step header."""
27
+ print(f"\n{'=' * 60}")
28
+ print(f"🔧 STEP {step}: {description}")
29
+ print(f"{'=' * 60}")
30
+
31
+ def print_success(self, message: str):
32
+ """Print a success message."""
33
+ print(f"✅ {message}")
34
+
35
+ def print_error(self, message: str):
36
+ """Print an error message."""
37
+ print(f"❌ {message}")
38
+
39
+ def print_info(self, message: str):
40
+ """Print an info message."""
41
+ print(f"ℹ️ {message}")
42
+
43
+ def update_config_file(self, config_file: str, certificate_mappings: Dict[str, str]) -> bool:
44
+ """Update a single configuration file with correct certificate paths."""
45
+ config_path = self.configs_dir / config_file
46
+
47
+ if not config_path.exists():
48
+ self.print_error(f"Configuration file not found: {config_file}")
49
+ return False
50
+
51
+ try:
52
+ # Load configuration
53
+ with open(config_path, 'r') as f:
54
+ config = json.load(f)
55
+
56
+ # Update certificate paths
57
+ updated = False
58
+ for path, new_value in certificate_mappings.items():
59
+ if self.update_nested_path(config, path, new_value):
60
+ updated = True
61
+
62
+ if updated:
63
+ # Save updated configuration
64
+ with open(config_path, 'w') as f:
65
+ json.dump(config, f, indent=2)
66
+ self.print_success(f"Updated {config_file}")
67
+ return True
68
+ else:
69
+ self.print_info(f"No updates needed for {config_file}")
70
+ return True
71
+
72
+ except Exception as e:
73
+ self.print_error(f"Failed to update {config_file}: {e}")
74
+ return False
75
+
76
+ def update_nested_path(self, config: Dict[str, Any], path: str, value: str) -> bool:
77
+ """Update a nested path in configuration dictionary."""
78
+ keys = path.split('.')
79
+ current = config
80
+
81
+ # Navigate to the parent of the target key
82
+ for key in keys[:-1]:
83
+ if key not in current:
84
+ return False
85
+ current = current[key]
86
+
87
+ # Update the target key
88
+ target_key = keys[-1]
89
+ if target_key in current and current[target_key] != value:
90
+ current[target_key] = value
91
+ return True
92
+
93
+ return False
94
+
95
+ def update_all_configs(self) -> bool:
96
+ """Update all configuration files with correct certificate paths."""
97
+ self.print_step("1", "Updating Configuration Files")
98
+
99
+ success_count = 0
100
+ total_count = len(CONFIG_CERTIFICATE_MAPPINGS)
101
+
102
+ for config_file, certificate_mappings in CONFIG_CERTIFICATE_MAPPINGS.items():
103
+ self.print_info(f"Updating {config_file}...")
104
+ if self.update_config_file(config_file, certificate_mappings):
105
+ success_count += 1
106
+
107
+ # Print summary
108
+ self.print_step("2", "Update Summary")
109
+ print(f"📊 Configuration Update Results:")
110
+ print(f" Total configurations: {total_count}")
111
+ print(f" Successfully updated: {success_count}")
112
+ print(f" Failed: {total_count - success_count}")
113
+ print(f" Success rate: {(success_count/total_count)*100:.1f}%")
114
+
115
+ return success_count == total_count
116
+
117
+
118
+ def main():
119
+ """Main entry point."""
120
+ updater = ConfigUpdater()
121
+
122
+ try:
123
+ success = updater.update_all_configs()
124
+ if success:
125
+ print(f"\n🎉 All configuration files updated successfully!")
126
+ else:
127
+ print(f"\n❌ Some configuration files failed to update")
128
+ return success
129
+ except Exception as e:
130
+ print(f"❌ Fatal error: {e}")
131
+ return False
132
+
133
+
134
+ if __name__ == "__main__":
135
+ success = main()
136
+ exit(0 if success else 1)