diff --git a/OWNERS b/OWNERS index 7a9af02a0..a3c5139fc 100644 --- a/OWNERS +++ b/OWNERS @@ -5,7 +5,7 @@ providers/bind @tlimoncelli providers/cloudns @pragmaton providers/digitalocean @Deraen providers/dnsimple @aeden -providers/gandi @TomOnTime +providers/gandi_v5 @TomOnTime # providers/gcloud providers/hexonet @papakai providers/internetbs @pragmaton diff --git a/build/azure-pipelines/integration.yml b/build/azure-pipelines/integration.yml index 6f3327b15..afeb6361f 100644 --- a/build/azure-pipelines/integration.yml +++ b/build/azure-pipelines/integration.yml @@ -62,14 +62,14 @@ jobs: DO_DOMAIN: $(DO_DOMAIN) DO_TOKEN: $(DO_TOKEN) -- job: Gandi +- job: GandiV5 steps: - template: go-env.yaml - - script: go test -v -verbose -provider GANDI + - script: go test -v -verbose -provider GANDI_V5 workingDirectory: $(wd) env: - GANDI_KEY: $(GANDI_KEY) - GANDI_DOMAIN: $(GANDI_DOMAIN) + GANDI_KEY: $(GANDI_V5_APIKEY) + GANDI_DOMAIN: $(GANDI_V5_DOMAIN) # - job: GandiLive # steps: diff --git a/docs/_includes/matrix.html b/docs/_includes/matrix.html index 5fde8ddfc..3b67bae3e 100644 --- a/docs/_includes/matrix.html +++ b/docs/_includes/matrix.html @@ -14,8 +14,6 @@
DIGITALOCEAN
DNSIMPLE
EXOSCALE
-
GANDI
-
GANDI-LIVEDNS
GANDI_V5
GCLOUD
HEXONET
diff --git a/docs/_providers/gandi.md b/docs/_providers/gandi.md deleted file mode 100644 index 786a62176..000000000 --- a/docs/_providers/gandi.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -name: Gandi -title: Gandi Provider -layout: default -jsId: GANDI ---- -# Gandi Provider - -There are two providers for Gandi: - - 1. `GANDI` uses the v3 API and is able to act as a registrar provider - and a DNS provider. It is not able to handle domains that have - migrated to the new LiveDNS API. You need to get the API key from - the [v4 interface][]. - - 2. `GANDI-LIVEDNS` uses the LiveDNS API and is only able to act as a - DNS provider. You need to get the API key from the [v5 interface][]. - -[v4 interface]: https://v4.gandi.net -[v5 interface]: https://v5.gandi.net - -## Configuration -In your credentials file you must provide your Gandi.net API key: - -{% highlight json %} -{ - "gandi": { - "apikey": "your-gandi-key" - } -} -{% endhighlight %} - -## Metadata -This provider does not recognize any special metadata fields unique to Gandi. - -## Usage -Example Javascript: - -{% highlight js %} -var GANDI = NewDnsProvider("gandi", "GANDI"); -var REG_GANDI = NewRegistrar("gandi", "GANDI"); - -D("example.tld", REG_GANDI, DnsProvider(GANDI), - A("test","1.2.3.4") -); -{% endhighlight %} - -## New domains -If a domain does not exist in your Gandi account, DNSControl will *not* automatically add it with the `create-domains` command. You'll need to do that via the control panel manually. - - -## Common errors - -This is the error we see when someone uses GANDI instead of GANDI-LIVEDNS. - -``` -Error getting corrections: error: "Error on object : OBJECT_ZONE (CAUSE_NOTFOUND) [no such zone (id: 0)]" code: 581042 -``` diff --git a/docs/_providers/gandi_v5.md b/docs/_providers/gandi_v5.md index 1418453d0..3f1f7a183 100644 --- a/docs/_providers/gandi_v5.md +++ b/docs/_providers/gandi_v5.md @@ -2,7 +2,7 @@ name: Gandi_v5 title: Gandi_v5 Provider layout: default -jsId: GANDI +jsId: GANDI_V5 --- # Gandi_v5 Provider diff --git a/docs/getting-started.md b/docs/getting-started.md index 558582005..b77a9cb5f 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -125,9 +125,9 @@ jq: jq < creds.json -FYI: `creds.json` fields can be an environment variable. The field must begin with a `$` followed by the variable name. No other text. For example: +FYI: `creds.json` fields can be read from an environment variable. The field must begin with a `$` followed by the variable name. No other text. For example: - "apiuser": "$GANDI_APIUSER", + "apikey": "$GANDI_V5_APIKEY", ## 5. Test the sample files. diff --git a/docs/provider-list.md b/docs/provider-list.md index e57324fc0..dc687ee98 100644 --- a/docs/provider-list.md +++ b/docs/provider-list.md @@ -76,8 +76,6 @@ Maintainers of contributed providers: * `DNSIMPLE` @aeden * `EXOSCALE` @pierre-emmanuelJ * `GANDI_V5` @TomOnTime -* `GANDI-LIVEDNS` (going away in 3.0) -* `GANDI` (going away in 3.0) * `HEXONET` @papakai * `INTERNETBS` @pragmaton * `LINODE` @koesie10 diff --git a/go.mod b/go.mod index 50cf519a6..5ef401d1b 100644 --- a/go.mod +++ b/go.mod @@ -25,20 +25,17 @@ require ( github.com/google/go-cmp v0.4.0 // indirect github.com/google/go-github v17.0.0+incompatible github.com/google/go-querystring v1.0.1-0.20190318165438-c8c88dbee036 // indirect - github.com/google/uuid v1.1.2-0.20190416172445-c2e93f3ae59f github.com/gopherjs/jquery v0.0.0-20191017083323-73f4c7416038 github.com/hashicorp/vault/api v1.0.4 github.com/hexonet/go-sdk v2.2.3+incompatible github.com/jarcoal/httpmock v1.0.4 // indirect github.com/jmespath/go-jmespath v0.0.0-20200310193758-2437e8417af5 // indirect - github.com/kolo/xmlrpc v0.0.0-20150413191830-0826b98aaa29 // indirect github.com/malexdev/utfutil v0.0.0-20180510171754-00c8d4a8e7a8 // indirect github.com/miekg/dns v1.1.27 github.com/mjibson/esc v0.2.0 github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d - github.com/prasmussen/gandi-api v0.0.0-20180224132202-58d3d4205661 github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff github.com/sergi/go-diff v1.1.0 // indirect diff --git a/go.sum b/go.sum index 5fba9f10c..654f72064 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,6 @@ github.com/google/go-querystring v1.0.1-0.20190318165438-c8c88dbee036/go.mod h1: github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/uuid v1.1.2-0.20190416172445-c2e93f3ae59f h1:XXzyYlFbxK3kWfcmu3Wc+Tv8/QQl/VqwsWuSYF1Rj0s= -github.com/google/uuid v1.1.2-0.20190416172445-c2e93f3ae59f/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -166,8 +164,6 @@ github.com/jmespath/go-jmespath v0.0.0-20200310193758-2437e8417af5/go.mod h1:9Qt github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/kolo/xmlrpc v0.0.0-20150413191830-0826b98aaa29 h1:A9Cxbd2chMbJwYR6WpWelyovi0v8Pv4xTUc64pO1gxE= -github.com/kolo/xmlrpc v0.0.0-20150413191830-0826b98aaa29/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -206,8 +202,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prasmussen/gandi-api v0.0.0-20180224132202-58d3d4205661 h1:Frjzb2MZatv22HHLQ6BVv2rFBnYxITOk/tePom2DY0o= -github.com/prasmussen/gandi-api v0.0.0-20180224132202-58d3d4205661/go.mod h1:zZBfqqLFWgViJUcsGfFksd9RK9pDUVPkYDiWE/uIHy4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOekn6B5G/+GMtks9UKbvRU/CMM/o= github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= diff --git a/integrationTest/integration_test.go b/integrationTest/integration_test.go index dfa7637c1..f921e6af1 100644 --- a/integrationTest/integration_test.go +++ b/integrationTest/integration_test.go @@ -139,7 +139,7 @@ func testPermitted(t *testing.T, p string, f TestGroup) error { func makeChanges(t *testing.T, prv providers.DNSServiceProvider, dc *models.DomainConfig, tst *TestCase, desc string, expectChanges bool, origConfig map[string]string) bool { domainName := dc.Name - return t.Run(desc, func(t *testing.T) { + return t.Run(desc+":"+tst.Desc, func(t *testing.T) { dom, _ := dc.Copy() for _, r := range tst.Records { rc := models.RecordConfig(*r) @@ -631,12 +631,18 @@ func makeTests(t *testing.T) []*TestGroup { tc("Change a TXT", txt("foo", "changed")), clear(), tc("Create a TXT with spaces", txt("foo", "with spaces")), - tc("Change a TXT with spaces", txt("foo", "with whitespace ")), tc("Create 1 TXT as array", txtmulti("foo", []string{"simple"})), clear(), tc("Create a 255-byte TXT", txt("foo", strings.Repeat("A", 255))), ), + testgroup("ws TXT", + not("CLOUDFLAREAPI", "NAMEDOTCOM"), + // These providers strip whitespace at the end of TXT records. + // TODO(tal): Add a check for this in normalize/validate.go + tc("Change a TXT with ws at end", txt("foo", "with space at end ")), + ), + testgroup("empty TXT", not("DNSIMPLE", "CLOUDFLAREAPI"), tc("TXT with empty str", txt("foo1", "")), // https://github.com/StackExchange/dnscontrol/issues/598 @@ -676,10 +682,10 @@ func makeTests(t *testing.T) []*TestGroup { testgroup("page size", // Tests the paging code of providers. Many providers page at 100. // Notes: - // - gandi: page size is 100, therefore we test with 99, 100, and 101 - // - ns1: free acct only allows 50 records, therefore we skip - // - digitalocean: fails due to rate limiting, not page limits. - not("NS1"), + // - Gandi: page size is 100, therefore we test with 99, 100, and 101 + // - NS1: free acct only allows 50 records, therefore we skip + // - DigitalOcean: fails due to rate limiting, not page limits. + not("NS1", "DIGITALOCEAN"), tc("99 records", manyA("rec%04d", "1.2.3.4", 99)...), tc("100 records", manyA("rec%04d", "1.2.3.4", 100)...), tc("101 records", manyA("rec%04d", "1.2.3.4", 101)...), @@ -745,7 +751,7 @@ func makeTests(t *testing.T) []*TestGroup { tc("Change Weight", srv("_sip._tcp", 52, 62, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")), tc("Change Port", srv("_sip._tcp", 52, 62, 72, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")), ), - testgroup("SRV w/ null target", not("NAMEDOTCOM", "HEXONET", "EXOSCALE"), + testgroup("SRV w/ null target", not("EXOSCALE", "HEXONET", "NAMEDOTCOM"), tc("Null Target", srv("_sip._tcp", 52, 62, 72, "foo.com."), srv("_sip._tcp", 15, 65, 75, ".")), ), diff --git a/integrationTest/providers.json b/integrationTest/providers.json index 906f42738..e223c213a 100644 --- a/integrationTest/providers.json +++ b/integrationTest/providers.json @@ -33,7 +33,6 @@ "token": "$DO_TOKEN" }, "DNSIMPLE": { - "COMMENT": "20-22: no ns records managable. Not even for subdomains.", "baseurl": "https://api.sandbox.dnsimple.com", "domain": "$DNSIMPLE_DOMAIN", "token": "$DNSIMPLE_TOKEN" @@ -44,16 +43,6 @@ "domain": "$EXOSCALE_DOMAIN", "secretkey": "$EXOSCALE_SECRET_KEY" }, - "GANDI": { - "COMMENT": "5: gandi does not accept TTLs less than 300", - "apikey": "$GANDI_KEY", - "domain": "$GANDI_DOMAIN" - }, - "GANDI-LIVEDNS": { - "COMMENT": "5: gandi does not accept TTLs less than 300", - "apikey": "$GANDILIVE_KEY", - "domain": "$GANDILIVE_DOMAIN" - }, "GANDI_V5": { "apikey": "$GANDI_V5_APIKEY", "domain": "$GANDI_V5_DOMAIN" @@ -74,7 +63,6 @@ "ipaddress": "$HEXONET_IP" }, "LINODE": { - "COMMENT": "25: Linode's hostname validation does not allow the target domain TLD", "domain": "$LINODE_DOMAIN", "token": "$LINODE_TOKEN" }, @@ -109,7 +97,6 @@ "domain": "$R53_DOMAIN" }, "SOFTLAYER": { - "COMMENT": "22-25 softlayer fails at direct internationalization, puncode works though", "api_key": "$SL_API_KEY", "domain": "$SL_DOMAIN", "username": "$SL_USERNAME" diff --git a/integrationTest/test-numbers.txt b/integrationTest/test-numbers.txt new file mode 100644 index 000000000..e33a1f5b1 --- /dev/null +++ b/integrationTest/test-numbers.txt @@ -0,0 +1,112 @@ + --- PASS: TestDNSProviders/example.com/0:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/1:_Create_an_A_record (0.00s) + --- PASS: TestDNSProviders/example.com/2:_Change_it (0.00s) + --- PASS: TestDNSProviders/example.com/3:_Add_another (0.00s) + --- PASS: TestDNSProviders/example.com/4:_Add_another(same_name) (0.00s) + --- PASS: TestDNSProviders/example.com/5:_Change_a_ttl (0.00s) + --- PASS: TestDNSProviders/example.com/6:_Change_single_target_from_set (0.00s) + --- PASS: TestDNSProviders/example.com/7:_Change_all_ttls (0.00s) + --- PASS: TestDNSProviders/example.com/8:_Delete_one (0.00s) + --- PASS: TestDNSProviders/example.com/9:_Add_back_and_change_ttl (0.00s) + --- PASS: TestDNSProviders/example.com/10:_Change_targets_and_ttls (0.00s) + --- PASS: TestDNSProviders/example.com/11:_Create_wildcard (0.00s) + --- PASS: TestDNSProviders/example.com/12:_Delete_wildcard (0.00s) + --- PASS: TestDNSProviders/example.com/13:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/14:_Create_a_CNAME (0.00s) + --- PASS: TestDNSProviders/example.com/15:_Change_it (0.00s) + --- PASS: TestDNSProviders/example.com/16:_Change_to_A_record (0.00s) + --- PASS: TestDNSProviders/example.com/17:_Change_back_to_CNAME (0.00s) + --- PASS: TestDNSProviders/example.com/18:_Record_pointing_to_@ (0.00s) + --- PASS: TestDNSProviders/example.com/19:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/20:_NS_for_subdomain (0.00s) + --- PASS: TestDNSProviders/example.com/21:_Dual_NS_for_subdomain (0.00s) + --- PASS: TestDNSProviders/example.com/22:_NS_Record_pointing_to_@ (0.00s) + --- PASS: TestDNSProviders/example.com/23:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/24:_Internationalized_name (0.00s) + --- PASS: TestDNSProviders/example.com/25:_Change_IDN (0.00s) + --- PASS: TestDNSProviders/example.com/26:_Internationalized_CNAME_Target (0.00s) + --- PASS: TestDNSProviders/example.com/27:_IDN_CNAME_AND_Target (0.00s) + --- PASS: TestDNSProviders/example.com/28:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/29:_MX_record (0.00s) + --- PASS: TestDNSProviders/example.com/30:_Second_MX_record,_same_prio (0.00s) + --- PASS: TestDNSProviders/example.com/31:_3_MX (0.00s) + --- PASS: TestDNSProviders/example.com/32:_Delete_one (0.00s) + --- PASS: TestDNSProviders/example.com/33:_Change_to_other_name (0.00s) + --- PASS: TestDNSProviders/example.com/34:_Change_Preference (0.00s) + --- PASS: TestDNSProviders/example.com/35:_Record_pointing_to_@ (0.00s) + --- PASS: TestDNSProviders/example.com/36:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/37:_Create_PTR_record (0.00s) + --- PASS: TestDNSProviders/example.com/38:_Modify_PTR_record (0.00s) + --- PASS: TestDNSProviders/example.com/39:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/40:_NAPTR_record (0.00s) + --- PASS: TestDNSProviders/example.com/41:_NAPTR_second_record (0.00s) + --- PASS: TestDNSProviders/example.com/42:_NAPTR_delete_record (0.00s) + --- PASS: TestDNSProviders/example.com/43:_NAPTR_change_target (0.00s) + --- PASS: TestDNSProviders/example.com/44:_NAPTR_change_order (0.00s) + --- PASS: TestDNSProviders/example.com/45:_NAPTR_change_preference (0.00s) + --- PASS: TestDNSProviders/example.com/46:_NAPTR_change_flags (0.00s) + --- PASS: TestDNSProviders/example.com/47:_NAPTR_change_service (0.00s) + --- PASS: TestDNSProviders/example.com/48:_NAPTR_change_regexp (0.00s) + --- PASS: TestDNSProviders/example.com/49:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/50:_SRV_record (0.00s) + --- PASS: TestDNSProviders/example.com/51:_Second_SRV_record,_same_prio (0.00s) + --- PASS: TestDNSProviders/example.com/52:_3_SRV (0.00s) + --- PASS: TestDNSProviders/example.com/53:_Delete_one (0.00s) + --- PASS: TestDNSProviders/example.com/54:_Change_Target (0.00s) + --- PASS: TestDNSProviders/example.com/55:_Change_Priority (0.00s) + --- PASS: TestDNSProviders/example.com/56:_Change_Weight (0.00s) + --- PASS: TestDNSProviders/example.com/57:_Change_Port (0.00s) + --- PASS: TestDNSProviders/example.com/58:_Null_Target (0.00s) + --- PASS: TestDNSProviders/example.com/59:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/60:_SSHFP_record (0.00s) + --- PASS: TestDNSProviders/example.com/61:_SSHFP_change_algorithm (0.00s) + --- PASS: TestDNSProviders/example.com/62:_SSHFP_change_fingerprint_and_type (0.00s) + --- PASS: TestDNSProviders/example.com/63:_SSHFP_Delete_one (0.00s) + --- PASS: TestDNSProviders/example.com/64:_SSHFP_add_many_records (0.00s) + --- PASS: TestDNSProviders/example.com/65:_SSHFP_delete_two (0.00s) + --- PASS: TestDNSProviders/example.com/66:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/67:_CAA_record (0.00s) + --- PASS: TestDNSProviders/example.com/68:_CAA_change_tag (0.00s) + --- PASS: TestDNSProviders/example.com/69:_CAA_change_target (0.00s) + --- PASS: TestDNSProviders/example.com/70:_CAA_change_flag (0.00s) + --- PASS: TestDNSProviders/example.com/71:_CAA_many_records (0.00s) + --- PASS: TestDNSProviders/example.com/72:_CAA_delete (0.00s) + --- PASS: TestDNSProviders/example.com/73:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/74:_TLSA_record (0.00s) + --- PASS: TestDNSProviders/example.com/75:_TLSA_change_usage (0.00s) + --- PASS: TestDNSProviders/example.com/76:_TLSA_change_selector (0.00s) + --- PASS: TestDNSProviders/example.com/77:_TLSA_change_matchingtype (0.00s) + --- PASS: TestDNSProviders/example.com/78:_TLSA_change_certificate (0.00s) + --- PASS: TestDNSProviders/example.com/79:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/80:_Create_CAPS (0.00s) + --- PASS: TestDNSProviders/example.com/81:_Downcase_label (0.00s) + --- PASS: TestDNSProviders/example.com/82:_Downcase_target (0.00s) + --- PASS: TestDNSProviders/example.com/83:_Upcase_both (0.00s) + --- PASS: TestDNSProviders/example.com/84:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/85:_99_records (0.01s) + --- PASS: TestDNSProviders/example.com/86:_100_records (0.01s) + --- PASS: TestDNSProviders/example.com/87:_101_records (0.03s) + --- PASS: TestDNSProviders/example.com/88:_Empty (0.01s) + --- PASS: TestDNSProviders/example.com/89:_Create_a_TXT (0.03s) + --- PASS: TestDNSProviders/example.com/90:_Change_a_TXT (0.00s) + --- PASS: TestDNSProviders/example.com/91:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/92:_Create_a_TXT_with_spaces (0.00s) + --- PASS: TestDNSProviders/example.com/93:_Change_a_TXT_with_spaces (0.00s) + --- PASS: TestDNSProviders/example.com/94:_Create_1_TXT_as_array (0.01s) + --- PASS: TestDNSProviders/example.com/95:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/96:_Create_a_255-byte_TXT (0.00s) + --- PASS: TestDNSProviders/example.com/97:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/98:_Create_TXTMulti_1 (0.01s) + --- PASS: TestDNSProviders/example.com/99:_Create_TXTMulti_2 (0.01s) + --- PASS: TestDNSProviders/example.com/100:_Create_TXTMulti_3 (0.02s) + --- PASS: TestDNSProviders/example.com/101:_Create_TXTMulti_with_quotes (0.00s) + --- PASS: TestDNSProviders/example.com/102:_Change_TXTMulti (0.00s) + --- PASS: TestDNSProviders/example.com/103:_Empty (0.00s) + --- PASS: TestDNSProviders/example.com/104:_3x255-byte_TXTMulti (0.00s) + --- PASS: TestDNSProviders/example.com/105:_Empty (0.01s) + --- PASS: TestDNSProviders/example.com/106:_Create_some_records (0.00s) + --- PASS: TestDNSProviders/example.com/107:_Add_a_new_record_-_ignoring_foo (0.02s) + --- PASS: TestDNSProviders/example.com/108:_Empty (0.01s) + --- PASS: TestDNSProviders/example.com/109:_Create_some_records (0.01s) + --- PASS: TestDNSProviders/example.com/110:_Add_a_new_record_-_ignoring_*.foo (0.00s) + --- PASS: TestDNSProviders/example.com/111:_Empty (0.01s) diff --git a/pkg/js/parse_tests/017-txt.js b/pkg/js/parse_tests/017-txt.js index 721705092..abc4a818a 100644 --- a/pkg/js/parse_tests/017-txt.js +++ b/pkg/js/parse_tests/017-txt.js @@ -1,6 +1,7 @@ -D("foo.com","none" - , TXT("@","simple") - , TXT("@",["one"]) - , TXT("@",["bonie", "clyde"]) - , TXT("@",["straw", "wood", "brick"]) -); +D("foo.com","none" + , TXT("a","simple") + , TXT("b","ws at end ") + , TXT("c",["one"]) + , TXT("d",["bonie", "clyde"]) + , TXT("e",["straw", "wood", "brick"]) +); diff --git a/pkg/js/parse_tests/017-txt.json b/pkg/js/parse_tests/017-txt.json index f8fbd7efa..aa9b5cfe4 100644 --- a/pkg/js/parse_tests/017-txt.json +++ b/pkg/js/parse_tests/017-txt.json @@ -9,7 +9,7 @@ "records": [ { "type": "TXT", - "name": "@", + "name": "a", "target": "simple", "txtstrings": [ "simple" @@ -17,7 +17,15 @@ }, { "type": "TXT", - "name": "@", + "name": "b", + "target": "ws at end ", + "txtstrings": [ + "ws at end " + ] + }, + { + "type": "TXT", + "name": "c", "target": "one", "txtstrings": [ "one" @@ -25,7 +33,7 @@ }, { "type": "TXT", - "name": "@", + "name": "d", "target": "bonie", "txtstrings": [ "bonie", @@ -34,7 +42,7 @@ }, { "type": "TXT", - "name": "@", + "name": "e", "target": "straw", "txtstrings": [ "straw", @@ -45,4 +53,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/providers/_all/all.go b/providers/_all/all.go index 396377cd3..e3ca2152b 100644 --- a/providers/_all/all.go +++ b/providers/_all/all.go @@ -11,7 +11,6 @@ import ( _ "github.com/StackExchange/dnscontrol/v2/providers/digitalocean" _ "github.com/StackExchange/dnscontrol/v2/providers/dnsimple" _ "github.com/StackExchange/dnscontrol/v2/providers/exoscale" - _ "github.com/StackExchange/dnscontrol/v2/providers/gandi" _ "github.com/StackExchange/dnscontrol/v2/providers/gandi_v5" _ "github.com/StackExchange/dnscontrol/v2/providers/gcloud" _ "github.com/StackExchange/dnscontrol/v2/providers/hexonet" diff --git a/providers/cloudflare/rest.go b/providers/cloudflare/rest.go index 09a470a72..5a896a19c 100644 --- a/providers/cloudflare/rest.go +++ b/providers/cloudflare/rest.go @@ -75,7 +75,6 @@ func (c *CloudflareApi) getRecordsForDomain(id string, domain string) ([]*models } page++ } - // fmt.Printf("DEBUG REORDS=%v\n", records) return records, nil } diff --git a/providers/gandi/gandiProvider.go b/providers/gandi/gandiProvider.go deleted file mode 100644 index 29c19a7e5..000000000 --- a/providers/gandi/gandiProvider.go +++ /dev/null @@ -1,215 +0,0 @@ -package gandi - -import ( - "encoding/json" - "fmt" - "sort" - "strings" - - gandidomain "github.com/prasmussen/gandi-api/domain" - gandirecord "github.com/prasmussen/gandi-api/domain/zone/record" - - "github.com/StackExchange/dnscontrol/v2/models" - "github.com/StackExchange/dnscontrol/v2/pkg/diff" - "github.com/StackExchange/dnscontrol/v2/pkg/printer" - "github.com/StackExchange/dnscontrol/v2/providers" -) - -/* - -Gandi API DNS provider: - -Info required in `creds.json`: - - apikey - -*/ - -var deprecationWarned bool - -var features = providers.DocumentationNotes{ - providers.CanUseCAA: providers.Can(), - providers.CanUsePTR: providers.Can(), - providers.CanUseSRV: providers.Can(), - providers.CantUseNOPURGE: providers.Cannot(), - providers.DocCreateDomains: providers.Cannot("Can only manage domains registered through their service"), - providers.DocOfficiallySupported: providers.Cannot(), - providers.CanGetZones: providers.Unimplemented(), -} - -func init() { - providers.RegisterDomainServiceProviderType("GANDI", newDsp, features) - providers.RegisterRegistrarType("GANDI", newReg) -} - -// GandiApi is the API handle for this module. -type GandiApi struct { - ApiKey string - domainIndex map[string]int64 // Map of domainname to index - nameservers map[string][]*models.Nameserver - ZoneId int64 -} - -type gandiRecord struct { - gandirecord.RecordInfo -} - -func (c *GandiApi) getDomainInfo(domain string) (*gandidomain.DomainInfo, error) { - if err := c.fetchDomainList(); err != nil { - return nil, err - } - _, ok := c.domainIndex[domain] - if !ok { - return nil, fmt.Errorf("'%s' not a zone in gandi account", domain) - } - return c.fetchDomainInfo(domain) -} - -// GetNameservers returns the nameservers for domain. -func (c *GandiApi) GetNameservers(domain string) ([]*models.Nameserver, error) { - domaininfo, err := c.getDomainInfo(domain) - if err != nil { - return nil, err - } - ns := []*models.Nameserver{} - for _, nsname := range domaininfo.Nameservers { - ns = append(ns, &models.Nameserver{Name: nsname}) - } - return ns, nil -} - -// GetZoneRecords gets the records of a zone and returns them in RecordConfig format. -func (client *GandiApi) GetZoneRecords(domain string) (models.Records, error) { - return nil, fmt.Errorf("not implemented") - // This enables the get-zones subcommand. - // Implement this by extracting the code from GetDomainCorrections into - // a single function. For most providers this should be relatively easy. -} - -// GetDomainCorrections returns a list of corrections recommended for this domain. -func (c *GandiApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) { - dc.Punycode() - domaininfo, err := c.getDomainInfo(dc.Name) - if err != nil { - return nil, err - } - foundRecords, err := c.getZoneRecords(domaininfo.ZoneId, dc.Name) - if err != nil { - return nil, err - } - - expectedRecordSets := make([]gandirecord.RecordSet, 0, len(dc.Records)) - recordsToKeep := make([]*models.RecordConfig, 0, len(dc.Records)) - for _, rec := range dc.Records { - if rec.TTL < 300 { - printer.Warnf("Gandi does not support ttls < 300. Setting %s from %d to 300\n", rec.GetLabelFQDN(), rec.TTL) - rec.TTL = 300 - } - if rec.TTL > 2592000 { - return nil, fmt.Errorf("ERROR: Gandi does not support TTLs > 30 days (TTL=%d)", rec.TTL) - } - if rec.Type == "TXT" { - rec.SetTarget("\"" + rec.GetTargetField() + "\"") // FIXME(tlim): Should do proper quoting. - } - if rec.Type == "NS" && rec.GetLabel() == "@" { - if !strings.HasSuffix(rec.GetTargetField(), ".gandi.net.") { - printer.Warnf("Gandi does not support changing apex NS records. %s will not be added.\n", rec.GetTargetField()) - } - continue - } - rs := gandirecord.RecordSet{ - "type": rec.Type, - "name": rec.GetLabel(), - "value": rec.GetTargetCombined(), - "ttl": rec.TTL, - } - expectedRecordSets = append(expectedRecordSets, rs) - recordsToKeep = append(recordsToKeep, rec) - } - dc.Records = recordsToKeep - - // Normalize - models.PostProcessRecords(foundRecords) - - differ := diff.New(dc) - _, create, del, mod := differ.IncrementalDiff(foundRecords) - - // Print a list of changes. Generate an actual change that is the zone - changes := false - desc := "" - for _, i := range create { - changes = true - desc += "\n" + i.String() - } - for _, i := range del { - changes = true - desc += "\n" + i.String() - } - for _, i := range mod { - changes = true - desc += "\n" + i.String() - } - - msg := fmt.Sprintf("GENERATE_ZONE: %s (%d records)%s", dc.Name, len(dc.Records), desc) - corrections := []*models.Correction{} - if changes { - corrections = append(corrections, - &models.Correction{ - Msg: msg, - F: func() error { - printer.Printf("CREATING ZONE: %v\n", dc.Name) - return c.createGandiZone(dc.Name, domaininfo.ZoneId, expectedRecordSets) - }, - }) - } - - return corrections, nil -} - -func newDsp(conf map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) { - return newGandi(conf, metadata) -} - -func newReg(conf map[string]string) (providers.Registrar, error) { - return newGandi(conf, nil) -} - -func newGandi(m map[string]string, metadata json.RawMessage) (*GandiApi, error) { - if !deprecationWarned { - deprecationWarned = true - fmt.Printf("WARNING: GANDI is deprecated and will disappear in 3.0. Please migrate to GANDI_V5.\n") - } - api := &GandiApi{} - api.ApiKey = m["apikey"] - if api.ApiKey == "" { - return nil, fmt.Errorf("missing Gandi apikey") - } - - return api, nil -} - -// GetRegistrarCorrections returns a list of corrections for this registrar. -func (c *GandiApi) GetRegistrarCorrections(dc *models.DomainConfig) ([]*models.Correction, error) { - domaininfo, err := c.getDomainInfo(dc.Name) - if err != nil { - return nil, err - } - sort.Strings(domaininfo.Nameservers) - found := strings.Join(domaininfo.Nameservers, ",") - desiredNs := []string{} - for _, d := range dc.Nameservers { - desiredNs = append(desiredNs, d.Name) - } - sort.Strings(desiredNs) - desired := strings.Join(desiredNs, ",") - if found != desired { - return []*models.Correction{ - { - Msg: fmt.Sprintf("Change Nameservers from '%s' to '%s'", found, desired), - F: func() (err error) { - _, err = c.setDomainNameservers(dc.Name, desiredNs) - return - }}, - }, nil - } - return nil, nil -} diff --git a/providers/gandi/livedns.go b/providers/gandi/livedns.go deleted file mode 100644 index 8945bc29c..000000000 --- a/providers/gandi/livedns.go +++ /dev/null @@ -1,292 +0,0 @@ -package gandi - -import ( - "bytes" - "encoding/json" - "fmt" - "strings" - "time" - - "github.com/google/uuid" - gandiclient "github.com/prasmussen/gandi-api/client" - gandilivedomain "github.com/prasmussen/gandi-api/live_dns/domain" - gandiliverecord "github.com/prasmussen/gandi-api/live_dns/record" - gandilivezone "github.com/prasmussen/gandi-api/live_dns/zone" - - "github.com/StackExchange/dnscontrol/v2/models" - "github.com/StackExchange/dnscontrol/v2/pkg/diff" - "github.com/StackExchange/dnscontrol/v2/pkg/printer" - "github.com/StackExchange/dnscontrol/v2/providers" -) - -var liveFeatures = providers.DocumentationNotes{ - providers.CanUseCAA: providers.Can(), - providers.CanUsePTR: providers.Can(), - providers.CanUseSRV: providers.Can(), - providers.CanUseTXTMulti: providers.Can(), - providers.CantUseNOPURGE: providers.Cannot(), - providers.DocCreateDomains: providers.Cannot("Can only manage domains registered through their service"), - providers.DocOfficiallySupported: providers.Cannot(), -} - -func init() { - providers.RegisterDomainServiceProviderType("GANDI-LIVEDNS", newLiveDsp, liveFeatures) -} - -func newLiveDsp(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) { - APIKey := m["apikey"] - if APIKey == "" { - return nil, fmt.Errorf("missing Gandi apikey") - } - - return newLiveClient(APIKey), nil -} - -type domainManager interface { - Info(string) (*gandilivedomain.Info, error) - Records(string) gandiliverecord.Manager -} - -type zoneManager interface { - InfoByUUID(uuid.UUID) (*gandilivezone.Info, error) - Create(gandilivezone.Info) (*gandilivezone.CreateStatus, error) - Set(string, gandilivezone.Info) (*gandilivezone.Status, error) - Records(gandilivezone.Info) gandiliverecord.Manager -} - -type liveClient struct { - client *gandiclient.Client - zoneManager zoneManager - domainManager domainManager -} - -func newLiveClient(APIKey string) *liveClient { - cl := gandiclient.New(APIKey, gandiclient.LiveDNS) - return &liveClient{ - client: cl, - zoneManager: gandilivezone.New(cl), - domainManager: gandilivedomain.New(cl), - } -} - -// GetNameservers returns the list of gandi name servers for a given domain -func (c *liveClient) GetNameservers(domain string) ([]*models.Nameserver, error) { - domains := []string{} - response, err := c.client.Get("/nameservers/"+domain, &domains) - if err != nil { - return nil, fmt.Errorf("failed to get nameservers for domain %s", domain) - } - defer response.Body.Close() - - ns := []*models.Nameserver{} - for _, domain := range domains { - ns = append(ns, &models.Nameserver{Name: domain}) - } - return ns, nil -} - -// GetZoneRecords gets the records of a zone and returns them in RecordConfig format. -func (client *liveClient) GetZoneRecords(domain string) (models.Records, error) { - return nil, fmt.Errorf("not implemented") - // This enables the get-zones subcommand. - // Implement this by extracting the code from GetDomainCorrections into - // a single function. For most providers this should be relatively easy. -} - -// GetDomainCorrections returns a list of corrections recommended for this domain. -func (c *liveClient) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) { - dc.Punycode() - records, err := c.domainManager.Records(dc.Name).List() - if err != nil { - return nil, err - } - foundRecords := c.recordConfigFromInfo(records, dc.Name) - recordsToKeep, records, err := c.recordsToInfo(dc.Records) - if err != nil { - return nil, err - } - dc.Records = recordsToKeep - - // Normalize - models.PostProcessRecords(foundRecords) - - differ := diff.New(dc) - - _, create, del, mod := differ.IncrementalDiff(foundRecords) - - buf := &bytes.Buffer{} - // Print a list of changes. Generate an actual change that is the zone - changes := false - for _, i := range create { - changes = true - fmt.Fprintln(buf, i) - } - for _, i := range del { - changes = true - fmt.Fprintln(buf, i) - } - for _, i := range mod { - changes = true - fmt.Fprintln(buf, i) - } - - if changes { - message := fmt.Sprintf("Setting dns records for %s:", dc.Name) - message += "\n" + buf.String() - return []*models.Correction{ - { - Msg: message, - F: func() error { - return c.createZone(dc.Name, records) - }, - }, - }, nil - } - return []*models.Correction{}, nil -} - -// createZone creates a new empty zone for the domain, populates it with the record infos and associates the domain to it -func (c *liveClient) createZone(domainname string, records []*gandiliverecord.Info) error { - domainInfo, err := c.domainManager.Info(domainname) - infos, err := c.zoneManager.InfoByUUID(*domainInfo.ZoneUUID) - if err != nil { - return err - } - infos.Name = fmt.Sprintf("zone created by dnscontrol for %s on %s", domainname, time.Now().Format(time.RFC3339)) - printer.Debugf("DEBUG: createZone SharingID=%v\n", infos.SharingID) - - // duplicate zone Infos - status, err := c.zoneManager.Create(*infos) - if err != nil { - return err - } - zoneInfos, err := c.zoneManager.InfoByUUID(*status.UUID) - if err != nil { - // gandi might take some time to make the new zone available - for i := 0; i < 10; i++ { - printer.Printf("zone info not yet available. Delay and retry: %s\n", err.Error()) - time.Sleep(100 * time.Millisecond) - zoneInfos, err = c.zoneManager.InfoByUUID(*status.UUID) - if err == nil { - break - } - } - } - if err != nil { - return err - } - recordManager := c.zoneManager.Records(*zoneInfos) - for _, record := range records { - _, err := recordManager.Create(*record) - if err != nil { - return err - } - } - _, err = c.zoneManager.Set(domainname, *zoneInfos) - if err != nil { - return err - } - - return nil -} - -// recordConfigFromInfo takes a DNS record from Gandi liveDNS and returns our native RecordConfig format. -func (c *liveClient) recordConfigFromInfo(infos []*gandiliverecord.Info, origin string) []*models.RecordConfig { - rcs := []*models.RecordConfig{} - for _, info := range infos { - // TXT records might have multiple values. In that case, - // they are all for the TXT record at that label. - if info.Type == "TXT" { - rc := &models.RecordConfig{ - Type: info.Type, - Original: info, - TTL: uint32(info.TTL), - } - rc.SetLabel(info.Name, origin) - var parsed []string - for _, txt := range info.Values { - parsed = append(parsed, models.StripQuotes(txt)) - } - err := rc.SetTargetTXTs(parsed) - if err != nil { - panic(fmt.Errorf("recordConfigFromInfo=TXT failed: %w", err)) - } - rcs = append(rcs, rc) - } else { - // All other record types might have multiple values, but that means - // we should create one Recordconfig for each one. - for _, value := range info.Values { - rc := &models.RecordConfig{ - Type: info.Type, - Original: info, - TTL: uint32(info.TTL), - } - rc.SetLabel(info.Name, origin) - switch rtype := info.Type; rtype { - default: - err := rc.PopulateFromString(rtype, value, origin) - if err != nil { - panic(fmt.Errorf("recordConfigFromInfo failed: %w", err)) - } - } - rcs = append(rcs, rc) - } - } - } - return rcs -} - -// recordsToInfo generates gandi record sets and filters incompatible entries from native records format -func (c *liveClient) recordsToInfo(records models.Records) (models.Records, []*gandiliverecord.Info, error) { - recordSets := map[string]map[string]*gandiliverecord.Info{} - recordInfos := []*gandiliverecord.Info{} - recordToKeep := models.Records{} - - for _, rec := range records { - if rec.TTL < 300 { - printer.Warnf("Gandi does not support ttls < 300. %s will not be set to %d.\n", rec.GetLabelFQDN(), rec.TTL) - rec.TTL = 300 - } - if rec.TTL > 2592000 { - return nil, nil, fmt.Errorf("ERROR: Gandi does not support TTLs > 30 days (TTL=%d)", rec.TTL) - } - if rec.Type == "NS" && rec.GetLabel() == "@" { - if !strings.HasSuffix(rec.GetTargetField(), ".gandi.net.") { - printer.Warnf("Gandi does not support changing apex NS records. %s will not be added.\n", rec.GetTargetField()) - } - continue - } - r, ok := recordSets[rec.GetLabel()][rec.Type] - if !ok { - _, ok := recordSets[rec.GetLabel()] - if !ok { - recordSets[rec.GetLabel()] = map[string]*gandiliverecord.Info{} - } - r = &gandiliverecord.Info{ - Type: rec.Type, - Name: rec.GetLabel(), - TTL: int64(rec.TTL), - } - recordInfos = append(recordInfos, r) - recordSets[rec.GetLabel()][rec.Type] = r - } else { - if r.TTL != int64(rec.TTL) { - printer.Warnf( - "Gandi liveDNS API does not support different TTL for the couple fqdn/type. Will use TTL of %d for %s %s\n", - r.TTL, - r.Type, - r.Name, - ) - } - } - recordToKeep = append(recordToKeep, rec) - if rec.Type == "TXT" { - for _, t := range rec.TxtStrings { - r.Values = append(r.Values, "\""+t+"\"") // FIXME(tlim): Should do proper quoting. - } - } else { - r.Values = append(r.Values, rec.GetTargetCombined()) - } - } - return recordToKeep, recordInfos, nil -} diff --git a/providers/gandi/livedns_test.go b/providers/gandi/livedns_test.go deleted file mode 100644 index 2a520a817..000000000 --- a/providers/gandi/livedns_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package gandi - -import ( - "testing" - - "github.com/StackExchange/dnscontrol/v2/models" - "github.com/prasmussen/gandi-api/live_dns/record" - "github.com/stretchr/testify/assert" -) - -func makeRC(label, domain, target string, rc models.RecordConfig) *models.RecordConfig { - rc.SetLabel(label, domain) - rc.SetTarget(target) - return &rc -} -func TestRecordConfigFromInfo(t *testing.T) { - - for _, data := range []struct { - info *record.Info - config []*models.RecordConfig - }{ - { - &record.Info{ - Name: "www", - Type: "A", - TTL: 500, - Values: []string{"127.0.0.1", "127.1.0.1"}, - }, - []*models.RecordConfig{ - makeRC("www", "example.com", "127.0.0.1", models.RecordConfig{ - Type: "A", - TTL: 500, - }), - makeRC("www", "example.com", "127.1.0.1", models.RecordConfig{ - Type: "A", - TTL: 500, - }), - }, - }, - { - &record.Info{ - Name: "www", - Type: "TXT", - TTL: 500, - Values: []string{"\"test 2\"", "\"test message test message test message\""}, - }, - []*models.RecordConfig{ - makeRC("www", "example.com", "test 2", models.RecordConfig{ - Type: "TXT", - TxtStrings: []string{"test 2", "test message test message test message"}, - TTL: 500, - }), - }, - }, - { - &record.Info{ - Name: "www", - Type: "CAA", - TTL: 500, - // examples from https://sslmate.com/caa/ - Values: []string{"0 issue \"www.certinomis.com\"", "0 issuewild \"buypass.com\""}, - }, - []*models.RecordConfig{ - makeRC("www", "example.com", "www.certinomis.com", models.RecordConfig{ - Type: "CAA", - CaaFlag: 0, - CaaTag: "issue", - TTL: 500, - }), - makeRC("www", "example.com", "buypass.com", models.RecordConfig{ - Type: "CAA", - CaaFlag: 0, - CaaTag: "issuewild", - TTL: 500, - }), - }, - }, - { - &record.Info{ - Name: "test", - Type: "SRV", - TTL: 500, - Values: []string{"20 0 5060 backupbox.example.com."}, - }, - []*models.RecordConfig{ - makeRC("test", "example.com", "backupbox.example.com.", models.RecordConfig{ - Type: "SRV", - SrvPriority: 20, - SrvWeight: 0, - SrvPort: 5060, - TTL: 500, - }), - }, - }, - { - &record.Info{ - Name: "mail", - Type: "MX", - TTL: 500, - Values: []string{"50 fb.mail.gandi.net.", "10 spool.mail.gandi.net."}, - }, - []*models.RecordConfig{ - makeRC("mail", "example.com", "fb.mail.gandi.net.", models.RecordConfig{ - Type: "MX", - MxPreference: 50, - TTL: 500, - }), - makeRC("mail", "example.com", "spool.mail.gandi.net.", models.RecordConfig{ - Type: "MX", - MxPreference: 10, - TTL: 500, - }), - }, - }, - } { - t.Run("with record type "+data.info.Type, func(t *testing.T) { - c := liveClient{} - for _, c := range data.config { - c.Original = data.info - } - t.Run("Convert gandi info to record config", func(t *testing.T) { - recordConfig := c.recordConfigFromInfo([]*record.Info{data.info}, "example.com") - assert.Equal(t, data.config, recordConfig) - }) - t.Run("Convert record config to gandi info", func(t *testing.T) { - _, recordInfos, err := c.recordsToInfo(data.config) - assert.NoError(t, err) - assert.Equal(t, []*record.Info{data.info}, recordInfos) - }) - }) - } -} diff --git a/providers/gandi/protocol.go b/providers/gandi/protocol.go deleted file mode 100644 index 4263eb8d5..000000000 --- a/providers/gandi/protocol.go +++ /dev/null @@ -1,201 +0,0 @@ -package gandi - -import ( - "fmt" - - gandiclient "github.com/prasmussen/gandi-api/client" - gandidomain "github.com/prasmussen/gandi-api/domain" - gandinameservers "github.com/prasmussen/gandi-api/domain/nameservers" - gandizone "github.com/prasmussen/gandi-api/domain/zone" - gandirecord "github.com/prasmussen/gandi-api/domain/zone/record" - gandiversion "github.com/prasmussen/gandi-api/domain/zone/version" - gandioperation "github.com/prasmussen/gandi-api/operation" - - "github.com/StackExchange/dnscontrol/v2/models" -) - -// fetchDomainList gets list of domains for account. Cache ids for easy lookup. -func (c *GandiApi) fetchDomainList() error { - if c.domainIndex != nil { - return nil - } - c.domainIndex = map[string]int64{} - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - domain := gandidomain.New(gc) - domains, err := domain.List() - if err != nil { - // fmt.Println(err) - return err - } - for _, d := range domains { - c.domainIndex[d.Fqdn] = d.Id - } - return nil -} - -// fetchDomainInfo gets information about a domain. -func (c *GandiApi) fetchDomainInfo(fqdn string) (*gandidomain.DomainInfo, error) { - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - domain := gandidomain.New(gc) - return domain.Info(fqdn) -} - -// setDomainNameservers updates the nameservers of a domain. -func (c *GandiApi) setDomainNameservers(fqdn string, nameservers []string) (*gandioperation.OperationInfo, error) { - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - nameserversapi := gandinameservers.New(gc) - return nameserversapi.Set(fqdn, nameservers) -} - -// getRecordsForDomain returns a list of records for a zone. -func (c *GandiApi) getZoneRecords(zoneid int64, origin string) ([]*models.RecordConfig, error) { - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - record := gandirecord.New(gc) - recs, err := record.List(zoneid, 0) - if err != nil { - return nil, err - } - rcs := make([]*models.RecordConfig, 0, len(recs)) - for _, r := range recs { - rcs = append(rcs, nativeToRecord(r, origin)) - } - return rcs, nil -} - -// convert takes a DNS record from Gandi and returns our native RecordConfig format. -func nativeToRecord(r *gandirecord.RecordInfo, origin string) *models.RecordConfig { - - rc := &models.RecordConfig{ - //NameFQDN: dnsutil.AddOrigin(r.Name, origin), - //Name: r.Name, - //Type: r.Type, - TTL: uint32(r.Ttl), - Original: r, - //Target: r.Value, - } - rc.SetLabel(r.Name, origin) - switch rtype := r.Type; rtype { - default: // "A", "AAAA", "CAA", "NS", "CNAME", "MX", "PTR", "SRV", "TXT" - if err := rc.PopulateFromString(rtype, r.Value, origin); err != nil { - panic(fmt.Errorf("unparsable record received from gandi: %w", err)) - } - } - return rc -} - -// listZones retrieves the list of zones. -func (c *GandiApi) listZones() ([]*gandizone.ZoneInfoBase, error) { - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - zone := gandizone.New(gc) - return zone.List() -} - -// setZone assigns a particular zone to a domain. -func (c *GandiApi) setZones(domainname string, zoneID int64) (*gandidomain.DomainInfo, error) { - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - zone := gandizone.New(gc) - return zone.Set(domainname, zoneID) -} - -// getZoneInfo gets ZoneInfo about a zone. -func (c *GandiApi) getZoneInfo(zoneid int64) (*gandizone.ZoneInfo, error) { - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - zone := gandizone.New(gc) - return zone.Info(zoneid) -} - -// createZone creates an entirely new zone. -func (c *GandiApi) createZone(name string) (*gandizone.ZoneInfo, error) { - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - zone := gandizone.New(gc) - return zone.Create(name) -} - -func (c *GandiApi) getEditableZone(domainname string, zoneinfo *gandizone.ZoneInfo) (int64, error) { - var zoneID int64 - if zoneinfo.Domains < 2 { - // If there is only on{ domain linked to this zone, use it. - zoneID = zoneinfo.Id - fmt.Printf("Using zone id=%d named %#v\n", zoneID, zoneinfo.Name) - return zoneID, nil - } - - // We can't use the zone_id given to us. Let's make/find a new one. - zones, err := c.listZones() - if err != nil { - return 0, err - } - zonename := fmt.Sprintf("%s dnscontrol", domainname) - for _, z := range zones { - if z.Name == zonename { - zoneID = z.Id - fmt.Printf("Recycling zone id=%d named %#v\n", zoneID, z.Name) - return zoneID, nil - } - } - zoneinfo, err = c.createZone(zonename) - if err != nil { - return 0, err - } - zoneID = zoneinfo.Id - fmt.Printf("Created zone id=%d named %#v\n", zoneID, zoneinfo.Name) - return zoneID, nil -} - -// makeEditableZone -func (c *GandiApi) makeEditableZone(zoneID int64) (int64, error) { - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - version := gandiversion.New(gc) - return version.New(zoneID, 0) -} - -// setZoneRecords -func (c *GandiApi) setZoneRecords(zoneID, versionID int64, records []gandirecord.RecordSet) ([]*gandirecord.RecordInfo, error) { - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - record := gandirecord.New(gc) - return record.SetRecords(zoneID, versionID, records) -} - -// activateVersion -func (c *GandiApi) activateVersion(zoneID, versionID int64) (bool, error) { - gc := gandiclient.New(c.ApiKey, gandiclient.Production) - version := gandiversion.New(gc) - return version.Set(zoneID, versionID) -} - -func (c *GandiApi) createGandiZone(domainname string, zoneID int64, records []gandirecord.RecordSet) error { - - // Get the zone_id of the zone we'll be updating. - zoneinfo, err := c.getZoneInfo(zoneID) - if err != nil { - return err - } - zoneID, err = c.getEditableZone(domainname, zoneinfo) - if err != nil { - return err - } - - // Get the versionID of the zone we're updating. - versionID, err := c.makeEditableZone(zoneID) - if err != nil { - return err - } - - // Update the new version. - _, err = c.setZoneRecords(zoneID, versionID, records) - if err != nil { - return err - } - - // Activate zone version - _, err = c.activateVersion(zoneID, versionID) - if err != nil { - return err - } - _, err = c.setZones(domainname, zoneID) - if err != nil { - return err - } - - return nil -} diff --git a/vendor/github.com/google/uuid/.travis.yml b/vendor/github.com/google/uuid/.travis.yml deleted file mode 100644 index d8156a60b..000000000 --- a/vendor/github.com/google/uuid/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - 1.4.3 - - 1.5.3 - - tip - -script: - - go test -v ./... diff --git a/vendor/github.com/google/uuid/CONTRIBUTING.md b/vendor/github.com/google/uuid/CONTRIBUTING.md deleted file mode 100644 index 04fdf09f1..000000000 --- a/vendor/github.com/google/uuid/CONTRIBUTING.md +++ /dev/null @@ -1,10 +0,0 @@ -# How to contribute - -We definitely welcome patches and contribution to this project! - -### Legal requirements - -In order to protect both you and ourselves, you will need to sign the -[Contributor License Agreement](https://cla.developers.google.com/clas). - -You may have already signed it for other Google projects. diff --git a/vendor/github.com/google/uuid/CONTRIBUTORS b/vendor/github.com/google/uuid/CONTRIBUTORS deleted file mode 100644 index b4bb97f6b..000000000 --- a/vendor/github.com/google/uuid/CONTRIBUTORS +++ /dev/null @@ -1,9 +0,0 @@ -Paul Borman -bmatsuo -shawnps -theory -jboverfelt -dsymonds -cd1 -wallclockbuilder -dansouza diff --git a/vendor/github.com/google/uuid/LICENSE b/vendor/github.com/google/uuid/LICENSE deleted file mode 100644 index 5dc68268d..000000000 --- a/vendor/github.com/google/uuid/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009,2014 Google Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/google/uuid/README.md b/vendor/github.com/google/uuid/README.md deleted file mode 100644 index 9d92c11f1..000000000 --- a/vendor/github.com/google/uuid/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master) -The uuid package generates and inspects UUIDs based on -[RFC 4122](http://tools.ietf.org/html/rfc4122) -and DCE 1.1: Authentication and Security Services. - -This package is based on the github.com/pborman/uuid package (previously named -code.google.com/p/go-uuid). It differs from these earlier packages in that -a UUID is a 16 byte array rather than a byte slice. One loss due to this -change is the ability to represent an invalid UUID (vs a NIL UUID). - -###### Install -`go get github.com/google/uuid` - -###### Documentation -[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid) - -Full `go doc` style documentation for the package can be viewed online without -installing this package by using the GoDoc site here: -http://godoc.org/github.com/google/uuid diff --git a/vendor/github.com/google/uuid/dce.go b/vendor/github.com/google/uuid/dce.go deleted file mode 100644 index fa820b9d3..000000000 --- a/vendor/github.com/google/uuid/dce.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" - "fmt" - "os" -) - -// A Domain represents a Version 2 domain -type Domain byte - -// Domain constants for DCE Security (Version 2) UUIDs. -const ( - Person = Domain(0) - Group = Domain(1) - Org = Domain(2) -) - -// NewDCESecurity returns a DCE Security (Version 2) UUID. -// -// The domain should be one of Person, Group or Org. -// On a POSIX system the id should be the users UID for the Person -// domain and the users GID for the Group. The meaning of id for -// the domain Org or on non-POSIX systems is site defined. -// -// For a given domain/id pair the same token may be returned for up to -// 7 minutes and 10 seconds. -func NewDCESecurity(domain Domain, id uint32) (UUID, error) { - uuid, err := NewUUID() - if err == nil { - uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 - uuid[9] = byte(domain) - binary.BigEndian.PutUint32(uuid[0:], id) - } - return uuid, err -} - -// NewDCEPerson returns a DCE Security (Version 2) UUID in the person -// domain with the id returned by os.Getuid. -// -// NewDCESecurity(Person, uint32(os.Getuid())) -func NewDCEPerson() (UUID, error) { - return NewDCESecurity(Person, uint32(os.Getuid())) -} - -// NewDCEGroup returns a DCE Security (Version 2) UUID in the group -// domain with the id returned by os.Getgid. -// -// NewDCESecurity(Group, uint32(os.Getgid())) -func NewDCEGroup() (UUID, error) { - return NewDCESecurity(Group, uint32(os.Getgid())) -} - -// Domain returns the domain for a Version 2 UUID. Domains are only defined -// for Version 2 UUIDs. -func (uuid UUID) Domain() Domain { - return Domain(uuid[9]) -} - -// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2 -// UUIDs. -func (uuid UUID) ID() uint32 { - return binary.BigEndian.Uint32(uuid[0:4]) -} - -func (d Domain) String() string { - switch d { - case Person: - return "Person" - case Group: - return "Group" - case Org: - return "Org" - } - return fmt.Sprintf("Domain%d", int(d)) -} diff --git a/vendor/github.com/google/uuid/doc.go b/vendor/github.com/google/uuid/doc.go deleted file mode 100644 index 5b8a4b9af..000000000 --- a/vendor/github.com/google/uuid/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package uuid generates and inspects UUIDs. -// -// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security -// Services. -// -// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to -// maps or compared directly. -package uuid diff --git a/vendor/github.com/google/uuid/go.mod b/vendor/github.com/google/uuid/go.mod deleted file mode 100644 index fc84cd79d..000000000 --- a/vendor/github.com/google/uuid/go.mod +++ /dev/null @@ -1 +0,0 @@ -module github.com/google/uuid diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go deleted file mode 100644 index b17461631..000000000 --- a/vendor/github.com/google/uuid/hash.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "crypto/md5" - "crypto/sha1" - "hash" -) - -// Well known namespace IDs and UUIDs -var ( - NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) - NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) - NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) - NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) - Nil UUID // empty UUID, all zeros -) - -// NewHash returns a new UUID derived from the hash of space concatenated with -// data generated by h. The hash should be at least 16 byte in length. The -// first 16 bytes of the hash are used to form the UUID. The version of the -// UUID will be the lower 4 bits of version. NewHash is used to implement -// NewMD5 and NewSHA1. -func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { - h.Reset() - h.Write(space[:]) - h.Write(data) - s := h.Sum(nil) - var uuid UUID - copy(uuid[:], s) - uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) - uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant - return uuid -} - -// NewMD5 returns a new MD5 (Version 3) UUID based on the -// supplied name space and data. It is the same as calling: -// -// NewHash(md5.New(), space, data, 3) -func NewMD5(space UUID, data []byte) UUID { - return NewHash(md5.New(), space, data, 3) -} - -// NewSHA1 returns a new SHA1 (Version 5) UUID based on the -// supplied name space and data. It is the same as calling: -// -// NewHash(sha1.New(), space, data, 5) -func NewSHA1(space UUID, data []byte) UUID { - return NewHash(sha1.New(), space, data, 5) -} diff --git a/vendor/github.com/google/uuid/marshal.go b/vendor/github.com/google/uuid/marshal.go deleted file mode 100644 index 7f9e0c6c0..000000000 --- a/vendor/github.com/google/uuid/marshal.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import "fmt" - -// MarshalText implements encoding.TextMarshaler. -func (uuid UUID) MarshalText() ([]byte, error) { - var js [36]byte - encodeHex(js[:], uuid) - return js[:], nil -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (uuid *UUID) UnmarshalText(data []byte) error { - id, err := ParseBytes(data) - if err == nil { - *uuid = id - } - return err -} - -// MarshalBinary implements encoding.BinaryMarshaler. -func (uuid UUID) MarshalBinary() ([]byte, error) { - return uuid[:], nil -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler. -func (uuid *UUID) UnmarshalBinary(data []byte) error { - if len(data) != 16 { - return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) - } - copy(uuid[:], data) - return nil -} diff --git a/vendor/github.com/google/uuid/node.go b/vendor/github.com/google/uuid/node.go deleted file mode 100644 index d651a2b06..000000000 --- a/vendor/github.com/google/uuid/node.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "sync" -) - -var ( - nodeMu sync.Mutex - ifname string // name of interface being used - nodeID [6]byte // hardware for version 1 UUIDs - zeroID [6]byte // nodeID with only 0's -) - -// NodeInterface returns the name of the interface from which the NodeID was -// derived. The interface "user" is returned if the NodeID was set by -// SetNodeID. -func NodeInterface() string { - defer nodeMu.Unlock() - nodeMu.Lock() - return ifname -} - -// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. -// If name is "" then the first usable interface found will be used or a random -// Node ID will be generated. If a named interface cannot be found then false -// is returned. -// -// SetNodeInterface never fails when name is "". -func SetNodeInterface(name string) bool { - defer nodeMu.Unlock() - nodeMu.Lock() - return setNodeInterface(name) -} - -func setNodeInterface(name string) bool { - iname, addr := getHardwareInterface(name) // null implementation for js - if iname != "" && addr != nil { - ifname = iname - copy(nodeID[:], addr) - return true - } - - // We found no interfaces with a valid hardware address. If name - // does not specify a specific interface generate a random Node ID - // (section 4.1.6) - if name == "" { - ifname = "random" - randomBits(nodeID[:]) - return true - } - return false -} - -// NodeID returns a slice of a copy of the current Node ID, setting the Node ID -// if not already set. -func NodeID() []byte { - defer nodeMu.Unlock() - nodeMu.Lock() - if nodeID == zeroID { - setNodeInterface("") - } - nid := nodeID - return nid[:] -} - -// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes -// of id are used. If id is less than 6 bytes then false is returned and the -// Node ID is not set. -func SetNodeID(id []byte) bool { - if len(id) < 6 { - return false - } - defer nodeMu.Unlock() - nodeMu.Lock() - copy(nodeID[:], id) - ifname = "user" - return true -} - -// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is -// not valid. The NodeID is only well defined for version 1 and 2 UUIDs. -func (uuid UUID) NodeID() []byte { - var node [6]byte - copy(node[:], uuid[10:]) - return node[:] -} diff --git a/vendor/github.com/google/uuid/node_js.go b/vendor/github.com/google/uuid/node_js.go deleted file mode 100644 index 24b78edc9..000000000 --- a/vendor/github.com/google/uuid/node_js.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2017 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build js - -package uuid - -// getHardwareInterface returns nil values for the JS version of the code. -// This remvoves the "net" dependency, because it is not used in the browser. -// Using the "net" library inflates the size of the transpiled JS code by 673k bytes. -func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/vendor/github.com/google/uuid/node_net.go b/vendor/github.com/google/uuid/node_net.go deleted file mode 100644 index 0cbbcddbd..000000000 --- a/vendor/github.com/google/uuid/node_net.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2017 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !js - -package uuid - -import "net" - -var interfaces []net.Interface // cached list of interfaces - -// getHardwareInterface returns the name and hardware address of interface name. -// If name is "" then the name and hardware address of one of the system's -// interfaces is returned. If no interfaces are found (name does not exist or -// there are no interfaces) then "", nil is returned. -// -// Only addresses of at least 6 bytes are returned. -func getHardwareInterface(name string) (string, []byte) { - if interfaces == nil { - var err error - interfaces, err = net.Interfaces() - if err != nil { - return "", nil - } - } - for _, ifs := range interfaces { - if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { - return ifs.Name, ifs.HardwareAddr - } - } - return "", nil -} diff --git a/vendor/github.com/google/uuid/sql.go b/vendor/github.com/google/uuid/sql.go deleted file mode 100644 index f326b54db..000000000 --- a/vendor/github.com/google/uuid/sql.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "database/sql/driver" - "fmt" -) - -// Scan implements sql.Scanner so UUIDs can be read from databases transparently -// Currently, database types that map to string and []byte are supported. Please -// consult database-specific driver documentation for matching types. -func (uuid *UUID) Scan(src interface{}) error { - switch src := src.(type) { - case nil: - return nil - - case string: - // if an empty UUID comes from a table, we return a null UUID - if src == "" { - return nil - } - - // see Parse for required string format - u, err := Parse(src) - if err != nil { - return fmt.Errorf("Scan: %v", err) - } - - *uuid = u - - case []byte: - // if an empty UUID comes from a table, we return a null UUID - if len(src) == 0 { - return nil - } - - // assumes a simple slice of bytes if 16 bytes - // otherwise attempts to parse - if len(src) != 16 { - return uuid.Scan(string(src)) - } - copy((*uuid)[:], src) - - default: - return fmt.Errorf("Scan: unable to scan type %T into UUID", src) - } - - return nil -} - -// Value implements sql.Valuer so that UUIDs can be written to databases -// transparently. Currently, UUIDs map to strings. Please consult -// database-specific driver documentation for matching types. -func (uuid UUID) Value() (driver.Value, error) { - return uuid.String(), nil -} diff --git a/vendor/github.com/google/uuid/time.go b/vendor/github.com/google/uuid/time.go deleted file mode 100644 index e6ef06cdc..000000000 --- a/vendor/github.com/google/uuid/time.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" - "sync" - "time" -) - -// A Time represents a time as the number of 100's of nanoseconds since 15 Oct -// 1582. -type Time int64 - -const ( - lillian = 2299160 // Julian day of 15 Oct 1582 - unix = 2440587 // Julian day of 1 Jan 1970 - epoch = unix - lillian // Days between epochs - g1582 = epoch * 86400 // seconds between epochs - g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs -) - -var ( - timeMu sync.Mutex - lasttime uint64 // last time we returned - clockSeq uint16 // clock sequence for this run - - timeNow = time.Now // for testing -) - -// UnixTime converts t the number of seconds and nanoseconds using the Unix -// epoch of 1 Jan 1970. -func (t Time) UnixTime() (sec, nsec int64) { - sec = int64(t - g1582ns100) - nsec = (sec % 10000000) * 100 - sec /= 10000000 - return sec, nsec -} - -// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and -// clock sequence as well as adjusting the clock sequence as needed. An error -// is returned if the current time cannot be determined. -func GetTime() (Time, uint16, error) { - defer timeMu.Unlock() - timeMu.Lock() - return getTime() -} - -func getTime() (Time, uint16, error) { - t := timeNow() - - // If we don't have a clock sequence already, set one. - if clockSeq == 0 { - setClockSequence(-1) - } - now := uint64(t.UnixNano()/100) + g1582ns100 - - // If time has gone backwards with this clock sequence then we - // increment the clock sequence - if now <= lasttime { - clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000 - } - lasttime = now - return Time(now), clockSeq, nil -} - -// ClockSequence returns the current clock sequence, generating one if not -// already set. The clock sequence is only used for Version 1 UUIDs. -// -// The uuid package does not use global static storage for the clock sequence or -// the last time a UUID was generated. Unless SetClockSequence is used, a new -// random clock sequence is generated the first time a clock sequence is -// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) -func ClockSequence() int { - defer timeMu.Unlock() - timeMu.Lock() - return clockSequence() -} - -func clockSequence() int { - if clockSeq == 0 { - setClockSequence(-1) - } - return int(clockSeq & 0x3fff) -} - -// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to -// -1 causes a new sequence to be generated. -func SetClockSequence(seq int) { - defer timeMu.Unlock() - timeMu.Lock() - setClockSequence(seq) -} - -func setClockSequence(seq int) { - if seq == -1 { - var b [2]byte - randomBits(b[:]) // clock sequence - seq = int(b[0])<<8 | int(b[1]) - } - oldSeq := clockSeq - clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant - if oldSeq != clockSeq { - lasttime = 0 - } -} - -// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in -// uuid. The time is only defined for version 1 and 2 UUIDs. -func (uuid UUID) Time() Time { - time := int64(binary.BigEndian.Uint32(uuid[0:4])) - time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 - time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 - return Time(time) -} - -// ClockSequence returns the clock sequence encoded in uuid. -// The clock sequence is only well defined for version 1 and 2 UUIDs. -func (uuid UUID) ClockSequence() int { - return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff -} diff --git a/vendor/github.com/google/uuid/util.go b/vendor/github.com/google/uuid/util.go deleted file mode 100644 index 5ea6c7378..000000000 --- a/vendor/github.com/google/uuid/util.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "io" -) - -// randomBits completely fills slice b with random data. -func randomBits(b []byte) { - if _, err := io.ReadFull(rander, b); err != nil { - panic(err.Error()) // rand should never fail - } -} - -// xvalues returns the value of a byte as a hexadecimal digit or 255. -var xvalues = [256]byte{ - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -} - -// xtob converts hex characters x1 and x2 into a byte. -func xtob(x1, x2 byte) (byte, bool) { - b1 := xvalues[x1] - b2 := xvalues[x2] - return (b1 << 4) | b2, b1 != 255 && b2 != 255 -} diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go deleted file mode 100644 index 524404cc5..000000000 --- a/vendor/github.com/google/uuid/uuid.go +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright 2018 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "bytes" - "crypto/rand" - "encoding/hex" - "errors" - "fmt" - "io" - "strings" -) - -// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC -// 4122. -type UUID [16]byte - -// A Version represents a UUID's version. -type Version byte - -// A Variant represents a UUID's variant. -type Variant byte - -// Constants returned by Variant. -const ( - Invalid = Variant(iota) // Invalid UUID - RFC4122 // The variant specified in RFC4122 - Reserved // Reserved, NCS backward compatibility. - Microsoft // Reserved, Microsoft Corporation backward compatibility. - Future // Reserved for future definition. -) - -var rander = rand.Reader // random function - -// Parse decodes s into a UUID or returns an error. Both the standard UUID -// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the -// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex -// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. -func Parse(s string) (UUID, error) { - var uuid UUID - switch len(s) { - // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - case 36: - - // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - case 36 + 9: - if strings.ToLower(s[:9]) != "urn:uuid:" { - return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) - } - s = s[9:] - - // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} - case 36 + 2: - s = s[1:] - - // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - case 32: - var ok bool - for i := range uuid { - uuid[i], ok = xtob(s[i*2], s[i*2+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - } - return uuid, nil - default: - return uuid, fmt.Errorf("invalid UUID length: %d", len(s)) - } - // s is now at least 36 bytes long - // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { - return uuid, errors.New("invalid UUID format") - } - for i, x := range [16]int{ - 0, 2, 4, 6, - 9, 11, - 14, 16, - 19, 21, - 24, 26, 28, 30, 32, 34} { - v, ok := xtob(s[x], s[x+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - uuid[i] = v - } - return uuid, nil -} - -// ParseBytes is like Parse, except it parses a byte slice instead of a string. -func ParseBytes(b []byte) (UUID, error) { - var uuid UUID - switch len(b) { - case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) { - return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) - } - b = b[9:] - case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} - b = b[1:] - case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - var ok bool - for i := 0; i < 32; i += 2 { - uuid[i/2], ok = xtob(b[i], b[i+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - } - return uuid, nil - default: - return uuid, fmt.Errorf("invalid UUID length: %d", len(b)) - } - // s is now at least 36 bytes long - // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' { - return uuid, errors.New("invalid UUID format") - } - for i, x := range [16]int{ - 0, 2, 4, 6, - 9, 11, - 14, 16, - 19, 21, - 24, 26, 28, 30, 32, 34} { - v, ok := xtob(b[x], b[x+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - uuid[i] = v - } - return uuid, nil -} - -// MustParse is like Parse but panics if the string cannot be parsed. -// It simplifies safe initialization of global variables holding compiled UUIDs. -func MustParse(s string) UUID { - uuid, err := Parse(s) - if err != nil { - panic(`uuid: Parse(` + s + `): ` + err.Error()) - } - return uuid -} - -// FromBytes creates a new UUID from a byte slice. Returns an error if the slice -// does not have a length of 16. The bytes are copied from the slice. -func FromBytes(b []byte) (uuid UUID, err error) { - err = uuid.UnmarshalBinary(b) - return uuid, err -} - -// Must returns uuid if err is nil and panics otherwise. -func Must(uuid UUID, err error) UUID { - if err != nil { - panic(err) - } - return uuid -} - -// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -// , or "" if uuid is invalid. -func (uuid UUID) String() string { - var buf [36]byte - encodeHex(buf[:], uuid) - return string(buf[:]) -} - -// URN returns the RFC 2141 URN form of uuid, -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. -func (uuid UUID) URN() string { - var buf [36 + 9]byte - copy(buf[:], "urn:uuid:") - encodeHex(buf[9:], uuid) - return string(buf[:]) -} - -func encodeHex(dst []byte, uuid UUID) { - hex.Encode(dst, uuid[:4]) - dst[8] = '-' - hex.Encode(dst[9:13], uuid[4:6]) - dst[13] = '-' - hex.Encode(dst[14:18], uuid[6:8]) - dst[18] = '-' - hex.Encode(dst[19:23], uuid[8:10]) - dst[23] = '-' - hex.Encode(dst[24:], uuid[10:]) -} - -// Variant returns the variant encoded in uuid. -func (uuid UUID) Variant() Variant { - switch { - case (uuid[8] & 0xc0) == 0x80: - return RFC4122 - case (uuid[8] & 0xe0) == 0xc0: - return Microsoft - case (uuid[8] & 0xe0) == 0xe0: - return Future - default: - return Reserved - } -} - -// Version returns the version of uuid. -func (uuid UUID) Version() Version { - return Version(uuid[6] >> 4) -} - -func (v Version) String() string { - if v > 15 { - return fmt.Sprintf("BAD_VERSION_%d", v) - } - return fmt.Sprintf("VERSION_%d", v) -} - -func (v Variant) String() string { - switch v { - case RFC4122: - return "RFC4122" - case Reserved: - return "Reserved" - case Microsoft: - return "Microsoft" - case Future: - return "Future" - case Invalid: - return "Invalid" - } - return fmt.Sprintf("BadVariant%d", int(v)) -} - -// SetRand sets the random number generator to r, which implements io.Reader. -// If r.Read returns an error when the package requests random data then -// a panic will be issued. -// -// Calling SetRand with nil sets the random number generator to the default -// generator. -func SetRand(r io.Reader) { - if r == nil { - rander = rand.Reader - return - } - rander = r -} diff --git a/vendor/github.com/google/uuid/version1.go b/vendor/github.com/google/uuid/version1.go deleted file mode 100644 index 199a1ac65..000000000 --- a/vendor/github.com/google/uuid/version1.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" -) - -// NewUUID returns a Version 1 UUID based on the current NodeID and clock -// sequence, and the current time. If the NodeID has not been set by SetNodeID -// or SetNodeInterface then it will be set automatically. If the NodeID cannot -// be set NewUUID returns nil. If clock sequence has not been set by -// SetClockSequence then it will be set automatically. If GetTime fails to -// return the current NewUUID returns nil and an error. -// -// In most cases, New should be used. -func NewUUID() (UUID, error) { - nodeMu.Lock() - if nodeID == zeroID { - setNodeInterface("") - } - nodeMu.Unlock() - - var uuid UUID - now, seq, err := GetTime() - if err != nil { - return uuid, err - } - - timeLow := uint32(now & 0xffffffff) - timeMid := uint16((now >> 32) & 0xffff) - timeHi := uint16((now >> 48) & 0x0fff) - timeHi |= 0x1000 // Version 1 - - binary.BigEndian.PutUint32(uuid[0:], timeLow) - binary.BigEndian.PutUint16(uuid[4:], timeMid) - binary.BigEndian.PutUint16(uuid[6:], timeHi) - binary.BigEndian.PutUint16(uuid[8:], seq) - copy(uuid[10:], nodeID[:]) - - return uuid, nil -} diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go deleted file mode 100644 index 9ad1abad0..000000000 --- a/vendor/github.com/google/uuid/version4.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import "io" - -// New creates a new random UUID or panics. New is equivalent to -// the expression -// -// uuid.Must(uuid.NewRandom()) -func New() UUID { - return Must(NewRandom()) -} - -// NewRandom returns a Random (Version 4) UUID. -// -// The strength of the UUIDs is based on the strength of the crypto/rand -// package. -// -// A note about uniqueness derived from the UUID Wikipedia entry: -// -// Randomly generated UUIDs have 122 random bits. One's annual risk of being -// hit by a meteorite is estimated to be one chance in 17 billion, that -// means the probability is about 0.00000000006 (6 × 10−11), -// equivalent to the odds of creating a few tens of trillions of UUIDs in a -// year and having one duplicate. -func NewRandom() (UUID, error) { - return NewRandomFromReader(rander) -} - -func NewRandomFromReader(r io.Reader) (UUID, error) { - var uuid UUID - _, err := io.ReadFull(r, uuid[:]) - if err != nil { - return Nil, err - } - uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 - uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 - return uuid, nil -} - diff --git a/vendor/github.com/kolo/xmlrpc/LICENSE b/vendor/github.com/kolo/xmlrpc/LICENSE deleted file mode 100644 index 8103dd139..000000000 --- a/vendor/github.com/kolo/xmlrpc/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2012 Dmitry Maksimov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/kolo/xmlrpc/README.md b/vendor/github.com/kolo/xmlrpc/README.md deleted file mode 100644 index 12b7692e9..000000000 --- a/vendor/github.com/kolo/xmlrpc/README.md +++ /dev/null @@ -1,79 +0,0 @@ -## Overview - -xmlrpc is an implementation of client side part of XMLRPC protocol in Go language. - -## Installation - -To install xmlrpc package run `go get github.com/kolo/xmlrpc`. To use -it in application add `"github.com/kolo/xmlrpc"` string to `import` -statement. - -## Usage - - client, _ := xmlrpc.NewClient("https://bugzilla.mozilla.org/xmlrpc.cgi", nil) - result := struct{ - Version string `xmlrpc:"version"` - }{} - client.Call("Bugzilla.version", nil, &result) - fmt.Printf("Version: %s\n", result.Version) // Version: 4.2.7+ - -Second argument of NewClient function is an object that implements -[http.RoundTripper](http://golang.org/pkg/net/http/#RoundTripper) -interface, it can be used to get more control over connection options. -By default it initialized by http.DefaultTransport object. - -### Arguments encoding - -xmlrpc package supports encoding of native Go data types to method -arguments. - -Data types encoding rules: -* int, int8, int16, int32, int64 encoded to int; -* float32, float64 encoded to double; -* bool encoded to boolean; -* string encoded to string; -* time.Time encoded to datetime.iso8601; -* xmlrpc.Base64 encoded to base64; -* slice decoded to array; - -Structs decoded to struct by following rules: -* all public field become struct members; -* field name become member name; -* if field has xmlrpc tag, its value become member name. - -Server method can accept few arguments, to handle this case there is -special approach to handle slice of empty interfaces (`[]interface{}`). -Each value of such slice encoded as separate argument. - -### Result decoding - -Result of remote function is decoded to native Go data type. - -Data types decoding rules: -* int, i4 decoded to int, int8, int16, int32, int64; -* double decoded to float32, float64; -* boolean decoded to bool; -* string decoded to string; -* array decoded to slice; -* structs decoded following the rules described in previous section; -* datetime.iso8601 decoded as time.Time data type; -* base64 decoded to string. - -## Implementation details - -xmlrpc package contains clientCodec type, that implements [rpc.ClientCodec](http://golang.org/pkg/net/rpc/#ClientCodec) -interface of [net/rpc](http://golang.org/pkg/net/rpc) package. - -xmlrpc package works over HTTP protocol, but some internal functions -and data type were made public to make it easier to create another -implementation of xmlrpc that works over another protocol. To encode -request body there is EncodeMethodCall function. To decode server -response Response data type can be used. - -## Contribution - -Feel free to fork the project, submit pull requests, ask questions. - -## Authors - -Dmitry Maksimov (dmtmax@gmail.com) diff --git a/vendor/github.com/kolo/xmlrpc/client.go b/vendor/github.com/kolo/xmlrpc/client.go deleted file mode 100644 index fb66b65fb..000000000 --- a/vendor/github.com/kolo/xmlrpc/client.go +++ /dev/null @@ -1,144 +0,0 @@ -package xmlrpc - -import ( - "fmt" - "io/ioutil" - "net/http" - "net/http/cookiejar" - "net/rpc" - "net/url" -) - -type Client struct { - *rpc.Client -} - -// clientCodec is rpc.ClientCodec interface implementation. -type clientCodec struct { - // url presents url of xmlrpc service - url *url.URL - - // httpClient works with HTTP protocol - httpClient *http.Client - - // cookies stores cookies received on last request - cookies http.CookieJar - - // responses presents map of active requests. It is required to return request id, that - // rpc.Client can mark them as done. - responses map[uint64]*http.Response - - response *Response - - // ready presents channel, that is used to link request and it`s response. - ready chan uint64 -} - -func (codec *clientCodec) WriteRequest(request *rpc.Request, args interface{}) (err error) { - httpRequest, err := NewRequest(codec.url.String(), request.ServiceMethod, args) - - if codec.cookies != nil { - for _, cookie := range codec.cookies.Cookies(codec.url) { - httpRequest.AddCookie(cookie) - } - } - - if err != nil { - return err - } - - var httpResponse *http.Response - httpResponse, err = codec.httpClient.Do(httpRequest) - - if err != nil { - return err - } - - if codec.cookies != nil { - codec.cookies.SetCookies(codec.url, httpResponse.Cookies()) - } - - codec.responses[request.Seq] = httpResponse - codec.ready <- request.Seq - - return nil -} - -func (codec *clientCodec) ReadResponseHeader(response *rpc.Response) (err error) { - seq := <-codec.ready - httpResponse := codec.responses[seq] - - if httpResponse.StatusCode < 200 || httpResponse.StatusCode >= 300 { - return fmt.Errorf("request error: bad status code - %d", httpResponse.StatusCode) - } - - respData, err := ioutil.ReadAll(httpResponse.Body) - - if err != nil { - return err - } - - httpResponse.Body.Close() - - resp := NewResponse(respData) - - if resp.Failed() { - response.Error = fmt.Sprintf("%v", resp.Err()) - } - - codec.response = resp - - response.Seq = seq - delete(codec.responses, seq) - - return nil -} - -func (codec *clientCodec) ReadResponseBody(v interface{}) (err error) { - if v == nil { - return nil - } - - if err = codec.response.Unmarshal(v); err != nil { - return err - } - - return nil -} - -func (codec *clientCodec) Close() error { - transport := codec.httpClient.Transport.(*http.Transport) - transport.CloseIdleConnections() - return nil -} - -// NewClient returns instance of rpc.Client object, that is used to send request to xmlrpc service. -func NewClient(requrl string, transport http.RoundTripper) (*Client, error) { - if transport == nil { - transport = http.DefaultTransport - } - - httpClient := &http.Client{Transport: transport} - - jar, err := cookiejar.New(nil) - - if err != nil { - return nil, err - } - - u, err := url.Parse(requrl) - - if err != nil { - return nil, err - } - - codec := clientCodec{ - url: u, - httpClient: httpClient, - ready: make(chan uint64), - responses: make(map[uint64]*http.Response), - cookies: jar, - } - - return &Client{rpc.NewClientWithCodec(&codec)}, nil -} diff --git a/vendor/github.com/kolo/xmlrpc/decoder.go b/vendor/github.com/kolo/xmlrpc/decoder.go deleted file mode 100644 index b73955978..000000000 --- a/vendor/github.com/kolo/xmlrpc/decoder.go +++ /dev/null @@ -1,449 +0,0 @@ -package xmlrpc - -import ( - "bytes" - "encoding/xml" - "errors" - "fmt" - "io" - "reflect" - "strconv" - "strings" - "time" -) - -const iso8601 = "20060102T15:04:05" - -var ( - // CharsetReader is a function to generate reader which converts a non UTF-8 - // charset into UTF-8. - CharsetReader func(string, io.Reader) (io.Reader, error) - - invalidXmlError = errors.New("invalid xml") -) - -type TypeMismatchError string - -func (e TypeMismatchError) Error() string { return string(e) } - -type decoder struct { - *xml.Decoder -} - -func unmarshal(data []byte, v interface{}) (err error) { - dec := &decoder{xml.NewDecoder(bytes.NewBuffer(data))} - - if CharsetReader != nil { - dec.CharsetReader = CharsetReader - } - - var tok xml.Token - for { - if tok, err = dec.Token(); err != nil { - return err - } - - if t, ok := tok.(xml.StartElement); ok { - if t.Name.Local == "value" { - val := reflect.ValueOf(v) - if val.Kind() != reflect.Ptr { - return errors.New("non-pointer value passed to unmarshal") - } - if err = dec.decodeValue(val.Elem()); err != nil { - return err - } - - break - } - } - } - - // read until end of document - err = dec.Skip() - if err != nil && err != io.EOF { - return err - } - - return nil -} - -func (dec *decoder) decodeValue(val reflect.Value) error { - var tok xml.Token - var err error - - if val.Kind() == reflect.Ptr { - if val.IsNil() { - val.Set(reflect.New(val.Type().Elem())) - } - val = val.Elem() - } - - var typeName string - for { - if tok, err = dec.Token(); err != nil { - return err - } - - if t, ok := tok.(xml.EndElement); ok { - if t.Name.Local == "value" { - return nil - } else { - return invalidXmlError - } - } - - if t, ok := tok.(xml.StartElement); ok { - typeName = t.Name.Local - break - } - - // Treat value data without type identifier as string - if t, ok := tok.(xml.CharData); ok { - if value := strings.TrimSpace(string(t)); value != "" { - if err = checkType(val, reflect.String); err != nil { - return err - } - - val.SetString(value) - return nil - } - } - } - - switch typeName { - case "struct": - ismap := false - pmap := val - valType := val.Type() - - if err = checkType(val, reflect.Struct); err != nil { - if checkType(val, reflect.Map) == nil { - if valType.Key().Kind() != reflect.String { - return fmt.Errorf("only maps with string key type can be unmarshalled") - } - ismap = true - } else if checkType(val, reflect.Interface) == nil && val.IsNil() { - var dummy map[string]interface{} - pmap = reflect.New(reflect.TypeOf(dummy)).Elem() - valType = pmap.Type() - ismap = true - } else { - return err - } - } - - var fields map[string]reflect.Value - - if !ismap { - fields = make(map[string]reflect.Value) - - for i := 0; i < valType.NumField(); i++ { - field := valType.Field(i) - fieldVal := val.FieldByName(field.Name) - - if fieldVal.CanSet() { - if fn := field.Tag.Get("xmlrpc"); fn != "" { - fields[fn] = fieldVal - } else { - fields[field.Name] = fieldVal - } - } - } - } else { - // Create initial empty map - pmap.Set(reflect.MakeMap(valType)) - } - - // Process struct members. - StructLoop: - for { - if tok, err = dec.Token(); err != nil { - return err - } - switch t := tok.(type) { - case xml.StartElement: - if t.Name.Local != "member" { - return invalidXmlError - } - - tagName, fieldName, err := dec.readTag() - if err != nil { - return err - } - if tagName != "name" { - return invalidXmlError - } - - var fv reflect.Value - ok := true - - if !ismap { - fv, ok = fields[string(fieldName)] - } else { - fv = reflect.New(valType.Elem()) - } - - if ok { - for { - if tok, err = dec.Token(); err != nil { - return err - } - if t, ok := tok.(xml.StartElement); ok && t.Name.Local == "value" { - if err = dec.decodeValue(fv); err != nil { - return err - } - - // - if err = dec.Skip(); err != nil { - return err - } - - break - } - } - } - - // - if err = dec.Skip(); err != nil { - return err - } - - if ismap { - pmap.SetMapIndex(reflect.ValueOf(string(fieldName)), reflect.Indirect(fv)) - val.Set(pmap) - } - case xml.EndElement: - break StructLoop - } - } - case "array": - pslice := val - if checkType(val, reflect.Interface) == nil && val.IsNil() { - var dummy []interface{} - pslice = reflect.New(reflect.TypeOf(dummy)).Elem() - } else if err = checkType(val, reflect.Slice); err != nil { - return err - } - - ArrayLoop: - for { - if tok, err = dec.Token(); err != nil { - return err - } - - switch t := tok.(type) { - case xml.StartElement: - if t.Name.Local != "data" { - return invalidXmlError - } - - slice := reflect.MakeSlice(pslice.Type(), 0, 0) - - DataLoop: - for { - if tok, err = dec.Token(); err != nil { - return err - } - - switch tt := tok.(type) { - case xml.StartElement: - if tt.Name.Local != "value" { - return invalidXmlError - } - - v := reflect.New(pslice.Type().Elem()) - if err = dec.decodeValue(v); err != nil { - return err - } - - slice = reflect.Append(slice, v.Elem()) - - // - if err = dec.Skip(); err != nil { - return err - } - case xml.EndElement: - pslice.Set(slice) - val.Set(pslice) - break DataLoop - } - } - case xml.EndElement: - break ArrayLoop - } - } - default: - if tok, err = dec.Token(); err != nil { - return err - } - - var data []byte - - switch t := tok.(type) { - case xml.EndElement: - return nil - case xml.CharData: - data = []byte(t.Copy()) - default: - return invalidXmlError - } - - switch typeName { - case "int", "i4", "i8": - if checkType(val, reflect.Interface) == nil && val.IsNil() { - i, err := strconv.ParseInt(string(data), 10, 64) - if err != nil { - return err - } - - pi := reflect.New(reflect.TypeOf(i)).Elem() - pi.SetInt(i) - val.Set(pi) - } else if err = checkType(val, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64); err != nil { - return err - } else { - i, err := strconv.ParseInt(string(data), 10, val.Type().Bits()) - if err != nil { - return err - } - - val.SetInt(i) - } - case "string", "base64": - str := string(data) - if checkType(val, reflect.Interface) == nil && val.IsNil() { - pstr := reflect.New(reflect.TypeOf(str)).Elem() - pstr.SetString(str) - val.Set(pstr) - } else if err = checkType(val, reflect.String); err != nil { - return err - } else { - val.SetString(str) - } - case "dateTime.iso8601": - t, err := time.Parse(iso8601, string(data)) - if err != nil { - return err - } - - if checkType(val, reflect.Interface) == nil && val.IsNil() { - ptime := reflect.New(reflect.TypeOf(t)).Elem() - ptime.Set(reflect.ValueOf(t)) - val.Set(ptime) - } else if _, ok := val.Interface().(time.Time); !ok { - return TypeMismatchError(fmt.Sprintf("error: type mismatch error - can't decode %v to time", val.Kind())) - } else { - val.Set(reflect.ValueOf(t)) - } - case "boolean": - v, err := strconv.ParseBool(string(data)) - if err != nil { - return err - } - - if checkType(val, reflect.Interface) == nil && val.IsNil() { - pv := reflect.New(reflect.TypeOf(v)).Elem() - pv.SetBool(v) - val.Set(pv) - } else if err = checkType(val, reflect.Bool); err != nil { - return err - } else { - val.SetBool(v) - } - case "double": - if checkType(val, reflect.Interface) == nil && val.IsNil() { - i, err := strconv.ParseFloat(string(data), 64) - if err != nil { - return err - } - - pdouble := reflect.New(reflect.TypeOf(i)).Elem() - pdouble.SetFloat(i) - val.Set(pdouble) - } else if err = checkType(val, reflect.Float32, reflect.Float64); err != nil { - return err - } else { - i, err := strconv.ParseFloat(string(data), val.Type().Bits()) - if err != nil { - return err - } - - val.SetFloat(i) - } - default: - return errors.New("unsupported type") - } - - // - if err = dec.Skip(); err != nil { - return err - } - } - - return nil -} - -func (dec *decoder) readTag() (string, []byte, error) { - var tok xml.Token - var err error - - var name string - for { - if tok, err = dec.Token(); err != nil { - return "", nil, err - } - - if t, ok := tok.(xml.StartElement); ok { - name = t.Name.Local - break - } - } - - value, err := dec.readCharData() - if err != nil { - return "", nil, err - } - - return name, value, dec.Skip() -} - -func (dec *decoder) readCharData() ([]byte, error) { - var tok xml.Token - var err error - - if tok, err = dec.Token(); err != nil { - return nil, err - } - - if t, ok := tok.(xml.CharData); ok { - return []byte(t.Copy()), nil - } else { - return nil, invalidXmlError - } -} - -func checkType(val reflect.Value, kinds ...reflect.Kind) error { - if len(kinds) == 0 { - return nil - } - - if val.Kind() == reflect.Ptr { - val = val.Elem() - } - - match := false - - for _, kind := range kinds { - if val.Kind() == kind { - match = true - break - } - } - - if !match { - return TypeMismatchError(fmt.Sprintf("error: type mismatch - can't unmarshal %v to %v", - val.Kind(), kinds[0])) - } - - return nil -} diff --git a/vendor/github.com/kolo/xmlrpc/encoder.go b/vendor/github.com/kolo/xmlrpc/encoder.go deleted file mode 100644 index bb1285ff7..000000000 --- a/vendor/github.com/kolo/xmlrpc/encoder.go +++ /dev/null @@ -1,164 +0,0 @@ -package xmlrpc - -import ( - "bytes" - "encoding/xml" - "fmt" - "reflect" - "strconv" - "time" -) - -type encodeFunc func(reflect.Value) ([]byte, error) - -func marshal(v interface{}) ([]byte, error) { - if v == nil { - return []byte{}, nil - } - - val := reflect.ValueOf(v) - return encodeValue(val) -} - -func encodeValue(val reflect.Value) ([]byte, error) { - var b []byte - var err error - - if val.Kind() == reflect.Ptr || val.Kind() == reflect.Interface { - if val.IsNil() { - return []byte(""), nil - } - - val = val.Elem() - } - - switch val.Kind() { - case reflect.Struct: - switch val.Interface().(type) { - case time.Time: - t := val.Interface().(time.Time) - b = []byte(fmt.Sprintf("%s", t.Format(iso8601))) - default: - b, err = encodeStruct(val) - } - case reflect.Map: - b, err = encodeMap(val) - case reflect.Slice: - b, err = encodeSlice(val) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - b = []byte(fmt.Sprintf("%s", strconv.FormatInt(val.Int(), 10))) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - b = []byte(fmt.Sprintf("%s", strconv.FormatUint(val.Uint(), 10))) - case reflect.Float32, reflect.Float64: - b = []byte(fmt.Sprintf("%s", - strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()))) - case reflect.Bool: - if val.Bool() { - b = []byte("1") - } else { - b = []byte("0") - } - case reflect.String: - var buf bytes.Buffer - - xml.Escape(&buf, []byte(val.String())) - - if _, ok := val.Interface().(Base64); ok { - b = []byte(fmt.Sprintf("%s", buf.String())) - } else { - b = []byte(fmt.Sprintf("%s", buf.String())) - } - default: - return nil, fmt.Errorf("xmlrpc encode error: unsupported type") - } - - if err != nil { - return nil, err - } - - return []byte(fmt.Sprintf("%s", string(b))), nil -} - -func encodeStruct(val reflect.Value) ([]byte, error) { - var b bytes.Buffer - - b.WriteString("") - - t := val.Type() - for i := 0; i < t.NumField(); i++ { - b.WriteString("") - f := t.Field(i) - - name := f.Tag.Get("xmlrpc") - if name == "" { - name = f.Name - } - b.WriteString(fmt.Sprintf("%s", name)) - - p, err := encodeValue(val.FieldByName(f.Name)) - if err != nil { - return nil, err - } - b.Write(p) - - b.WriteString("") - } - - b.WriteString("") - - return b.Bytes(), nil -} - -func encodeMap(val reflect.Value) ([]byte, error) { - var t = val.Type() - - if t.Key().Kind() != reflect.String { - return nil, fmt.Errorf("xmlrpc encode error: only maps with string keys are supported") - } - - var b bytes.Buffer - - b.WriteString("") - - keys := val.MapKeys() - - for i := 0; i < val.Len(); i++ { - key := keys[i] - kval := val.MapIndex(key) - - b.WriteString("") - b.WriteString(fmt.Sprintf("%s", key.String())) - - p, err := encodeValue(kval) - - if err != nil { - return nil, err - } - - b.Write(p) - b.WriteString("") - } - - b.WriteString("") - - return b.Bytes(), nil -} - -func encodeSlice(val reflect.Value) ([]byte, error) { - var b bytes.Buffer - - b.WriteString("") - - for i := 0; i < val.Len(); i++ { - p, err := encodeValue(val.Index(i)) - if err != nil { - return nil, err - } - - b.Write(p) - } - - b.WriteString("") - - return b.Bytes(), nil -} diff --git a/vendor/github.com/kolo/xmlrpc/request.go b/vendor/github.com/kolo/xmlrpc/request.go deleted file mode 100644 index acb8251b2..000000000 --- a/vendor/github.com/kolo/xmlrpc/request.go +++ /dev/null @@ -1,57 +0,0 @@ -package xmlrpc - -import ( - "bytes" - "fmt" - "net/http" -) - -func NewRequest(url string, method string, args interface{}) (*http.Request, error) { - var t []interface{} - var ok bool - if t, ok = args.([]interface{}); !ok { - if args != nil { - t = []interface{}{args} - } - } - - body, err := EncodeMethodCall(method, t...) - if err != nil { - return nil, err - } - - request, err := http.NewRequest("POST", url, bytes.NewReader(body)) - if err != nil { - return nil, err - } - - request.Header.Set("Content-Type", "text/xml") - request.Header.Set("Content-Length", fmt.Sprintf("%d", len(body))) - - return request, nil -} - -func EncodeMethodCall(method string, args ...interface{}) ([]byte, error) { - var b bytes.Buffer - b.WriteString(``) - b.WriteString(fmt.Sprintf("%s", method)) - - if args != nil { - b.WriteString("") - - for _, arg := range args { - p, err := marshal(arg) - if err != nil { - return nil, err - } - - b.WriteString(fmt.Sprintf("%s", string(p))) - } - - b.WriteString("") - } - - b.WriteString("") - - return b.Bytes(), nil -} diff --git a/vendor/github.com/kolo/xmlrpc/response.go b/vendor/github.com/kolo/xmlrpc/response.go deleted file mode 100644 index 6742a1c74..000000000 --- a/vendor/github.com/kolo/xmlrpc/response.go +++ /dev/null @@ -1,52 +0,0 @@ -package xmlrpc - -import ( - "regexp" -) - -var ( - faultRx = regexp.MustCompile(`(\s|\S)+`) -) - -type failedResponse struct { - Code int `xmlrpc:"faultCode"` - Error string `xmlrpc:"faultString"` -} - -func (r *failedResponse) err() error { - return &xmlrpcError{ - code: r.Code, - err: r.Error, - } -} - -type Response struct { - data []byte -} - -func NewResponse(data []byte) *Response { - return &Response{ - data: data, - } -} - -func (r *Response) Failed() bool { - return faultRx.Match(r.data) -} - -func (r *Response) Err() error { - failedResp := new(failedResponse) - if err := unmarshal(r.data, failedResp); err != nil { - return err - } - - return failedResp.err() -} - -func (r *Response) Unmarshal(v interface{}) error { - if err := unmarshal(r.data, v); err != nil { - return err - } - - return nil -} diff --git a/vendor/github.com/kolo/xmlrpc/test_server.rb b/vendor/github.com/kolo/xmlrpc/test_server.rb deleted file mode 100644 index 1b1ff8760..000000000 --- a/vendor/github.com/kolo/xmlrpc/test_server.rb +++ /dev/null @@ -1,25 +0,0 @@ -# encoding: utf-8 - -require "xmlrpc/server" - -class Service - def time - Time.now - end - - def upcase(s) - s.upcase - end - - def sum(x, y) - x + y - end - - def error - raise XMLRPC::FaultException.new(500, "Server error") - end -end - -server = XMLRPC::Server.new 5001, 'localhost' -server.add_handler "service", Service.new -server.serve diff --git a/vendor/github.com/kolo/xmlrpc/xmlrpc.go b/vendor/github.com/kolo/xmlrpc/xmlrpc.go deleted file mode 100644 index 8766403af..000000000 --- a/vendor/github.com/kolo/xmlrpc/xmlrpc.go +++ /dev/null @@ -1,19 +0,0 @@ -package xmlrpc - -import ( - "fmt" -) - -// xmlrpcError represents errors returned on xmlrpc request. -type xmlrpcError struct { - code int - err string -} - -// Error() method implements Error interface -func (e *xmlrpcError) Error() string { - return fmt.Sprintf("error: \"%s\" code: %d", e.err, e.code) -} - -// Base64 represents value in base64 encoding -type Base64 string diff --git a/vendor/github.com/prasmussen/gandi-api/LICENSE b/vendor/github.com/prasmussen/gandi-api/LICENSE deleted file mode 100644 index 4f2fadb51..000000000 --- a/vendor/github.com/prasmussen/gandi-api/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License - -Copyright (c) 2013 Petter Rasmussen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/vendor/github.com/prasmussen/gandi-api/client/client.go b/vendor/github.com/prasmussen/gandi-api/client/client.go deleted file mode 100644 index 478fd9817..000000000 --- a/vendor/github.com/prasmussen/gandi-api/client/client.go +++ /dev/null @@ -1,208 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net/http" - "strings" - - "github.com/kolo/xmlrpc" -) - -const ( - // Production is the SystemType to provide to New to use the production XML API - Production SystemType = iota - // Testing is the SystemType to provide to New to use the test XML API - Testing - // LiveDNS is the SystemType to provide to New to use the Live DNS REST API - // Full documentation of the API is available here: http://doc.livedns.gandi.net/ - LiveDNS -) - -// Enable/disable debug output: -const debug = false - -// SystemType is the type used to resolve gandi API address -type SystemType int - -// Url returns the actual gandi API base URL -func (s SystemType) Url() string { - if s == Production { - return "https://rpc.gandi.net/xmlrpc/" - } - if s == LiveDNS { - return "https://dns.api.gandi.net/api/v5/" - } - return "https://rpc.ote.gandi.net/xmlrpc/" -} - -// Client holds the configuration of a gandi client -type Client struct { - // Key is the API key to provide to gandi - Key string - // Url is the base URL of the gandi API - Url string -} - -// New creates a new gandi client for the given system -func New(apiKey string, system SystemType) *Client { - return &Client{ - Key: apiKey, - Url: system.Url(), - } -} - -// Call performs an acual XML RPC call to the gandi API -func (c *Client) Call(serviceMethod string, args []interface{}, reply interface{}) error { - rpc, err := xmlrpc.NewClient(c.Url, nil) - if err != nil { - return err - } - return rpc.Call(serviceMethod, args, reply) -} - -// DoRest performs a request to gandi LiveDNS api and optionnally decodes the reply -func (c *Client) DoRest(req *http.Request, decoded interface{}) (*http.Response, error) { - if decoded != nil { - req.Header.Set("Accept", "application/json") - } - client := http.Client{} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - if resp.StatusCode == http.StatusUnauthorized { - return nil, fmt.Errorf("the server returned unauthorized code. Your API key might be invalid or have expired") - } - // - defer func() { err = resp.Body.Close() }() - if decoded != nil { - b, e := ioutil.ReadAll(resp.Body) - if e != nil { - return nil, e - } - if len(b) > 0 { - e = json.Unmarshal(b, decoded) - if e != nil { - return nil, e - } - if resp.StatusCode == http.StatusBadRequest { - return nil, fmt.Errorf("the server returned 400 bad request (%v)", string(b)) - } - } - resp.Body = ioutil.NopCloser(bytes.NewReader(b)) - } - return resp, err -} - -// NewJSONRequest creates a new authenticated to gandi live DNS REST API. -// If data is not null, it will be encoded as json and prodived in the request body -func (c *Client) NewJSONRequest(method string, url string, data interface{}) (*http.Request, error) { - var reader io.Reader - if data != nil { - b, err := json.Marshal(data) - if err != nil { - return nil, err - } - reader = bytes.NewReader(b) - } - req, err := http.NewRequest(method, fmt.Sprintf("%s/%s", strings.TrimRight(c.Url, "/"), strings.TrimLeft(url, "/")), reader) - if err != nil { - return nil, err - } - if data != nil { - req.Header.Set("Content-Type", "application/json") - } - req.Header.Set("X-Api-Key", c.Key) - return req, nil -} - -// Get performs a Get request to gandi Live DNS api and decodes the returned data if a not null decoded pointer is provided -func (c *Client) Get(URI string, decoded interface{}) (*http.Response, error) { - req, err := c.NewJSONRequest("GET", URI, nil) - if err != nil { - return nil, err - } - resp, err := c.DoRest(req, decoded) - if err != nil { - return nil, err - } - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Unexpected http code %d on URL %v. expecting %d", resp.StatusCode, resp.Request.URL, http.StatusOK) - } - return resp, err -} - -// Delete performs a Delete request to gandi Live DNS api and decodes the returned data if a not null decoded pointer is provided -func (c *Client) Delete(URI string, decoded interface{}) (*http.Response, error) { - req, err := c.NewJSONRequest("DELETE", URI, nil) - if err != nil { - return nil, err - } - resp, err := c.DoRest(req, decoded) - if err != nil { - return nil, err - } - if resp.StatusCode != http.StatusNoContent { - return nil, fmt.Errorf("Unexpected http code %d on URL %v. expecting %d", resp.StatusCode, resp.Request.URL, http.StatusNoContent) - } - return resp, err -} - -// Post performs a Post request request to gandi Live DNS api -// - with data encoded as JSON if a not null data pointer is provided -// - decodes the returned data if a not null decoded pointer is provided -// - ensures the status code is an HTTP accepted -func (c *Client) Post(URI string, data interface{}, decoded interface{}) (*http.Response, error) { - if debug { - fmt.Printf("DEBUG: POST URI=%s\n", URI) - } - req, err := c.NewJSONRequest("POST", URI, data) - if err != nil { - return nil, err - } - if debug { - fmt.Printf("DEBUG: POST req=%v decoded=%v\n", req, decoded) - } - resp, err := c.DoRest(req, decoded) - if err != nil { - return nil, err - } - if resp.StatusCode != http.StatusCreated { - return nil, fmt.Errorf("Unexpected http code %d on URL %v. expecting %d", resp.StatusCode, resp.Request.URL, http.StatusCreated) - } - return resp, err -} - -// Put performs a Put request to gandi Live DNS api -// - with data encoded as JSON if a not null data pointer is provided -// - decodes the returned data if a not null decoded pointer is provided -func (c *Client) Put(URI string, data interface{}, decoded interface{}) (*http.Response, error) { - req, err := c.NewJSONRequest("PUT", URI, data) - if err != nil { - return nil, err - } - return c.DoRest(req, decoded) -} - -// Patch performs a Patch request to gandi Live DNS api -// - with data encoded as JSON if a not null data pointer is provided -// - decodes the returned data if a not null decoded pointer is provided -// - ensures the status code is an HTTP accepted -func (c *Client) Patch(URI string, data interface{}, decoded interface{}) (*http.Response, error) { - req, err := c.NewJSONRequest("PATCH", URI, data) - if err != nil { - return nil, err - } - resp, err := c.DoRest(req, decoded) - if err != nil { - return nil, err - } - if resp.StatusCode != http.StatusAccepted { - return nil, fmt.Errorf("Unexpected http code %d on URL %v. expecting %d", resp.StatusCode, resp.Request.URL, http.StatusAccepted) - } - return resp, err -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/domain.go b/vendor/github.com/prasmussen/gandi-api/domain/domain.go deleted file mode 100644 index 83b955ec6..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/domain.go +++ /dev/null @@ -1,87 +0,0 @@ -package domain - -import ( - "github.com/prasmussen/gandi-api/client" - "github.com/prasmussen/gandi-api/operation" -) - -type Domain struct { - *client.Client -} - -func New(c *client.Client) *Domain { - return &Domain{c} -} - -// Check the availability of some domain -func (self *Domain) Available(name string) (string, error) { - var result map[string]interface{} - domain := []string{name} - params := []interface{}{self.Key, domain} - if err := self.Call("domain.available", params, &result); err != nil { - return "", err - } - return result[name].(string), nil -} - -// Get domain information -func (self *Domain) Info(name string) (*DomainInfo, error) { - var res map[string]interface{} - params := []interface{}{self.Key, name} - if err := self.Call("domain.info", params, &res); err != nil { - return nil, err - } - return ToDomainInfo(res), nil -} - -// List domains associated to the contact represented by apikey -func (self *Domain) List() ([]*DomainInfoBase, error) { - opts := &struct { - Page int `xmlrpc:"page"` - }{0} - const perPage = 100 - params := []interface{}{self.Key, opts} - domains := make([]*DomainInfoBase, 0) - for { - var res []interface{} - if err := self.Call("domain.list", params, &res); err != nil { - return nil, err - } - for _, r := range res { - domain := ToDomainInfoBase(r.(map[string]interface{})) - domains = append(domains, domain) - } - if len(res) < perPage { - break - } - opts.Page++ - } - return domains, nil -} - -// Count domains associated to the contact represented by apikey -func (self *Domain) Count() (int64, error) { - var result int64 - params := []interface{}{self.Key} - if err := self.Call("domain.count", params, &result); err != nil { - return -1, err - } - return result, nil -} - -// Create a domain -func (self *Domain) Create(name, contactHandle string, years int64) (*operation.OperationInfo, error) { - var res map[string]interface{} - createArgs := map[string]interface{}{ - "admin": contactHandle, - "bill": contactHandle, - "owner": contactHandle, - "tech": contactHandle, - "duration": years, - } - params := []interface{}{self.Key, name, createArgs} - if err := self.Call("domain.create", params, &res); err != nil { - return nil, err - } - return operation.ToOperationInfo(res), nil -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/nameservers/nameservers.go b/vendor/github.com/prasmussen/gandi-api/domain/nameservers/nameservers.go deleted file mode 100644 index 7dd4a5224..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/nameservers/nameservers.go +++ /dev/null @@ -1,24 +0,0 @@ -package zone - -import ( - "github.com/prasmussen/gandi-api/client" - "github.com/prasmussen/gandi-api/operation" -) - -type Nameservers struct { - *client.Client -} - -func New(c *client.Client) *Nameservers { - return &Nameservers{c} -} - -// Set the current zone of a domain -func (self *Nameservers) Set(domainName string, nameservers []string) (*operation.OperationInfo, error) { - var res map[string]interface{} - params := []interface{}{self.Key, domainName, nameservers} - if err := self.Call("domain.nameservers.set", params, &res); err != nil { - return nil, err - } - return operation.ToOperationInfo(res), nil -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/structs.go b/vendor/github.com/prasmussen/gandi-api/domain/structs.go deleted file mode 100644 index d7d7ff6a8..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/structs.go +++ /dev/null @@ -1,57 +0,0 @@ -package domain - -import ( - "time" -) - -type DomainInfoBase struct { - AuthInfo string - DateCreated time.Time - DateRegistryCreation time.Time - DateRegistryEnd time.Time - DateUpdated time.Time - Fqdn string - Id int64 - Status []string - Tld string -} - -type DomainInfoExtra struct { - DateDelete time.Time - DateHoldBegin time.Time - DateHoldEnd time.Time - DatePendingDeleteEnd time.Time - DateRenewBegin time.Time - DateRestoreEnd time.Time - Nameservers []string - Services []string - ZoneId int64 - Autorenew *AutorenewInfo - Contacts *ContactInfo -} - -type DomainInfo struct { - *DomainInfoBase - *DomainInfoExtra -} - -type AutorenewInfo struct { - Active bool - Contact string - Id int64 - ProductId int64 - ProductTypeId int64 -} - -type ContactInfo struct { - Admin *ContactDetails - Bill *ContactDetails - Owner *ContactDetails - Reseller *ContactDetails - Tech *ContactDetails -} - -type ContactDetails struct { - Handle string - Id int64 -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/util.go b/vendor/github.com/prasmussen/gandi-api/domain/util.go deleted file mode 100644 index be4ece2f8..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/util.go +++ /dev/null @@ -1,69 +0,0 @@ -package domain - -import ( - "github.com/prasmussen/gandi-api/util" -) - -func ToDomainInfoBase(res map[string]interface{}) *DomainInfoBase { - return &DomainInfoBase{ - AuthInfo: util.ToString(res["authinfo"]), - DateCreated: util.ToTime(res["date_created"]), - DateRegistryCreation: util.ToTime(res["date_registry_creation"]), - DateRegistryEnd: util.ToTime(res["date_registry_end"]), - DateUpdated: util.ToTime(res["date_updated"]), - Fqdn: util.ToString(res["fqdn"]), - Id: util.ToInt64(res["id"]), - Status: util.ToStringSlice(util.ToInterfaceSlice(res["status"])), - Tld: util.ToString(res["tld"]), - } -} - -func ToDomainInfoExtra(res map[string]interface{}) *DomainInfoExtra { - return &DomainInfoExtra{ - DateDelete: util.ToTime(res["date_delete"]), - DateHoldBegin: util.ToTime(res["date_hold_begin"]), - DateHoldEnd: util.ToTime(res["date_hold_end"]), - DatePendingDeleteEnd: util.ToTime(res["date_pending_delete_end"]), - DateRenewBegin: util.ToTime(res["date_renew_begin"]), - DateRestoreEnd: util.ToTime(res["date_restore_end"]), - Nameservers: util.ToStringSlice(util.ToInterfaceSlice(res["nameservers"])), - Services: util.ToStringSlice(util.ToInterfaceSlice(res["services"])), - ZoneId: util.ToInt64(res["zone_id"]), - Autorenew: toAutorenewInfo(util.ToXmlrpcStruct(res["autorenew"])), - Contacts: toContactInfo(util.ToXmlrpcStruct(res["contacts"])), - } -} - -func ToDomainInfo(res map[string]interface{}) *DomainInfo { - return &DomainInfo{ - ToDomainInfoBase(res), - ToDomainInfoExtra(res), - } -} - -func toAutorenewInfo(res map[string]interface{}) *AutorenewInfo { - return &AutorenewInfo{ - Active: util.ToBool(res["active"]), - Contact: util.ToString(res["contact"]), - Id: util.ToInt64(res["id"]), - ProductId: util.ToInt64(res["product_id"]), - ProductTypeId: util.ToInt64(res["product_type_id"]), - } -} - -func toContactInfo(res map[string]interface{}) *ContactInfo { - return &ContactInfo{ - Admin: toContactDetails(util.ToXmlrpcStruct(res["admin"])), - Bill: toContactDetails(util.ToXmlrpcStruct(res["bill"])), - Owner: toContactDetails(util.ToXmlrpcStruct(res["owner"])), - Reseller: toContactDetails(util.ToXmlrpcStruct(res["reseller"])), - Tech: toContactDetails(util.ToXmlrpcStruct(res["tech"])), - } -} - -func toContactDetails(res map[string]interface{}) *ContactDetails { - return &ContactDetails{ - Handle: util.ToString(res["handle"]), - Id: util.ToInt64(res["id"]), - } -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/zone/record/record.go b/vendor/github.com/prasmussen/gandi-api/domain/zone/record/record.go deleted file mode 100644 index b06f7b500..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/zone/record/record.go +++ /dev/null @@ -1,129 +0,0 @@ -package record - -import ( - "github.com/prasmussen/gandi-api/client" -) - -type Record struct { - *client.Client -} - -func New(c *client.Client) *Record { - return &Record{c} -} - -// Count number of records for a given zone/version -func (self *Record) Count(zoneId, version int64) (int64, error) { - var result int64 - params := []interface{}{self.Key, zoneId, version} - if err := self.Call("domain.zone.record.count", params, &result); err != nil { - return -1, err - } - return result, nil -} - -// List records of a version of a DNS zone -func (self *Record) List(zoneId, version int64) ([]*RecordInfo, error) { - opts := &struct { - Page int `xmlrpc:"page"` - }{0} - const perPage = 100 - params := []interface{}{self.Key, zoneId, version, opts} - records := make([]*RecordInfo, 0) - for { - var res []interface{} - if err := self.Call("domain.zone.record.list", params, &res); err != nil { - return nil, err - } - for _, r := range res { - record := ToRecordInfo(r.(map[string]interface{})) - records = append(records, record) - } - if len(res) < perPage { - break - } - opts.Page++ - } - return records, nil -} - -// Add a new record to zone -func (self *Record) Add(args RecordAdd) (*RecordInfo, error) { - var res map[string]interface{} - createArgs := map[string]interface{}{ - "name": args.Name, - "type": args.Type, - "value": args.Value, - "ttl": args.Ttl, - } - - params := []interface{}{self.Key, args.Zone, args.Version, createArgs} - if err := self.Call("domain.zone.record.add", params, &res); err != nil { - return nil, err - } - return ToRecordInfo(res), nil -} - -// Remove a record from a zone/version -func (self *Record) Delete(zoneId, version int64, recordId string) (bool, error) { - var res int64 - deleteArgs := map[string]interface{}{"id": recordId} - params := []interface{}{self.Key, zoneId, version, deleteArgs} - if err := self.Call("domain.zone.record.delete", params, &res); err != nil { - return false, err - } - return (res == 1), nil -} - -// Update a record from zone/version -func (self *Record) Update(args RecordUpdate) ([]*RecordInfo, error) { - var res []interface{} - updateArgs := map[string]interface{}{ - "name": args.Name, - "type": args.Type, - "value": args.Value, - "ttl": args.Ttl, - } - updateOpts := map[string]string{ - "id": args.Id, - } - - params := []interface{}{self.Key, args.Zone, args.Version, updateOpts, updateArgs} - if err := self.Call("domain.zone.record.update", params, &res); err != nil { - return nil, err - } - - records := make([]*RecordInfo, 0) - for _, r := range res { - record := ToRecordInfo(r.(map[string]interface{})) - records = append(records, record) - } - return records, nil -} - -// SetRecords replaces the entire zone with new records. -func (self *Record) SetRecords(zone_id, version_id int64, args []RecordSet) ([]*RecordInfo, error) { - var res []interface{} - - params := []interface{}{self.Key, zone_id, version_id, args} - if err := self.Call("domain.zone.record.set", params, &res); err != nil { - return nil, err - } - - records := make([]*RecordInfo, 0) - for _, r := range res { - record := ToRecordInfo(r.(map[string]interface{})) - records = append(records, record) - } - return records, nil -} - -//// Set the current zone of a domain -//func (self *Record) Set(domainName string, id int64) (*domain.DomainInfo, error) { -// var res map[string]interface{} -// params := []interface{}{self.Key, domainName, id} -// if err := self.zone.set", params, &res); err != nil { -// return nil, err -// } -// return domain.ToDomainInfo(res), nil -//} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/zone/record/structs.go b/vendor/github.com/prasmussen/gandi-api/domain/zone/record/structs.go deleted file mode 100644 index ea9fd143d..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/zone/record/structs.go +++ /dev/null @@ -1,30 +0,0 @@ -package record - -type RecordInfo struct { - Id string - Name string - Ttl int64 - Type string - Value string -} - -type RecordAdd struct { - Zone int64 `goptions:"-z, --zone, obligatory, description='Zone id'"` - Version int64 `goptions:"-v, --version, obligatory, description='Zone version'"` - Name string `goptions:"-n, --name, obligatory, description='Record name. Relative name, may contain leading wildcard. @ for empty name'"` - Type string `goptions:"-t, --type, obligatory, description='Record type'"` - Value string `goptions:"-V, --value, obligatory, description='Value for record. Semantics depends on the record type.'"` - Ttl int64 `goptions:"-T, --ttl, description='Time to live, in seconds, between 5 minutes and 30 days'"` -} - -type RecordUpdate struct { - Zone int64 `goptions:"-z, --zone, obligatory, description='Zone id'"` - Version int64 `goptions:"-v, --version, obligatory, description='Zone version'"` - Name string `goptions:"-n, --name, obligatory, description='Record name. Relative name, may contain leading wildcard. @ for empty name'"` - Type string `goptions:"-t, --type, obligatory, description='Record type'"` - Value string `goptions:"-V, --value, obligatory, description='Value for record. Semantics depends on the record type.'"` - Ttl int64 `goptions:"-T, --ttl, description='Time to live, in seconds, between 5 minutes and 30 days'"` - Id string `goptions:"-r, --record, obligatory, description='Record id'"` -} - -type RecordSet map[string]interface{} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/zone/record/util.go b/vendor/github.com/prasmussen/gandi-api/domain/zone/record/util.go deleted file mode 100644 index 9a6add585..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/zone/record/util.go +++ /dev/null @@ -1,15 +0,0 @@ -package record - -import ( - "github.com/prasmussen/gandi-api/util" -) - -func ToRecordInfo(res map[string]interface{}) *RecordInfo { - return &RecordInfo{ - Id: util.ToString(res["id"]), - Name: util.ToString(res["name"]), - Ttl: util.ToInt64(res["ttl"]), - Type: util.ToString(res["type"]), - Value: util.ToString(res["value"]), - } -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/zone/structs.go b/vendor/github.com/prasmussen/gandi-api/domain/zone/structs.go deleted file mode 100644 index b42c659b9..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/zone/structs.go +++ /dev/null @@ -1,24 +0,0 @@ -package zone - -import ( - "time" -) - -type ZoneInfoBase struct { - DateUpdated time.Time - Id int64 - Name string - Public bool - Version int64 -} - -type ZoneInfoExtra struct { - Domains int64 - Owner string - Versions []int64 -} - -type ZoneInfo struct { - *ZoneInfoBase - *ZoneInfoExtra -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/zone/util.go b/vendor/github.com/prasmussen/gandi-api/domain/zone/util.go deleted file mode 100644 index cb21ec933..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/zone/util.go +++ /dev/null @@ -1,30 +0,0 @@ -package zone - -import ( - "github.com/prasmussen/gandi-api/util" -) - -func ToZoneInfoBase(res map[string]interface{}) *ZoneInfoBase { - return &ZoneInfoBase{ - DateUpdated: util.ToTime(res["date_updated"]), - Id: util.ToInt64(res["id"]), - Name: util.ToString(res["name"]), - Public: util.ToBool(res["public"]), - Version: util.ToInt64(res["version"]), - } -} - -func ToZoneInfoExtra(res map[string]interface{}) *ZoneInfoExtra { - return &ZoneInfoExtra{ - Domains: util.ToInt64(res["domains"]), - Owner: util.ToString(res["owner"]), - Versions: util.ToIntSlice(util.ToInterfaceSlice(res["versions"])), - } -} - -func ToZoneInfo(res map[string]interface{}) *ZoneInfo { - return &ZoneInfo{ - ToZoneInfoBase(res), - ToZoneInfoExtra(res), - } -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/zone/version/structs.go b/vendor/github.com/prasmussen/gandi-api/domain/zone/version/structs.go deleted file mode 100644 index a563efd2c..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/zone/version/structs.go +++ /dev/null @@ -1,10 +0,0 @@ -package version - -import ( - "time" -) - -type VersionInfo struct { - Id int64 - DateCreated time.Time -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/zone/version/util.go b/vendor/github.com/prasmussen/gandi-api/domain/zone/version/util.go deleted file mode 100644 index 95027b09a..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/zone/version/util.go +++ /dev/null @@ -1,13 +0,0 @@ -package version - -import ( - "github.com/prasmussen/gandi-api/util" -) - - -func ToVersionInfo(res map[string]interface{}) *VersionInfo { - return &VersionInfo{ - Id: util.ToInt64(res["id"]), - DateCreated: util.ToTime(res["date_created"]), - } -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/zone/version/version.go b/vendor/github.com/prasmussen/gandi-api/domain/zone/version/version.go deleted file mode 100644 index 1a61e99d9..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/zone/version/version.go +++ /dev/null @@ -1,68 +0,0 @@ -package version - -import "github.com/prasmussen/gandi-api/client" - -type Version struct { - *client.Client -} - -func New(c *client.Client) *Version { - return &Version{c} -} - -// Count this zone versions -func (self *Version) Count(zoneId int64) (int64, error) { - var result int64 - params := []interface{}{self.Key, zoneId} - if err := self.Call("domain.zone.version.count", params, &result); err != nil { - return -1, err - } - return result, nil -} - -// List this zone versions, with their creation date -func (self *Version) List(zoneId int64) ([]*VersionInfo, error) { - var res []interface{} - params := []interface{}{self.Key, zoneId} - if err := self.Call("domain.zone.version.list", params, &res); err != nil { - return nil, err - } - - versions := make([]*VersionInfo, 0) - for _, r := range res { - version := ToVersionInfo(r.(map[string]interface{})) - versions = append(versions, version) - } - return versions, nil -} - -// Create a new version from another version. This will duplicate the version’s records -func (self *Version) New(zoneId, version int64) (int64, error) { - var res int64 - - params := []interface{}{self.Key, zoneId, version} - if err := self.Call("domain.zone.version.new", params, &res); err != nil { - return -1, err - } - return res, nil -} - -// Delete a specific version -func (self *Version) Delete(zoneId, version int64) (bool, error) { - var res bool - params := []interface{}{self.Key, zoneId, version} - if err := self.Call("domain.zone.version.delete", params, &res); err != nil { - return false, err - } - return res, nil -} - -// Set the active version of a zone -func (self *Version) Set(zoneId, version int64) (bool, error) { - var res bool - params := []interface{}{self.Key, zoneId, version} - if err := self.Call("domain.zone.version.set", params, &res); err != nil { - return false, err - } - return res, nil -} diff --git a/vendor/github.com/prasmussen/gandi-api/domain/zone/zone.go b/vendor/github.com/prasmussen/gandi-api/domain/zone/zone.go deleted file mode 100644 index d4e49744f..000000000 --- a/vendor/github.com/prasmussen/gandi-api/domain/zone/zone.go +++ /dev/null @@ -1,81 +0,0 @@ -package zone - -import ( - "github.com/prasmussen/gandi-api/client" - "github.com/prasmussen/gandi-api/domain" -) - -type Zone struct { - *client.Client -} - -func New(c *client.Client) *Zone { - return &Zone{c} -} - -// Counts accessible zones -func (self *Zone) Count() (int64, error) { - var result int64 - params := []interface{}{self.Key} - if err := self.Call("domain.zone.count", params, &result); err != nil { - return -1, err - } - return result, nil -} - -// Get zone information -func (self *Zone) Info(id int64) (*ZoneInfo, error) { - var res map[string]interface{} - params := []interface{}{self.Key, id} - if err := self.Call("domain.zone.info", params, &res); err != nil { - return nil, err - } - return ToZoneInfo(res), nil -} - -// List accessible DNS zones. -func (self *Zone) List() ([]*ZoneInfoBase, error) { - var res []interface{} - params := []interface{}{self.Key} - if err := self.Call("domain.zone.list", params, &res); err != nil { - return nil, err - } - - zones := make([]*ZoneInfoBase, 0) - for _, r := range res { - zone := ToZoneInfoBase(r.(map[string]interface{})) - zones = append(zones, zone) - } - return zones, nil -} - -// Create a zone -func (self *Zone) Create(name string) (*ZoneInfo, error) { - var res map[string]interface{} - createArgs := map[string]interface{}{"name": name} - params := []interface{}{self.Key, createArgs} - if err := self.Call("domain.zone.create", params, &res); err != nil { - return nil, err - } - return ToZoneInfo(res), nil -} - -// Delete a zone -func (self *Zone) Delete(id int64) (bool, error) { - var res bool - params := []interface{}{self.Key, id} - if err := self.Call("domain.zone.delete", params, &res); err != nil { - return false, err - } - return res, nil -} - -// Set the current zone of a domain -func (self *Zone) Set(domainName string, id int64) (*domain.DomainInfo, error) { - var res map[string]interface{} - params := []interface{}{self.Key, domainName, id} - if err := self.Call("domain.zone.set", params, &res); err != nil { - return nil, err - } - return domain.ToDomainInfo(res), nil -} diff --git a/vendor/github.com/prasmussen/gandi-api/live_dns/domain/domain.go b/vendor/github.com/prasmussen/gandi-api/live_dns/domain/domain.go deleted file mode 100644 index bf9b7ab03..000000000 --- a/vendor/github.com/prasmussen/gandi-api/live_dns/domain/domain.go +++ /dev/null @@ -1,35 +0,0 @@ -package domain - -import ( - "fmt" - - "github.com/prasmussen/gandi-api/client" - "github.com/prasmussen/gandi-api/live_dns/record" -) - -// Domain holds the domain client stucture -type Domain struct { - *client.Client -} - -// New instanciates a new Domain client -func New(c *client.Client) *Domain { - return &Domain{c} -} - -// List domains associated to the contact represented by apikey -func (d *Domain) List() (domains []*InfoBase, err error) { - _, err = d.Get("/domains", &domains) - return -} - -// Info Gets domain information -func (d *Domain) Info(name string) (infos *Info, err error) { - _, err = d.Get(fmt.Sprintf("/domains/%s", name), &infos) - return -} - -// Records gets a record client for the current domain -func (d *Domain) Records(name string) record.Manager { - return record.New(d.Client, fmt.Sprintf("/domains/%s", name)) -} diff --git a/vendor/github.com/prasmussen/gandi-api/live_dns/domain/structs.go b/vendor/github.com/prasmussen/gandi-api/live_dns/domain/structs.go deleted file mode 100644 index 1f579e041..000000000 --- a/vendor/github.com/prasmussen/gandi-api/live_dns/domain/structs.go +++ /dev/null @@ -1,32 +0,0 @@ -package domain - -import "github.com/google/uuid" - -// InfoBase holds the basic domain informations returned by the domain listing -type InfoBase struct { - // Fqdn stands for Fully Qualified Domain Name. It is the domain name managed by gandi (.) - Fqdn string `json:"fqdn,omitempty"` - // DomainRecordsHref contains the API URL to retrieve all records registered for the domain - DomainRecordsHref string `json:"domain_records_href,omitempty"` - // DomainHref contains the API URL to retrieve full DomainInfo for this domain - DomainHref string `json:"domain_href,omitempty"` -} - -// InfoExtra holds the extra domain informations returned by domain details -type InfoExtra struct { - // ZomeUUID is the id of the zone currently configured on this domain - ZoneUUID *uuid.UUID `json:"zone_uuid,omitempty"` - // DomainKeysHref contains the API URL to list DNSSEC keys for this domain - // note: DNSSEC is currently not supported by this library. - DomainKeysHref string `json:"domain_keys_href,omitempty"` - // ZoneHref contains the API URL to retrieve informations about the zone - ZoneHref string `json:"zone_href,omitempty"` - // ZoneRecordsHref contains the API URL to retrieve all records registered for the zone linked to this domain - ZoneRecordsHref string `json:"zone_records_href,omitempty"` -} - -// Info holds all domain information -type Info struct { - *InfoBase - *InfoExtra -} diff --git a/vendor/github.com/prasmussen/gandi-api/live_dns/record/record.go b/vendor/github.com/prasmussen/gandi-api/live_dns/record/record.go deleted file mode 100644 index f1a4fc04f..000000000 --- a/vendor/github.com/prasmussen/gandi-api/live_dns/record/record.go +++ /dev/null @@ -1,185 +0,0 @@ -package record - -import ( - "fmt" - "strings" - - "github.com/prasmussen/gandi-api/client" -) - -// Record holds the zone client structure -type Record struct { - *client.Client - Prefix string -} - -// Creator is an interface to create new record entries -type Creator interface { - // Create creates a new record entry - // possible calls are: - // Create(recordInfo) - // Create(recordInfo, "entry") - // Create(recordInfo, "entry", "type") - // where "entry" matches entry.example.com - // and "type" is the record type (A, CNAME, ...) - Create(recordInfo Info, args ...string) (status *Status, err error) -} - -// Updater is an interface to update existing record entries -type Updater interface { - // Update creates a new record entry - // possible calls are: - // Update(recordInfo) - // Update(recordInfo, "entry") - // Update(recordInfo, "entry", "type") - // where "entry" matches entry.example.com - // and "type" is the record type (A, CNAME, ...) - Update(recordInfo Info, args ...string) (status *Status, err error) -} - -// Lister is an interface to list existing record entries -type Lister interface { - // List creates a new record entry - // possible calls are: - // List(recordInfo) - // List(recordInfo, "entry") - // List(recordInfo, "entry", "type") - // where "entry" matches entry.example.com - // and "type" is the record type (A, CNAME, ...) - List(args ...string) (list []*Info, err error) -} - -// Deleter is an interface to delete existing record entries -type Deleter interface { - // Delete creates a new record entry - // possible calls are: - // Delete(recordInfo) - // Delete(recordInfo, "entry") - // Delete(recordInfo, "entry", "type") - // where "entry" matches entry.example.com - // and "type" is the record type (A, CNAME, ...) - Delete(args ...string) (err error) -} - -// Manager is an interface to manage records (for a zone or domain) -type Manager interface { - Creator - Updater - Lister - Deleter -} - -// New instanciates a new instance of a Zone client -func New(c *client.Client, prefix string) *Record { - return &Record{c, prefix} -} - -func (r *Record) uri(pattern string, paths ...string) string { - args := make([]interface{}, len(paths)) - for i, v := range paths { - args[i] = v - } - return fmt.Sprintf("%s/%s", - strings.TrimRight(r.Prefix, "/"), - strings.TrimLeft(fmt.Sprintf(pattern, args...), "/")) -} - -func (r *Record) formatCallError(function string, args ...string) error { - format := "unexpected arguments for function %s." + - " supported calls are: %s(), %s(), %s(, )" + - " %s called with" - a := []interface{}{ - function, - function, function, function, - function, - } - for _, v := range args { - format = format + " %s" - a = append(a, v) - } - return fmt.Errorf(format, a...) -} - -// Create creates a new record entry -// possible calls are: -// Create(recordInfo) -// Create(recordInfo, "entry") -// Create(recordInfo, "entry", "type") -// where "entry" matches entry.example.com -// and "type" is the record type (A, CNAME, ...) -func (r *Record) Create(recordInfo Info, args ...string) (status *Status, err error) { - switch len(args) { - case 0: - _, err = r.Post(r.uri("/records"), recordInfo, &status) - case 1: - _, err = r.Post(r.uri("/records/%s", args...), recordInfo, &status) - case 2: - _, err = r.Post(r.uri("/records/%s/%s", args...), recordInfo, &status) - default: - err = r.formatCallError("Create", args...) - } - return -} - -// Update creates a new record entry -// possible calls are: -// Update(recordInfo) -// Update(recordInfo, "entry") -// Update(recordInfo, "entry", "type") -// where "entry" matches entry.example.com -// and "type" is the record type (A, CNAME, ...) -func (r *Record) Update(recordInfo Info, args ...string) (status *Status, err error) { - switch len(args) { - case 0: - _, err = r.Put(r.uri("/records"), recordInfo, &status) - case 1: - _, err = r.Put(r.uri("/records/%s", args...), recordInfo, &status) - case 2: - _, err = r.Put(r.uri("/records/%s/%s", args...), recordInfo, &status) - default: - err = r.formatCallError("Update", args...) - } - return -} - -// List creates a new record entry -// possible calls are: -// List(recordInfo) -// List(recordInfo, "entry") -// List(recordInfo, "entry", "type") -// where "entry" matches entry.example.com -// and "type" is the record type (A, CNAME, ...) -func (r *Record) List(args ...string) (list []*Info, err error) { - switch len(args) { - case 0: - _, err = r.Get(r.uri("/records"), &list) - case 1: - _, err = r.Get(r.uri("/records/%s", args...), &list) - case 2: - _, err = r.Get(r.uri("/records/%s/%s", args...), &list) - default: - err = r.formatCallError("List", args...) - } - return -} - -// Delete creates a new record entry -// possible calls are: -// Delete(recordInfo) -// Delete(recordInfo, "entry") -// Delete(recordInfo, "entry", "type") -// where "entry" matches entry.example.com -// and "type" is the record type (A, CNAME, ...) -func (r *Record) Delete(args ...string) (err error) { - switch len(args) { - case 0: - _, err = r.Client.Delete(r.uri("/records"), nil) - case 1: - _, err = r.Client.Delete(r.uri("/records/%s", args...), nil) - case 2: - _, err = r.Client.Delete(r.uri("/records/%s/%s", args...), nil) - default: - err = r.formatCallError("Delete", args...) - } - return -} diff --git a/vendor/github.com/prasmussen/gandi-api/live_dns/record/structs.go b/vendor/github.com/prasmussen/gandi-api/live_dns/record/structs.go deleted file mode 100644 index 0b011a009..000000000 --- a/vendor/github.com/prasmussen/gandi-api/live_dns/record/structs.go +++ /dev/null @@ -1,68 +0,0 @@ -package record - -const ( - // A is the type of record that hold a 32-bit IPv4 address, most commonly used to map hostnames to an IP address of the host - A = "A" - // AAAA is the type of record that hold a Returns a 128-bit IPv6 address, most commonly used to map hostnames to an IP address of the host - AAAA = "AAAA" - // CAA is the type of record that hold the DNS Certification Authority Authorization, constraining acceptable CAs for a host/domain - CAA = "CAA" - // CDS is the type of record that hold the child copy of DS record, for transfer to parent - CDS = "CDS" - // CNAME is the type of record that hold the alias of one name to another: the DNS lookup will continue by retrying the lookup with the new name - CNAME = "CNAME" - // DNAME is the type of record that hold the alias for a name and all its subnames, unlike CNAME, which is an alias for only the exact name. - // Like a CNAME record, the DNS lookup will continue by retrying the lookup with the new name - DNAME = "DNAME" - // DS is the type of record that hold the record used to identify the DNSSEC signing key of a delegated zone - DS = "DS" - // LOC is the type of record that specifies a geographical location associated with a domain name - LOC = "LOC" - // MX is the type of record that maps a domain name to a list of message transfer agents for that domain - MX = "MX" - // NS is the type of record that delegates a DNS zone to use the given authoritative name servers - NS = "NS" - // PTR is the type of record that hold a pointer to a canonical name. Unlike a CNAME, DNS processing stops and just the name is returned. - // The most common use is for implementing reverse DNS lookups, but other uses include such things as DNS-SD. - PTR = "PTR" - // SPF (99) (from RFC 4408) was specified as part of the Sender Policy Framework protocol as an alternative to storing SPF data in TXT records, - // using the same format. It was later found that the majority of SPF deployments lack proper support for this record type, and support for it was discontinued in RFC 7208 - SPF = "SPF" - // SRV is the type of record that hold the generalized service location record, used for newer protocols instead of creating protocol-specific records such as MX. - SRV = "SRV" - // SSHFP is the type of record that hold resource record for publishing SSH public host key fingerprints in the DNS System, - // in order to aid in verifying the authenticity of the host. RFC 6594 defines ECC SSH keys and SHA-256 hashes - SSHFP = "SSHFP" - // TLSA is the type of record that hold a record for DANE. - // record for DANE. RFC 6698 defines "The TLSA DNS resource record is used to associate a TLS server - // certificate or public key with the domain name where the record is found, thus forming a 'TLSA certificate association'". - TLSA = "TLSA" - // TXT is the type of record that hold human readable text. - // Since the early 1990s, however, this record more often carries machine-readable data, - // such as specified by RFC 1464, opportunistic encryption, Sender Policy Framework, DKIM, DMARC, DNS-SD, etc. - TXT = "TXT" - // WKS is the type of record that describe well-known services supported by a host. Not used in practice. - // The current recommendation and practice is to determine whether a service is supported on an IP address by trying to connect to it. - // SMTP is even prohibited from using WKS records in MX processing - WKS = "WKS" -) - -// Info holds the record informations for a single record entry -type Info struct { - // Href contains the API URL to get the record informations - Href string `json:"rrset_href,omitempty"` - // Name contains name of the subdomain for this record - Name string `json:"rrset_name,omitempty"` - // TTL contains the life time of the record. - TTL int64 `json:"rrset_ttl,omitempty"` - // Type contains the DNS record type - Type string `json:"rrset_type,omitempty"` - // Values contains the DNS values resolved by the record - Values []string `json:"rrset_values,omitempty"` -} - -// Status holds the data returned by the API in case of record creation or update -type Status struct { - // Message is the status message returned by the gandi api - Message string `json:"message"` -} diff --git a/vendor/github.com/prasmussen/gandi-api/live_dns/zone/structs.go b/vendor/github.com/prasmussen/gandi-api/live_dns/zone/structs.go deleted file mode 100644 index aee43f12c..000000000 --- a/vendor/github.com/prasmussen/gandi-api/live_dns/zone/structs.go +++ /dev/null @@ -1,56 +0,0 @@ -package zone - -import "github.com/google/uuid" - -// Source: http://knowledgelayer.softlayer.com/faq/what-does-serial-refresh-retry-expire-minimum-and-ttl-mean - -// Info holds the DNS zone informations -type Info struct { - // Retry is the amount of time in seconds that a domain's primary name server (or servers) - // should wait if an attempt to refresh by a secondary name server failed before - // attempting to refresh a domain's zone with that secondary name server again. - Retry int `json:"retry,omitempty"` - // UUID is the zone id - UUID *uuid.UUID `json:"uuid,omitempty"` - // Minimum is the amount of time in seconds that a domain's resource records are valid. - // This is also known as a minimum TTL, and can be overridden by an individual resource record's TTL - Minimum int `json:"minimum,omitempty"` - // Refresh is the amount of time in seconds that a secondary name server should wait to check for - // a new copy of a DNS zone from the domain's primary name server. If a zone file has changed then - // the secondary DNS server will update it's copy of the zone to match the primary DNS server's zone - Refresh int `json:"refresh,omitempty"` - // Expire is the amount of time in seconds that a secondary name server (or servers) will - // hold a zone before it is no longer considered authoritative - Expire int64 `json:"expire,omitempty"` - // SharingID is currently undocumented in http://doc.livedns.gandi.net/ - // But seems to be the ID used to https://admin.gandi.net/domain/<...> - SharingID *uuid.UUID `json:"sharing_id,omitempty"` - // Serial is the revision number of this zone file. Increment this number each time the zone - // file is changed so that the changes will be distributed to any secondary DNS servers - Serial int `json:"serial,omitempty"` - // Email is listed but undocumented in http://doc.livedns.gandi.net/ - Email string `json:"email,omitempty"` - // PrimaryNS is the name of the nameserver to be used for this zone - PrimaryNS string `json:"primary_ns,omitempty"` - // Name is the name of the zone - Name string `json:"name,omitempty"` - // DomainsHref contains the API URL to retrieve all domains using this zone - DomainsHref string `json:"domains_href,omitempty"` - // ZoneHref contains the API URL to retrieve full DomainInfo for this domain - ZoneHref string `json:"zone_href,omitempty"` - // ZoneRecordsHref contains the API URL to retrieve all records registered for the zone linked to this zone - ZoneRecordsHref string `json:"zone_records_href,omitempty"` -} - -// Status holds the data returned by the API in case of zone update or association to a domain -type Status struct { - // Message is the status message returned by the gandi api - Message string `json:"message"` -} - -// CreateStatus holds the data for returned by the API zone creation -type CreateStatus struct { - *Status - // UUID is the created zone ID - UUID *uuid.UUID `json:"uuid"` -} diff --git a/vendor/github.com/prasmussen/gandi-api/live_dns/zone/zone.go b/vendor/github.com/prasmussen/gandi-api/live_dns/zone/zone.go deleted file mode 100644 index 3c882ac3c..000000000 --- a/vendor/github.com/prasmussen/gandi-api/live_dns/zone/zone.go +++ /dev/null @@ -1,100 +0,0 @@ -package zone - -import ( - "fmt" - - "github.com/google/uuid" - "github.com/prasmussen/gandi-api/client" - "github.com/prasmussen/gandi-api/live_dns/domain" - "github.com/prasmussen/gandi-api/live_dns/record" -) - -// Enable/disable debug output: -const debug = false - -// Zone holds the zone client structure -type Zone struct { - *client.Client -} - -// New instanciates a new instance of a Zone client -func New(c *client.Client) *Zone { - return &Zone{c} -} - -// List accessible DNS zones. -func (z *Zone) List() (zones []*Info, err error) { - _, err = z.Get("/zones", &zones) - return -} - -// InfoByUUID Gets zone information from its UUID -func (z *Zone) InfoByUUID(uuid uuid.UUID) (info *Info, err error) { - _, err = z.Get(fmt.Sprintf("/zones/%s", uuid), &info) - if debug { - fmt.Printf("DEBUG: InfoByUUID returned SharingID=%v domain=%v\n", info.SharingID, info.Name) - } - return -} - -// Info Gets zone information -func (z *Zone) Info(zoneInfo Info) (info *Info, err error) { - if zoneInfo.UUID == nil { - return nil, fmt.Errorf("can not get zone info %s without an id", zoneInfo.Name) - } - return z.InfoByUUID(*zoneInfo.UUID) -} - -// Create creates a new zone -func (z *Zone) Create(zoneInfo Info) (status *CreateStatus, err error) { - if debug { - fmt.Printf("DEBUG: Create WILL SET SharingID=%v domain=%v\n", zoneInfo.SharingID, zoneInfo.Name) - } - _, err = z.Post(fmt.Sprintf("/zones?sharing_id=%s", zoneInfo.SharingID), zoneInfo, &status) - return -} - -// Update updates an existing zone -func (z *Zone) Update(zoneInfo Info) (status *Status, err error) { - if zoneInfo.UUID == nil { - return nil, fmt.Errorf("can not update zone %s without an id", zoneInfo.Name) - } - _, err = z.Patch(fmt.Sprintf("/zones/%s", zoneInfo.UUID), zoneInfo, &status) - return -} - -// Delete Deletes an existing zone -func (z *Zone) Delete(zoneInfo Info) (err error) { - if zoneInfo.UUID == nil { - return fmt.Errorf("can not update zone %s without an id", zoneInfo.Name) - } - _, err = z.Client.Delete(fmt.Sprintf("/zones/%s", zoneInfo.UUID), nil) - return -} - -// Domains lists all domains using a zone -func (z *Zone) Domains(zoneInfo Info) (domains []*domain.InfoBase, err error) { - if zoneInfo.UUID == nil { - return nil, fmt.Errorf("can not get domains on a zone %s without an id", zoneInfo.Name) - } - _, err = z.Get(fmt.Sprintf("/zones/%s/domains", zoneInfo.UUID), &domains) - return - -} - -// Set the current zone of a domain -func (z *Zone) Set(domainName string, zoneInfo Info) (status *Status, err error) { - if zoneInfo.UUID == nil { - return nil, fmt.Errorf("can not attach a domain %s to a zone %s without an id", domainName, zoneInfo.Name) - } - if debug { - fmt.Printf("DEBUG: Set WILL SET SharingID=%v domain=%s dn=%v\n", zoneInfo.SharingID, domainName, zoneInfo.Name) - } - _, err = z.Post(fmt.Sprintf("/zones/%s/domains/%s", zoneInfo.UUID, domainName), nil, &status) - return -} - -// Records gets a record client for the current zone -func (z *Zone) Records(zoneInfo Info) record.Manager { - return record.New(z.Client, fmt.Sprintf("/zones/%s", zoneInfo.UUID)) -} diff --git a/vendor/github.com/prasmussen/gandi-api/operation/operation.go b/vendor/github.com/prasmussen/gandi-api/operation/operation.go deleted file mode 100644 index 844cddbc9..000000000 --- a/vendor/github.com/prasmussen/gandi-api/operation/operation.go +++ /dev/null @@ -1,60 +0,0 @@ -package operation - -import "github.com/prasmussen/gandi-api/client" - -type Operation struct { - *client.Client -} - -func New(c *client.Client) *Operation { - return &Operation{c} -} - -// Count operations created by this contact -func (self *Operation) Count() (int64, error) { - var result int64 - // params := Params{Params: []interface{}{self.Key}} - params := []interface{}{self.Key} - if err := self.Call("operation.count", params, &result); err != nil { - return -1, err - } - return result, nil -} - -// Get operation information -func (self *Operation) Info(id int64) (*OperationInfo, error) { - var res map[string]interface{} - // params := Params{Params: []interface{}{self.Key, id}} - params := []interface{}{self.Key, id} - if err := self.Call("operation.info", params, &res); err != nil { - return nil, err - } - return ToOperationInfo(res), nil -} - -// Cancel an operation -func (self *Operation) Cancel(id int64) (bool, error) { - var res bool - // params := Params{Params: []interface{}{self.Key, id}} - params := []interface{}{self.Key, id} - if err := self.Call("operation.cancel", params, &res); err != nil { - return false, err - } - return res, nil -} - -// List operations created by this contact -func (self *Operation) List() ([]*OperationInfo, error) { - var res []interface{} - // params := Params{Params: []interface{}{self.Key}} - params := []interface{}{self.Key} - if err := self.Call("operation.list", params, &res); err != nil { - return nil, err - } - - operations := make([]*OperationInfo, len(res), len(res)) - for i, r := range res { - operations[i] = ToOperationInfo(r.(map[string]interface{})) - } - return operations, nil -} diff --git a/vendor/github.com/prasmussen/gandi-api/operation/structs.go b/vendor/github.com/prasmussen/gandi-api/operation/structs.go deleted file mode 100644 index 2625031ae..000000000 --- a/vendor/github.com/prasmussen/gandi-api/operation/structs.go +++ /dev/null @@ -1,29 +0,0 @@ -package operation - -import ( - "time" -) - -type OperationInfo struct { - DateCreated time.Time - DateStart time.Time - DateUpdated time.Time - Eta string - Id int64 - LastError string - SessionId int64 - Source string - Step string - Type string - Params map[string]interface{} - OperationDetails *OperationDetails -} - -type OperationDetails struct { - Id string - Label string - ProductAction string - ProductName string - ProductType string - Quantity int64 -} diff --git a/vendor/github.com/prasmussen/gandi-api/operation/util.go b/vendor/github.com/prasmussen/gandi-api/operation/util.go deleted file mode 100644 index 5f5800848..000000000 --- a/vendor/github.com/prasmussen/gandi-api/operation/util.go +++ /dev/null @@ -1,33 +0,0 @@ -package operation - -import ( - "github.com/prasmussen/gandi-api/util" -) - -func ToOperationInfo(res map[string]interface{}) *OperationInfo { - return &OperationInfo{ - DateCreated: util.ToTime(res["date_created"]), - DateStart: util.ToTime(res["date_start"]), - DateUpdated: util.ToTime(res["date_updated"]), - Eta: util.ToString(res["eta"]), - Id: util.ToInt64(res["id"]), - LastError: util.ToString(res["last_error"]), - SessionId: util.ToInt64(res["session_id"]), - Source: util.ToString(res["source"]), - Step: util.ToString(res["step"]), - Type: util.ToString(res["type"]), - OperationDetails: ToOperationDetails(util.ToXmlrpcStruct(res["infos"])), - Params: util.ToXmlrpcStruct(res["params"]), - } -} - -func ToOperationDetails(res map[string]interface{}) *OperationDetails { - return &OperationDetails{ - Id: util.ToString(res["id"]), - Label: util.ToString(res["label"]), - ProductAction: util.ToString(res["product_action"]), - ProductName: util.ToString(res["product_name"]), - ProductType: util.ToString(res["product_type"]), - Quantity: util.ToInt64(res["quantity"]), - } -} diff --git a/vendor/github.com/prasmussen/gandi-api/util/util.go b/vendor/github.com/prasmussen/gandi-api/util/util.go deleted file mode 100644 index be6221a9e..000000000 --- a/vendor/github.com/prasmussen/gandi-api/util/util.go +++ /dev/null @@ -1,76 +0,0 @@ -package util - -import "time" - -func ToStringSlice(is []interface{}) []string { - ss := make([]string, len(is), len(is)) - - for i, _ := range is { - ss[i] = is[i].(string) - } - return ss -} - -func ToString(i interface{}) string { - if v, ok := i.(string); ok { - return v - } - return "" -} - -func ToTime(i interface{}) time.Time { - if v, ok := i.(time.Time); ok { - return v - } - var t time.Time - return t -} - -func ToInterfaceSlice(i interface{}) []interface{} { - if v, ok := i.([]interface{}); ok { - return v - } - var s []interface{} - return s -} - -func ToInt64(i interface{}) int64 { - if v, ok := i.(int64); ok { - return v - } - var n int64 - return n -} - -func ToFloat64(i interface{}) float64 { - if v, ok := i.(float64); ok { - return v - } - var n float64 - return n -} - -func ToXmlrpcStruct(i interface{}) map[string]interface{} { - if v, ok := i.(map[string]interface{}); ok { - return v - } - var s map[string]interface{} - return s -} - -func ToBool(i interface{}) bool { - if v, ok := i.(bool); ok { - return v - } - var b bool - return b -} - -func ToIntSlice(is []interface{}) []int64 { - numbers := make([]int64, len(is), len(is)) - - for i, _ := range is { - numbers[i] = ToInt64(is[i]) - } - return numbers -} diff --git a/vendor/modules.txt b/vendor/modules.txt index e8f67c7d5..5913a81cf 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -147,9 +147,6 @@ github.com/google/go-github/github # github.com/google/go-querystring v1.0.1-0.20190318165438-c8c88dbee036 ## explicit github.com/google/go-querystring/query -# github.com/google/uuid v1.1.2-0.20190416172445-c2e93f3ae59f -## explicit -github.com/google/uuid # github.com/googleapis/gax-go/v2 v2.0.5 github.com/googleapis/gax-go/v2 # github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 @@ -208,9 +205,6 @@ github.com/hexonet/go-sdk/socketconfig # github.com/jmespath/go-jmespath v0.0.0-20200310193758-2437e8417af5 ## explicit github.com/jmespath/go-jmespath -# github.com/kolo/xmlrpc v0.0.0-20150413191830-0826b98aaa29 -## explicit -github.com/kolo/xmlrpc # github.com/malexdev/utfutil v0.0.0-20180510171754-00c8d4a8e7a8 ## explicit # github.com/miekg/dns v1.1.27 @@ -240,19 +234,6 @@ github.com/pierrec/lz4/internal/xxh32 github.com/pkg/errors # github.com/pmezard/go-difflib v1.0.0 github.com/pmezard/go-difflib/difflib -# github.com/prasmussen/gandi-api v0.0.0-20180224132202-58d3d4205661 -## explicit -github.com/prasmussen/gandi-api/client -github.com/prasmussen/gandi-api/domain -github.com/prasmussen/gandi-api/domain/nameservers -github.com/prasmussen/gandi-api/domain/zone -github.com/prasmussen/gandi-api/domain/zone/record -github.com/prasmussen/gandi-api/domain/zone/version -github.com/prasmussen/gandi-api/live_dns/domain -github.com/prasmussen/gandi-api/live_dns/record -github.com/prasmussen/gandi-api/live_dns/zone -github.com/prasmussen/gandi-api/operation -github.com/prasmussen/gandi-api/util # github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 ## explicit github.com/renier/xmlrpc