set acme record

master
Joshua Herring 1 month ago
parent 4e87b79ccf
commit b85f78146c

@ -0,0 +1,120 @@
package commands
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
type SetAcmeRecordArgs struct {
APIToken string
ZoneID string
RecordName string
RecordValue string
}
type cfDNSRecordRequest struct {
Type string `json:"type"`
Name string `json:"name"`
Content string `json:"content"`
TTL int `json:"ttl"`
}
type cfDNSRecord struct {
ID string `json:"id"`
Name string `json:"name"`
Content string `json:"content"`
}
type cfDNSRecordResponse struct {
Success bool `json:"success"`
Errors []struct {
Message string `json:"message"`
} `json:"errors"`
Result cfDNSRecord `json:"result"`
}
type cfDNSListResponse struct {
Success bool `json:"success"`
Errors []struct {
Message string `json:"message"`
} `json:"errors"`
Result []cfDNSRecord `json:"result"`
}
func cfRequest(method, url, token string, body []byte) (*http.Response, error) {
req, err := http.NewRequest(method, url, bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
return (&http.Client{}).Do(req)
}
func SetAcmeRecord(args SetAcmeRecordArgs, stdout, stderr io.Writer) error {
listURL := fmt.Sprintf("https://api.cloudflare.com/client/v4/zones/%s/dns_records?type=TXT&name=%s", args.ZoneID, args.RecordName)
resp, err := cfRequest("GET", listURL, args.APIToken, nil)
if err != nil {
return fmt.Errorf("error listing DNS records: %w", err)
}
defer resp.Body.Close()
var listResult cfDNSListResponse
if err := json.NewDecoder(resp.Body).Decode(&listResult); err != nil {
return fmt.Errorf("error decoding list response: %w", err)
}
if !listResult.Success {
msg := "Cloudflare API error:"
for _, e := range listResult.Errors {
msg += " " + e.Message
}
return fmt.Errorf("%s", msg)
}
record := cfDNSRecordRequest{
Type: "TXT",
Name: args.RecordName,
Content: args.RecordValue,
TTL: 1,
}
body, err := json.Marshal(record)
if err != nil {
return fmt.Errorf("error marshaling request: %w", err)
}
var method, recordURL, action string
if len(listResult.Result) > 0 {
method = "PUT"
recordURL = fmt.Sprintf("https://api.cloudflare.com/client/v4/zones/%s/dns_records/%s", args.ZoneID, listResult.Result[0].ID)
action = "Updated"
} else {
method = "POST"
recordURL = fmt.Sprintf("https://api.cloudflare.com/client/v4/zones/%s/dns_records", args.ZoneID)
action = "Created"
}
resp2, err := cfRequest(method, recordURL, args.APIToken, body)
if err != nil {
return fmt.Errorf("error calling Cloudflare API: %w", err)
}
defer resp2.Body.Close()
var result cfDNSRecordResponse
if err := json.NewDecoder(resp2.Body).Decode(&result); err != nil {
return fmt.Errorf("error decoding response: %w", err)
}
if !result.Success {
msg := "Cloudflare API error:"
for _, e := range result.Errors {
msg += " " + e.Message
}
return fmt.Errorf("%s", msg)
}
fmt.Fprintf(stdout, "%s TXT record:\n ID: %s\n Name: %s\n Content: %s\n",
action, result.Result.ID, result.Result.Name, result.Result.Content)
return nil
}
Loading…
Cancel
Save