dnsign 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +34 -0
- data/Rakefile +2 -0
- data/bin/dnsign +18 -0
- data/config/example.yml +4 -0
- data/dnsign.gemspec +30 -0
- data/lib/dnsign.rb +15 -0
- data/lib/dnsign/config_loader.rb +49 -0
- data/lib/dnsign/dns_service.rb +33 -0
- data/lib/dnsign/dns_services/digital_ocean.rb +63 -0
- data/lib/dnsign/dns_services/linode.rb +64 -0
- data/lib/dnsign/error.rb +9 -0
- data/lib/dnsign/ip_resolver.rb +21 -0
- data/lib/dnsign/ip_resolvers/ip_info_io.rb +23 -0
- data/lib/dnsign/resolve_update_loop.rb +70 -0
- data/lib/dnsign/version.rb +3 -0
- data/lib/vendor/droplet_kit.rb +28 -0
- data/spec/dns_services/digital_ocean_spec.rb +43 -0
- data/spec/dns_services/linode_spec.rb +43 -0
- data/spec/fixtures/vcr_cassettes/digital_ocean_create_domain_record.yml +129 -0
- data/spec/fixtures/vcr_cassettes/digital_ocean_read_domain_record.yml +65 -0
- data/spec/fixtures/vcr_cassettes/digital_ocean_update_domain_record.yml +129 -0
- data/spec/fixtures/vcr_cassettes/ip_resolver_ip_info_io_response.yml +48 -0
- data/spec/fixtures/vcr_cassettes/linode_create_domain_record.yml +159 -0
- data/spec/fixtures/vcr_cassettes/linode_read_domain_record.yml +81 -0
- data/spec/fixtures/vcr_cassettes/linode_update_domain_record.yml +120 -0
- data/spec/ip_resolver_spec.rb +13 -0
- data/spec/resolve_update_loop_spec.rb +25 -0
- data/spec/spec_helper.rb +31 -0
- metadata +205 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'timers'
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
require 'dnsign/error'
|
6
|
+
require 'dnsign/ip_resolver'
|
7
|
+
require 'dnsign/dns_service'
|
8
|
+
|
9
|
+
module Dnsign
|
10
|
+
class ResolveUpdateLoop
|
11
|
+
|
12
|
+
def initialize(domain, dns_service, ip_resolver, opts={})
|
13
|
+
@domain = domain
|
14
|
+
@ip_resolver = ip_resolver
|
15
|
+
@dns_service = dns_service
|
16
|
+
@timers = Timers::Group.new
|
17
|
+
|
18
|
+
@verbose = opts[:verbose].nil? ? true : opts[:verbose]
|
19
|
+
@interval = opts[:interval] || 300
|
20
|
+
end
|
21
|
+
|
22
|
+
def kickoff
|
23
|
+
if @interval > 0
|
24
|
+
@timer = @timers.every( @interval ) { update }
|
25
|
+
loop { @timers.wait }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def update
|
30
|
+
real_ip = resolve_real_ip
|
31
|
+
dns_ip = retrieve_dns_ip
|
32
|
+
|
33
|
+
if real_ip != dns_ip
|
34
|
+
update_dns_ip(real_ip)
|
35
|
+
log "UPDATE: Public #{real_ip} differs from the resolved #{dns_ip}"
|
36
|
+
true
|
37
|
+
else
|
38
|
+
log "SKIPPING: Public #{real_ip} matches with the resolved #{dns_ip}"
|
39
|
+
false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def resolve_real_ip
|
46
|
+
@ip_resolver.resolve
|
47
|
+
rescue InvalidResponseFromIpResolver => e
|
48
|
+
log e
|
49
|
+
end
|
50
|
+
|
51
|
+
def retrieve_dns_ip
|
52
|
+
@dns_service.retrieve_ip @domain
|
53
|
+
rescue RecordDoesNotExists => e
|
54
|
+
log e
|
55
|
+
end
|
56
|
+
|
57
|
+
def update_dns_ip(real_ip)
|
58
|
+
@dns_service.update_ip @domain, real_ip
|
59
|
+
rescue DomainDoesNotExists => e
|
60
|
+
log e
|
61
|
+
end
|
62
|
+
|
63
|
+
def log(msg)
|
64
|
+
if @verbose == true
|
65
|
+
puts ["[#{Time.now.utc}]", msg].join ' '
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
### Monkey patch
|
2
|
+
#
|
3
|
+
# DropletKit doesn't permit updating of 'data' attribute of domain record,
|
4
|
+
# even if DigitalOcean API documention says it should.
|
5
|
+
#
|
6
|
+
# https://github.com/digitalocean/droplet_kit/blob/master/lib/droplet_kit/mappings/domain_record_mapping.rb#L12
|
7
|
+
# https://developers.digitalocean.com/documentation/v2/#update-a-domain-record
|
8
|
+
# https://github.com/digitalocean/droplet_kit/issues/44
|
9
|
+
#
|
10
|
+
|
11
|
+
module DropletKit
|
12
|
+
class DomainRecordMapping
|
13
|
+
include Kartograph::DSL
|
14
|
+
|
15
|
+
kartograph do
|
16
|
+
mapping DomainRecord
|
17
|
+
root_key plural: 'domain_records', singular: 'domain_record', scopes: [:read]
|
18
|
+
|
19
|
+
property :id, scopes: [:read]
|
20
|
+
property :type, scopes: [:read, :create]
|
21
|
+
property :name, scopes: [:read, :create, :update]
|
22
|
+
property :data, scopes: [:read, :create, :update] # :update added
|
23
|
+
property :priority, scopes: [:read, :create]
|
24
|
+
property :port, scopes: [:read, :create]
|
25
|
+
property :weight, scopes: [:read, :create]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'dnsign/dns_services/digital_ocean'
|
2
|
+
|
3
|
+
RSpec.describe DnsServices::DigitalOcean do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
@service = DnsServices::DigitalOcean.new access_token: '...'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#update_ip' do
|
10
|
+
|
11
|
+
it 'creates new domain record' do
|
12
|
+
VCR.use_cassette('digital_ocean_create_domain_record') do
|
13
|
+
ip = @service.update_ip 'foo.floatingpoint.io', '127.0.0.1'
|
14
|
+
expect(ip).to eq('127.0.0.1')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'updates existing domain record' do
|
19
|
+
VCR.use_cassette('digital_ocean_update_domain_record') do
|
20
|
+
ip = @service.update_ip 'foo.floatingpoint.io', '127.0.1.1'
|
21
|
+
expect(ip).to eq('127.0.1.1')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#retrieve_ip' do
|
27
|
+
|
28
|
+
it 'fetches existing domain record and returns its IP' do
|
29
|
+
VCR.use_cassette('digital_ocean_read_domain_record') do
|
30
|
+
ip = @service.retrieve_ip 'foo.floatingpoint.io'
|
31
|
+
expect(ip).to eq('127.0.0.1')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns nil for nonexisting record name' do
|
36
|
+
VCR.use_cassette('digital_ocean_read_domain_record') do
|
37
|
+
ip = @service.retrieve_ip 'bar.floatingpoint.io'
|
38
|
+
expect(ip).to be_nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'dnsign/dns_services/linode'
|
2
|
+
|
3
|
+
RSpec.describe DnsServices::Linode do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
@service = DnsServices::Linode.new access_token: '...'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#update_ip' do
|
10
|
+
|
11
|
+
it 'creates new domain record' do
|
12
|
+
VCR.use_cassette('linode_create_domain_record') do
|
13
|
+
ip = @service.update_ip 'foo.floatingpoint.io', '127.0.0.1'
|
14
|
+
expect(ip).to eq('127.0.0.1')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'updates existing domain record' do
|
19
|
+
VCR.use_cassette('linode_update_domain_record') do
|
20
|
+
ip = @service.update_ip 'foo.floatingpoint.io', '127.0.1.1'
|
21
|
+
expect(ip).to eq('127.0.1.1')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#retrieve_ip' do
|
27
|
+
|
28
|
+
it 'fetches existing domain record and returns its IP' do
|
29
|
+
VCR.use_cassette('linode_read_domain_record') do
|
30
|
+
ip = @service.retrieve_ip 'foo.floatingpoint.io'
|
31
|
+
expect(ip).to eq('127.0.0.1')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns nil for nonexisting record name' do
|
36
|
+
VCR.use_cassette('linode_read_domain_record') do
|
37
|
+
ip = @service.retrieve_ip 'bar.floatingpoint.io'
|
38
|
+
expect(ip).to be_nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://api.digitalocean.com/v2/domains/floatingpoint.io/records
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/json
|
12
|
+
Authorization:
|
13
|
+
- Bearer ...
|
14
|
+
User-Agent:
|
15
|
+
- Faraday v0.9.1
|
16
|
+
Accept-Encoding:
|
17
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
18
|
+
Accept:
|
19
|
+
- "*/*"
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Server:
|
26
|
+
- cloudflare-nginx
|
27
|
+
Date:
|
28
|
+
- Mon, 13 Apr 2015 19:36:52 GMT
|
29
|
+
Content-Type:
|
30
|
+
- application/json; charset=utf-8
|
31
|
+
Transfer-Encoding:
|
32
|
+
- chunked
|
33
|
+
Connection:
|
34
|
+
- keep-alive
|
35
|
+
Set-Cookie:
|
36
|
+
- __cfduid=d6dcb738dedb3817ef26bae5640926e731428953811; expires=Tue, 12-Apr-16
|
37
|
+
19:36:51 GMT; path=/; domain=.digitalocean.com; HttpOnly
|
38
|
+
Status:
|
39
|
+
- 200 OK
|
40
|
+
X-Frame-Options:
|
41
|
+
- SAMEORIGIN
|
42
|
+
X-Xss-Protection:
|
43
|
+
- 1; mode=block
|
44
|
+
X-Content-Type-Options:
|
45
|
+
- nosniff
|
46
|
+
Ratelimit-Limit:
|
47
|
+
- '5000'
|
48
|
+
Ratelimit-Remaining:
|
49
|
+
- '4994'
|
50
|
+
Ratelimit-Reset:
|
51
|
+
- '1428957146'
|
52
|
+
Cache-Control:
|
53
|
+
- max-age=0, private, must-revalidate
|
54
|
+
X-Request-Id:
|
55
|
+
- d9dfb763-61af-496c-a227-56b524c3ee73
|
56
|
+
X-Runtime:
|
57
|
+
- '0.135043'
|
58
|
+
Cf-Ray:
|
59
|
+
- 1d699f4b5efa02db-AMS
|
60
|
+
body:
|
61
|
+
encoding: UTF-8
|
62
|
+
string: '{"domain_records":[{"id":1851008,"type":"NS","name":"@","data":"ns1.digitalocean.com","priority":null,"port":null,"weight":null},{"id":1851009,"type":"NS","name":"@","data":"ns2.digitalocean.com","priority":null,"port":null,"weight":null},{"id":1851010,"type":"NS","name":"@","data":"ns3.digitalocean.com","priority":null,"port":null,"weight":null},{"id":1851925,"type":"A","name":"@","data":"178.62.198.200","priority":null,"port":null,"weight":null},{"id":1851934,"type":"A","name":"floatingpoint.io","data":"178.62.198.200","priority":null,"port":null,"weight":null},{"id":1851939,"type":"CNAME","name":"www","data":"@","priority":null,"port":null,"weight":null},{"id":1929343,"type":"MX","name":"@","data":"aspmx.l.google.com","priority":1,"port":null,"weight":null},{"id":1929344,"type":"MX","name":"@","data":"alt1.aspmx.l.google.com","priority":5,"port":null,"weight":null},{"id":1929345,"type":"MX","name":"@","data":"alt2.aspmx.l.google.com","priority":5,"port":null,"weight":null},{"id":1929346,"type":"MX","name":"@","data":"aspmx2.googlemail.com","priority":10,"port":null,"weight":null},{"id":1929347,"type":"MX","name":"@","data":"aspmx3.googlemail.com","priority":10,"port":null,"weight":null},{"id":3671318,"type":"CNAME","name":"jabber","data":"@","priority":null,"port":null,"weight":null},{"id":3671325,"type":"SRV","name":"_xmpp-client._tcp","data":"jabber","priority":0,"port":5222,"weight":5},{"id":3671326,"type":"SRV","name":"_xmpp-server._tcp","data":"jabber","priority":0,"port":5269,"weight":5},{"id":5529034,"type":"CNAME","name":"structuredmind","data":"@","priority":null,"port":null,"weight":null}],"links":{},"meta":{"total":15}}'
|
63
|
+
http_version:
|
64
|
+
recorded_at: Mon, 13 Apr 2015 19:36:51 GMT
|
65
|
+
- request:
|
66
|
+
method: post
|
67
|
+
uri: https://api.digitalocean.com/v2/domains/floatingpoint.io/records
|
68
|
+
body:
|
69
|
+
encoding: UTF-8
|
70
|
+
string: '{"type":"A","name":"foo","data":"127.0.0.1","priority":null,"port":null,"weight":null}'
|
71
|
+
headers:
|
72
|
+
Content-Type:
|
73
|
+
- application/json
|
74
|
+
Authorization:
|
75
|
+
- Bearer 740ed6dd3e97e498892b2c2d0fd74376dc259c2b4cf898b168fbaa650171b732
|
76
|
+
User-Agent:
|
77
|
+
- Faraday v0.9.1
|
78
|
+
Accept-Encoding:
|
79
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
80
|
+
Accept:
|
81
|
+
- "*/*"
|
82
|
+
response:
|
83
|
+
status:
|
84
|
+
code: 201
|
85
|
+
message: Created
|
86
|
+
headers:
|
87
|
+
Server:
|
88
|
+
- cloudflare-nginx
|
89
|
+
Date:
|
90
|
+
- Mon, 13 Apr 2015 19:36:54 GMT
|
91
|
+
Content-Type:
|
92
|
+
- application/json; charset=utf-8
|
93
|
+
Transfer-Encoding:
|
94
|
+
- chunked
|
95
|
+
Connection:
|
96
|
+
- keep-alive
|
97
|
+
Set-Cookie:
|
98
|
+
- __cfduid=d6aa26e5acbbfad1f7cd829526d828c9c1428953813; expires=Tue, 12-Apr-16
|
99
|
+
19:36:53 GMT; path=/; domain=.digitalocean.com; HttpOnly
|
100
|
+
Status:
|
101
|
+
- 201 Created
|
102
|
+
X-Frame-Options:
|
103
|
+
- SAMEORIGIN
|
104
|
+
X-Xss-Protection:
|
105
|
+
- 1; mode=block
|
106
|
+
X-Content-Type-Options:
|
107
|
+
- nosniff
|
108
|
+
Ratelimit-Limit:
|
109
|
+
- '5000'
|
110
|
+
Ratelimit-Remaining:
|
111
|
+
- '4993'
|
112
|
+
Ratelimit-Reset:
|
113
|
+
- '1428957146'
|
114
|
+
Etag:
|
115
|
+
- '"89d865317d5ead6eb139000676801d45"'
|
116
|
+
Cache-Control:
|
117
|
+
- max-age=0, private, must-revalidate
|
118
|
+
X-Request-Id:
|
119
|
+
- 4f54b117-79cb-4b13-be2b-929cb24d9362
|
120
|
+
X-Runtime:
|
121
|
+
- '0.240406'
|
122
|
+
Cf-Ray:
|
123
|
+
- 1d699f5961e700dd-AMS
|
124
|
+
body:
|
125
|
+
encoding: UTF-8
|
126
|
+
string: '{"domain_record":{"id":6221827,"type":"A","name":"foo","data":"127.0.0.1","priority":null,"port":null,"weight":null}}'
|
127
|
+
http_version:
|
128
|
+
recorded_at: Mon, 13 Apr 2015 19:36:53 GMT
|
129
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,65 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://api.digitalocean.com/v2/domains/floatingpoint.io/records
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/json
|
12
|
+
Authorization:
|
13
|
+
- Bearer ...
|
14
|
+
User-Agent:
|
15
|
+
- Faraday v0.9.1
|
16
|
+
Accept-Encoding:
|
17
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
18
|
+
Accept:
|
19
|
+
- "*/*"
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Server:
|
26
|
+
- cloudflare-nginx
|
27
|
+
Date:
|
28
|
+
- Mon, 13 Apr 2015 19:37:52 GMT
|
29
|
+
Content-Type:
|
30
|
+
- application/json; charset=utf-8
|
31
|
+
Transfer-Encoding:
|
32
|
+
- chunked
|
33
|
+
Connection:
|
34
|
+
- keep-alive
|
35
|
+
Set-Cookie:
|
36
|
+
- __cfduid=de5d21637edd51517b39f58b486a037bc1428953871; expires=Tue, 12-Apr-16
|
37
|
+
19:37:51 GMT; path=/; domain=.digitalocean.com; HttpOnly
|
38
|
+
Status:
|
39
|
+
- 200 OK
|
40
|
+
X-Frame-Options:
|
41
|
+
- SAMEORIGIN
|
42
|
+
X-Xss-Protection:
|
43
|
+
- 1; mode=block
|
44
|
+
X-Content-Type-Options:
|
45
|
+
- nosniff
|
46
|
+
Ratelimit-Limit:
|
47
|
+
- '5000'
|
48
|
+
Ratelimit-Remaining:
|
49
|
+
- '4990'
|
50
|
+
Ratelimit-Reset:
|
51
|
+
- '1428957146'
|
52
|
+
Cache-Control:
|
53
|
+
- max-age=0, private, must-revalidate
|
54
|
+
X-Request-Id:
|
55
|
+
- 92b081c0-f198-461c-a23e-e4db62582a7e
|
56
|
+
X-Runtime:
|
57
|
+
- '0.153754'
|
58
|
+
Cf-Ray:
|
59
|
+
- 1d69a0c204ab0c17-AMS
|
60
|
+
body:
|
61
|
+
encoding: UTF-8
|
62
|
+
string: '{"domain_records":[{"id":1851008,"type":"NS","name":"@","data":"ns1.digitalocean.com","priority":null,"port":null,"weight":null},{"id":1851009,"type":"NS","name":"@","data":"ns2.digitalocean.com","priority":null,"port":null,"weight":null},{"id":1851010,"type":"NS","name":"@","data":"ns3.digitalocean.com","priority":null,"port":null,"weight":null},{"id":1851925,"type":"A","name":"@","data":"178.62.198.200","priority":null,"port":null,"weight":null},{"id":1851934,"type":"A","name":"floatingpoint.io","data":"178.62.198.200","priority":null,"port":null,"weight":null},{"id":1851939,"type":"CNAME","name":"www","data":"@","priority":null,"port":null,"weight":null},{"id":1929343,"type":"MX","name":"@","data":"aspmx.l.google.com","priority":1,"port":null,"weight":null},{"id":1929344,"type":"MX","name":"@","data":"alt1.aspmx.l.google.com","priority":5,"port":null,"weight":null},{"id":1929345,"type":"MX","name":"@","data":"alt2.aspmx.l.google.com","priority":5,"port":null,"weight":null},{"id":1929346,"type":"MX","name":"@","data":"aspmx2.googlemail.com","priority":10,"port":null,"weight":null},{"id":1929347,"type":"MX","name":"@","data":"aspmx3.googlemail.com","priority":10,"port":null,"weight":null},{"id":3671318,"type":"CNAME","name":"jabber","data":"@","priority":null,"port":null,"weight":null},{"id":3671325,"type":"SRV","name":"_xmpp-client._tcp","data":"jabber","priority":0,"port":5222,"weight":5},{"id":3671326,"type":"SRV","name":"_xmpp-server._tcp","data":"jabber","priority":0,"port":5269,"weight":5},{"id":5529034,"type":"CNAME","name":"structuredmind","data":"@","priority":null,"port":null,"weight":null},{"id":6221827,"type":"A","name":"foo","data":"127.0.0.1","priority":null,"port":null,"weight":null}],"links":{},"meta":{"total":16}}'
|
63
|
+
http_version:
|
64
|
+
recorded_at: Mon, 13 Apr 2015 19:37:52 GMT
|
65
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,129 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://api.digitalocean.com/v2/domains/floatingpoint.io/records
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/json
|
12
|
+
Authorization:
|
13
|
+
- Bearer ...
|
14
|
+
User-Agent:
|
15
|
+
- Faraday v0.9.12
|
16
|
+
Accept-Encoding:
|
17
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
18
|
+
Accept:
|
19
|
+
- "*/*"
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Server:
|
26
|
+
- cloudflare-nginx
|
27
|
+
Date:
|
28
|
+
- Thu, 16 Apr 2015 19:29:20 GMT
|
29
|
+
Content-Type:
|
30
|
+
- application/json; charset=utf-8
|
31
|
+
Transfer-Encoding:
|
32
|
+
- chunked
|
33
|
+
Connection:
|
34
|
+
- keep-alive
|
35
|
+
Set-Cookie:
|
36
|
+
- __cfduid=df01ae98350a0aa7920da8d212da6e7311429212560; expires=Fri, 15-Apr-16
|
37
|
+
19:29:20 GMT; path=/; domain=.digitalocean.com; HttpOnly
|
38
|
+
Status:
|
39
|
+
- 200 OK
|
40
|
+
X-Frame-Options:
|
41
|
+
- SAMEORIGIN
|
42
|
+
X-Xss-Protection:
|
43
|
+
- 1; mode=block
|
44
|
+
X-Content-Type-Options:
|
45
|
+
- nosniff
|
46
|
+
Ratelimit-Limit:
|
47
|
+
- '5000'
|
48
|
+
Ratelimit-Remaining:
|
49
|
+
- '4999'
|
50
|
+
Ratelimit-Reset:
|
51
|
+
- '1429216160'
|
52
|
+
Cache-Control:
|
53
|
+
- max-age=0, private, must-revalidate
|
54
|
+
X-Request-Id:
|
55
|
+
- ccf97b83-481c-4cd1-bac0-3bf5e8c89d10
|
56
|
+
X-Runtime:
|
57
|
+
- '0.137237'
|
58
|
+
Cf-Ray:
|
59
|
+
- 1d824c65923b0557-VIE
|
60
|
+
body:
|
61
|
+
encoding: UTF-8
|
62
|
+
string: '{"domain_records":[{"id":1851008,"type":"NS","name":"@","data":"ns1.digitalocean.com","priority":null,"port":null,"weight":null},{"id":1851009,"type":"NS","name":"@","data":"ns2.digitalocean.com","priority":null,"port":null,"weight":null},{"id":1851010,"type":"NS","name":"@","data":"ns3.digitalocean.com","priority":null,"port":null,"weight":null},{"id":1851925,"type":"A","name":"@","data":"178.62.198.200","priority":null,"port":null,"weight":null},{"id":1851934,"type":"A","name":"floatingpoint.io","data":"178.62.198.200","priority":null,"port":null,"weight":null},{"id":1851939,"type":"CNAME","name":"www","data":"@","priority":null,"port":null,"weight":null},{"id":1929343,"type":"MX","name":"@","data":"aspmx.l.google.com","priority":1,"port":null,"weight":null},{"id":1929344,"type":"MX","name":"@","data":"alt1.aspmx.l.google.com","priority":5,"port":null,"weight":null},{"id":1929345,"type":"MX","name":"@","data":"alt2.aspmx.l.google.com","priority":5,"port":null,"weight":null},{"id":1929346,"type":"MX","name":"@","data":"aspmx2.googlemail.com","priority":10,"port":null,"weight":null},{"id":1929347,"type":"MX","name":"@","data":"aspmx3.googlemail.com","priority":10,"port":null,"weight":null},{"id":3671318,"type":"CNAME","name":"jabber","data":"@","priority":null,"port":null,"weight":null},{"id":3671325,"type":"SRV","name":"_xmpp-client._tcp","data":"jabber","priority":0,"port":5222,"weight":5},{"id":3671326,"type":"SRV","name":"_xmpp-server._tcp","data":"jabber","priority":0,"port":5269,"weight":5},{"id":5529034,"type":"CNAME","name":"structuredmind","data":"@","priority":null,"port":null,"weight":null},{"id":6232286,"type":"A","name":"office","data":"93.136.62.55","priority":null,"port":null,"weight":null}],"links":{},"meta":{"total":16}}'
|
63
|
+
http_version:
|
64
|
+
recorded_at: Thu, 16 Apr 2015 19:29:20 GMT
|
65
|
+
- request:
|
66
|
+
method: post
|
67
|
+
uri: https://api.digitalocean.com/v2/domains/floatingpoint.io/records
|
68
|
+
body:
|
69
|
+
encoding: UTF-8
|
70
|
+
string: '{"type":"A","name":"foo","data":"127.0.1.1","priority":null,"port":null,"weight":null}'
|
71
|
+
headers:
|
72
|
+
Content-Type:
|
73
|
+
- application/json
|
74
|
+
Authorization:
|
75
|
+
- Bearer 740ed6dd3e97e498892b2c2d0fd74376dc259c2b4cf898b168fbaa650171b732
|
76
|
+
User-Agent:
|
77
|
+
- Faraday v0.9.1
|
78
|
+
Accept-Encoding:
|
79
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
80
|
+
Accept:
|
81
|
+
- "*/*"
|
82
|
+
response:
|
83
|
+
status:
|
84
|
+
code: 201
|
85
|
+
message: Created
|
86
|
+
headers:
|
87
|
+
Server:
|
88
|
+
- cloudflare-nginx
|
89
|
+
Date:
|
90
|
+
- Thu, 16 Apr 2015 19:29:22 GMT
|
91
|
+
Content-Type:
|
92
|
+
- application/json; charset=utf-8
|
93
|
+
Transfer-Encoding:
|
94
|
+
- chunked
|
95
|
+
Connection:
|
96
|
+
- keep-alive
|
97
|
+
Set-Cookie:
|
98
|
+
- __cfduid=d9a857770dc4aca53f30819ba4871437d1429212561; expires=Fri, 15-Apr-16
|
99
|
+
19:29:21 GMT; path=/; domain=.digitalocean.com; HttpOnly
|
100
|
+
Status:
|
101
|
+
- 201 Created
|
102
|
+
X-Frame-Options:
|
103
|
+
- SAMEORIGIN
|
104
|
+
X-Xss-Protection:
|
105
|
+
- 1; mode=block
|
106
|
+
X-Content-Type-Options:
|
107
|
+
- nosniff
|
108
|
+
Ratelimit-Limit:
|
109
|
+
- '5000'
|
110
|
+
Ratelimit-Remaining:
|
111
|
+
- '4998'
|
112
|
+
Ratelimit-Reset:
|
113
|
+
- '1429216160'
|
114
|
+
Etag:
|
115
|
+
- '"154a5bdcde3e91c31f170b4680f057b6"'
|
116
|
+
Cache-Control:
|
117
|
+
- max-age=0, private, must-revalidate
|
118
|
+
X-Request-Id:
|
119
|
+
- 3bbcd5f5-d1e8-490f-b6e8-7d431a563aa3
|
120
|
+
X-Runtime:
|
121
|
+
- '0.269614'
|
122
|
+
Cf-Ray:
|
123
|
+
- 1d824c6b973f0a3c-VIE
|
124
|
+
body:
|
125
|
+
encoding: UTF-8
|
126
|
+
string: '{"domain_record":{"id":6261986,"type":"A","name":"foo","data":"127.0.1.1","priority":null,"port":null,"weight":null}}'
|
127
|
+
http_version:
|
128
|
+
recorded_at: Thu, 16 Apr 2015 19:29:22 GMT
|
129
|
+
recorded_with: VCR 2.9.3
|