2020-04-18 01:58:44 +08:00
|
|
|
package netcup
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2022-08-15 00:50:15 +08:00
|
|
|
"io"
|
2020-04-18 01:58:44 +08:00
|
|
|
"net/http"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
endpoint = "https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON"
|
|
|
|
)
|
|
|
|
|
2020-10-26 21:25:30 +08:00
|
|
|
type netcupProvider struct {
|
2020-04-18 01:58:44 +08:00
|
|
|
domainIndex map[string]string
|
|
|
|
nameserversNames []string
|
|
|
|
credentials struct {
|
|
|
|
apikey string
|
|
|
|
customernumber string
|
2020-06-18 21:37:57 +08:00
|
|
|
sessionID string
|
2020-04-18 01:58:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-26 21:25:30 +08:00
|
|
|
func (api *netcupProvider) createRecord(domain string, rec *record) error {
|
2020-04-18 01:58:44 +08:00
|
|
|
rec.Delete = false
|
|
|
|
data := paramUpdateRecords{
|
|
|
|
Key: api.credentials.apikey,
|
2020-06-18 21:37:57 +08:00
|
|
|
SessionID: api.credentials.sessionID,
|
2020-04-18 01:58:44 +08:00
|
|
|
CustomerNumber: api.credentials.customernumber,
|
|
|
|
DomainName: domain,
|
|
|
|
RecordSet: records{Records: []record{
|
|
|
|
*rec,
|
|
|
|
}},
|
|
|
|
}
|
|
|
|
_, err := api.get("updateDnsRecords", data)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error while trying to create a record: %s", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-26 21:25:30 +08:00
|
|
|
func (api *netcupProvider) deleteRecord(domain string, rec *record) error {
|
2020-04-18 01:58:44 +08:00
|
|
|
rec.Delete = true
|
|
|
|
data := paramUpdateRecords{
|
|
|
|
Key: api.credentials.apikey,
|
2020-06-18 21:37:57 +08:00
|
|
|
SessionID: api.credentials.sessionID,
|
2020-04-18 01:58:44 +08:00
|
|
|
CustomerNumber: api.credentials.customernumber,
|
|
|
|
DomainName: domain,
|
|
|
|
RecordSet: records{Records: []record{
|
|
|
|
*rec,
|
|
|
|
}},
|
|
|
|
}
|
|
|
|
_, err := api.get("updateDnsRecords", data)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error while trying to delete a record: %s", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-26 21:25:30 +08:00
|
|
|
func (api *netcupProvider) modifyRecord(domain string, rec *record) error {
|
2020-04-18 01:58:44 +08:00
|
|
|
rec.Delete = false
|
|
|
|
data := paramUpdateRecords{
|
|
|
|
Key: api.credentials.apikey,
|
2020-06-18 21:37:57 +08:00
|
|
|
SessionID: api.credentials.sessionID,
|
2020-04-18 01:58:44 +08:00
|
|
|
CustomerNumber: api.credentials.customernumber,
|
|
|
|
DomainName: domain,
|
|
|
|
RecordSet: records{Records: []record{
|
|
|
|
*rec,
|
|
|
|
}},
|
|
|
|
}
|
|
|
|
_, err := api.get("updateDnsRecords", data)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error while trying to modify a record: %s", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-26 21:25:30 +08:00
|
|
|
func (api *netcupProvider) getRecords(domain string) ([]record, error) {
|
2020-04-18 01:58:44 +08:00
|
|
|
data := paramGetRecords{
|
|
|
|
Key: api.credentials.apikey,
|
2020-06-18 21:37:57 +08:00
|
|
|
SessionID: api.credentials.sessionID,
|
2020-04-18 01:58:44 +08:00
|
|
|
CustomerNumber: api.credentials.customernumber,
|
|
|
|
DomainName: domain,
|
|
|
|
}
|
2020-06-18 21:37:57 +08:00
|
|
|
rawJSON, err := api.get("infoDnsRecords", data)
|
2020-04-18 01:58:44 +08:00
|
|
|
if err != nil {
|
2020-08-31 07:52:37 +08:00
|
|
|
return nil, fmt.Errorf("failed while trying to login (netcup): %s", err)
|
2020-04-18 01:58:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
resp := &records{}
|
2020-06-18 21:37:57 +08:00
|
|
|
json.Unmarshal(rawJSON, &resp)
|
2020-04-18 01:58:44 +08:00
|
|
|
return resp.Records, nil
|
|
|
|
}
|
|
|
|
|
2020-10-26 21:25:30 +08:00
|
|
|
func (api *netcupProvider) login(apikey, password, customernumber string) error {
|
2020-04-18 01:58:44 +08:00
|
|
|
data := paramLogin{
|
|
|
|
Key: apikey,
|
|
|
|
Password: password,
|
|
|
|
CustomerNumber: customernumber,
|
|
|
|
}
|
2020-06-18 21:37:57 +08:00
|
|
|
rawJSON, err := api.get("login", data)
|
2020-04-18 01:58:44 +08:00
|
|
|
if err != nil {
|
2020-08-31 07:52:37 +08:00
|
|
|
return fmt.Errorf("failed while trying to login to (netcup): %s", err)
|
2020-04-18 01:58:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
resp := &responseLogin{}
|
2020-06-18 21:37:57 +08:00
|
|
|
json.Unmarshal(rawJSON, &resp)
|
2020-04-18 01:58:44 +08:00
|
|
|
api.credentials.apikey = apikey
|
|
|
|
api.credentials.customernumber = customernumber
|
2020-06-18 21:37:57 +08:00
|
|
|
api.credentials.sessionID = resp.SessionID
|
2020-04-18 01:58:44 +08:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-26 21:25:30 +08:00
|
|
|
func (api *netcupProvider) logout() error {
|
2020-04-18 01:58:44 +08:00
|
|
|
data := paramLogout{
|
|
|
|
Key: api.credentials.apikey,
|
2020-06-18 21:37:57 +08:00
|
|
|
SessionID: api.credentials.sessionID,
|
2020-04-18 01:58:44 +08:00
|
|
|
CustomerNumber: api.credentials.customernumber,
|
|
|
|
}
|
|
|
|
_, err := api.get("logout", data)
|
|
|
|
if err != nil {
|
2020-08-31 07:52:37 +08:00
|
|
|
return fmt.Errorf("failed to logout from netcup: %s", err)
|
2020-04-18 01:58:44 +08:00
|
|
|
}
|
2020-06-18 21:37:57 +08:00
|
|
|
api.credentials.apikey, api.credentials.sessionID, api.credentials.customernumber = "", "", ""
|
2020-04-18 01:58:44 +08:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-26 21:25:30 +08:00
|
|
|
func (api *netcupProvider) get(action string, params interface{}) (json.RawMessage, error) {
|
2020-04-18 01:58:44 +08:00
|
|
|
reqParam := request{
|
|
|
|
Action: action,
|
|
|
|
Param: params,
|
|
|
|
}
|
2020-06-18 21:37:57 +08:00
|
|
|
reqJSON, _ := json.Marshal(reqParam)
|
2020-04-18 01:58:44 +08:00
|
|
|
|
|
|
|
client := &http.Client{}
|
2020-06-18 21:37:57 +08:00
|
|
|
req, _ := http.NewRequest("POST", endpoint, bytes.NewBuffer(reqJSON))
|
2020-04-18 01:58:44 +08:00
|
|
|
resp, err := client.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-08-15 00:50:15 +08:00
|
|
|
bodyString, _ := io.ReadAll(resp.Body)
|
2020-04-18 01:58:44 +08:00
|
|
|
|
|
|
|
respData := &response{}
|
|
|
|
err = json.Unmarshal(bodyString, &respData)
|
2020-07-07 08:18:24 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-04-18 01:58:44 +08:00
|
|
|
|
|
|
|
// Yeah, netcup implemented an empty recordset as an error - don't ask.
|
|
|
|
if action == "infoDnsRecords" && respData.StatusCode == 5029 {
|
|
|
|
emptyRecords, _ := json.Marshal(records{})
|
|
|
|
return emptyRecords, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check for any errors and log them
|
|
|
|
if respData.StatusCode != 2000 && (action == "") {
|
2020-06-18 21:37:57 +08:00
|
|
|
return nil, fmt.Errorf("netcup API error: %v\n%v", reqParam, respData)
|
2020-04-18 01:58:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return respData.Data, nil
|
|
|
|
}
|