forked from TrueCloudLab/lego
constellix: improve challenge. (#1115)
This commit is contained in:
parent
c0bc316a5f
commit
b58c9499ca
13 changed files with 261 additions and 91 deletions
|
@ -104,22 +104,26 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
return fmt.Errorf("constellix: could not find zone for domain %q and fqdn %q : %w", domain, fqdn, err)
|
return fmt.Errorf("constellix: could not find zone for domain %q and fqdn %q : %w", domain, fqdn, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
domainID, err := d.client.Domains.GetID(dns01.UnFqdn(authZone))
|
dom, err := d.client.Domains.GetByName(dns01.UnFqdn(authZone))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("constellix: failed to get domain ID: %w", err)
|
return fmt.Errorf("constellix: failed to get domain: %w", err)
|
||||||
}
|
|
||||||
|
|
||||||
records, err := d.client.TxtRecords.GetAll(domainID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("constellix: failed to get TXT records: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recordName := getRecordName(fqdn, authZone)
|
recordName := getRecordName(fqdn, authZone)
|
||||||
|
|
||||||
record := findRecords(records, recordName)
|
records, err := d.client.TxtRecords.Search(dom.ID, internal.Exact, recordName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("constellix: failed to get TXT records: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(records) > 1 {
|
||||||
|
return errors.New("constellix: failed to get TXT records")
|
||||||
|
}
|
||||||
|
|
||||||
// TXT record entry already existing
|
// TXT record entry already existing
|
||||||
if record != nil {
|
if len(records) == 1 {
|
||||||
|
record := records[0]
|
||||||
|
|
||||||
if containsValue(record, value) {
|
if containsValue(record, value) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -130,7 +134,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
RoundRobin: append(record.RoundRobin, internal.RecordValue{Value: fmt.Sprintf(`"%s"`, value)}),
|
RoundRobin: append(record.RoundRobin, internal.RecordValue{Value: fmt.Sprintf(`"%s"`, value)}),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = d.client.TxtRecords.Update(domainID, record.ID, request)
|
_, err = d.client.TxtRecords.Update(dom.ID, record.ID, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("constellix: failed to update TXT records: %w", err)
|
return fmt.Errorf("constellix: failed to update TXT records: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -145,7 +149,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = d.client.TxtRecords.Create(domainID, request)
|
_, err = d.client.TxtRecords.Create(dom.ID, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("constellix: failed to create TXT record %s: %w", fqdn, err)
|
return fmt.Errorf("constellix: failed to create TXT record %s: %w", fqdn, err)
|
||||||
}
|
}
|
||||||
|
@ -162,30 +166,35 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
return fmt.Errorf("constellix: could not find zone for domain %q and fqdn %q : %w", domain, fqdn, err)
|
return fmt.Errorf("constellix: could not find zone for domain %q and fqdn %q : %w", domain, fqdn, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
domainID, err := d.client.Domains.GetID(dns01.UnFqdn(authZone))
|
dom, err := d.client.Domains.GetByName(dns01.UnFqdn(authZone))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("constellix: failed to get domain ID: %w", err)
|
return fmt.Errorf("constellix: failed to get domain: %w", err)
|
||||||
}
|
|
||||||
|
|
||||||
records, err := d.client.TxtRecords.GetAll(domainID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("constellix: failed to get TXT records: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recordName := getRecordName(fqdn, authZone)
|
recordName := getRecordName(fqdn, authZone)
|
||||||
|
|
||||||
record := findRecords(records, recordName)
|
records, err := d.client.TxtRecords.Search(dom.ID, internal.Exact, recordName)
|
||||||
if record == nil {
|
if err != nil {
|
||||||
|
return fmt.Errorf("constellix: failed to get TXT records: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(records) > 1 {
|
||||||
|
return errors.New("constellix: failed to get TXT records")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(records) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record := records[0]
|
||||||
|
|
||||||
if !containsValue(record, value) {
|
if !containsValue(record, value) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// only 1 record value, the whole record must be deleted.
|
// only 1 record value, the whole record must be deleted.
|
||||||
if len(record.Value) == 1 {
|
if len(record.Value) == 1 {
|
||||||
_, err = d.client.TxtRecords.Delete(domainID, record.ID)
|
_, err = d.client.TxtRecords.Delete(dom.ID, record.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("constellix: failed to delete TXT records: %w", err)
|
return fmt.Errorf("constellix: failed to delete TXT records: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -203,7 +212,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = d.client.TxtRecords.Update(domainID, record.ID, request)
|
_, err = d.client.TxtRecords.Update(dom.ID, record.ID, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("constellix: failed to update TXT records: %w", err)
|
return fmt.Errorf("constellix: failed to update TXT records: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -211,17 +220,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func findRecords(records []internal.Record, name string) *internal.Record {
|
func containsValue(record internal.Record, value string) bool {
|
||||||
for _, r := range records {
|
|
||||||
if r.Name == name {
|
|
||||||
return &r
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func containsValue(record *internal.Record, value string) bool {
|
|
||||||
for _, val := range record.Value {
|
for _, val := range record.Value {
|
||||||
if val.Value == fmt.Sprintf(`"%s"`, value) {
|
if val.Value == fmt.Sprintf(`"%s"`, value) {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -96,11 +96,20 @@ func checkResponse(resp *http.Response) error {
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
if err == nil && data != nil {
|
if err == nil && data != nil {
|
||||||
msg := APIError{}
|
msg := &APIError{StatusCode: resp.StatusCode}
|
||||||
if json.Unmarshal(data, &msg) != nil {
|
|
||||||
|
if json.Unmarshal(data, msg) != nil {
|
||||||
return fmt.Errorf("API error: status code: %d: %v", resp.StatusCode, string(data))
|
return fmt.Errorf("API error: status code: %d: %v", resp.StatusCode, string(data))
|
||||||
}
|
}
|
||||||
return msg
|
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case http.StatusNotFound:
|
||||||
|
return &NotFound{APIError: msg}
|
||||||
|
case http.StatusBadRequest:
|
||||||
|
return &BadRequest{APIError: msg}
|
||||||
|
default:
|
||||||
|
return msg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("API error, status code: %d", resp.StatusCode)
|
return fmt.Errorf("API error, status code: %d", resp.StatusCode)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
@ -10,48 +11,8 @@ import (
|
||||||
// DomainService API access to Domain.
|
// DomainService API access to Domain.
|
||||||
type DomainService service
|
type DomainService service
|
||||||
|
|
||||||
// GetID for a domain name.
|
|
||||||
func (s *DomainService) GetID(domainName string) (int64, error) {
|
|
||||||
params := &PaginationParameters{
|
|
||||||
Offset: 0,
|
|
||||||
Max: 100,
|
|
||||||
Sort: "name",
|
|
||||||
Order: "asc",
|
|
||||||
}
|
|
||||||
|
|
||||||
domains, err := s.GetAll(params)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for len(domains) > 0 {
|
|
||||||
for _, domain := range domains {
|
|
||||||
if domain.Name == domainName {
|
|
||||||
return domain.ID, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if params.Max > len(domains) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
params = &PaginationParameters{
|
|
||||||
Offset: params.Max,
|
|
||||||
Max: 100,
|
|
||||||
Sort: "name",
|
|
||||||
Order: "asc",
|
|
||||||
}
|
|
||||||
|
|
||||||
domains, err = s.GetAll(params)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, fmt.Errorf("domain not found: %s", domainName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAll domains.
|
// GetAll domains.
|
||||||
|
// https://api-docs.constellix.com/?version=latest#484c3f21-d724-4ee4-a6fa-ab22c8eb9e9b
|
||||||
func (s *DomainService) GetAll(params *PaginationParameters) ([]Domain, error) {
|
func (s *DomainService) GetAll(params *PaginationParameters) ([]Domain, error) {
|
||||||
endpoint, err := s.client.createEndpoint(defaultVersion, "domains")
|
endpoint, err := s.client.createEndpoint(defaultVersion, "domains")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -79,3 +40,50 @@ func (s *DomainService) GetAll(params *PaginationParameters) ([]Domain, error) {
|
||||||
|
|
||||||
return domains, nil
|
return domains, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetByName Gets domain by name.
|
||||||
|
func (s *DomainService) GetByName(domainName string) (Domain, error) {
|
||||||
|
domains, err := s.Search(Exact, domainName)
|
||||||
|
if err != nil {
|
||||||
|
return Domain{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(domains) == 0 {
|
||||||
|
return Domain{}, fmt.Errorf("domain not found: %s", domainName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(domains) > 1 {
|
||||||
|
return Domain{}, fmt.Errorf("multiple domains found: %v", domains)
|
||||||
|
}
|
||||||
|
|
||||||
|
return domains[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search searches for a domain by name.
|
||||||
|
// https://api-docs.constellix.com/?version=latest#3d7b2679-2209-49f3-b011-b7d24e512008
|
||||||
|
func (s *DomainService) Search(filter searchFilter, value string) ([]Domain, error) {
|
||||||
|
endpoint, err := s.client.createEndpoint(defaultVersion, "domains", "search")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create request endpoint: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
query := req.URL.Query()
|
||||||
|
query.Set(string(filter), value)
|
||||||
|
req.URL.RawQuery = query.Encode()
|
||||||
|
|
||||||
|
var domains []Domain
|
||||||
|
err = s.client.do(req, &domains)
|
||||||
|
if err != nil {
|
||||||
|
var nf *NotFound
|
||||||
|
if !errors.As(err, &nf) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return domains, nil
|
||||||
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ func TestDomainService_GetAll(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open("./fixtures/domains-01.json")
|
file, err := os.Open("./fixtures/domains-GetAll.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -49,23 +49,26 @@ func TestDomainService_GetAll(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
expected := []Domain{
|
expected := []Domain{
|
||||||
{ID: 273302, Name: "lego.wtf", TypeID: 1, Version: 9, Status: "ACTIVE"},
|
{ID: 273301, Name: "aaa.wtf", TypeID: 1, Version: 9, Status: "ACTIVE"},
|
||||||
|
{ID: 273302, Name: "bbb.wtf", TypeID: 1, Version: 9, Status: "ACTIVE"},
|
||||||
|
{ID: 273303, Name: "ccc.wtf", TypeID: 1, Version: 9, Status: "ACTIVE"},
|
||||||
|
{ID: 273304, Name: "ddd.wtf", TypeID: 1, Version: 9, Status: "ACTIVE"},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, expected, data)
|
assert.Equal(t, expected, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDomainService_GetID(t *testing.T) {
|
func TestDomainService_Search(t *testing.T) {
|
||||||
client, handler, tearDown := setupAPIMock()
|
client, handler, tearDown := setupAPIMock()
|
||||||
defer tearDown()
|
defer tearDown()
|
||||||
|
|
||||||
handler.HandleFunc("/v1/domains", func(rw http.ResponseWriter, req *http.Request) {
|
handler.HandleFunc("/v1/domains/search", func(rw http.ResponseWriter, req *http.Request) {
|
||||||
if req.Method != http.MethodGet {
|
if req.Method != http.MethodGet {
|
||||||
http.Error(rw, "invalid method: "+req.Method, http.StatusBadRequest)
|
http.Error(rw, "invalid method: "+req.Method, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open("./fixtures/domains-02.json")
|
file, err := os.Open("./fixtures/domains-Search.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -79,8 +82,12 @@ func TestDomainService_GetID(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
data, err := client.Domains.GetID("ddd.wtf")
|
data, err := client.Domains.Search(Exact, "lego.wtf")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.EqualValues(t, 273304, data)
|
expected := []Domain{
|
||||||
|
{ID: 273302, Name: "lego.wtf", TypeID: 1, Version: 9, Status: "ACTIVE"},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, expected, data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 3557066,
|
||||||
|
"type": "TXT",
|
||||||
|
"recordType": "txt",
|
||||||
|
"name": "test",
|
||||||
|
"recordOption": "roundRobin",
|
||||||
|
"ttl": 300,
|
||||||
|
"gtdRegion": 1,
|
||||||
|
"parentId": 273302,
|
||||||
|
"parent": "domain",
|
||||||
|
"source": "Domain",
|
||||||
|
"modifiedTs": 1580908547865,
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"value": "\"test\""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"roundRobin": [
|
||||||
|
{
|
||||||
|
"value": "\"test\""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,25 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 3557066,
|
||||||
|
"type": "TXT",
|
||||||
|
"recordType": "txt",
|
||||||
|
"name": "test",
|
||||||
|
"recordOption": "roundRobin",
|
||||||
|
"ttl": 300,
|
||||||
|
"gtdRegion": 1,
|
||||||
|
"parentId": 273302,
|
||||||
|
"parent": "domain",
|
||||||
|
"source": "Domain",
|
||||||
|
"modifiedTs": 1580908547865,
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"value": "\"test\""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"roundRobin": [
|
||||||
|
{
|
||||||
|
"value": "\"test\""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -1,16 +1,46 @@
|
||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Search filters
|
||||||
|
const (
|
||||||
|
StartsWith searchFilter = "startswith"
|
||||||
|
Exact searchFilter = "exact"
|
||||||
|
EndsWith searchFilter = "endswith"
|
||||||
|
Contains searchFilter = "contains"
|
||||||
|
)
|
||||||
|
|
||||||
|
type searchFilter string
|
||||||
|
|
||||||
|
// NotFound Not found error.
|
||||||
|
type NotFound struct {
|
||||||
|
*APIError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *NotFound) Unwrap() error {
|
||||||
|
return e.APIError
|
||||||
|
}
|
||||||
|
|
||||||
|
// BadRequest Bad request error.
|
||||||
|
type BadRequest struct {
|
||||||
|
*APIError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BadRequest) Unwrap() error {
|
||||||
|
return e.APIError
|
||||||
|
}
|
||||||
|
|
||||||
// APIError is the representation of an API error.
|
// APIError is the representation of an API error.
|
||||||
type APIError struct {
|
type APIError struct {
|
||||||
Errors []string `json:"errors"`
|
StatusCode int `json:"statusCode"`
|
||||||
|
Errors []string `json:"errors"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a APIError) Error() string {
|
func (a APIError) Error() string {
|
||||||
return strings.Join(a.Errors, ": ")
|
return fmt.Sprintf("%d: %s", a.StatusCode, strings.Join(a.Errors, ": "))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuccessMessage is the representation of a success message.
|
// SuccessMessage is the representation of a success message.
|
||||||
|
|
|
@ -3,6 +3,7 @@ package internal
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -130,3 +131,33 @@ func (s *TxtRecordService) Delete(domainID, recordID int64) (*SuccessMessage, er
|
||||||
|
|
||||||
return msg, nil
|
return msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search searches for a TXT record by name.
|
||||||
|
// https://api-docs.constellix.com/?version=latest#81003e4f-bd3f-413f-a18d-6d9d18f10201
|
||||||
|
func (s *TxtRecordService) Search(domainID int64, filter searchFilter, value string) ([]Record, error) {
|
||||||
|
endpoint, err := s.client.createEndpoint(defaultVersion, "domains", strconv.FormatInt(domainID, 10), "records", "txt", "search")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create request endpoint: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
query := req.URL.Query()
|
||||||
|
query.Set(string(filter), value)
|
||||||
|
req.URL.RawQuery = query.Encode()
|
||||||
|
|
||||||
|
var records []Record
|
||||||
|
|
||||||
|
err = s.client.do(req, &records)
|
||||||
|
if err != nil {
|
||||||
|
var nf *NotFound
|
||||||
|
if !errors.As(err, &nf) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return records, nil
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func TestTxtRecordService_Create(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open("./fixtures/records-01.json")
|
file, err := os.Open("./fixtures/records-Create.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -42,7 +42,7 @@ func TestTxtRecordService_Create(t *testing.T) {
|
||||||
recordsJSON, err := json.Marshal(records)
|
recordsJSON, err := json.Marshal(records)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
expectedContent, err := ioutil.ReadFile("./fixtures/records-01.json")
|
expectedContent, err := ioutil.ReadFile("./fixtures/records-Create.json")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.JSONEq(t, string(expectedContent), string(recordsJSON))
|
assert.JSONEq(t, string(expectedContent), string(recordsJSON))
|
||||||
|
@ -58,7 +58,7 @@ func TestTxtRecordService_GetAll(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open("./fixtures/records-01.json")
|
file, err := os.Open("./fixtures/records-GetAll.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -78,7 +78,7 @@ func TestTxtRecordService_GetAll(t *testing.T) {
|
||||||
recordsJSON, err := json.Marshal(records)
|
recordsJSON, err := json.Marshal(records)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
expectedContent, err := ioutil.ReadFile("./fixtures/records-01.json")
|
expectedContent, err := ioutil.ReadFile("./fixtures/records-GetAll.json")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.JSONEq(t, string(expectedContent), string(recordsJSON))
|
assert.JSONEq(t, string(expectedContent), string(recordsJSON))
|
||||||
|
@ -94,7 +94,7 @@ func TestTxtRecordService_Get(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open("./fixtures/records-02.json")
|
file, err := os.Open("./fixtures/records-Get.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -180,3 +180,39 @@ func TestTxtRecordService_Delete(t *testing.T) {
|
||||||
expected := &SuccessMessage{Success: "Record deleted successfully"}
|
expected := &SuccessMessage{Success: "Record deleted successfully"}
|
||||||
assert.Equal(t, expected, msg)
|
assert.Equal(t, expected, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTxtRecordService_Search(t *testing.T) {
|
||||||
|
client, handler, tearDown := setupAPIMock()
|
||||||
|
defer tearDown()
|
||||||
|
|
||||||
|
handler.HandleFunc("/v1/domains/12345/records/txt/search", func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
if req.Method != http.MethodGet {
|
||||||
|
http.Error(rw, "invalid method: "+req.Method, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open("./fixtures/records-Search.json")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func() { _ = file.Close() }()
|
||||||
|
|
||||||
|
_, err = io.Copy(rw, file)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
records, err := client.TxtRecords.Search(12345, Exact, "test")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
recordsJSON, err := json.Marshal(records)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expectedContent, err := ioutil.ReadFile("./fixtures/records-Search.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.JSONEq(t, string(expectedContent), string(recordsJSON))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue