|
| 1 | +# Infrastructure Module Organization: Execution Context Separation |
| 2 | + |
| 3 | +**Status**: Accepted |
| 4 | +**Date**: 2025-12-11 |
| 5 | +**Deciders**: Development Team |
| 6 | +**Issue**: [#220](https://github.com/torrust/torrust-tracker-deployer/issues/220) |
| 7 | + |
| 8 | +## Context |
| 9 | + |
| 10 | +The infrastructure layer contains components that interact with external systems. However, there are two fundamentally different types of external interactions: |
| 11 | + |
| 12 | +1. **SSH-based operations**: Commands executed **inside the VM** via SSH connection |
| 13 | +2. **External validation**: HTTP requests made **from outside the VM** to test end-to-end functionality |
| 14 | + |
| 15 | +Previously, both types were mixed in `infrastructure/remote_actions/`, creating architectural confusion: |
| 16 | + |
| 17 | +- `remote_actions/validators/docker.rs` - Executes `docker --version` inside VM via SSH |
| 18 | +- `remote_actions/validators/running_services.rs` - Makes HTTP requests to services from outside VM |
| 19 | + |
| 20 | +This mixing obscured the critical distinction of **where the code executes** and **what it validates**. |
| 21 | + |
| 22 | +## Decision |
| 23 | + |
| 24 | +We separate infrastructure modules by execution context: |
| 25 | + |
| 26 | +```text |
| 27 | +src/infrastructure/ |
| 28 | +├── remote_actions/ # SSH-based operations executed INSIDE the VM |
| 29 | +│ └── validators/ |
| 30 | +│ ├── cloud_init.rs |
| 31 | +│ ├── docker.rs |
| 32 | +│ └── docker_compose.rs |
| 33 | +└── external_validators/ # E2E validation from OUTSIDE the VM |
| 34 | + └── running_services.rs |
| 35 | +``` |
| 36 | + |
| 37 | +### Module Purposes |
| 38 | + |
| 39 | +**`remote_actions/`** (SSH-based, inside VM): |
| 40 | + |
| 41 | +- Execute commands via SSH connection inside the VM |
| 42 | +- Validate internal VM state and configuration |
| 43 | +- Examples: Check if Docker is installed, verify cloud-init completion |
| 44 | +- Scope: Internal system state |
| 45 | + |
| 46 | +**`external_validators/`** (HTTP-based, outside VM): |
| 47 | + |
| 48 | +- Make HTTP requests from test runner/deployment machine |
| 49 | +- Validate end-to-end service accessibility |
| 50 | +- Test network configuration and firewall rules |
| 51 | +- Examples: Health check endpoints, service availability tests |
| 52 | +- Scope: External accessibility and E2E functionality |
| 53 | + |
| 54 | +## Rationale |
| 55 | + |
| 56 | +### Why Both Remain in Infrastructure Layer (DDD) |
| 57 | + |
| 58 | +Both modules are infrastructure concerns because they: |
| 59 | + |
| 60 | +- Interact with external systems (VMs, networks, services) |
| 61 | +- Provide technical capabilities for application layer |
| 62 | +- Depend on adapters (SSH client, HTTP client) |
| 63 | +- Are not business logic or domain concepts |
| 64 | + |
| 65 | +The distinction is **execution context**, not **DDD layer**. |
| 66 | + |
| 67 | +### Why Separation Improves Architecture |
| 68 | + |
| 69 | +1. **Clarity**: Developers immediately understand where code executes |
| 70 | +2. **Testability**: Different testing strategies for SSH vs HTTP operations |
| 71 | +3. **Documentation**: Module names self-document their purpose |
| 72 | +4. **Maintainability**: Related code grouped by execution context |
| 73 | +5. **Discoverability**: New validators know which module to use |
| 74 | + |
| 75 | +### Comparison with Remote Actions Module |
| 76 | + |
| 77 | +| Aspect | `remote_actions/` | `external_validators/` | |
| 78 | +| ------------------ | --------------------------------- | ----------------------------- | |
| 79 | +| Execution location | Inside VM via SSH | Outside VM (test runner) | |
| 80 | +| Connection type | SSH | HTTP/HTTPS | |
| 81 | +| Validates | Internal state | External accessibility | |
| 82 | +| Examples | Docker version, cloud-init status | Service health, API endpoints | |
| 83 | +| Firewall impact | Not validated | Implicitly validated | |
| 84 | + |
| 85 | +## Consequences |
| 86 | + |
| 87 | +### Positive |
| 88 | + |
| 89 | +- **Clear architectural boundaries**: Execution context is explicit |
| 90 | +- **Better code organization**: Related validators grouped together |
| 91 | +- **Improved documentation**: Module purpose is self-evident |
| 92 | +- **Easier testing**: Different strategies for SSH vs HTTP |
| 93 | +- **Scalable**: Future validators know which module to use |
| 94 | + |
| 95 | +### Neutral |
| 96 | + |
| 97 | +- **Module proliferation**: More top-level infrastructure modules |
| 98 | +- **Import paths change**: Code needs import updates (one-time cost) |
| 99 | + |
| 100 | +### Negative |
| 101 | + |
| 102 | +- **None identified**: This is a pure improvement in organization |
| 103 | + |
| 104 | +## Alternatives Considered |
| 105 | + |
| 106 | +### Alternative 1: Keep Everything in `remote_actions/` |
| 107 | + |
| 108 | +**Rejected because**: |
| 109 | + |
| 110 | +- Mixes fundamentally different execution contexts |
| 111 | +- "Remote actions" implies SSH operations, confusing for HTTP validators |
| 112 | +- Harder to understand what code does without reading implementation |
| 113 | + |
| 114 | +### Alternative 2: Move to Application Layer Services |
| 115 | + |
| 116 | +**Rejected because**: |
| 117 | + |
| 118 | +- Not business logic or use cases |
| 119 | +- Depends on infrastructure adapters (SSH, HTTP clients) |
| 120 | +- Violates DDD layer boundaries (application depends on infrastructure) |
| 121 | +- `RunningServicesValidator` performs infrastructure concerns (external system validation) |
| 122 | + |
| 123 | +### Alternative 3: Create `e2e_validators/` Instead |
| 124 | + |
| 125 | +**Rejected because**: |
| 126 | + |
| 127 | +- "E2E" describes testing strategy, not execution context |
| 128 | +- Less clear than "external" for where code runs |
| 129 | +- Could be confused with test helpers |
| 130 | + |
| 131 | +## Implementation |
| 132 | + |
| 133 | +### File Reorganization |
| 134 | + |
| 135 | +1. Create `src/infrastructure/external_validators/mod.rs` |
| 136 | +2. Move `running_services.rs` from `remote_actions/validators/` to `external_validators/` |
| 137 | +3. Update infrastructure module exports |
| 138 | +4. Update all import paths in application and testing code |
| 139 | + |
| 140 | +### Documentation Updates |
| 141 | + |
| 142 | +1. Update `docs/codebase-architecture.md` with new structure |
| 143 | +2. Add module-level documentation explaining execution context |
| 144 | +3. Update validator documentation to reference execution context |
| 145 | + |
| 146 | +## Related Decisions |
| 147 | + |
| 148 | +- [Port Zero Not Supported](port-zero-not-supported.md) - Validates port configuration |
| 149 | +- [DDD Layer Placement](../contributing/ddd-layer-placement.md) - Explains infrastructure layer |
| 150 | + |
| 151 | +## Notes |
| 152 | + |
| 153 | +This refactoring maintains all existing functionality while improving code organization and clarity. The change is purely structural - no behavior changes. |
0 commit comments