fix: gcloud. (#742)

This commit is contained in:
Ludovic Fernandez 2019-01-02 20:45:17 +01:00 committed by GitHub
parent 8d8ec2c92c
commit 9979087572
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 256 additions and 3 deletions

View file

@ -40,6 +40,7 @@
"exported (type|method|function) (.+) should have comment or be unexported", "exported (type|method|function) (.+) should have comment or be unexported",
"possible misuse of unsafe.Pointer", "possible misuse of unsafe.Pointer",
"cyclomatic complexity (.+) of func `NewDNSChallengeProviderByName` is high (.+)", # providers/dns/dns_providers.go "cyclomatic complexity (.+) of func `NewDNSChallengeProviderByName` is high (.+)", # providers/dns/dns_providers.go
"string `(lego\\.wtf|manhattan)` has (\\d+) occurrences, make it a constant", #providers/dns/gcloud/googlecloud_test.go
"`(tlsFeatureExtensionOID|ocspMustStapleFeature)` is a global variable", # certcrypto/crypto.go "`(tlsFeatureExtensionOID|ocspMustStapleFeature)` is a global variable", # certcrypto/crypto.go
"`(defaultNameservers|recursiveNameservers|dnsTimeout|fqdnToZone|muFqdnToZone)` is a global variable", # challenge/dns01/nameserver.go "`(defaultNameservers|recursiveNameservers|dnsTimeout|fqdnToZone|muFqdnToZone)` is a global variable", # challenge/dns01/nameserver.go

View file

@ -21,6 +21,10 @@ import (
"google.golang.org/api/googleapi" "google.golang.org/api/googleapi"
) )
const (
changeStatusDone = "done"
)
// Config is used to configure the creation of the DNSProvider // Config is used to configure the creation of the DNSProvider
type Config struct { type Config struct {
Debug bool Debug bool
@ -174,7 +178,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
for _, rrSet := range existingRrSet { for _, rrSet := range existingRrSet {
for _, rr := range rrSet.Rrdatas { for _, rr := range rrSet.Rrdatas {
if rr != value { if rr != value {
rec.Rrdatas = append(rec.Rrdatas, rrSet.Rrdatas...) rec.Rrdatas = append(rec.Rrdatas, rr)
} }
} }
} }
@ -208,7 +212,7 @@ func (d *DNSProvider) applyChanges(zone string, change *dns.Change) error {
return fmt.Errorf("failed to perform changes [zone %s, change %s]: %v", zone, string(data), err) return fmt.Errorf("failed to perform changes [zone %s, change %s]: %v", zone, string(data), err)
} }
if chg.Status == "done" { if chg.Status == changeStatusDone {
return nil return nil
} }
@ -227,7 +231,7 @@ func (d *DNSProvider) applyChanges(zone string, change *dns.Change) error {
return false, fmt.Errorf("failed to get changes [zone %s, change %s]: %v", zone, string(data), err) return false, fmt.Errorf("failed to get changes [zone %s, change %s]: %v", zone, string(data), err)
} }
if chg.Status == "done" { if chg.Status == changeStatusDone {
return true, nil return true, nil
} }

View file

@ -1,6 +1,11 @@
package gcloud package gcloud
import ( import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"sort"
"testing" "testing"
"time" "time"
@ -114,6 +119,249 @@ func TestNewDNSProviderConfig(t *testing.T) {
} }
} }
func TestPresentNoExistingRR(t *testing.T) {
mux := http.NewServeMux()
// getHostedZone: /manhattan/managedZones?alt=json&dnsName=lego.wtf.
mux.HandleFunc("/manhattan/managedZones", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
mzlrs := &dns.ManagedZonesListResponse{
ManagedZones: []*dns.ManagedZone{
{Name: "test"},
},
}
err := json.NewEncoder(w).Encode(mzlrs)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
// findTxtRecords: /manhattan/managedZones/test/rrsets?alt=json&name=_acme-challenge.lego.wtf.&type=TXT
mux.HandleFunc("/manhattan/managedZones/test/rrsets", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
rrslr := &dns.ResourceRecordSetsListResponse{
Rrsets: []*dns.ResourceRecordSet{},
}
err := json.NewEncoder(w).Encode(rrslr)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
// applyChanges [Create]: /manhattan/managedZones/test/changes?alt=json
mux.HandleFunc("/manhattan/managedZones/test/changes", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
var chgReq dns.Change
if err := json.NewDecoder(r.Body).Decode(&chgReq); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
chgResp := chgReq
chgResp.Status = changeStatusDone
if err := json.NewEncoder(w).Encode(chgResp); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
server := httptest.NewServer(mux)
config := NewDefaultConfig()
config.HTTPClient = &http.Client{}
config.Project = "manhattan"
p, err := NewDNSProviderConfig(config)
require.NoError(t, err)
p.client.BasePath = server.URL
domain := "lego.wtf"
err = p.Present(domain, "", "")
require.NoError(t, err)
}
func TestPresentWithExistingRR(t *testing.T) {
mux := http.NewServeMux()
// getHostedZone: /manhattan/managedZones?alt=json&dnsName=lego.wtf.
mux.HandleFunc("/manhattan/managedZones", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
mzlrs := &dns.ManagedZonesListResponse{
ManagedZones: []*dns.ManagedZone{
{Name: "test"},
},
}
err := json.NewEncoder(w).Encode(mzlrs)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
// findTxtRecords: /manhattan/managedZones/test/rrsets?alt=json&name=_acme-challenge.lego.wtf.&type=TXT
mux.HandleFunc("/manhattan/managedZones/test/rrsets", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
rrslr := &dns.ResourceRecordSetsListResponse{
Rrsets: []*dns.ResourceRecordSet{{
Name: "_acme-challenge.lego.wtf.",
Rrdatas: []string{`"X7DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU"`, `"huji"`},
Ttl: 120,
Type: "TXT",
}},
}
err := json.NewEncoder(w).Encode(rrslr)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
// applyChanges [Create]: /manhattan/managedZones/test/changes?alt=json
mux.HandleFunc("/manhattan/managedZones/test/changes", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
var chgReq dns.Change
if err := json.NewDecoder(r.Body).Decode(&chgReq); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if len(chgReq.Additions) > 0 {
sort.Strings(chgReq.Additions[0].Rrdatas)
}
var prevVal string
for _, addition := range chgReq.Additions {
for _, value := range addition.Rrdatas {
if prevVal == value {
http.Error(w, fmt.Sprintf("The resource %s already exists", value), http.StatusConflict)
return
}
prevVal = value
}
}
chgResp := chgReq
chgResp.Status = changeStatusDone
if err := json.NewEncoder(w).Encode(chgResp); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
server := httptest.NewServer(mux)
config := NewDefaultConfig()
config.HTTPClient = &http.Client{}
config.Project = "manhattan"
p, err := NewDNSProviderConfig(config)
require.NoError(t, err)
p.client.BasePath = server.URL
domain := "lego.wtf"
err = p.Present(domain, "", "")
require.NoError(t, err)
}
func TestPresentSkipExistingRR(t *testing.T) {
mux := http.NewServeMux()
// getHostedZone: /manhattan/managedZones?alt=json&dnsName=lego.wtf.
mux.HandleFunc("/manhattan/managedZones", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
mzlrs := &dns.ManagedZonesListResponse{
ManagedZones: []*dns.ManagedZone{
{Name: "test"},
},
}
err := json.NewEncoder(w).Encode(mzlrs)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
// findTxtRecords: /manhattan/managedZones/test/rrsets?alt=json&name=_acme-challenge.lego.wtf.&type=TXT
mux.HandleFunc("/manhattan/managedZones/test/rrsets", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
rrslr := &dns.ResourceRecordSetsListResponse{
Rrsets: []*dns.ResourceRecordSet{{
Name: "_acme-challenge.lego.wtf.",
Rrdatas: []string{`"47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU"`, `"X7DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU"`, `"huji"`},
Ttl: 120,
Type: "TXT",
}},
}
err := json.NewEncoder(w).Encode(rrslr)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
server := httptest.NewServer(mux)
config := NewDefaultConfig()
config.HTTPClient = &http.Client{}
config.Project = "manhattan"
p, err := NewDNSProviderConfig(config)
require.NoError(t, err)
p.client.BasePath = server.URL
domain := "lego.wtf"
err = p.Present(domain, "", "")
require.NoError(t, err)
}
func TestLivePresent(t *testing.T) { func TestLivePresent(t *testing.T) {
if !envTest.IsLiveTest() { if !envTest.IsLiveTest() {
t.Skip("skipping live test") t.Skip("skipping live test")