Some checks are pending
Go Benchmark / Performance Regression Check (push) Waiting to run
Cerberus Integration / Cerberus Security Stack Integration (push) Waiting to run
Upload Coverage to Codecov / Backend Codecov Upload (push) Waiting to run
Upload Coverage to Codecov / Frontend Codecov Upload (push) Waiting to run
CodeQL - Analyze / CodeQL analysis (go) (push) Waiting to run
CodeQL - Analyze / CodeQL analysis (javascript-typescript) (push) Waiting to run
CrowdSec Integration / CrowdSec Bouncer Integration (push) Waiting to run
Docker Build, Publish & Test / build-and-push (push) Waiting to run
Docker Build, Publish & Test / Security Scan PR Image (push) Blocked by required conditions
Quality Checks / Auth Route Protection Contract (push) Waiting to run
Quality Checks / Codecov Trigger/Comment Parity Guard (push) Waiting to run
Quality Checks / Backend (Go) (push) Waiting to run
Quality Checks / Frontend (React) (push) Waiting to run
Rate Limit integration / Rate Limiting Integration (push) Waiting to run
Security Scan (PR) / Trivy Binary Scan (push) Waiting to run
Supply Chain Verification (PR) / Verify Supply Chain (push) Waiting to run
WAF integration / Coraza WAF Integration (push) Waiting to run
130 lines
3.0 KiB
Go
Executable File
130 lines
3.0 KiB
Go
Executable File
package dnsprovider
|
|
|
|
import (
|
|
"sort"
|
|
"sync"
|
|
)
|
|
|
|
// Registry is a thread-safe registry of DNS provider plugins.
|
|
type Registry struct {
|
|
providers map[string]ProviderPlugin
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
// globalRegistry is the singleton registry instance.
|
|
var globalRegistry = &Registry{
|
|
providers: make(map[string]ProviderPlugin),
|
|
}
|
|
|
|
// Global returns the global provider registry.
|
|
func Global() *Registry {
|
|
return globalRegistry
|
|
}
|
|
|
|
// NewRegistry creates a new registry instance for testing purposes.
|
|
// Use Global() for production code.
|
|
func NewRegistry() *Registry {
|
|
return &Registry{
|
|
providers: make(map[string]ProviderPlugin),
|
|
}
|
|
}
|
|
|
|
// Register adds a provider to the registry.
|
|
// Returns ErrInvalidPlugin if the provider type is empty,
|
|
// or ErrProviderAlreadyRegistered if the type is already registered.
|
|
func (r *Registry) Register(provider ProviderPlugin) error {
|
|
if provider == nil {
|
|
return ErrInvalidPlugin
|
|
}
|
|
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
providerType := provider.Type()
|
|
if providerType == "" {
|
|
return ErrInvalidPlugin
|
|
}
|
|
|
|
if _, exists := r.providers[providerType]; exists {
|
|
return ErrProviderAlreadyRegistered
|
|
}
|
|
|
|
r.providers[providerType] = provider
|
|
return nil
|
|
}
|
|
|
|
// Get retrieves a provider by type.
|
|
// Returns the provider and true if found, nil and false otherwise.
|
|
func (r *Registry) Get(providerType string) (ProviderPlugin, bool) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
provider, ok := r.providers[providerType]
|
|
return provider, ok
|
|
}
|
|
|
|
// List returns all registered providers.
|
|
// The returned slice is sorted alphabetically by provider type.
|
|
func (r *Registry) List() []ProviderPlugin {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
providers := make([]ProviderPlugin, 0, len(r.providers))
|
|
for _, p := range r.providers {
|
|
providers = append(providers, p)
|
|
}
|
|
|
|
// Sort by type for consistent ordering
|
|
sort.Slice(providers, func(i, j int) bool {
|
|
return providers[i].Type() < providers[j].Type()
|
|
})
|
|
|
|
return providers
|
|
}
|
|
|
|
// Types returns all registered provider type identifiers.
|
|
// The returned slice is sorted alphabetically.
|
|
func (r *Registry) Types() []string {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
types := make([]string, 0, len(r.providers))
|
|
for t := range r.providers {
|
|
types = append(types, t)
|
|
}
|
|
|
|
sort.Strings(types)
|
|
return types
|
|
}
|
|
|
|
// IsSupported checks if a provider type is registered.
|
|
func (r *Registry) IsSupported(providerType string) bool {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
_, ok := r.providers[providerType]
|
|
return ok
|
|
}
|
|
|
|
// Unregister removes a provider from the registry.
|
|
// Used primarily for plugin unloading during shutdown.
|
|
// Safe to call with a type that doesn't exist.
|
|
func (r *Registry) Unregister(providerType string) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
delete(r.providers, providerType)
|
|
}
|
|
|
|
// Count returns the number of registered providers.
|
|
func (r *Registry) Count() int {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
return len(r.providers)
|
|
}
|
|
|
|
// Clear removes all providers from the registry.
|
|
// Primarily used for testing.
|
|
func (r *Registry) Clear() {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
r.providers = make(map[string]ProviderPlugin)
|
|
}
|