mcp-souschef 3.2.0__py3-none-any.whl → 3.5.2__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.
- {mcp_souschef-3.2.0.dist-info → mcp_souschef-3.5.2.dist-info}/METADATA +159 -30
- {mcp_souschef-3.2.0.dist-info → mcp_souschef-3.5.2.dist-info}/RECORD +19 -14
- {mcp_souschef-3.2.0.dist-info → mcp_souschef-3.5.2.dist-info}/WHEEL +1 -1
- souschef/assessment.py +81 -25
- souschef/cli.py +265 -6
- souschef/converters/playbook.py +413 -156
- souschef/converters/template.py +122 -5
- souschef/core/ai_schemas.py +81 -0
- souschef/core/http_client.py +394 -0
- souschef/core/logging.py +344 -0
- souschef/core/metrics.py +73 -6
- souschef/core/url_validation.py +230 -0
- souschef/server.py +130 -0
- souschef/ui/app.py +20 -6
- souschef/ui/pages/ai_settings.py +151 -30
- souschef/ui/pages/chef_server_settings.py +300 -0
- souschef/ui/pages/cookbook_analysis.py +66 -10
- {mcp_souschef-3.2.0.dist-info → mcp_souschef-3.5.2.dist-info}/entry_points.txt +0 -0
- {mcp_souschef-3.2.0.dist-info → mcp_souschef-3.5.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,33 +1,40 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-souschef
|
|
3
|
-
Version: 3.2
|
|
3
|
+
Version: 3.5.2
|
|
4
4
|
Summary: AI-powered MCP server for Chef to Ansible conversion
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: chef,ansible,migration,infrastructure,automation,mcp,ai,conversion
|
|
8
8
|
Author: SousChef Contributors
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.10,<4.0
|
|
10
10
|
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: Intended Audience :: System Administrators
|
|
13
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
20
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
22
|
Classifier: Topic :: System :: Systems Administration
|
|
20
23
|
Classifier: Topic :: Utilities
|
|
24
|
+
Provides-Extra: ai
|
|
25
|
+
Provides-Extra: all
|
|
21
26
|
Provides-Extra: ui
|
|
22
|
-
Requires-Dist: anthropic (>=0.75.0)
|
|
27
|
+
Requires-Dist: anthropic (>=0.75.0) ; extra == "ai" or extra == "all"
|
|
23
28
|
Requires-Dist: click (>=8.1.0)
|
|
24
29
|
Requires-Dist: mcp (>=1.25.0)
|
|
25
|
-
Requires-Dist: openai (>=1.0.0)
|
|
26
|
-
Requires-Dist: pandas (>=2.0.0) ; extra == "ui"
|
|
27
|
-
Requires-Dist: plotly (>=5.0.0)
|
|
30
|
+
Requires-Dist: openai (>=1.0.0) ; extra == "ai" or extra == "all"
|
|
31
|
+
Requires-Dist: pandas (>=2.0.0) ; extra == "ui" or extra == "all"
|
|
32
|
+
Requires-Dist: plotly (>=5.17.0,<7.0) ; extra == "ui" or extra == "all"
|
|
33
|
+
Requires-Dist: pydantic (>=2.0.0)
|
|
28
34
|
Requires-Dist: python-dotenv (>=1.2.1)
|
|
29
35
|
Requires-Dist: pyyaml (>=6.0.0)
|
|
30
|
-
Requires-Dist:
|
|
36
|
+
Requires-Dist: requests (>=2.31.0)
|
|
37
|
+
Requires-Dist: streamlit (>=1.28.0) ; extra == "ui" or extra == "all"
|
|
31
38
|
Project-URL: Documentation, https://kpeacocke.github.io/souschef/
|
|
32
39
|
Project-URL: Homepage, https://github.com/kpeacocke/souschef
|
|
33
40
|
Project-URL: Repository, https://github.com/kpeacocke/souschef
|
|
@@ -40,7 +47,7 @@ An AI-powered MCP (Model Context Protocol) server that provides comprehensive Ch
|
|
|
40
47
|
[](https://github.com/kpeacocke/souschef/releases)
|
|
41
48
|
[](https://www.python.org/downloads/)
|
|
42
49
|
[](https://opensource.org/licenses/MIT)
|
|
43
|
-
[](htmlcov/index.html)
|
|
44
51
|
[](https://github.com/astral-sh/ruff)
|
|
45
52
|
[](http://mypy-lang.org/)
|
|
46
53
|
[](https://sonarcloud.io/summary/new_code?id=kpeacocke_souschef)
|
|
@@ -49,17 +56,17 @@ An AI-powered MCP (Model Context Protocol) server that provides comprehensive Ch
|
|
|
49
56
|
|
|
50
57
|
## Overview - Chef to Ansible features
|
|
51
58
|
|
|
52
|
-
SousChef is a complete enterprise-grade migration platform with **
|
|
59
|
+
SousChef is a complete enterprise-grade migration platform with **35 primary MCP tools** organised across **11 major capability areas** to facilitate Chef-to-Ansible AWX/AAP migrations. From cookbook analysis to deployment pattern conversion, including Chef Habitat to containerised deployments, Chef Server integration, and CI/CD pipeline generation, SousChef provides everything needed for a successful infrastructure automation migration.
|
|
53
60
|
|
|
54
61
|
### About Tool Counts
|
|
55
62
|
|
|
56
|
-
**Why
|
|
63
|
+
**Why 35 tools in the documentation but more in the server?**
|
|
57
64
|
|
|
58
|
-
The MCP server provides **
|
|
65
|
+
The MCP server provides **38 total tools**. This documentation focuses on the **35 primary user-facing tools** that cover the main migration capabilities. The remaining 3 tools are low-level filesystem operations used internally by the main tools.
|
|
59
66
|
|
|
60
|
-
As a user, you'll primarily interact with the
|
|
67
|
+
As a user, you'll primarily interact with the documented tools. Your AI assistant may use the additional tools automatically when needed, but you don't need to know about them for successful migrations.
|
|
61
68
|
|
|
62
|
-
> **For developers:** See `souschef/server.py` for the complete list of all
|
|
69
|
+
> **For developers:** See `souschef/server.py` for the complete list of all 38 registered tools.
|
|
63
70
|
|
|
64
71
|
## Model Agnostic - Works with Any AI Model
|
|
65
72
|
|
|
@@ -72,7 +79,7 @@ As a user, you'll primarily interact with the 27 documented tools. Your AI assis
|
|
|
72
79
|
- **Local Models** (Ollama, llama.cpp, etc.)
|
|
73
80
|
- **Custom Enterprise Models**
|
|
74
81
|
|
|
75
|
-
**How it works:** You choose your AI model provider in your MCP client. SousChef provides the Chef/Ansible expertise through
|
|
82
|
+
**How it works:** You choose your AI model provider in your MCP client. SousChef provides the Chef/Ansible expertise through 35 specialized tools. The model calls these tools to help with your migration.
|
|
76
83
|
|
|
77
84
|
> See [config/CONFIGURATION.md](config/CONFIGURATION.md) for configuration examples with different model providers.
|
|
78
85
|
|
|
@@ -83,6 +90,28 @@ As a user, you'll primarily interact with the 27 documented tools. Your AI assis
|
|
|
83
90
|
- **[API Reference](docs/api-reference/)** - Detailed tool documentation
|
|
84
91
|
- **[Migration Guide](docs/migration-guide/)** - Step-by-step migration process
|
|
85
92
|
|
|
93
|
+
## What's New in v3.4.0-beta
|
|
94
|
+
|
|
95
|
+
**Chef Server Integration & AI-Enhanced Template Conversion** - New tools for dynamic inventory and intelligent template conversion:
|
|
96
|
+
|
|
97
|
+
- **Chef Server Connectivity**: Validate Chef Server connections and query nodes with `validate_chef_server_connection` and `get_chef_nodes`
|
|
98
|
+
- **AI-Enhanced Templates**: Convert ERB to Jinja2 with AI validation using `convert_template_with_ai` for complex Ruby logic
|
|
99
|
+
- **CLI Commands**: New commands `validate-chef-server`, `query-chef-nodes`, and `convert-template-ai` for command-line access
|
|
100
|
+
- **Streamlit UI**: Chef Server Settings page for managing server configuration and validation
|
|
101
|
+
|
|
102
|
+
## What's New in v3.3.0
|
|
103
|
+
|
|
104
|
+
**AI-Assisted Effort Estimation** - SousChef now displays realistic migration effort comparisons directly in the Streamlit UI:
|
|
105
|
+
|
|
106
|
+
- **Manual Migration Estimates**: Full effort without AI assistance
|
|
107
|
+
- **SousChef-Assisted Estimates**: 50% time reduction through automated boilerplate conversion
|
|
108
|
+
- **Time Savings Display**: Instant visual comparison showing hours saved and efficiency gains
|
|
109
|
+
- **Interactive Metrics**: Summary and per-cookbook effort comparisons with clear deltas
|
|
110
|
+
|
|
111
|
+
Example: A cookbook estimated at 40 hours of manual work shows SousChef-assisted time as 20 hours, saving 20 hours (50%) and reducing team needs from 2 developers to 1.
|
|
112
|
+
|
|
113
|
+
See the [Assessment Guide](docs/migration-guide/assessment.md#effort-estimation-model) for details on the effort estimation model.
|
|
114
|
+
|
|
86
115
|
## Installation
|
|
87
116
|
|
|
88
117
|
```bash
|
|
@@ -299,6 +328,54 @@ Output formats:
|
|
|
299
328
|
- **analyse_cookbook_dependencies** - Analyse dependencies and migration order
|
|
300
329
|
- **generate_migration_report** - Generate executive and technical migration reports
|
|
301
330
|
|
|
331
|
+
### 12. Chef Server Integration & Dynamic Inventory
|
|
332
|
+
|
|
333
|
+
Dynamic inventory generation and Chef Server connectivity for hybrid environments:
|
|
334
|
+
|
|
335
|
+
- **validate_chef_server_connection** - Test Chef Server REST API connectivity and authentication
|
|
336
|
+
- **get_chef_nodes** - Query Chef Server for nodes matching search criteria, extracting roles, environment, platform, and IP information
|
|
337
|
+
- **convert_template_with_ai** - Convert ERB templates to Jinja2 with AI-based validation for complex Ruby logic
|
|
338
|
+
|
|
339
|
+
#### Chef Server Features
|
|
340
|
+
|
|
341
|
+
- **Connection Validation**: Test Chef Server connectivity before migrations
|
|
342
|
+
- **Dynamic Node Queries**: Search Chef Server by role, environment, or custom attributes
|
|
343
|
+
- **Node Metadata Extraction**: Retrieve IP addresses, FQDNs, platforms, and roles for inventory
|
|
344
|
+
- **AI-Enhanced Conversion**: Intelligent ERB→Jinja2 conversion with validation for complex Ruby constructs
|
|
345
|
+
- **Fallback Handling**: Graceful degradation when Chef Server is unavailable
|
|
346
|
+
|
|
347
|
+
#### Usage Examples
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
# Validate Chef Server connection
|
|
351
|
+
souschef validate-chef-server --server-url https://chef.example.com --node-name admin
|
|
352
|
+
|
|
353
|
+
# Query Chef Server for nodes
|
|
354
|
+
souschef query-chef-nodes --search-query "role:web_server" --json
|
|
355
|
+
|
|
356
|
+
# Convert template with AI assistance
|
|
357
|
+
souschef convert-template-ai /path/to/template.erb --ai --output /path/to/output.j2
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
#### MCP Tool Usage
|
|
361
|
+
|
|
362
|
+
```python
|
|
363
|
+
# Validate Chef Server from AI assistant
|
|
364
|
+
validate_chef_server_connection(
|
|
365
|
+
server_url="https://chef.example.com",
|
|
366
|
+
node_name="admin"
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
# Query nodes for dynamic inventory
|
|
370
|
+
get_chef_nodes(search_query="role:web_server AND environment:production")
|
|
371
|
+
|
|
372
|
+
# Convert template with AI validation
|
|
373
|
+
convert_template_with_ai(
|
|
374
|
+
erb_path="/path/to/template.erb",
|
|
375
|
+
use_ai_enhancement=True
|
|
376
|
+
)
|
|
377
|
+
```
|
|
378
|
+
|
|
302
379
|
## Migration Workflow
|
|
303
380
|
|
|
304
381
|
### Phase 1: Discovery & Assessment
|
|
@@ -389,7 +466,12 @@ profile_parsing_operation recipe /path/to/recipe.rb --detailed
|
|
|
389
466
|
Interactive web-based interface for Chef-to-Ansible migration planning and visualization:
|
|
390
467
|
|
|
391
468
|
- **Cookbook Analysis Dashboard**: Interactive directory scanning with metadata parsing and complexity assessment
|
|
392
|
-
- **
|
|
469
|
+
- **AI-Assisted Effort Estimation** (v3.3.0+):
|
|
470
|
+
- **Manual Migration Estimate**: Full effort without AI assistance
|
|
471
|
+
- **SousChef-Assisted Estimate**: 50% time reduction through automated boilerplate conversion
|
|
472
|
+
- **Time Savings Display**: Clear comparison showing hours saved and efficiency percentage
|
|
473
|
+
- **Visual Metrics**: Side-by-side metric cards for instant visual comparison
|
|
474
|
+
- **Migration Planning Wizard**: Step-by-step migration planning with dual effort scenarios and risk analysis
|
|
393
475
|
- **Dependency Mapping**: Visual dependency graphs showing cookbook relationships and migration ordering
|
|
394
476
|
- **Validation Reports**: Conversion validation results with syntax checking and best practice compliance
|
|
395
477
|
- **Progress Tracking**: Real-time migration progress with completion metrics and bottleneck identification
|
|
@@ -420,6 +502,51 @@ docker run -p 9999:9999 souschef-ui
|
|
|
420
502
|
docker-compose up
|
|
421
503
|
```
|
|
422
504
|
|
|
505
|
+
**Run Published Image from GitHub Container Registry:**
|
|
506
|
+
|
|
507
|
+
SousChef images are automatically published to GitHub Container Registry (GHCR) on each release:
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
# Pull the latest released image
|
|
511
|
+
docker pull ghcr.io/mcp-souschef:latest
|
|
512
|
+
|
|
513
|
+
# Or pull a specific version
|
|
514
|
+
docker pull ghcr.io/mcp-souschef:3.2.0
|
|
515
|
+
|
|
516
|
+
# Run the image with your .env file
|
|
517
|
+
docker run -p 9999:9999 \
|
|
518
|
+
--env-file .env \
|
|
519
|
+
ghcr.io/mcp-souschef:latest
|
|
520
|
+
|
|
521
|
+
# Or with docker-compose
|
|
522
|
+
cat > docker-compose.override.yml << 'EOF'
|
|
523
|
+
version: '3.8'
|
|
524
|
+
services:
|
|
525
|
+
souschef-ui:
|
|
526
|
+
image: ghcr.io/mcp-souschef:latest
|
|
527
|
+
build: ~
|
|
528
|
+
EOF
|
|
529
|
+
docker-compose up
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Container Images:**
|
|
533
|
+
|
|
534
|
+
- **Registry**: GitHub Container Registry (GHCR)
|
|
535
|
+
- **Image Name**: `mcp-souschef`
|
|
536
|
+
- **Full URL**: `ghcr.io/mcp-souschef`
|
|
537
|
+
- **Available Tags**:
|
|
538
|
+
- `latest` - Most recent release
|
|
539
|
+
- `3.2.0` - Specific version (semver)
|
|
540
|
+
- `3.2` - Latest patch of a minor version
|
|
541
|
+
- `3` - Latest patch of a major version
|
|
542
|
+
|
|
543
|
+
**Why use GHCR?**
|
|
544
|
+
|
|
545
|
+
- Integrated with GitHub releases and CI/CD
|
|
546
|
+
- Faster pulls for users in GitHub ecosystem
|
|
547
|
+
- Security scanning and SBOM included
|
|
548
|
+
- Multi-platform support (amd64, arm64)
|
|
549
|
+
|
|
423
550
|
**Docker Environment Configuration:**
|
|
424
551
|
|
|
425
552
|
SousChef supports AI configuration via environment variables in Docker containers. Create a `.env` file in your project root:
|
|
@@ -443,6 +570,7 @@ SOUSCHEF_AI_BASE_URL=
|
|
|
443
570
|
SOUSCHEF_AI_PROJECT_ID=
|
|
444
571
|
SOUSCHEF_AI_TEMPERATURE=0.7
|
|
445
572
|
SOUSCHEF_AI_MAX_TOKENS=4000
|
|
573
|
+
SOUSCHEF_ALLOWED_HOSTNAMES=api.example.com,*.example.org
|
|
446
574
|
|
|
447
575
|
# Streamlit Configuration (optional)
|
|
448
576
|
STREAMLIT_SERVER_PORT=9999
|
|
@@ -465,6 +593,7 @@ STREAMLIT_SERVER_HEADLESS=true
|
|
|
465
593
|
- `SOUSCHEF_AI_PROJECT_ID` - Project ID for Watsonx (optional)
|
|
466
594
|
- `SOUSCHEF_AI_TEMPERATURE` - Model temperature 0.0-2.0 (optional, default: 0.7)
|
|
467
595
|
- `SOUSCHEF_AI_MAX_TOKENS` - Maximum tokens to generate (optional, default: 4000)
|
|
596
|
+
- `SOUSCHEF_ALLOWED_HOSTNAMES` - Comma-separated list of allowed hostnames for outbound API requests (optional)
|
|
468
597
|
|
|
469
598
|
**Docker Compose (recommended for development):**
|
|
470
599
|
|
|
@@ -506,7 +635,7 @@ The UI includes sophisticated dependency graph visualization powered by NetworkX
|
|
|
506
635
|
- **Interactive Exploration**: Zoom, pan, and hover over nodes to explore complex dependency relationships
|
|
507
636
|
- **Color Coding**: Visual distinction between cookbooks, dependencies, community cookbooks, and circular dependencies
|
|
508
637
|
- **Static Export**: Matplotlib-based static graphs for reports and documentation
|
|
509
|
-
- **Large Graph Support**:
|
|
638
|
+
- **Large Graph Support**: Optimised layouts for complex cookbook ecosystems
|
|
510
639
|
|
|
511
640
|
#### Real-Time Progress Tracking
|
|
512
641
|
|
|
@@ -699,7 +828,7 @@ Following enterprise-grade testing standards with comprehensive test coverage:
|
|
|
699
828
|
- **Specialized Tests**: Enhanced guards (test_enhanced_guards.py), error handling (test_error_paths.py, test_error_recovery.py), real-world fixtures (test_real_world_fixtures.py)
|
|
700
829
|
- **Performance Tests**: Benchmarking and optimization validation (test_performance.py)
|
|
701
830
|
- **Snapshot Tests**: Regression testing for output stability (test_snapshots.py)
|
|
702
|
-
- **
|
|
831
|
+
- **83% Coverage**: Comprehensive test coverage approaching the 90% target for production readiness
|
|
703
832
|
|
|
704
833
|
### Quality Assurance
|
|
705
834
|
|
|
@@ -1069,18 +1198,18 @@ poetry run pytest
|
|
|
1069
1198
|
poetry run pytest --cov=souschef --cov-report=term-missing --cov-report=html
|
|
1070
1199
|
|
|
1071
1200
|
# Run specific test suites
|
|
1072
|
-
poetry run pytest tests/test_server.py # Core unit tests
|
|
1073
|
-
poetry run pytest tests/test_cli.py # CLI tests
|
|
1074
|
-
poetry run pytest tests/test_mcp.py
|
|
1075
|
-
poetry run pytest tests/test_integration.py # Integration tests
|
|
1076
|
-
poetry run pytest tests/test_integration_accuracy.py # Accuracy validation
|
|
1077
|
-
poetry run pytest tests/test_enhanced_guards.py # Guard conversion tests
|
|
1078
|
-
poetry run pytest tests/test_error_paths.py # Error handling
|
|
1079
|
-
poetry run pytest tests/test_error_recovery.py # Error recovery
|
|
1080
|
-
poetry run pytest tests/test_real_world_fixtures.py # Real-world cookbooks
|
|
1081
|
-
poetry run pytest tests/test_property_based.py # Hypothesis fuzz tests
|
|
1082
|
-
poetry run pytest tests/test_performance.py # Performance benchmarks
|
|
1083
|
-
poetry run pytest tests/test_snapshots.py # Snapshot regression tests
|
|
1201
|
+
poetry run pytest tests/unit/test_server.py # Core unit tests
|
|
1202
|
+
poetry run pytest tests/unit/test_cli.py # CLI tests
|
|
1203
|
+
poetry run pytest tests/e2e/test_mcp.py # MCP protocol tests
|
|
1204
|
+
poetry run pytest tests/integration/test_integration.py # Integration tests
|
|
1205
|
+
poetry run pytest tests/integration/test_integration_accuracy.py # Accuracy validation
|
|
1206
|
+
poetry run pytest tests/unit/test_enhanced_guards.py # Guard conversion tests
|
|
1207
|
+
poetry run pytest tests/unit/test_error_paths.py # Error handling
|
|
1208
|
+
poetry run pytest tests/unit/test_error_recovery.py # Error recovery
|
|
1209
|
+
poetry run pytest tests/integration/test_real_world_fixtures.py # Real-world cookbooks
|
|
1210
|
+
poetry run pytest tests/unit/test_property_based.py # Hypothesis fuzz tests
|
|
1211
|
+
poetry run pytest tests/integration/test_performance.py # Performance benchmarks
|
|
1212
|
+
poetry run pytest tests/unit/test_snapshots.py # Snapshot regression tests
|
|
1084
1213
|
|
|
1085
1214
|
# Run with benchmarks
|
|
1086
1215
|
poetry run pytest --benchmark-only
|
|
@@ -1120,7 +1249,7 @@ The project includes comprehensive test coverage across multiple dimensions:
|
|
|
1120
1249
|
- **Snapshots** (`test_snapshots.py`): Regression testing for output stability
|
|
1121
1250
|
|
|
1122
1251
|
5. **Test Fixtures**
|
|
1123
|
-
|
|
1252
|
+
- Sample Chef cookbooks in `tests/integration/fixtures/`
|
|
1124
1253
|
- Multiple cookbook types: apache2, docker, mysql, nodejs, legacy Chef 12, Habitat plans
|
|
1125
1254
|
- Real-world metadata, recipes, attributes, and resources
|
|
1126
1255
|
- Used across integration and accuracy testing
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
souschef/__init__.py,sha256=EqHUtFUSPV2fOQO3lhmyhMPfX7cUso88I6rEjvG8PRA,1434
|
|
2
|
-
souschef/assessment.py,sha256=
|
|
2
|
+
souschef/assessment.py,sha256=g_fxMjek_n5LgLlkZz_yWIADS9A3Z3qhFGGOz7lqm6M,100982
|
|
3
3
|
souschef/ci/__init__.py,sha256=GHaqDk4auB2kI7_fQtF2FRg5nP-iX6wJchj_uTlXcYg,411
|
|
4
4
|
souschef/ci/common.py,sha256=vHX1wtDNaTPiPfwW9If3aBm1hRmnTto2r3MkZGwYPTM,4757
|
|
5
5
|
souschef/ci/github_actions.py,sha256=EVnnOPTLCeUmTfR-acpLp-c_dxapMfrrDWaK4SSBkdM,7818
|
|
6
6
|
souschef/ci/gitlab_ci.py,sha256=4FcK8edci3ixuiUtYb6EFaAfsqjz0OBmW-lyPLH3YzY,6708
|
|
7
7
|
souschef/ci/jenkins_pipeline.py,sha256=XEuZrVKVmOlQOKucgGcd3vhAFh5qT05ILNnjKjkqTPU,7362
|
|
8
|
-
souschef/cli.py,sha256=
|
|
8
|
+
souschef/cli.py,sha256=O26NaN3HR6qfWDfWETkwQNqaIeWZh2VWNKATVoZBn1w,47702
|
|
9
9
|
souschef/converters/__init__.py,sha256=kkPm758XiFDdUYvdVPAVjssFvf15LasJcob1EY1EMIs,681
|
|
10
10
|
souschef/converters/cookbook_specific.py,sha256=ZvE9-bZtyXuf2E3HW4E9_GWzAqtm7e4YHj9qm1Xu_XI,3767
|
|
11
11
|
souschef/converters/habitat.py,sha256=4eVGAcX0576zLXW9yqYvuaRxOK2g6BOIJo_ws-PonHU,22516
|
|
12
|
-
souschef/converters/playbook.py,sha256=
|
|
12
|
+
souschef/converters/playbook.py,sha256=F_6tSFyrlT55vLdi632g7Yd5rkNRPlq4pnb5HSMrs78,102773
|
|
13
13
|
souschef/converters/resource.py,sha256=NYMcp1-obg_ad_XPuYDuUH_0j65agRbAeWzXPfbSi5c,13570
|
|
14
|
-
souschef/converters/template.py,sha256=
|
|
14
|
+
souschef/converters/template.py,sha256=sXMLm2egA2dSOY-SLoKjXOYH1dHK_ozj67YC89sg8dc,9268
|
|
15
15
|
souschef/core/__init__.py,sha256=PXiZSEfXw77te3SvMRKy0_g0CwQqworbgFLca89u7wA,1969
|
|
16
|
+
souschef/core/ai_schemas.py,sha256=TJCLsZ_3l8ub2zcVuSE0h6usMqxnrce8o3n2fxAKjvM,2860
|
|
16
17
|
souschef/core/constants.py,sha256=AyIpc9cJjQEDc1yOcoKc_2-cJB4PekSpPKEK2S9jDl8,5122
|
|
17
18
|
souschef/core/errors.py,sha256=zj_LHDRxUvHmcs-nZjOWu4B_MhY5WVq2okyZOxyycCI,8605
|
|
18
|
-
souschef/core/
|
|
19
|
+
souschef/core/http_client.py,sha256=f7laiNsIAX95-fVyAfnQXUdOL-Cv7ZWxi5xLnmTAkF4,12873
|
|
20
|
+
souschef/core/logging.py,sha256=3X6u6JUI5reIa7p1I4T22O69ME2ALrOxC8xacA6MKO0,9974
|
|
21
|
+
souschef/core/metrics.py,sha256=NuZNKi2o6UcrsJ52s8QQAoDeUiEi0HClZHNfPXsVRo4,12797
|
|
19
22
|
souschef/core/path_utils.py,sha256=eU5lNujUX45MbMahstm4C0gJxKN14QIKaxmgD6O5l9U,8993
|
|
20
23
|
souschef/core/ruby_utils.py,sha256=vUeFZBdjbFFFJlwo4fIboR23rXmbcYL2Tztt4RYhps0,1043
|
|
24
|
+
souschef/core/url_validation.py,sha256=AeUKNVN_AWBxkp5b5QskRgQ-4IB--A-D60ltRbN_chI,6169
|
|
21
25
|
souschef/core/validation.py,sha256=DXfkm1p5prSAJ-Oruk5JekNiDFI49Dql1bGEzKymYXs,19158
|
|
22
26
|
souschef/deployment.py,sha256=UKxq9G06b7de_5ioA7RdxdjwQaW2mJKf6WlNl0Sq5wk,62193
|
|
23
27
|
souschef/filesystem/__init__.py,sha256=2H7Pdeedz0MfmgpRlmii_vx61qr0jtxFndT0APPm6Qs,142
|
|
@@ -33,15 +37,16 @@ souschef/parsers/recipe.py,sha256=PNGQKVv0wwqj_q8WYT2NjsSavLA9WXdo2C9bp6pY9qc,71
|
|
|
33
37
|
souschef/parsers/resource.py,sha256=WcKsUjP3yZx2-2nsTUTLPxIxtfwEihHVNkv3OC6bBHs,5359
|
|
34
38
|
souschef/parsers/template.py,sha256=v51BMUHmr9FYwE7zDNFA01dsClWHLrc_YD3rCM-2lqc,10543
|
|
35
39
|
souschef/profiling.py,sha256=a6Pn57CZR3UPR1YIY8gfbuTPRuPkFrfIFBmctOcaZgY,17315
|
|
36
|
-
souschef/server.py,sha256=
|
|
40
|
+
souschef/server.py,sha256=Mzf8hnoGd83C46fO99mCw_4dHS7KttXfOmlVn7MJQ9c,125886
|
|
37
41
|
souschef/ui/__init__.py,sha256=U3W6X4ww7CxQVuetcocObWn5iY6lUFiNX7WoDBJeD34,195
|
|
38
|
-
souschef/ui/app.py,sha256=
|
|
42
|
+
souschef/ui/app.py,sha256=ru1KDYqnEDQvq46HHLNu1JGwzIScr7Lm11BeqnXpvQs,102343
|
|
39
43
|
souschef/ui/health_check.py,sha256=mEzec8L6XPRekOBAXngqQz5dnzal-a4p3D70mkPriiA,903
|
|
40
|
-
souschef/ui/pages/ai_settings.py,sha256=
|
|
41
|
-
souschef/ui/pages/
|
|
44
|
+
souschef/ui/pages/ai_settings.py,sha256=AevsSuiRcfYuQqtYcu1ijp8x3G3PYAUBXzxLmSSVp2c,22105
|
|
45
|
+
souschef/ui/pages/chef_server_settings.py,sha256=_ch7qvZ02luwNRFqWN6ATMbVUuenYlrbCpRGEFjr-40,8585
|
|
46
|
+
souschef/ui/pages/cookbook_analysis.py,sha256=ilAQTzFQyJsH6Mk65jjQbk5LKIsBkj9XibF4q648tpg,148623
|
|
42
47
|
souschef/ui/pages/validation_reports.py,sha256=R3xHTJb_y2b0tI8N0qPF1oS4f9ZVb539_82dj5nmmxA,7593
|
|
43
|
-
mcp_souschef-3.2.
|
|
44
|
-
mcp_souschef-3.2.
|
|
45
|
-
mcp_souschef-3.2.
|
|
46
|
-
mcp_souschef-3.2.
|
|
47
|
-
mcp_souschef-3.2.
|
|
48
|
+
mcp_souschef-3.5.2.dist-info/METADATA,sha256=ih95vf1qxSdw0VKL_wkka3Sx3aj8SoxB1SgGbhVPBAM,47268
|
|
49
|
+
mcp_souschef-3.5.2.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
|
|
50
|
+
mcp_souschef-3.5.2.dist-info/entry_points.txt,sha256=NVSk61tLG4W0xEkWGOMXAVCIUyodyZCY_j3Z_0m6rkQ,80
|
|
51
|
+
mcp_souschef-3.5.2.dist-info/licenses/LICENSE,sha256=t31dYSuvYYNw6trj-coWSsLK-Tg_Iyl8ObcolQcrUKM,1078
|
|
52
|
+
mcp_souschef-3.5.2.dist-info/RECORD,,
|
souschef/assessment.py
CHANGED
|
@@ -25,6 +25,7 @@ from souschef.core.metrics import (
|
|
|
25
25
|
estimate_effort_for_complexity,
|
|
26
26
|
)
|
|
27
27
|
from souschef.core.path_utils import _validated_candidate, safe_glob
|
|
28
|
+
from souschef.core.url_validation import validate_user_provided_url
|
|
28
29
|
from souschef.core.validation import (
|
|
29
30
|
ValidationEngine,
|
|
30
31
|
ValidationLevel,
|
|
@@ -34,9 +35,9 @@ from souschef.core.validation import (
|
|
|
34
35
|
|
|
35
36
|
# Optional AI provider imports
|
|
36
37
|
try:
|
|
37
|
-
import requests
|
|
38
|
+
import requests
|
|
38
39
|
except ImportError:
|
|
39
|
-
requests = None
|
|
40
|
+
requests = None # type: ignore[assignment]
|
|
40
41
|
|
|
41
42
|
try:
|
|
42
43
|
from ibm_watsonx_ai import APIClient # type: ignore[import-not-found]
|
|
@@ -1200,17 +1201,28 @@ def _assess_single_cookbook(cookbook_path: Path) -> dict:
|
|
|
1200
1201
|
|
|
1201
1202
|
|
|
1202
1203
|
def _format_overall_metrics(metrics: dict) -> str:
|
|
1203
|
-
"""Format overall migration metrics."""
|
|
1204
|
+
"""Format overall migration metrics with manual and SousChef-assisted estimates."""
|
|
1205
|
+
effort_metrics = EffortMetrics(metrics["estimated_effort_days"])
|
|
1206
|
+
|
|
1204
1207
|
return f"""• Total Cookbooks: {metrics["total_cookbooks"]}
|
|
1205
1208
|
• Total Recipes: {metrics["total_recipes"]}
|
|
1206
1209
|
• Total Resources: {metrics["total_resources"]}
|
|
1207
1210
|
• Average Complexity: {metrics.get("avg_complexity", 0):.1f}/100
|
|
1208
|
-
|
|
1209
|
-
|
|
1211
|
+
|
|
1212
|
+
## Manual Migration Effort (Without SousChef):
|
|
1213
|
+
• Estimated Effort: {metrics["estimated_effort_days"]:.1f} person-days ({effort_metrics.estimated_hours:.0f} hours)
|
|
1214
|
+
• Estimated Duration: {effort_metrics.estimated_weeks_range}
|
|
1215
|
+
• Team Required: {max(2, int(metrics["estimated_effort_days"] / 15))} developers
|
|
1216
|
+
|
|
1217
|
+
## AI-Assisted Migration (With SousChef):
|
|
1218
|
+
• Estimated Effort: {effort_metrics.estimated_days_with_souschef:.1f} person-days ({effort_metrics.estimated_hours_with_souschef:.0f} hours)
|
|
1219
|
+
• Estimated Duration: {effort_metrics.estimated_weeks_range_with_souschef}
|
|
1220
|
+
• Team Required: {max(1, int(effort_metrics.estimated_days_with_souschef / 15))} developers
|
|
1221
|
+
• **Time Saved: {effort_metrics.time_saved:.1f} days ({effort_metrics.efficiency_gain_percent}% faster)**"""
|
|
1210
1222
|
|
|
1211
1223
|
|
|
1212
1224
|
def _format_cookbook_assessments(assessments: list) -> str:
|
|
1213
|
-
"""Format individual cookbook assessments."""
|
|
1225
|
+
"""Format individual cookbook assessments with manual and AI-assisted estimates."""
|
|
1214
1226
|
if not assessments:
|
|
1215
1227
|
return "No cookbooks assessed."
|
|
1216
1228
|
|
|
@@ -1226,13 +1238,14 @@ def _format_cookbook_assessments(assessments: list) -> str:
|
|
|
1226
1238
|
formatted = []
|
|
1227
1239
|
for assessment in assessments:
|
|
1228
1240
|
priority_icon = _get_priority_icon(assessment["migration_priority"])
|
|
1241
|
+
effort_metrics = EffortMetrics(assessment["estimated_effort_days"])
|
|
1242
|
+
|
|
1229
1243
|
formatted.append(f"""### {assessment["cookbook_name"]} {priority_icon}
|
|
1230
1244
|
• Complexity Score: {assessment["complexity_score"]:.1f}/100
|
|
1231
|
-
•
|
|
1232
|
-
•
|
|
1233
|
-
•
|
|
1234
|
-
•
|
|
1235
|
-
• Challenges: {len(assessment["challenges"])}""")
|
|
1245
|
+
• Recipes: {assessment["metrics"]["recipe_count"]} | Resources: {assessment["metrics"]["resource_count"]} | Custom Resources: {assessment["metrics"]["custom_resources"]}
|
|
1246
|
+
• Manual Effort: {assessment["estimated_effort_days"]:.1f} days ({effort_metrics.estimated_weeks_range})
|
|
1247
|
+
• With SousChef: {effort_metrics.estimated_days_with_souschef:.1f} days ({effort_metrics.estimated_weeks_range_with_souschef}) - Save {effort_metrics.time_saved:.1f} days
|
|
1248
|
+
• Migration Challenges: {len(assessment["challenges"])}""")
|
|
1236
1249
|
|
|
1237
1250
|
return "\n\n".join(formatted)
|
|
1238
1251
|
|
|
@@ -1445,26 +1458,56 @@ def _assess_migration_risks(assessments: list, target_platform: str) -> str:
|
|
|
1445
1458
|
|
|
1446
1459
|
|
|
1447
1460
|
def _estimate_resource_requirements(metrics: dict, target_platform: str) -> str:
|
|
1448
|
-
"""Estimate resource requirements for migration."""
|
|
1461
|
+
"""Estimate resource requirements for migration with and without SousChef."""
|
|
1449
1462
|
total_effort = metrics["estimated_effort_days"]
|
|
1463
|
+
effort_metrics = EffortMetrics(total_effort)
|
|
1450
1464
|
|
|
1451
|
-
#
|
|
1465
|
+
# Manual migration requirements
|
|
1452
1466
|
if total_effort < 20:
|
|
1453
|
-
|
|
1454
|
-
|
|
1467
|
+
manual_team = "1 developer + 1 reviewer"
|
|
1468
|
+
manual_timeline = "4-6 weeks"
|
|
1455
1469
|
elif total_effort < 50:
|
|
1456
|
-
|
|
1457
|
-
|
|
1470
|
+
manual_team = "2 developers + 1 senior reviewer"
|
|
1471
|
+
manual_timeline = "6-10 weeks"
|
|
1472
|
+
else:
|
|
1473
|
+
manual_team = "3-4 developers + 1 tech lead + 1 architect"
|
|
1474
|
+
manual_timeline = "10-16 weeks"
|
|
1475
|
+
|
|
1476
|
+
# SousChef-assisted requirements
|
|
1477
|
+
souschef_effort = effort_metrics.estimated_days_with_souschef
|
|
1478
|
+
if souschef_effort < 20:
|
|
1479
|
+
souschef_team = "1 developer (with SousChef AI assistance)"
|
|
1480
|
+
souschef_timeline = "2-3 weeks"
|
|
1481
|
+
elif souschef_effort < 50:
|
|
1482
|
+
souschef_team = "1-2 developers + 1 reviewer (with SousChef)"
|
|
1483
|
+
souschef_timeline = "3-5 weeks"
|
|
1458
1484
|
else:
|
|
1459
|
-
|
|
1460
|
-
|
|
1485
|
+
souschef_team = "2-3 developers + 1 tech lead (with SousChef)"
|
|
1486
|
+
souschef_timeline = "5-8 weeks"
|
|
1461
1487
|
|
|
1462
|
-
return f"""
|
|
1463
|
-
• **
|
|
1464
|
-
• **
|
|
1488
|
+
return f"""## Manual Migration (Without AI Assistance):
|
|
1489
|
+
• **Team Size:** {manual_team}
|
|
1490
|
+
• **Estimated Timeline:** {manual_timeline}
|
|
1491
|
+
• **Total Effort:** {total_effort:.1f} person-days ({effort_metrics.estimated_hours:.0f} hours)
|
|
1492
|
+
• **Infrastructure:** {target_platform.replace("_", "/").upper()} environment
|
|
1493
|
+
• **Testing:** Dedicated test environment required
|
|
1494
|
+
• **Training:** 3-5 days Ansible/AWX training for team
|
|
1495
|
+
|
|
1496
|
+
## AI-Assisted Migration (With SousChef):
|
|
1497
|
+
• **Team Size:** {souschef_team}
|
|
1498
|
+
• **Estimated Timeline:** {souschef_timeline}
|
|
1499
|
+
• **Total Effort:** {souschef_effort:.1f} person-days ({effort_metrics.estimated_hours_with_souschef:.0f} hours)
|
|
1500
|
+
• **Time Savings:** {effort_metrics.time_saved:.1f} days ({effort_metrics.efficiency_gain_percent}% reduction)
|
|
1465
1501
|
• **Infrastructure:** {target_platform.replace("_", "/").upper()} environment
|
|
1466
|
-
• **Testing:**
|
|
1467
|
-
• **Training:** 2
|
|
1502
|
+
• **Testing:** Automated validation + human review
|
|
1503
|
+
• **Training:** 1-2 days SousChef usage + Ansible basics
|
|
1504
|
+
|
|
1505
|
+
**SousChef Benefits:**
|
|
1506
|
+
• Automated boilerplate conversion (60-70% of work)
|
|
1507
|
+
• Built-in best practices validation
|
|
1508
|
+
• Faster iteration cycles
|
|
1509
|
+
• Consistent output quality
|
|
1510
|
+
• Reduced human error"""
|
|
1468
1511
|
|
|
1469
1512
|
|
|
1470
1513
|
def _analyse_cookbook_dependencies_detailed(cookbook_path: Path | str) -> dict:
|
|
@@ -2554,8 +2597,21 @@ def _call_ai_api(
|
|
|
2554
2597
|
elif ai_provider == "openai":
|
|
2555
2598
|
return _call_openai_api(prompt, api_key, model, temperature, max_tokens)
|
|
2556
2599
|
elif ai_provider == "watson":
|
|
2600
|
+
validated_url = None
|
|
2601
|
+
if base_url:
|
|
2602
|
+
try:
|
|
2603
|
+
validated_url = validate_user_provided_url(base_url)
|
|
2604
|
+
except ValueError:
|
|
2605
|
+
return None
|
|
2606
|
+
|
|
2557
2607
|
return _call_watson_api(
|
|
2558
|
-
prompt,
|
|
2608
|
+
prompt,
|
|
2609
|
+
api_key,
|
|
2610
|
+
model,
|
|
2611
|
+
temperature,
|
|
2612
|
+
max_tokens,
|
|
2613
|
+
project_id,
|
|
2614
|
+
validated_url,
|
|
2559
2615
|
)
|
|
2560
2616
|
else:
|
|
2561
2617
|
return None
|