diagram-to-iac 0.8.0__py3-none-any.whl → 0.10.0__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.
- diagram_to_iac/r2d.py +345 -13
- diagram_to_iac-0.10.0.dist-info/METADATA +256 -0
- {diagram_to_iac-0.8.0.dist-info → diagram_to_iac-0.10.0.dist-info}/RECORD +6 -6
- {diagram_to_iac-0.8.0.dist-info → diagram_to_iac-0.10.0.dist-info}/entry_points.txt +2 -0
- diagram_to_iac-0.8.0.dist-info/METADATA +0 -99
- {diagram_to_iac-0.8.0.dist-info → diagram_to_iac-0.10.0.dist-info}/WHEEL +0 -0
- {diagram_to_iac-0.8.0.dist-info → diagram_to_iac-0.10.0.dist-info}/top_level.txt +0 -0
diagram_to_iac/r2d.py
CHANGED
@@ -1,13 +1,345 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
R2D (Repo-to-Deployment) CLI - DevOps-in-a-Box Entry Point
|
4
|
+
|
5
|
+
This is the main CLI for the R2D workflow, which orchestrates the complete
|
6
|
+
Repo-to-Deployment process using the SupervisorAgent.
|
7
|
+
|
8
|
+
Usage:
|
9
|
+
diagram-to-iac <repository_url>
|
10
|
+
r2d-agent <repository_url>
|
11
|
+
|
12
|
+
The CLI will:
|
13
|
+
1. Validate the repository URL
|
14
|
+
2. Initialize the SupervisorAgent
|
15
|
+
3. Execute the complete R2D workflow
|
16
|
+
4. Handle errors gracefully with GitHub Issues
|
17
|
+
5. Generate observability artifacts
|
18
|
+
|
19
|
+
Mission: "One container, many minds—zero manual toil."
|
20
|
+
"""
|
21
|
+
|
22
|
+
import sys
|
23
|
+
import argparse
|
24
|
+
import logging
|
25
|
+
from pathlib import Path
|
26
|
+
from datetime import datetime
|
27
|
+
import os
|
28
|
+
|
29
|
+
def setup_logging(verbose: bool = False) -> None:
|
30
|
+
"""Configure logging for the R2D CLI."""
|
31
|
+
level = logging.DEBUG if verbose else logging.INFO
|
32
|
+
logging.basicConfig(
|
33
|
+
level=level,
|
34
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
35
|
+
datefmt='%Y-%m-%d %H:%M:%S'
|
36
|
+
)
|
37
|
+
|
38
|
+
def print_banner() -> None:
|
39
|
+
"""Print the DevOps-in-a-Box banner."""
|
40
|
+
banner = """
|
41
|
+
╔══════════════════════════════════════════════════════════════════════════════╗
|
42
|
+
║ 🤖 DevOps-in-a-Box: R2D CLI ║
|
43
|
+
║ "One container, many minds—zero manual toil." ║
|
44
|
+
║ ║
|
45
|
+
║ Mission: Self-healing, Terraform-first DevOps automation ║
|
46
|
+
║ Workflow: Clone → Classify → Validate → Deploy → Auto-fix → Summarize ║
|
47
|
+
╚══════════════════════════════════════════════════════════════════════════════╝
|
48
|
+
"""
|
49
|
+
print(banner)
|
50
|
+
|
51
|
+
def validate_repository_url(repo_url: str) -> bool:
|
52
|
+
"""Validate that the repository URL is properly formatted."""
|
53
|
+
if not repo_url:
|
54
|
+
return False
|
55
|
+
|
56
|
+
# Basic validation for common Git URL formats
|
57
|
+
valid_patterns = [
|
58
|
+
'https://github.com/',
|
59
|
+
'https://gitlab.com/',
|
60
|
+
'git@github.com:',
|
61
|
+
'git@gitlab.com:',
|
62
|
+
'https://bitbucket.org/',
|
63
|
+
]
|
64
|
+
|
65
|
+
return any(repo_url.startswith(pattern) for pattern in valid_patterns)
|
66
|
+
|
67
|
+
def validate_environment_variables() -> tuple[bool, list[str]]:
|
68
|
+
"""
|
69
|
+
Validate required environment variables for R2D workflow.
|
70
|
+
|
71
|
+
Returns:
|
72
|
+
tuple: (is_valid, list of missing/invalid variables)
|
73
|
+
"""
|
74
|
+
errors = []
|
75
|
+
|
76
|
+
# Check for required GitHub token
|
77
|
+
github_token = os.getenv('GITHUB_TOKEN')
|
78
|
+
if not github_token:
|
79
|
+
errors.append("GITHUB_TOKEN is required for repository operations and issue creation")
|
80
|
+
|
81
|
+
# Check for at least one AI API key
|
82
|
+
ai_keys = {
|
83
|
+
'OPENAI_API_KEY': os.getenv('OPENAI_API_KEY'),
|
84
|
+
'ANTHROPIC_API_KEY': os.getenv('ANTHROPIC_API_KEY'),
|
85
|
+
'GOOGLE_API_KEY': os.getenv('GOOGLE_API_KEY'),
|
86
|
+
}
|
87
|
+
|
88
|
+
available_keys = [key for key, value in ai_keys.items() if value]
|
89
|
+
|
90
|
+
if not available_keys:
|
91
|
+
errors.append(
|
92
|
+
"At least one AI API key is required (OPENAI_API_KEY, ANTHROPIC_API_KEY, or GOOGLE_API_KEY)\n"
|
93
|
+
" The SupervisorAgent and other agents require AI capabilities for decision-making"
|
94
|
+
)
|
95
|
+
|
96
|
+
return len(errors) == 0, errors
|
97
|
+
|
98
|
+
def print_environment_status() -> None:
|
99
|
+
"""Print the status of environment variables."""
|
100
|
+
print("🔍 Environment Validation")
|
101
|
+
print("═══════════════════════")
|
102
|
+
|
103
|
+
# GitHub token
|
104
|
+
github_token = os.getenv('GITHUB_TOKEN')
|
105
|
+
if github_token:
|
106
|
+
print("✅ GITHUB_TOKEN: configured")
|
107
|
+
else:
|
108
|
+
print("❌ GITHUB_TOKEN: missing")
|
109
|
+
|
110
|
+
# AI API keys
|
111
|
+
ai_keys = {
|
112
|
+
'OPENAI_API_KEY': os.getenv('OPENAI_API_KEY'),
|
113
|
+
'ANTHROPIC_API_KEY': os.getenv('ANTHROPIC_API_KEY'),
|
114
|
+
'GOOGLE_API_KEY': os.getenv('GOOGLE_API_KEY'),
|
115
|
+
}
|
116
|
+
|
117
|
+
available_ai_keys = []
|
118
|
+
for key, value in ai_keys.items():
|
119
|
+
if value:
|
120
|
+
print(f"✅ {key}: configured")
|
121
|
+
available_ai_keys.append(key)
|
122
|
+
else:
|
123
|
+
print(f"⚪ {key}: not configured")
|
124
|
+
|
125
|
+
if available_ai_keys:
|
126
|
+
print(f"✅ AI capabilities: enabled via {', '.join(available_ai_keys)}")
|
127
|
+
else:
|
128
|
+
print("❌ AI capabilities: no API keys configured")
|
129
|
+
|
130
|
+
# Optional tokens
|
131
|
+
tf_token = os.getenv('TFE_TOKEN')
|
132
|
+
if tf_token:
|
133
|
+
print("✅ TFE_TOKEN: configured (Terraform Cloud operations enabled)")
|
134
|
+
else:
|
135
|
+
print("⚪ TFE_TOKEN: not configured (Terraform Cloud operations disabled)")
|
136
|
+
|
137
|
+
print("")
|
138
|
+
|
139
|
+
def create_argument_parser() -> argparse.ArgumentParser:
|
140
|
+
"""Create and configure the argument parser for R2D CLI."""
|
141
|
+
parser = argparse.ArgumentParser(
|
142
|
+
prog='diagram-to-iac',
|
143
|
+
description='DevOps-in-a-Box R2D CLI - Automated Repo-to-Deployment',
|
144
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
145
|
+
epilog="""
|
146
|
+
Examples:
|
147
|
+
%(prog)s https://github.com/user/repo
|
148
|
+
%(prog)s https://github.com/user/infra-repo --dry-run
|
149
|
+
%(prog)s git@github.com:user/terraform-config.git --branch-name production
|
150
|
+
|
151
|
+
Environment Variables:
|
152
|
+
GITHUB_TOKEN - GitHub personal access token (required)
|
153
|
+
TFE_TOKEN - Terraform Cloud API token (recommended)
|
154
|
+
|
155
|
+
AI API Keys (at least one required):
|
156
|
+
OPENAI_API_KEY - OpenAI API key (for GPT models)
|
157
|
+
ANTHROPIC_API_KEY - Anthropic API key (for Claude models)
|
158
|
+
GOOGLE_API_KEY - Google API key (for Gemini models)
|
159
|
+
|
160
|
+
Mission: "One container, many minds—zero manual toil."
|
161
|
+
"""
|
162
|
+
)
|
163
|
+
|
164
|
+
# Positional argument for repository URL
|
165
|
+
parser.add_argument(
|
166
|
+
'repository_url',
|
167
|
+
help='Repository URL to process (GitHub, GitLab, Bitbucket supported)'
|
168
|
+
)
|
169
|
+
|
170
|
+
# Optional arguments
|
171
|
+
parser.add_argument(
|
172
|
+
'--dry-run',
|
173
|
+
action='store_true',
|
174
|
+
help='Run in dry-run mode - simulate actions without making changes'
|
175
|
+
)
|
176
|
+
parser.add_argument(
|
177
|
+
'--branch-name',
|
178
|
+
type=str,
|
179
|
+
help='Custom branch name for operations (auto-generated if not provided)'
|
180
|
+
)
|
181
|
+
parser.add_argument(
|
182
|
+
'--thread-id',
|
183
|
+
type=str,
|
184
|
+
help='Thread ID for conversation tracking and resumption'
|
185
|
+
)
|
186
|
+
parser.add_argument(
|
187
|
+
'--verbose',
|
188
|
+
action='store_true',
|
189
|
+
help='Enable verbose logging'
|
190
|
+
)
|
191
|
+
parser.add_argument(
|
192
|
+
'--no-interactive',
|
193
|
+
action='store_true',
|
194
|
+
help='Skip interactive prompts'
|
195
|
+
)
|
196
|
+
parser.add_argument(
|
197
|
+
'--config-path',
|
198
|
+
type=str,
|
199
|
+
help='Path to custom configuration file'
|
200
|
+
)
|
201
|
+
|
202
|
+
return parser
|
203
|
+
|
204
|
+
def main() -> int:
|
205
|
+
"""Main entry point for the R2D CLI."""
|
206
|
+
try:
|
207
|
+
# Parse arguments
|
208
|
+
parser = create_argument_parser()
|
209
|
+
args = parser.parse_args()
|
210
|
+
|
211
|
+
# Set up logging
|
212
|
+
setup_logging(args.verbose)
|
213
|
+
logger = logging.getLogger(__name__)
|
214
|
+
|
215
|
+
# Print banner
|
216
|
+
print_banner()
|
217
|
+
|
218
|
+
# Validate environment variables
|
219
|
+
print_environment_status()
|
220
|
+
env_valid, env_errors = validate_environment_variables()
|
221
|
+
|
222
|
+
if not env_valid:
|
223
|
+
print("❌ Environment validation failed:")
|
224
|
+
for error in env_errors:
|
225
|
+
print(f" • {error}")
|
226
|
+
print("")
|
227
|
+
print("ℹ️ Please set the required environment variables and try again")
|
228
|
+
print("💡 Tip: You can test API connectivity with: python -c 'from diagram_to_iac.tools.api_utils import test_all_apis; test_all_apis()'")
|
229
|
+
return 1
|
230
|
+
|
231
|
+
# Validate repository URL
|
232
|
+
if not validate_repository_url(args.repository_url):
|
233
|
+
print("❌ Error: Invalid repository URL format")
|
234
|
+
print("ℹ️ Supported formats: https://github.com/user/repo, git@github.com:user/repo.git")
|
235
|
+
return 1
|
236
|
+
|
237
|
+
# Validate environment variables
|
238
|
+
is_valid, validation_errors = validate_environment_variables()
|
239
|
+
if not is_valid:
|
240
|
+
print("❌ Error: Invalid environment configuration")
|
241
|
+
for error in validation_errors:
|
242
|
+
print(f"⚠️ {error}")
|
243
|
+
print("ℹ️ Please set the required environment variables and try again")
|
244
|
+
return 1
|
245
|
+
|
246
|
+
print(f"🎯 Repository: {args.repository_url}")
|
247
|
+
print(f"🧪 Dry run: {args.dry_run}")
|
248
|
+
print(f"🌿 Branch: {args.branch_name or 'auto-generated'}")
|
249
|
+
print("")
|
250
|
+
|
251
|
+
# Import SupervisorAgent (delayed import for faster CLI startup)
|
252
|
+
try:
|
253
|
+
from diagram_to_iac.agents.supervisor_langgraph import (
|
254
|
+
SupervisorAgent,
|
255
|
+
SupervisorAgentInput,
|
256
|
+
)
|
257
|
+
from diagram_to_iac.services import (
|
258
|
+
get_log_path,
|
259
|
+
generate_step_summary,
|
260
|
+
reset_log_bus
|
261
|
+
)
|
262
|
+
except ImportError as e:
|
263
|
+
logger.error(f"Failed to import required modules: {e}")
|
264
|
+
print("❌ Error: Required modules not available")
|
265
|
+
print("ℹ️ Please ensure diagram-to-iac is properly installed")
|
266
|
+
return 1
|
267
|
+
|
268
|
+
# Initialize SupervisorAgent
|
269
|
+
print("🚀 Initializing SupervisorAgent...")
|
270
|
+
try:
|
271
|
+
agent_kwargs = {}
|
272
|
+
if args.config_path:
|
273
|
+
agent_kwargs['config_path'] = args.config_path
|
274
|
+
|
275
|
+
supervisor = SupervisorAgent(**agent_kwargs)
|
276
|
+
except Exception as e:
|
277
|
+
logger.error(f"Failed to initialize SupervisorAgent: {e}")
|
278
|
+
print(f"❌ Error: Failed to initialize SupervisorAgent: {e}")
|
279
|
+
return 1
|
280
|
+
|
281
|
+
# Reset log bus for clean run
|
282
|
+
reset_log_bus()
|
283
|
+
|
284
|
+
# Prepare SupervisorAgent input
|
285
|
+
supervisor_input = SupervisorAgentInput(
|
286
|
+
repo_url=args.repository_url,
|
287
|
+
branch_name=args.branch_name,
|
288
|
+
thread_id=args.thread_id,
|
289
|
+
dry_run=args.dry_run,
|
290
|
+
)
|
291
|
+
|
292
|
+
# Execute R2D workflow
|
293
|
+
print("🔄 Executing R2D workflow...")
|
294
|
+
print("┌─────────────────────────────────────────────────────────────────────────────┐")
|
295
|
+
print("│ Workflow: Clone → Detect Stack → Branch Create → Terraform → Issue/PR │")
|
296
|
+
print("│ Agents: Git Agent | Shell Agent | Terraform Agent | Policy Agent │")
|
297
|
+
print("└─────────────────────────────────────────────────────────────────────────────┘")
|
298
|
+
print("")
|
299
|
+
|
300
|
+
result = supervisor.run(supervisor_input)
|
301
|
+
|
302
|
+
# Generate step summary
|
303
|
+
try:
|
304
|
+
step_summary_path = Path("step-summary.md")
|
305
|
+
generate_step_summary(get_log_path(), step_summary_path)
|
306
|
+
print(f"📊 Step summary generated: {step_summary_path}")
|
307
|
+
except Exception as e:
|
308
|
+
logger.warning(f"Failed to generate step summary: {e}")
|
309
|
+
|
310
|
+
# Display results
|
311
|
+
print("")
|
312
|
+
print("🏁 R2D Workflow Results")
|
313
|
+
print("═══════════════════════")
|
314
|
+
print(f"🎯 Repository: {result.repo_url}")
|
315
|
+
print(f"✅ Success: {result.success}")
|
316
|
+
print(f"🌿 Branch created: {result.branch_created}")
|
317
|
+
print(f"📝 Issues opened: {result.issues_opened}")
|
318
|
+
print(f"🏗️ Stack detected: {result.stack_detected}")
|
319
|
+
|
320
|
+
if result.terraform_summary:
|
321
|
+
print(f"⚡ Terraform summary: {result.terraform_summary}")
|
322
|
+
|
323
|
+
if result.message:
|
324
|
+
print(f"💬 Message: {result.message}")
|
325
|
+
|
326
|
+
if not result.success:
|
327
|
+
print("")
|
328
|
+
print("⚠️ R2D workflow encountered issues")
|
329
|
+
print("🔄 SupervisorAgent handles errors via GitHub Issues automatically")
|
330
|
+
print("📋 Check created issues for error details and auto-fix suggestions")
|
331
|
+
|
332
|
+
# Return appropriate exit code
|
333
|
+
return 0 if result.success else 1
|
334
|
+
|
335
|
+
except KeyboardInterrupt:
|
336
|
+
print("\n⚠️ Operation cancelled by user")
|
337
|
+
return 130
|
338
|
+
except Exception as e:
|
339
|
+
logger.error(f"Unexpected error in R2D CLI: {e}", exc_info=True)
|
340
|
+
print(f"❌ Unexpected error: {e}")
|
341
|
+
print("🐛 Please report this issue to: https://github.com/amartyamandal/diagram-to-iac/issues")
|
342
|
+
return 1
|
343
|
+
|
344
|
+
if __name__ == "__main__":
|
345
|
+
sys.exit(main())
|
@@ -0,0 +1,256 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: diagram-to-iac
|
3
|
+
Version: 0.10.0
|
4
|
+
Summary: Convert architecture diagrams into IaC modules
|
5
|
+
Author-email: vindpro <admin@vindpro.com>
|
6
|
+
Description-Content-Type: text/markdown
|
7
|
+
Requires-Dist: anthropic==0.54.0
|
8
|
+
Requires-Dist: google_api_python_client==2.172.0
|
9
|
+
Requires-Dist: langchain_anthropic==0.3.15
|
10
|
+
Requires-Dist: langchain-core<1.0.0,>=0.3.62
|
11
|
+
Requires-Dist: langchain_google_genai==2.1.5
|
12
|
+
Requires-Dist: langchain_openai==0.3.24
|
13
|
+
Requires-Dist: langgraph==0.4.8
|
14
|
+
Requires-Dist: openai==1.88.0
|
15
|
+
Requires-Dist: protobuf>=5.27.0
|
16
|
+
Requires-Dist: pydantic==2.11.7
|
17
|
+
Requires-Dist: PyYAML==6.0.2
|
18
|
+
Requires-Dist: Requests==2.32.4
|
19
|
+
Requires-Dist: GitPython<4.0,>=3.1
|
20
|
+
Requires-Dist: pytest-mock<4.0.0,>=3.10.0
|
21
|
+
|
22
|
+
# diagram-to-iac
|
23
|
+
|
24
|
+
> **"One container, many minds—zero manual toil."**
|
25
|
+
|
26
|
+
An automated DevOps-in-a-Box system that intelligently handles complete Repo-to-Deployment (R2D) workflows. The project combines AI-powered infrastructure analysis with GitHub automation for self-healing deployments.
|
27
|
+
|
28
|
+
## 🚀 DevOps-in-a-Box: R2D Action
|
29
|
+
|
30
|
+
The **R2D (Repo-to-Deployment) Action** is a self-healing, Terraform-first DevOps automation solution that lives inside a single GitHub Action. When you supply any repository URL, our SupervisorAgent marshals specialized agents to handle the complete deployment workflow.
|
31
|
+
|
32
|
+
### Quick Start with GitHub Actions
|
33
|
+
|
34
|
+
```yaml
|
35
|
+
name: Deploy Infrastructure
|
36
|
+
on:
|
37
|
+
push:
|
38
|
+
branches: [main]
|
39
|
+
|
40
|
+
jobs:
|
41
|
+
deploy:
|
42
|
+
runs-on: ubuntu-latest
|
43
|
+
steps:
|
44
|
+
- name: Deploy with R2D
|
45
|
+
uses: amartyamandal/diagram-to-iac/.github/actions/r2d@v1
|
46
|
+
with:
|
47
|
+
repo: ${{ github.server_url }}/${{ github.repository }}
|
48
|
+
env:
|
49
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
50
|
+
TF_CLOUD_TOKEN: ${{ secrets.TF_CLOUD_TOKEN }}
|
51
|
+
```
|
52
|
+
|
53
|
+
### Key Features
|
54
|
+
|
55
|
+
- **🤖 Self-Healing**: Automatically creates GitHub Issues for errors and suggests fixes
|
56
|
+
- **🔒 Security-First**: Non-root container execution with workspace isolation
|
57
|
+
- **🌍 Multi-Cloud**: Supports Terraform, PowerShell, Bash, and Ansible deployments
|
58
|
+
- **📊 Observable**: Rich logging, step summaries, and artifact collection
|
59
|
+
- **🔄 Resumable**: Thread-based conversation tracking for workflow continuation
|
60
|
+
- **🧪 Testable**: Comprehensive dry-run mode for safe testing
|
61
|
+
|
62
|
+
### The Cast: Specialized Agents
|
63
|
+
|
64
|
+
| Agent | Capability | Never Does |
|
65
|
+
|-------|------------|------------|
|
66
|
+
| **SupervisorAgent** | Orchestrates workflow, manages checkpoints | Edit code directly |
|
67
|
+
| **GitAgent** | Clone, branch, PR creation, assign @github-copilot | Guess network credentials |
|
68
|
+
| **ShellAgent** | Safe command execution, stack detection | Execute non-allowlisted binaries |
|
69
|
+
| **TerraformAgent** | Init/plan/apply, error classification | Apply with critical security issues |
|
70
|
+
| **PolicyAgent** | tfsec + OPA security gates | Ignore critical findings |
|
71
|
+
|
72
|
+
## 📦 Installation
|
73
|
+
|
74
|
+
Create a virtual environment with Python 3.11+ and install the project in editable mode. Development dependencies (linting, testing, etc.) are provided through the `dev` extra:
|
75
|
+
|
76
|
+
```bash
|
77
|
+
pip install -e .[dev]
|
78
|
+
```
|
79
|
+
|
80
|
+
## 🖥️ Running the CLI
|
81
|
+
|
82
|
+
The project exposes several entry points via `pyproject.toml`:
|
83
|
+
|
84
|
+
### Main R2D CLI
|
85
|
+
```bash
|
86
|
+
# Run complete R2D workflow
|
87
|
+
diagram-to-iac https://github.com/user/repo
|
88
|
+
r2d-agent https://github.com/user/repo --dry-run
|
89
|
+
|
90
|
+
# Get help
|
91
|
+
diagram-to-iac --help
|
92
|
+
```
|
93
|
+
|
94
|
+
### Individual Agent CLIs
|
95
|
+
```bash
|
96
|
+
# SupervisorAgent (orchestration)
|
97
|
+
supervisor-agent --repo-url https://github.com/user/repo
|
98
|
+
|
99
|
+
# GitAgent (repository operations)
|
100
|
+
git-agent --repo-url https://github.com/user/repo
|
101
|
+
|
102
|
+
# TerraformAgent (infrastructure deployment)
|
103
|
+
terraform-agent --query "terraform plan"
|
104
|
+
```
|
105
|
+
|
106
|
+
### Interactive Mode
|
107
|
+
|
108
|
+
Running without arguments enters interactive mode:
|
109
|
+
|
110
|
+
```bash
|
111
|
+
$ supervisor-agent --dry-run
|
112
|
+
╔══════════════════════════════════════════════════════════════════════════════╗
|
113
|
+
║ 🤖 DevOps-in-a-Box: SupervisorAgent ║
|
114
|
+
║ "One container, many minds—zero manual toil." ║
|
115
|
+
╚══════════════════════════════════════════════════════════════════════════════╝
|
116
|
+
|
117
|
+
Repository URL: https://github.com/octocat/Hello-World.git
|
118
|
+
🚀 R2D SupervisorAgent - Workflow Orchestration
|
119
|
+
📅 Default branch name: r2d-<timestamp>
|
120
|
+
📝 Press Enter to use default, or type a custom branch name:
|
121
|
+
```
|
122
|
+
|
123
|
+
The agent will continue with the complete workflow (clone → detect → deploy → issue creation). The `--dry-run` flag simulates actions without making changes.
|
124
|
+
|
125
|
+
## Running Tests
|
126
|
+
|
127
|
+
All tests use `pytest` and are located under the `tests` directory. After installing the development dependencies, run:
|
128
|
+
|
129
|
+
```bash
|
130
|
+
pytest
|
131
|
+
```
|
132
|
+
|
133
|
+
## 📊 Logs and Observability
|
134
|
+
|
135
|
+
DevOps-in-a-Box provides comprehensive observability for all R2D workflows:
|
136
|
+
|
137
|
+
### Structured Logging
|
138
|
+
Each run creates a JSONL log file under the `logs/` directory (e.g. `logs/run-<timestamp>.jsonl`).
|
139
|
+
Every significant event is logged as structured JSON for easy parsing and analysis:
|
140
|
+
|
141
|
+
```bash
|
142
|
+
# Follow live logs
|
143
|
+
tail -f logs/run-*.jsonl
|
144
|
+
|
145
|
+
# Parse with jq for specific events
|
146
|
+
cat logs/run-*.jsonl | jq '. | select(.event_type == "terraform_apply")'
|
147
|
+
```
|
148
|
+
|
149
|
+
### Step Summary Dashboard
|
150
|
+
After each workflow, a Markdown dashboard is generated at `step-summary.md` with:
|
151
|
+
- 📈 Terraform resource changes and cost estimates
|
152
|
+
- 🔒 Security findings from tfsec/OPA scans
|
153
|
+
- 🏗️ Infrastructure modules and dependencies
|
154
|
+
- ⚡ Performance metrics and execution times
|
155
|
+
|
156
|
+
### GitHub Integration
|
157
|
+
- **Issues**: Automatically created for errors with detailed context
|
158
|
+
- **Pull Requests**: Auto-drafted fixes assigned to @github-copilot
|
159
|
+
- **Workflow Summaries**: Rich GitHub Actions step summaries
|
160
|
+
- **Artifacts**: Logs, plans, and reports uploaded for download
|
161
|
+
|
162
|
+
### CI/CD Artifacts
|
163
|
+
In GitHub Actions, the following artifacts are automatically collected:
|
164
|
+
- `logs/` - Structured JSONL logs
|
165
|
+
- `*.tfplan` - Terraform plan files
|
166
|
+
- `step-summary.md` - Workflow dashboard
|
167
|
+
- `r2d-artifacts/` - Complete workflow artifacts
|
168
|
+
|
169
|
+
## 🔧 GitHub Actions Usage
|
170
|
+
|
171
|
+
Add the R2D action to your workflow for automated infrastructure deployment:
|
172
|
+
|
173
|
+
### Basic Setup
|
174
|
+
|
175
|
+
```yaml
|
176
|
+
name: Deploy Infrastructure
|
177
|
+
on:
|
178
|
+
push:
|
179
|
+
branches: [main]
|
180
|
+
|
181
|
+
jobs:
|
182
|
+
deploy:
|
183
|
+
runs-on: ubuntu-latest
|
184
|
+
steps:
|
185
|
+
- name: Deploy with R2D
|
186
|
+
uses: amartyamandal/diagram-to-iac/.github/actions/r2d@v1
|
187
|
+
with:
|
188
|
+
repo: ${{ github.server_url }}/${{ github.repository }}
|
189
|
+
env:
|
190
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
191
|
+
TF_CLOUD_TOKEN: ${{ secrets.TF_CLOUD_TOKEN }}
|
192
|
+
```
|
193
|
+
|
194
|
+
### Advanced Configuration
|
195
|
+
|
196
|
+
```yaml
|
197
|
+
- name: Deploy with Custom Settings
|
198
|
+
uses: amartyamandal/diagram-to-iac/.github/actions/r2d@v1
|
199
|
+
with:
|
200
|
+
repo: 'https://github.com/my-org/infrastructure'
|
201
|
+
package_version: 'v2.1.0'
|
202
|
+
dry_run: 'false'
|
203
|
+
branch_name: 'deploy-prod'
|
204
|
+
thread_id: 'prod-deployment-001'
|
205
|
+
env:
|
206
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
207
|
+
TF_CLOUD_TOKEN: ${{ secrets.TF_CLOUD_TOKEN }}
|
208
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
209
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
210
|
+
```
|
211
|
+
|
212
|
+
### Required Secrets
|
213
|
+
|
214
|
+
Configure these in your repository settings:
|
215
|
+
|
216
|
+
| Secret | Description | Required |
|
217
|
+
|--------|-------------|----------|
|
218
|
+
| `GITHUB_TOKEN` | GitHub API access (auto-provided) | ✅ Yes |
|
219
|
+
| `TF_CLOUD_TOKEN` | Terraform Cloud API token | ✅ Yes |
|
220
|
+
| `OPENAI_API_KEY` | OpenAI API key | ❌ Optional |
|
221
|
+
| `ANTHROPIC_API_KEY` | Claude API key | ❌ Optional |
|
222
|
+
| `GOOGLE_API_KEY` | Gemini API key | ❌ Optional |
|
223
|
+
|
224
|
+
### Example Workflows
|
225
|
+
|
226
|
+
See [`.github/actions/r2d/examples/`](.github/actions/r2d/examples/) for complete workflow examples:
|
227
|
+
|
228
|
+
- **Basic Deployment**: Simple push-to-deploy workflow
|
229
|
+
- **Multi-Environment**: Deploy to dev/staging/prod with approvals
|
230
|
+
- **PR Validation**: Validate infrastructure changes in pull requests
|
231
|
+
- **Drift Detection**: Scheduled infrastructure drift monitoring
|
232
|
+
- **External Repository**: Deploy from external repositories
|
233
|
+
|
234
|
+
|
235
|
+
After each workflow run, a Markdown dashboard is generated at `step-summary.md`
|
236
|
+
showing a high level overview of Terraform modules, resource changes and tfsec
|
237
|
+
findings. The dashboard is derived from the JSONL logs and can be viewed
|
238
|
+
directly in the repository or uploaded as a build artifact.
|
239
|
+
|
240
|
+
|
241
|
+
|
242
|
+
This repository provides a container action that runs the `SupervisorAgent` on the current repository. Add the action to a workflow as shown below:
|
243
|
+
|
244
|
+
```yaml
|
245
|
+
jobs:
|
246
|
+
supervisor:
|
247
|
+
runs-on: ubuntu-latest
|
248
|
+
steps:
|
249
|
+
- uses: actions/checkout@v4
|
250
|
+
- name: Run Supervisor Agent
|
251
|
+
uses: ./.github/actions/supervisor
|
252
|
+
env:
|
253
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
254
|
+
```
|
255
|
+
|
256
|
+
The action reads `GITHUB_REPOSITORY` and `GITHUB_TOKEN` automatically to clone the repository and execute the agent.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
diagram_to_iac/__init__.py,sha256=LnGvfFSFGIYc7cx-AkxfGPBU-H7wleyXLOL23s5C_XY,244
|
2
2
|
diagram_to_iac/cli.py,sha256=uumG1frF42eCkdLIZxyxQB1x6lDwtG-qKL4vcHnLLXY,400
|
3
|
-
diagram_to_iac/r2d.py,sha256=
|
3
|
+
diagram_to_iac/r2d.py,sha256=v4f9TegjEnITYPmnEZyBUgZ44s0x_Sct9993h6V0a8k,13021
|
4
4
|
diagram_to_iac/actions/__init__.py,sha256=P1CjjY4FYUA0Tcx8FQNLYYSI9fhv8yKd_TmRGtmhW50,229
|
5
5
|
diagram_to_iac/actions/git_entry.py,sha256=mhY6gYquUPVvyvnTC2S90z_uXEe1asqWLoi1989aB_Q,5403
|
6
6
|
diagram_to_iac/actions/supervisor_entry.py,sha256=vWhFn-4M0jQnrUQUSCb0I_YNxzGsKiBV0QNzkIkQfNE,3586
|
@@ -57,8 +57,8 @@ diagram_to_iac/tools/llm_utils/router.py,sha256=WHGanstQjUlo2SmDFKGAL6xtIb3xXWlg
|
|
57
57
|
diagram_to_iac/tools/shell/__init__.py,sha256=6UZjBcnbPabA6Qy7t4j-dCi3S2sE6sB2bTE9PIL98bA,292
|
58
58
|
diagram_to_iac/tools/shell/shell.py,sha256=SvgFHNPcwToq51jtDshnlvssFSwzex42Q_jY6I0L5M8,17771
|
59
59
|
diagram_to_iac/tools/tf/terraform.py,sha256=JFZTBy4jqwGK-bwRvdA9UxGChEhQSHXjo5DapxogF1w,36042
|
60
|
-
diagram_to_iac-0.
|
61
|
-
diagram_to_iac-0.
|
62
|
-
diagram_to_iac-0.
|
63
|
-
diagram_to_iac-0.
|
64
|
-
diagram_to_iac-0.
|
60
|
+
diagram_to_iac-0.10.0.dist-info/METADATA,sha256=ipoJ0CDNqX7QiTCDROmzEF2PBjF5sRUu0WBE15rFUx4,9062
|
61
|
+
diagram_to_iac-0.10.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
62
|
+
diagram_to_iac-0.10.0.dist-info/entry_points.txt,sha256=DfGCnmgWWGHtQpqU8VqcUWs5k_be-bfO67z1vOuTitA,277
|
63
|
+
diagram_to_iac-0.10.0.dist-info/top_level.txt,sha256=k1cV0YODiCUU46qlmbQaquMcbMXhNm05NZLxsinDUBA,15
|
64
|
+
diagram_to_iac-0.10.0.dist-info/RECORD,,
|
@@ -1,4 +1,6 @@
|
|
1
1
|
[console_scripts]
|
2
2
|
diagram-to-iac = diagram_to_iac.cli:main
|
3
3
|
git-agent = diagram_to_iac.actions.git_entry:main
|
4
|
+
r2d-agent = diagram_to_iac.r2d:main
|
4
5
|
supervisor-agent = diagram_to_iac.actions.supervisor_entry:main
|
6
|
+
terraform-agent = diagram_to_iac.actions.terraform_agent_entry:main
|
@@ -1,99 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: diagram-to-iac
|
3
|
-
Version: 0.8.0
|
4
|
-
Summary: Convert architecture diagrams into IaC modules
|
5
|
-
Author-email: vindpro <admin@vindpro.com>
|
6
|
-
Description-Content-Type: text/markdown
|
7
|
-
Requires-Dist: anthropic==0.54.0
|
8
|
-
Requires-Dist: google_api_python_client==2.172.0
|
9
|
-
Requires-Dist: langchain_anthropic==0.3.15
|
10
|
-
Requires-Dist: langchain-core<1.0.0,>=0.3.62
|
11
|
-
Requires-Dist: langchain_google_genai==2.1.5
|
12
|
-
Requires-Dist: langchain_openai==0.3.24
|
13
|
-
Requires-Dist: langgraph==0.4.8
|
14
|
-
Requires-Dist: openai==1.88.0
|
15
|
-
Requires-Dist: protobuf>=5.27.0
|
16
|
-
Requires-Dist: pydantic==2.11.7
|
17
|
-
Requires-Dist: PyYAML==6.0.2
|
18
|
-
Requires-Dist: Requests==2.32.4
|
19
|
-
Requires-Dist: GitPython<4.0,>=3.1
|
20
|
-
Requires-Dist: pytest-mock<4.0.0,>=3.10.0
|
21
|
-
|
22
|
-
# diagram-to-iac
|
23
|
-
An automated system that intelligently translates visual cloud infrastructure diagrams (specifically Azure) into deployable Infrastructure as Code (IaC). The project leverages AI for analysis and GitHub for collaborative refinement.
|
24
|
-
|
25
|
-
## Installation
|
26
|
-
|
27
|
-
Create a virtual environment with Python 3.11+ and install the project in editable mode. Development dependencies (linting, testing, etc.) are provided through the `dev` extra:
|
28
|
-
|
29
|
-
```bash
|
30
|
-
pip install -e .[dev]
|
31
|
-
```
|
32
|
-
|
33
|
-
## Running the CLI
|
34
|
-
|
35
|
-
The project exposes several entry points via `pyproject.toml`. The main one for end‑to‑end automation is `supervisor-agent`.
|
36
|
-
|
37
|
-
```bash
|
38
|
-
supervisor-agent --help
|
39
|
-
```
|
40
|
-
|
41
|
-
Running `supervisor-agent` without arguments enters an interactive mode. You will be prompted for the repository URL and branch name:
|
42
|
-
|
43
|
-
```bash
|
44
|
-
$ supervisor-agent --dry-run
|
45
|
-
Repository URL: https://github.com/octocat/Hello-World.git
|
46
|
-
🚀 R2D SupervisorAgent - Branch Creation
|
47
|
-
📅 Default branch name: r2d-<timestamp>
|
48
|
-
📝 Press Enter to use default, or type a custom branch name:
|
49
|
-
Branch name:
|
50
|
-
```
|
51
|
-
|
52
|
-
The agent will then continue with the workflow (cloning, analysis and issue creation). The `--dry-run` flag prints the generated issue text instead of creating it.
|
53
|
-
|
54
|
-
## Running Tests
|
55
|
-
|
56
|
-
All tests use `pytest` and are located under the `tests` directory. After installing the development dependencies, run:
|
57
|
-
|
58
|
-
```bash
|
59
|
-
pytest
|
60
|
-
```
|
61
|
-
|
62
|
-
## Logs and Observability
|
63
|
-
|
64
|
-
Each run creates a JSONL log file under the `logs/` directory (e.g. `logs/run-<timestamp>.jsonl`).
|
65
|
-
Every significant event emitted by the agents is appended as a single JSON line.
|
66
|
-
You can inspect the log with tools like `tail` to follow the workflow progress:
|
67
|
-
|
68
|
-
```bash
|
69
|
-
tail -f logs/run-*.jsonl
|
70
|
-
```
|
71
|
-
|
72
|
-
|
73
|
-
In CI runs, the `logs/` directory and any `*.tfplan` files are compressed and
|
74
|
-
uploaded as the `logs-and-plans` artifact. Download this artifact from the
|
75
|
-
workflow run to inspect full logs and Terraform plans.
|
76
|
-
|
77
|
-
|
78
|
-
After each workflow run, a Markdown dashboard is generated at `step-summary.md`
|
79
|
-
showing a high level overview of Terraform modules, resource changes and tfsec
|
80
|
-
findings. The dashboard is derived from the JSONL logs and can be viewed
|
81
|
-
directly in the repository or uploaded as a build artifact.
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
This repository provides a container action that runs the `SupervisorAgent` on the current repository. Add the action to a workflow as shown below:
|
86
|
-
|
87
|
-
```yaml
|
88
|
-
jobs:
|
89
|
-
supervisor:
|
90
|
-
runs-on: ubuntu-latest
|
91
|
-
steps:
|
92
|
-
- uses: actions/checkout@v4
|
93
|
-
- name: Run Supervisor Agent
|
94
|
-
uses: ./.github/actions/supervisor
|
95
|
-
env:
|
96
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
97
|
-
```
|
98
|
-
|
99
|
-
The action reads `GITHUB_REPOSITORY` and `GITHUB_TOKEN` automatically to clone the repository and execute the agent.
|
File without changes
|
File without changes
|