-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: rely on record id & lookup queries when missing to more reliab…
…ly update existing records (#3)
- Loading branch information
1 parent
f7c6860
commit c5d0f88
Showing
10 changed files
with
514 additions
and
372 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
_gitignore/ | ||
.env | ||
.vscode/ | ||
.vscode/ | ||
.idea |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
package porkbun | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"github.com/libdns/libdns" | ||
"io" | ||
"log" | ||
"net/http" | ||
"net/url" | ||
"strconv" | ||
"strings" | ||
"time" | ||
) | ||
|
||
const ApiBase = "https://porkbun.com/api/json/v3" | ||
|
||
// LibdnsZoneToPorkbunDomain Strips the trailing dot from a Zone | ||
func LibdnsZoneToPorkbunDomain(zone string) string { | ||
return strings.TrimSuffix(zone, ".") | ||
} | ||
|
||
// CheckCredentials allows verifying credentials work in test scripts | ||
func (p *Provider) CheckCredentials(_ context.Context) (string, error) { | ||
credentialJson, err := json.Marshal(p.getCredentials()) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
response, err := MakeApiRequest("/ping", bytes.NewReader(credentialJson), pkbnPingResponse{}) | ||
|
||
if err != nil { | ||
return "", err | ||
} | ||
|
||
if response.Status != "SUCCESS" { | ||
return "", err | ||
} | ||
|
||
return response.YourIP, nil | ||
} | ||
|
||
func (p *Provider) getCredentials() ApiCredentials { | ||
return ApiCredentials{p.APIKey, p.APISecretKey} | ||
} | ||
|
||
func (p *Provider) getMatchingRecord(r libdns.Record, zone string) ([]libdns.Record, error) { | ||
var recs []libdns.Record | ||
trimmedZone := LibdnsZoneToPorkbunDomain(zone) | ||
|
||
credentialJson, err := json.Marshal(p.getCredentials()) | ||
if err != nil { | ||
return recs, err | ||
} | ||
endpoint := fmt.Sprintf("/dns/retrieveByNameType/%s/%s/%s", trimmedZone, r.Type, r.Name) | ||
response, err := MakeApiRequest(endpoint, bytes.NewReader(credentialJson), pkbnRecordsResponse{}) | ||
|
||
if err != nil { | ||
return recs, err | ||
} | ||
|
||
recs = make([]libdns.Record, 0, len(response.Records)) | ||
for _, rec := range response.Records { | ||
recs = append(recs, rec.toLibdnsRecord(zone)) | ||
} | ||
return recs, nil | ||
} | ||
|
||
// UpdateRecords adds records to the zone. It returns the records that were added. | ||
func (p *Provider) updateRecords(_ context.Context, zone string, records []libdns.Record) ([]libdns.Record, error) { | ||
credentials := p.getCredentials() | ||
trimmedZone := LibdnsZoneToPorkbunDomain(zone) | ||
|
||
var createdRecords []libdns.Record | ||
|
||
for _, record := range records { | ||
if record.TTL/time.Second < 600 { | ||
record.TTL = 600 * time.Second | ||
} | ||
ttlInSeconds := int(record.TTL / time.Second) | ||
trimmedName := libdns.RelativeName(record.Name, zone) | ||
|
||
reqBody := pkbnRecordPayload{&credentials, record.Value, trimmedName, strconv.Itoa(ttlInSeconds), record.Type} | ||
reqJson, err := json.Marshal(reqBody) | ||
if err != nil { | ||
return nil, err | ||
} | ||
response, err := MakeApiRequest(fmt.Sprintf("/dns/edit/%s/%s", trimmedZone, record.ID), bytes.NewReader(reqJson), pkbnResponseStatus{}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if response.Status != "SUCCESS" { | ||
return nil, err | ||
} | ||
createdRecords = append(createdRecords, record) | ||
} | ||
|
||
return createdRecords, nil | ||
} | ||
|
||
func MakeApiRequest[T any](endpoint string, body io.Reader, responseType T) (T, error) { | ||
client := http.Client{} | ||
|
||
fullUrl := ApiBase + endpoint | ||
u, err := url.Parse(fullUrl) | ||
if err != nil { | ||
return responseType, err | ||
} | ||
|
||
req, err := http.NewRequest("POST", u.String(), body) | ||
if err != nil { | ||
return responseType, err | ||
} | ||
resp, err := client.Do(req) | ||
if err != nil { | ||
return responseType, err | ||
} | ||
defer func(Body io.ReadCloser) { | ||
err := Body.Close() | ||
if err != nil { | ||
log.Fatal("Couldn't close body") | ||
} | ||
}(resp.Body) | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
bodyBytes, _ := io.ReadAll(resp.Body) | ||
err = errors.New("Invalid http response status, " + string(bodyBytes)) | ||
return responseType, err | ||
} | ||
|
||
result, err := io.ReadAll(resp.Body) | ||
if err != nil { | ||
return responseType, err | ||
} | ||
|
||
err = json.Unmarshal(result, &responseType) | ||
|
||
if err != nil { | ||
return responseType, err | ||
} | ||
|
||
return responseType, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= | ||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= | ||
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis= | ||
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40= |
Oops, something went wrong.