Files
Charon/backend/pkg/dnsprovider/builtin/namecheap.go
GitHub Actions b86aa3921b feat(dns): add custom DNS provider plugin system
- Add plugin interface with lifecycle hooks (Init/Cleanup)
- Implement thread-safe provider registry
- Add plugin loader with SHA-256 signature verification
- Migrate 10 built-in providers to registry pattern
- Add multi-credential support to plugin interface
- Create plugin management UI with enable/disable controls
- Add dynamic credential fields based on provider metadata
- Include PowerDNS example plugin
- Add comprehensive user & developer documentation
- Fix frontend test hang (33min → 1.5min, 22x faster)

Platform: Linux/macOS only (Go plugin limitation)
Security: Signature verification, directory permission checks

Backend coverage: 85.1%
Frontend coverage: 85.31%

Closes: DNS Challenge Future Features - Phase 5
2026-01-07 02:54:01 +00:00

108 lines
2.6 KiB
Go

package builtin
import (
"fmt"
"time"
"github.com/Wikid82/charon/backend/pkg/dnsprovider"
)
// NamecheapProvider implements the ProviderPlugin interface for Namecheap DNS.
type NamecheapProvider struct{}
func (p *NamecheapProvider) Type() string {
return "namecheap"
}
func (p *NamecheapProvider) Metadata() dnsprovider.ProviderMetadata {
return dnsprovider.ProviderMetadata{
Type: "namecheap",
Name: "Namecheap",
Description: "Namecheap DNS with API credentials",
DocumentationURL: "https://www.namecheap.com/support/api/intro/",
IsBuiltIn: true,
Version: "1.0.0",
}
}
func (p *NamecheapProvider) Init() error {
return nil
}
func (p *NamecheapProvider) Cleanup() error {
return nil
}
func (p *NamecheapProvider) RequiredCredentialFields() []dnsprovider.CredentialFieldSpec {
return []dnsprovider.CredentialFieldSpec{
{
Name: "api_user",
Label: "API User",
Type: "text",
Placeholder: "Enter your Namecheap API username",
Hint: "Your Namecheap account username",
},
{
Name: "api_key",
Label: "API Key",
Type: "password",
Placeholder: "Enter your Namecheap API key",
Hint: "Enable API access in your Namecheap account",
},
}
}
func (p *NamecheapProvider) OptionalCredentialFields() []dnsprovider.CredentialFieldSpec {
return []dnsprovider.CredentialFieldSpec{
{
Name: "client_ip",
Label: "Client IP",
Type: "text",
Placeholder: "1.2.3.4",
Hint: "Optional: Whitelisted IP address for API access",
},
}
}
func (p *NamecheapProvider) ValidateCredentials(creds map[string]string) error {
if creds["api_user"] == "" {
return fmt.Errorf("api_user is required")
}
if creds["api_key"] == "" {
return fmt.Errorf("api_key is required")
}
return nil
}
func (p *NamecheapProvider) TestCredentials(creds map[string]string) error {
return p.ValidateCredentials(creds)
}
func (p *NamecheapProvider) SupportsMultiCredential() bool {
return false
}
func (p *NamecheapProvider) BuildCaddyConfig(creds map[string]string) map[string]any {
config := map[string]any{
"name": "namecheap",
"api_user": creds["api_user"],
"api_key": creds["api_key"],
}
if clientIP := creds["client_ip"]; clientIP != "" {
config["client_ip"] = clientIP
}
return config
}
func (p *NamecheapProvider) BuildCaddyConfigForZone(baseDomain string, creds map[string]string) map[string]any {
return p.BuildCaddyConfig(creds)
}
func (p *NamecheapProvider) PropagationTimeout() time.Duration {
return 300 * time.Second
}
func (p *NamecheapProvider) PollingInterval() time.Duration {
return 15 * time.Second
}