From e5fb1ffeb7a3ac7d1bf20e9a4bd711678ece7868 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Fri, 25 Jan 2019 10:24:04 +0100 Subject: [PATCH] Updates lego. --- Gopkg.lock | 7 +- Gopkg.toml | 2 +- docs/configuration/acme.md | 3 +- .../resources/compose/consul_catalog.yml | 5 +- vendor/github.com/xenolf/lego/acme/api/api.go | 2 +- .../lego/acme/api/internal/secure/jws.go | 2 +- .../acme/api/internal/sender/useragent.go | 2 +- .../lego/providers/dns/alidns/alidns.go | 2 +- .../lego/providers/dns/auroradns/auroradns.go | 2 +- .../providers/dns/cloudflare/cloudflare.go | 2 +- .../lego/providers/dns/dns_providers.go | 3 + .../lego/providers/dns/dnspod/dnspod.go | 2 +- .../lego/providers/dns/gcloud/googlecloud.go | 4 +- .../lego/providers/dns/namecheap/namecheap.go | 8 +- .../providers/dns/nifcloud/internal/client.go | 2 +- .../lego/providers/dns/zoneee/client.go | 132 +++++++++++++++++ .../lego/providers/dns/zoneee/zoneee.go | 134 ++++++++++++++++++ 17 files changed, 295 insertions(+), 19 deletions(-) create mode 100644 vendor/github.com/xenolf/lego/providers/dns/zoneee/client.go create mode 100644 vendor/github.com/xenolf/lego/providers/dns/zoneee/zoneee.go diff --git a/Gopkg.lock b/Gopkg.lock index c7e02393d..0c328bbdf 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1704,7 +1704,7 @@ revision = "0c8571ac0ce161a5feb57375a9cdf148c98c0f70" [[projects]] - digest = "1:9eab86777ed6cf496e7659b9c67a0b7ebd1d76f55e1771f8bf52fb68f5f2d040" + digest = "1:245afb86e7f760a9ccdfaa4ee052f2af723bdfab5fbeb257fc5d3aebf94a0bd2" name = "github.com/xenolf/lego" packages = [ "acme", @@ -1780,11 +1780,12 @@ "providers/dns/vscale", "providers/dns/vscale/internal", "providers/dns/vultr", + "providers/dns/zoneee", "registration", ] pruneopts = "NUT" - revision = "86c9de3db61436d07de2471508067f18c16c1997" - version = "v2.0.1" + revision = "00ad82dec10ad0af1e037ee652ad1f1cc7015178" + version = "v2.1.0" [[projects]] branch = "master" diff --git a/Gopkg.toml b/Gopkg.toml index a10a7a974..8e59571cf 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -180,7 +180,7 @@ [[constraint]] # branch = "master" name = "github.com/xenolf/lego" - version = "2.0.1" + version = "2.1.0" [[constraint]] name = "google.golang.org/grpc" diff --git a/docs/configuration/acme.md b/docs/configuration/acme.md index c6c93386d..7b53a2f38 100644 --- a/docs/configuration/acme.md +++ b/docs/configuration/acme.md @@ -288,7 +288,7 @@ Here is a list of supported `provider`s, that can automate the DNS verification, | [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | Not tested yet | | [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | Not tested yet | | [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | YES | -| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | No | +| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | YES | | [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | Not tested yet | | External Program | `exec` | `EXEC_PATH` | YES | | [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | YES | @@ -325,6 +325,7 @@ Here is a list of supported `provider`s, that can automate the DNS verification, | [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | Not tested yet | | [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | YES | | [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | Not tested yet | +| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | YES | - (1): more information about the HTTP message format can be found [here](https://github.com/xenolf/lego/blob/master/providers/dns/httpreq/readme.md) - (2): https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application diff --git a/integration/resources/compose/consul_catalog.yml b/integration/resources/compose/consul_catalog.yml index 3fbda0fe2..d9ac867d1 100644 --- a/integration/resources/compose/consul_catalog.yml +++ b/integration/resources/compose/consul_catalog.yml @@ -1,5 +1,8 @@ consul: - image: consul + # use v1.4.0 because https://github.com/hashicorp/consul/issues/5270 + # v1.4.1 cannot be used. + # waiting for v1.4.2 + image: consul:1.4.0 command: agent -server -bootstrap-expect 1 -client 0.0.0.0 -log-level debug -ui ports: - "8400:8400" diff --git a/vendor/github.com/xenolf/lego/acme/api/api.go b/vendor/github.com/xenolf/lego/acme/api/api.go index e14cd993a..14b18f52b 100644 --- a/vendor/github.com/xenolf/lego/acme/api/api.go +++ b/vendor/github.com/xenolf/lego/acme/api/api.go @@ -44,7 +44,7 @@ func New(httpClient *http.Client, userAgent string, caDirURL, kid string, privat jws := secure.NewJWS(privateKey, kid, nonceManager) - c := &Core{doer: doer, nonceManager: nonceManager, jws: jws, directory: dir} + c := &Core{doer: doer, nonceManager: nonceManager, jws: jws, directory: dir, HTTPClient: httpClient} c.common.core = c c.Accounts = (*AccountService)(&c.common) diff --git a/vendor/github.com/xenolf/lego/acme/api/internal/secure/jws.go b/vendor/github.com/xenolf/lego/acme/api/internal/secure/jws.go index 7645b6e99..6f26c4ea8 100644 --- a/vendor/github.com/xenolf/lego/acme/api/internal/secure/jws.go +++ b/vendor/github.com/xenolf/lego/acme/api/internal/secure/jws.go @@ -10,7 +10,7 @@ import ( "fmt" "github.com/xenolf/lego/acme/api/internal/nonces" - "gopkg.in/square/go-jose.v2" + jose "gopkg.in/square/go-jose.v2" ) // JWS Represents a JWS. diff --git a/vendor/github.com/xenolf/lego/acme/api/internal/sender/useragent.go b/vendor/github.com/xenolf/lego/acme/api/internal/sender/useragent.go index 66ab8e281..fa9096990 100644 --- a/vendor/github.com/xenolf/lego/acme/api/internal/sender/useragent.go +++ b/vendor/github.com/xenolf/lego/acme/api/internal/sender/useragent.go @@ -5,7 +5,7 @@ package sender const ( // ourUserAgent is the User-Agent of this underlying library package. - ourUserAgent = "xenolf-acme/2.0.1" + ourUserAgent = "xenolf-acme/2.1.0" // ourUserAgentComment is part of the UA comment linked to the version status of this underlying library package. // values: detach|release diff --git a/vendor/github.com/xenolf/lego/providers/dns/alidns/alidns.go b/vendor/github.com/xenolf/lego/providers/dns/alidns/alidns.go index e7ea22ef0..38efeb78c 100644 --- a/vendor/github.com/xenolf/lego/providers/dns/alidns/alidns.go +++ b/vendor/github.com/xenolf/lego/providers/dns/alidns/alidns.go @@ -150,7 +150,7 @@ func (d *DNSProvider) getHostedZone(domain string) (string, string, error) { domains = append(domains, response.Domains.Domain...) - if response.PageNumber >= response.PageSize { + if response.PageNumber*response.PageSize >= response.TotalCount { break } diff --git a/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go b/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go index 56dff6d0c..3b16b6587 100644 --- a/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go +++ b/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/ldez/go-auroradns" + auroradns "github.com/ldez/go-auroradns" "github.com/xenolf/lego/challenge/dns01" "github.com/xenolf/lego/platform/config/env" ) diff --git a/vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare.go b/vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare.go index c530326a4..97dc53568 100644 --- a/vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare.go +++ b/vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare.go @@ -7,7 +7,7 @@ import ( "net/http" "time" - "github.com/cloudflare/cloudflare-go" + cloudflare "github.com/cloudflare/cloudflare-go" "github.com/xenolf/lego/challenge/dns01" "github.com/xenolf/lego/log" "github.com/xenolf/lego/platform/config/env" diff --git a/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go b/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go index 3b661f658..ea8969b7c 100644 --- a/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go +++ b/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go @@ -54,6 +54,7 @@ import ( "github.com/xenolf/lego/providers/dns/vegadns" "github.com/xenolf/lego/providers/dns/vscale" "github.com/xenolf/lego/providers/dns/vultr" + "github.com/xenolf/lego/providers/dns/zoneee" ) // NewDNSChallengeProviderByName Factory for DNS providers @@ -159,6 +160,8 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) { return vultr.NewDNSProvider() case "vscale": return vscale.NewDNSProvider() + case "zoneee": + return zoneee.NewDNSProvider() default: return nil, fmt.Errorf("unrecognised DNS provider: %s", name) } diff --git a/vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod.go b/vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod.go index fb8afcbdb..06cb566fa 100644 --- a/vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod.go +++ b/vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/decker502/dnspod-go" + dnspod "github.com/decker502/dnspod-go" "github.com/xenolf/lego/challenge/dns01" "github.com/xenolf/lego/platform/config/env" ) diff --git a/vendor/github.com/xenolf/lego/providers/dns/gcloud/googlecloud.go b/vendor/github.com/xenolf/lego/providers/dns/gcloud/googlecloud.go index 3efd4a258..d2cd04f41 100644 --- a/vendor/github.com/xenolf/lego/providers/dns/gcloud/googlecloud.go +++ b/vendor/github.com/xenolf/lego/providers/dns/gcloud/googlecloud.go @@ -61,7 +61,7 @@ func NewDNSProvider() (*DNSProvider, error) { } // Use default credentials. - project := os.Getenv("GCE_PROJECT") + project := env.GetOrDefaultString("GCE_PROJECT", "") return NewDNSProviderCredentials(project) } @@ -98,7 +98,7 @@ func NewDNSProviderServiceAccount(saFile string) (*DNSProvider, error) { // If GCE_PROJECT is non-empty it overrides the project in the service // account file. - project := os.Getenv("GCE_PROJECT") + project := env.GetOrDefaultString("GCE_PROJECT", "") if project == "" { // read project id from service account file var datJSON struct { diff --git a/vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap.go b/vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap.go index 2bcf91989..e4749ab6b 100644 --- a/vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap.go +++ b/vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap.go @@ -180,10 +180,12 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { // Find the challenge TXT record and remove it if found. var found bool - for i, h := range records { + var newRecords []Record + for _, h := range records { if h.Name == ch.key && h.Type == "TXT" { - records = append(records[:i], records[i+1:]...) found = true + } else { + newRecords = append(newRecords, h) } } @@ -191,7 +193,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { return nil } - err = d.setHosts(ch.sld, ch.tld, records) + err = d.setHosts(ch.sld, ch.tld, newRecords) if err != nil { return fmt.Errorf("namecheap: %v", err) } diff --git a/vendor/github.com/xenolf/lego/providers/dns/nifcloud/internal/client.go b/vendor/github.com/xenolf/lego/providers/dns/nifcloud/internal/client.go index 4d229f3b2..a2eb8a763 100644 --- a/vendor/github.com/xenolf/lego/providers/dns/nifcloud/internal/client.go +++ b/vendor/github.com/xenolf/lego/providers/dns/nifcloud/internal/client.go @@ -13,7 +13,7 @@ import ( ) const ( - defaultBaseURL = "https://dns.api.cloud.nifty.com" + defaultBaseURL = "https://dns.api.nifcloud.com" apiVersion = "2012-12-12N2013-12-16" // XMLNs XML NS of Route53 XMLNs = "https://route53.amazonaws.com/doc/2012-12-12/" diff --git a/vendor/github.com/xenolf/lego/providers/dns/zoneee/client.go b/vendor/github.com/xenolf/lego/providers/dns/zoneee/client.go new file mode 100644 index 000000000..b48808b84 --- /dev/null +++ b/vendor/github.com/xenolf/lego/providers/dns/zoneee/client.go @@ -0,0 +1,132 @@ +package zoneee + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "path" +) + +const defaultEndpoint = "https://api.zone.eu/v2/dns/" + +type txtRecord struct { + // Identifier (identificator) + ID string `json:"id,omitempty"` + // Hostname + Name string `json:"name"` + // TXT content value + Destination string `json:"destination"` + // Can this record be deleted + Delete bool `json:"delete,omitempty"` + // Can this record be modified + Modify bool `json:"modify,omitempty"` + // API url to get this entity + ResourceURL string `json:"resource_url,omitempty"` +} + +func (d *DNSProvider) addTxtRecord(domain string, record txtRecord) ([]txtRecord, error) { + reqBody := &bytes.Buffer{} + if err := json.NewEncoder(reqBody).Encode(record); err != nil { + return nil, err + } + + req, err := d.makeRequest(http.MethodPost, path.Join(domain, "txt"), reqBody) + if err != nil { + return nil, err + } + + var resp []txtRecord + if err := d.sendRequest(req, &resp); err != nil { + return nil, err + } + return resp, nil +} + +func (d *DNSProvider) getTxtRecords(domain string) ([]txtRecord, error) { + req, err := d.makeRequest(http.MethodGet, path.Join(domain, "txt"), nil) + if err != nil { + return nil, err + } + + var resp []txtRecord + if err := d.sendRequest(req, &resp); err != nil { + return nil, err + } + return resp, nil +} + +func (d *DNSProvider) removeTxtRecord(domain, id string) error { + req, err := d.makeRequest(http.MethodDelete, path.Join(domain, "txt", id), nil) + if err != nil { + return err + } + + return d.sendRequest(req, nil) +} + +func (d *DNSProvider) makeRequest(method, resource string, body io.Reader) (*http.Request, error) { + uri, err := d.config.Endpoint.Parse(resource) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(method, uri.String(), body) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + req.SetBasicAuth(d.config.Username, d.config.APIKey) + + return req, nil +} + +func (d *DNSProvider) sendRequest(req *http.Request, result interface{}) error { + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return err + } + + if err = checkResponse(resp); err != nil { + return err + } + + defer resp.Body.Close() + + if result == nil { + return nil + } + + raw, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + err = json.Unmarshal(raw, result) + if err != nil { + return fmt.Errorf("unmarshaling %T error [status code=%d]: %v: %s", result, resp.StatusCode, err, string(raw)) + } + return err +} + +func checkResponse(resp *http.Response) error { + if resp.StatusCode < http.StatusBadRequest { + return nil + } + + if resp.Body == nil { + return fmt.Errorf("response body is nil, status code=%d", resp.StatusCode) + } + + defer resp.Body.Close() + + raw, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("unable to read body: status code=%d, error=%v", resp.StatusCode, err) + } + + return fmt.Errorf("status code=%d: %s", resp.StatusCode, string(raw)) +} diff --git a/vendor/github.com/xenolf/lego/providers/dns/zoneee/zoneee.go b/vendor/github.com/xenolf/lego/providers/dns/zoneee/zoneee.go new file mode 100644 index 000000000..0b136e303 --- /dev/null +++ b/vendor/github.com/xenolf/lego/providers/dns/zoneee/zoneee.go @@ -0,0 +1,134 @@ +// Package zoneee implements a DNS provider for solving the DNS-01 challenge through zone.ee. +package zoneee + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "time" + + "github.com/xenolf/lego/challenge/dns01" + "github.com/xenolf/lego/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Endpoint *url.URL + Username string + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + endpoint, _ := url.Parse(defaultEndpoint) + + return &Config{ + Endpoint: endpoint, + // zone.ee can take up to 5min to propagate according to the support + PropagationTimeout: env.GetOrDefaultSecond("ZONEEE_PROPAGATION_TIMEOUT", 5*time.Minute), + PollingInterval: env.GetOrDefaultSecond("ZONEEE_POLLING_INTERVAL", 5*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("ZONEEE_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider describes a provider for acme-proxy +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a DNSProvider instance. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("ZONEEE_API_USER", "ZONEEE_API_KEY") + if err != nil { + return nil, fmt.Errorf("zoneee: %v", err) + } + + rawEndpoint := env.GetOrDefaultString("ZONEEE_ENDPOINT", defaultEndpoint) + endpoint, err := url.Parse(rawEndpoint) + if err != nil { + return nil, fmt.Errorf("zoneee: %v", err) + } + + config := NewDefaultConfig() + config.Username = values["ZONEEE_API_USER"] + config.APIKey = values["ZONEEE_API_KEY"] + config.Endpoint = endpoint + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider . +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("zoneee: the configuration of the DNS provider is nil") + } + + if config.Username == "" { + return nil, fmt.Errorf("zoneee: credentials missing: username") + } + + if config.APIKey == "" { + return nil, fmt.Errorf("zoneee: credentials missing: API key") + } + + if config.Endpoint == nil { + return nil, errors.New("zoneee: the endpoint is missing") + } + + return &DNSProvider{config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + record := txtRecord{ + Name: fqdn[:len(fqdn)-1], + Destination: value, + } + + _, err := d.addTxtRecord(domain, record) + if err != nil { + return fmt.Errorf("zoneee: %v", err) + } + return nil +} + +// CleanUp removes the TXT record previously created +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + _, value := dns01.GetRecord(domain, keyAuth) + + records, err := d.getTxtRecords(domain) + if err != nil { + return fmt.Errorf("zoneee: %v", err) + } + + var id string + for _, record := range records { + if record.Destination == value { + id = record.ID + } + } + + if id == "" { + return fmt.Errorf("zoneee: txt record does not exist for %v", value) + } + + if err = d.removeTxtRecord(domain, id); err != nil { + return fmt.Errorf("zoneee: %v", err) + } + + return nil +}