dnscontrol/providers/joker/jokerProvider.go
Alex Trull ca64774004
Joker: Implement DNS Provider (#3661)
Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
2025-08-04 16:37:20 -04:00

91 lines
2.7 KiB
Go

package joker
import (
"encoding/json"
"errors"
"fmt"
"github.com/StackExchange/dnscontrol/v4/providers"
"net/http"
"time"
)
/*
Joker DMAPI provider:
Info required in `creds.json`:
- username
- password
OR
- api-key
*/
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Can(),
providers.CanConcur: providers.Cannot("Joker API has session-based authentication"),
providers.CanUseAlias: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDNSKEY: providers.Cannot(),
providers.CanUseDS: providers.Cannot(),
providers.CanUseDSForChildren: providers.Cannot(),
providers.CanUseHTTPS: providers.Cannot(),
providers.CanUseLOC: providers.Cannot(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Cannot(),
providers.CanUseSOA: providers.Cannot(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Cannot(),
providers.CanUseSVCB: providers.Cannot(),
providers.CanUseTLSA: providers.Cannot(),
providers.DocCreateDomains: providers.Can(),
providers.DocDualHost: providers.Cannot(),
providers.DocOfficiallySupported: providers.Cannot(),
}
func init() {
const providerName = "JOKER"
const providerMaintainer = "@atrull"
fns := providers.DspFuncs{
Initializer: newJoker,
RecordAuditor: AuditRecords,
}
providers.RegisterDomainServiceProviderType(providerName, fns, features)
providers.RegisterMaintainer(providerName, providerMaintainer)
}
// jokerProvider is the handle for API calls.
type jokerProvider struct {
apiURL string
username string
password string
apiKey string
authSID string
httpClient *http.Client
}
// newJoker creates a new Joker DMAPI provider.
func newJoker(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
api := &jokerProvider{
apiURL: "https://dmapi.joker.com/request/",
httpClient: &http.Client{Timeout: 30 * time.Second},
}
// Check for authentication methods
api.username = m["username"]
api.password = m["password"]
api.apiKey = m["api-key"]
if api.apiKey == "" && (api.username == "" || api.password == "") {
return nil, errors.New("missing Joker credentials: either 'api-key' or both 'username' and 'password' required")
}
// Authenticate to get session ID
if err := api.authenticate(); err != nil {
return nil, fmt.Errorf("authentication failed: %w", err)
}
return api, nil
}