mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-01-11 01:47:53 +08:00
148 lines
3.8 KiB
Go
148 lines
3.8 KiB
Go
package opensrs
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/StackExchange/dnscontrol/v4/models"
|
|
"github.com/StackExchange/dnscontrol/v4/providers"
|
|
opensrs "github.com/philhug/opensrs-go/opensrs"
|
|
)
|
|
|
|
var features = providers.DocumentationNotes{
|
|
// The default for unlisted capabilities is 'Cannot'.
|
|
// See providers/capabilities.go for the entire list of capabilities.
|
|
providers.CanConcur: providers.Cannot(),
|
|
}
|
|
|
|
func init() {
|
|
const providerName = "OPENSRS"
|
|
const providerMaintainer = "@philhug"
|
|
providers.RegisterRegistrarType(providerName, newReg, features)
|
|
providers.RegisterMaintainer(providerName, providerMaintainer)
|
|
}
|
|
|
|
var defaultNameServerNames = []string{
|
|
"ns1.systemdns.com",
|
|
"ns2.systemdns.com",
|
|
"ns3.systemdns.com",
|
|
}
|
|
|
|
// opensrsProvider is the api handle.
|
|
type opensrsProvider struct {
|
|
UserName string // reseller user name
|
|
APIKey string // API Key
|
|
|
|
BaseURL string // An alternate base URI
|
|
client *opensrs.Client // Client
|
|
}
|
|
|
|
// GetNameservers returns a list of nameservers.
|
|
func (c *opensrsProvider) GetNameservers(domainName string) ([]*models.Nameserver, error) {
|
|
return models.ToNameservers(defaultNameServerNames)
|
|
}
|
|
|
|
// GetRegistrarCorrections returns a list of corrections for a registrar.
|
|
func (c *opensrsProvider) GetRegistrarCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
|
|
corrections := []*models.Correction{}
|
|
|
|
nameServers, err := c.getNameservers(dc.Name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
sort.Strings(nameServers)
|
|
actual := strings.Join(nameServers, ",")
|
|
|
|
expectedSet := []string{}
|
|
for _, ns := range dc.Nameservers {
|
|
expectedSet = append(expectedSet, ns.Name)
|
|
}
|
|
sort.Strings(expectedSet)
|
|
expected := strings.Join(expectedSet, ",")
|
|
|
|
if actual != expected {
|
|
return []*models.Correction{
|
|
{
|
|
Msg: fmt.Sprintf("Update nameservers %s -> %s", actual, expected),
|
|
F: c.updateNameserversFunc(expectedSet, dc.Name),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
return corrections, nil
|
|
}
|
|
|
|
// OpenSRS calls
|
|
|
|
func (c *opensrsProvider) getClient() *opensrs.Client {
|
|
return c.client
|
|
}
|
|
|
|
// Returns the name server names that should be used. If the domain is registered
|
|
// then this method will return the delegation name servers. If this domain
|
|
// is hosted only, then it will return the default OpenSRS name servers.
|
|
func (c *opensrsProvider) getNameservers(domainName string) ([]string, error) {
|
|
client := c.getClient()
|
|
|
|
status, err := client.Domains.GetDomain(domainName, "status", 1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if status.Attributes.LockState == "0" {
|
|
dom, err := client.Domains.GetDomain(domainName, "nameservers", 1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return dom.Attributes.NameserverList.ToString(), nil
|
|
}
|
|
return nil, errors.New("domain is locked")
|
|
}
|
|
|
|
// Returns a function that can be invoked to change the delegation of the domain to the given name server names.
|
|
func (c *opensrsProvider) updateNameserversFunc(nameServerNames []string, domainName string) func() error {
|
|
return func() error {
|
|
client := c.getClient()
|
|
|
|
_, err := client.Domains.UpdateDomainNameservers(domainName, nameServerNames)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// constructors
|
|
|
|
func newReg(conf map[string]string) (providers.Registrar, error) {
|
|
return newProvider(conf, nil)
|
|
}
|
|
|
|
func newProvider(m map[string]string, metadata json.RawMessage) (*opensrsProvider, error) {
|
|
api := &opensrsProvider{}
|
|
api.APIKey = m["apikey"]
|
|
|
|
if api.APIKey == "" {
|
|
return nil, errors.New("openSRS apikey must be provided")
|
|
}
|
|
|
|
api.UserName = m["username"]
|
|
if api.UserName == "" {
|
|
return nil, errors.New("openSRS username key must be provided")
|
|
}
|
|
|
|
if m["baseurl"] != "" {
|
|
api.BaseURL = m["baseurl"]
|
|
}
|
|
|
|
api.client = opensrs.NewClient(opensrs.NewApiKeyMD5Credentials(api.UserName, api.APIKey))
|
|
if api.BaseURL != "" {
|
|
api.client.BaseURL = api.BaseURL
|
|
}
|
|
|
|
return api, nil
|
|
}
|