feat: add nightly branch workflow

This commit is contained in:
GitHub Actions
2026-01-13 22:11:28 +00:00
parent d27c925ba5
commit 4adcd9eda1
187 changed files with 8897 additions and 1614 deletions

View File

@@ -30,6 +30,7 @@ type DNSProviderConfig struct {
**File:** `backend/internal/caddy/manager.go` (Lines 51-58)
Created interface for improved testability:
```go
type CaddyClient interface {
Load(context.Context, io.Reader, bool) error
@@ -43,6 +44,7 @@ type CaddyClient interface {
**File:** `backend/internal/caddy/manager.go` (Lines 100-118)
Modified provider detection loop to properly handle multi-credential providers:
- Detects `UseMultiCredentials=true` flag
- Adds providers with empty Credentials field for Phase 2 processing
- Maintains backward compatibility for single-credential providers
@@ -52,6 +54,7 @@ Modified provider detection loop to properly handle multi-credential providers:
**File:** `backend/internal/caddy/manager.go` (Lines 147-213)
Implemented comprehensive credential resolution logic:
- Iterates through all proxy hosts
- Calls `getCredentialForDomain` helper for each domain
- Builds `ZoneCredentials` map per provider
@@ -59,6 +62,7 @@ Implemented comprehensive credential resolution logic:
- Error handling for missing credentials
**Key Code Segment:**
```go
// Phase 2: For multi-credential providers, resolve per-domain credentials
for _, providerConf := range dnsProviderConfigs {
@@ -86,17 +90,20 @@ for _, providerConf := range dnsProviderConfigs {
Enhanced `buildDNSChallengeIssuer` with conditional branching:
**Multi-Credential Path (Lines 184-254):**
- Creates separate TLS automation policies per domain
- Matches domains to base domains for proper credential mapping
- Builds per-domain provider configurations
- Supports exact match, wildcard, and catch-all zones
**Single-Credential Path (Lines 256-280):**
- Preserved original logic for backward compatibility
- Single policy for all domains
- Uses shared credentials
**Key Decision Logic:**
```go
if providerConf.UseMultiCredentials {
// Multi-credential: Create separate policy per domain
@@ -123,12 +130,14 @@ if providerConf.UseMultiCredentials {
Implemented 4 comprehensive integration test scenarios:
#### Test 1: Single-Credential Backward Compatibility
- **Purpose:** Verify existing single-credential providers work unchanged
- **Setup:** Standard DNSProvider with `UseMultiCredentials=false`
- **Validation:** Single TLS policy created with shared credentials
- **Result:** ✅ PASS
#### Test 2: Multi-Credential Exact Match
- **Purpose:** Test exact zone filter matching (example.com, example.org)
- **Setup:**
- Provider with `UseMultiCredentials=true`
@@ -140,6 +149,7 @@ Implemented 4 comprehensive integration test scenarios:
- **Result:** ✅ PASS
#### Test 3: Multi-Credential Wildcard Match
- **Purpose:** Test wildcard zone filter matching (*.example.com)
- **Setup:**
- Credential with `*.example.com` zone filter
@@ -148,6 +158,7 @@ Implemented 4 comprehensive integration test scenarios:
- **Result:** ✅ PASS
#### Test 4: Multi-Credential Catch-All
- **Purpose:** Test empty zone filter (catch-all) matching
- **Setup:**
- Credential with empty zone_filter
@@ -156,6 +167,7 @@ Implemented 4 comprehensive integration test scenarios:
- **Result:** ✅ PASS
**Helper Functions:**
- `encryptCredentials()`: AES-256-GCM encryption with proper base64 encoding
- `setupTestDB()`: Creates in-memory SQLite with all required tables
- `assertDNSChallengeCredential()`: Validates TLS policy credentials
@@ -164,6 +176,7 @@ Implemented 4 comprehensive integration test scenarios:
## Test Results
### Coverage Metrics
```
Total Coverage: 94.8%
Target: 85.0%
@@ -171,6 +184,7 @@ Status: PASS (+9.8%)
```
### Test Execution
```
Total Tests: 47
Passed: 47
@@ -179,6 +193,7 @@ Duration: 1.566s
```
### Key Test Scenarios Validated
✅ Single-credential backward compatibility
✅ Multi-credential exact match (example.com)
✅ Multi-credential wildcard match (*.example.com)
@@ -193,32 +208,40 @@ Duration: 1.566s
## Architecture Decisions
### 1. Two-Phase Processing
**Rationale:** Separates provider detection from credential resolution, enabling cleaner code and better error handling.
**Implementation:**
- **Phase 1:** Build provider config list, detect multi-credential flag
- **Phase 2:** Resolve per-domain credentials using helper function
### 2. Interface-Based Design
**Rationale:** Enables comprehensive testing without real Caddy server dependency.
**Implementation:**
- Created `CaddyClient` interface
- Modified `NewManager` signature to accept interface
- Implemented `MockClient` for testing
### 3. Credential Resolution Priority
**Rationale:** Provides flexible matching while ensuring most specific match wins.
**Priority Order:**
1. Exact match (example.com → example.com)
2. Wildcard match (app.example.com → *.example.com)
3. Catch-all (any domain → empty zone_filter)
### 4. Backward Compatibility First
**Rationale:** Existing single-credential deployments must continue working unchanged.
**Implementation:**
- Preserved original code paths
- Conditional branching based on `UseMultiCredentials` flag
- Comprehensive backward compatibility test
@@ -226,12 +249,15 @@ Duration: 1.566s
## Security Considerations
### Encryption
- AES-256-GCM for all stored credentials
- Base64 encoding for database storage
- Proper key version management
### Audit Trail
Every credential selection logs:
```
credential_uuid: <UUID>
zone_filter: <filter>
@@ -239,6 +265,7 @@ domain: <matched-domain>
```
### Error Handling
- No credential exposure in error messages
- Graceful degradation for missing credentials
- Clear error propagation for debugging
@@ -246,16 +273,19 @@ domain: <matched-domain>
## Performance Impact
### Database Queries
- Phase 1: Single query for all DNS providers
- Phase 2: Preloaded with Phase 1 data (no additional queries)
- Result: **No additional database load**
### Memory Footprint
- `ZoneCredentials` map: ~100 bytes per domain
- Typical deployment (10 domains): ~1KB additional memory
- Result: **Negligible impact**
### Config Generation
- Multi-credential: O(n) policies where n = domain count
- Single-credential: O(1) policy (unchanged)
- Result: **Linear scaling, acceptable for typical use cases**
@@ -263,6 +293,7 @@ domain: <matched-domain>
## Files Modified
### Core Implementation
1. `backend/internal/caddy/manager.go` (Modified)
- Added struct fields
- Created CaddyClient interface
@@ -279,29 +310,33 @@ domain: <matched-domain>
- No modifications required
### Testing
4. `backend/internal/caddy/manager_multicred_integration_test.go` (NEW)
1. `backend/internal/caddy/manager_multicred_integration_test.go` (NEW)
- 4 comprehensive integration tests
- Helper functions for setup and validation
- MockClient implementation
5. `backend/internal/caddy/manager_multicred_test.go` (Modified)
2. `backend/internal/caddy/manager_multicred_test.go` (Modified)
- Removed redundant unit tests
- Added documentation comment explaining integration test coverage
## Backward Compatibility
### Single-Credential Providers
- **Behavior:** Unchanged
- **Config:** Single TLS policy for all domains
- **Credentials:** Shared across all domains
- **Test Coverage:** Dedicated test validates this path
### Database Schema
- **New Fields:** `use_multi_credentials` (default: false)
- **Migration:** Existing providers default to single-credential mode
- **Impact:** Zero for existing deployments
### API Endpoints
- **Changes:** None required
- **Client Impact:** None
- **Deployment:** No coordination needed
@@ -309,22 +344,26 @@ domain: <matched-domain>
## Manual Verification Checklist
### Helper Functions ✅
- [x] `extractBaseDomain` strips wildcard prefix correctly
- [x] `matchesZoneFilter` handles exact, wildcard, and catch-all
- [x] `getCredentialForDomain` implements 3-priority resolution
### Integration Flow ✅
- [x] Phase 1 detects multi-credential providers
- [x] Phase 2 resolves credentials per domain
- [x] Config generation creates separate policies
- [x] Backward compatibility maintained
### Audit Logging ✅
- [x] credential_uuid logged for each selection
- [x] zone_filter logged for audit trail
- [x] domain logged for troubleshooting
### Error Handling ✅
- [x] Missing credentials handled gracefully
- [x] Encryption errors propagate clearly
- [x] No credential exposure in error messages
@@ -332,40 +371,48 @@ domain: <matched-domain>
## Definition of Done
**DNSProviderConfig struct has new fields**
- `UseMultiCredentials` bool added
- `ZoneCredentials` map added
**ApplyConfig resolves credentials per-domain**
- Phase 2 loop implemented
- Uses `getCredentialForDomain` helper
- Builds `ZoneCredentials` map
**buildDNSChallengeIssuer uses zone-specific credentials**
- Conditional branching on `UseMultiCredentials`
- Separate TLS policies per domain in multi-credential mode
- Single policy preserved for single-credential mode
**Integration tests implemented**
- 4 comprehensive test scenarios
- All scenarios passing
- Helper functions for setup and validation
**Backward compatibility maintained**
- Single-credential providers work unchanged
- Dedicated test validates backward compatibility
- No breaking changes
**Coverage ≥85%**
- Achieved: 94.8%
- Target: 85.0%
- Status: PASS (+9.8%)
**Audit logging implemented**
- credential_uuid logged
- zone_filter logged
- domain logged
**Manual verification complete**
- All helper functions tested
- Integration flow validated
- Error handling verified
@@ -374,6 +421,7 @@ domain: <matched-domain>
## Usage Examples
### Single-Credential Provider (Backward Compatible)
```go
provider := DNSProvider{
ProviderType: "cloudflare",
@@ -384,6 +432,7 @@ provider := DNSProvider{
```
### Multi-Credential Provider (New Feature)
```go
provider := DNSProvider{
ProviderType: "cloudflare",
@@ -398,6 +447,7 @@ provider := DNSProvider{
```
### Credential Resolution Flow
```
1. Domain: test1.example.com
-> Extract base: example.com
@@ -421,10 +471,12 @@ provider := DNSProvider{
## Deployment Notes
### Prerequisites
- Database migration adds `use_multi_credentials` column (default: false)
- Existing providers automatically use single-credential mode
### Rollout Strategy
1. Deploy backend with new code
2. Existing providers continue working (backward compatible)
3. Enable multi-credential mode per provider via admin UI
@@ -432,12 +484,15 @@ provider := DNSProvider{
5. Caddy config regenerates automatically on next apply
### Rollback Procedure
If rollback needed:
1. Set `use_multi_credentials=false` on all providers
2. Deploy previous backend version
3. No data loss, graceful degradation
### Monitoring
- Check audit logs for credential selection
- Monitor Caddy config generation time
- Watch for "failed to resolve credentials" errors
@@ -445,6 +500,7 @@ If rollback needed:
## Future Enhancements
### Potential Improvements
1. **Web UI for Multi-Credential Management**
- Add/edit/delete credentials per provider
- Zone filter validation
@@ -470,6 +526,7 @@ If rollback needed:
The Phase 3 Caddy Manager multi-credential integration is **COMPLETE** and **PRODUCTION-READY**. All requirements met, comprehensive testing in place, and backward compatibility ensured.
**Key Achievements:**
- ✅ 94.8% test coverage (9.8% above target)
- ✅ 47/47 tests passing
- ✅ Full backward compatibility
@@ -478,6 +535,7 @@ The Phase 3 Caddy Manager multi-credential integration is **COMPLETE** and **PRO
- ✅ Production-grade error handling
**Next Steps:**
1. Deploy to staging environment for integration testing
2. Perform end-to-end testing with real DNS providers
3. Validate SSL certificate generation with zone-specific credentials