droptoflare 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: aa41ce1dd29a53f85c60ff0af5142860fc49de88
4
+ data.tar.gz: 2b01def8c6ad5cb5eaa86e7f7fb7a8944a4dab75
5
+ SHA512:
6
+ metadata.gz: 62afa98fc08bb0b5ecff01e717932e0b008fc6ed8fdbf3ad1dad48d4882fca5e214baf5419ffc2ce328fe93d9f360e35b2acd7187355d01dca6b0d80099a029b
7
+ data.tar.gz: 018c393ec07e66a4dcb4dd78a62df9852a275b47399141549396e990144fbcf9ccc2b9cd60dac09860aedfb59b15e32b742466b2d88e5ec118db0fff0f46876a
data/.gemspec ADDED
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'droptoflare'
3
+ s.version = '0.0.1'
4
+ s.author = 'Johan Haals'
5
+ s.email = 'johan@haals.se'
6
+ s.homepage = 'https://github.com/jhaals/droptoflare'
7
+ s.summary = 'Populate Cloudflare DNS with DigitalOcean droplets'
8
+ s.license = 'Apache 2.0'
9
+
10
+ s.files = `git ls-files`.split("\n")
11
+ s.require_paths = ['lib', 'bin']
12
+ s.executables = 'droptoflare'
13
+ s.add_runtime_dependency 'httparty'
14
+ end
15
+
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ vendor
2
+ Gemfile.lock
3
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'droptoflare', :path => '.'
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ #droptoflare
2
+ droptoflare adds your DigitalOcean Droplets as A records in Cloudflare.
3
+ droptoflare will update DNS records if you re-create a Droplet with the same name.
4
+
5
+ Please note that this code has poor error reporting and no tests.
6
+
7
+ Create `~/.droptoflare.yaml` and add the following
8
+
9
+ domain: example.com
10
+ email: email_used_at_cloudflare@example.com
11
+ cf_token: Cloudflare t0ken
12
+ do_token: DigitalOcean t0ken'
13
+
14
+ Run!
15
+
16
+ $ droptoflare
17
+ Found 2 Droplets checking IP's against 3 CF records
18
+ Updating test.jhaals.se from 178.62.20.1 to 178.62.20.198
19
+ Updated 1 record(s)
20
+
21
+ $ droptoflare
22
+ Found 2 Droplets checking IP's against 3 CF records
23
+ Updated 0 record(s)
24
+
25
+ ### Todo
26
+ - tests
27
+ - error handling
28
+ - ability to set TTL (120s at the moment)
data/bin/droptoflare ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ require 'droptoflare/digitalocean'
3
+ require 'droptoflare/cloudflare'
4
+ require 'yaml'
5
+
6
+ begin
7
+ c = YAML.load_file(File.expand_path('~/.droptoflare.yaml'))
8
+ rescue Errno::ENOENT
9
+ puts 'Hey! you need to create ~/.droptoflare.yaml with this info:'
10
+ puts
11
+ puts 'domain: example.com
12
+ email: email_used_at_cloudflare@example.com
13
+ cf_token: Cloudflare t0ken
14
+ do_token: DigitalOcean t0ken'
15
+ exit 1
16
+ end
17
+
18
+ domain = c['domain']
19
+ cf = Cloudflare.new(c['cf_token'], domain, c['email'])
20
+ digitalocean = DigitalOcean.new(c['do_token'])
21
+
22
+ cf_records = cf.records
23
+ droplets = digitalocean.droplets
24
+ puts "Found #{droplets.length} Droplets checking IP's against #{cf_records.length} CF records"
25
+ result = 0
26
+ droplets.each do |name, ip|
27
+ domain_name = "#{name}.#{domain}"
28
+ if cf_records.key?(domain_name)
29
+ if ip != cf_records[domain_name][:ip]
30
+ puts "Updating #{domain_name} from #{cf_records[domain_name][:ip]} to #{ip}"
31
+ cf.update_record(name, ip, cf_records[domain_name][:id])
32
+ result += 1
33
+ end
34
+ else
35
+ puts "Creating new A record for #{name} pointing to #{ip}"
36
+ cf.create_record(name, ip)
37
+ result += 1
38
+ end
39
+ end
40
+
41
+ puts "Updated #{result} record(s)"
@@ -0,0 +1,74 @@
1
+ require 'json'
2
+ require 'httparty'
3
+
4
+ class Cloudflare
5
+ def initialize(cf_token, domain, email)
6
+ @cf_token = cf_token
7
+ @domain = domain
8
+ @email = email
9
+ end
10
+
11
+ def create_record(name, ip)
12
+ options = {
13
+ body: {
14
+ a: 'rec_new',
15
+ tkn: @cf_token,
16
+ email: @email,
17
+ z: @domain,
18
+ name: name,
19
+ content: ip,
20
+ type: 'A',
21
+ ttl: 120
22
+ }
23
+ }
24
+ r = JSON.parse(
25
+ HTTParty.post('https://www.cloudflare.com/api_json.html', options).body)
26
+ if r['result'] == 'error'
27
+ puts r['msg']
28
+ return false
29
+ end
30
+ return true if r['result'] == 'success'
31
+ end
32
+
33
+ def records
34
+ entries = {}
35
+ options = {
36
+ body: {
37
+ a: 'rec_load_all',
38
+ tkn: @cf_token,
39
+ email: @email,
40
+ z: @domain
41
+ }
42
+ }
43
+ r = JSON.parse(
44
+ HTTParty.post('https://www.cloudflare.com/api_json.html', options).body)
45
+ r['response']['recs']['objs'].each do |e|
46
+ next if e['type'] != 'A'
47
+ entries[e['name']] = { ip: e['content'], id: e['rec_id'] }
48
+ end
49
+ entries
50
+ end
51
+
52
+ def update_record(name, ip, id)
53
+ options = {
54
+ body: {
55
+ a: 'rec_edit',
56
+ tkn: @cf_token,
57
+ email: @email,
58
+ z: @domain,
59
+ name: name,
60
+ content: ip,
61
+ id: id,
62
+ type: 'A',
63
+ ttl: 120
64
+ }
65
+ }
66
+ r = JSON.parse(
67
+ HTTParty.post('https://www.cloudflare.com/api_json.html', options).body)
68
+ if r['result'] == 'error'
69
+ puts r['msg']
70
+ return false
71
+ end
72
+ return true if r['result'] == 'success'
73
+ end
74
+ end
@@ -0,0 +1,22 @@
1
+ require 'httparty'
2
+ require 'json'
3
+
4
+ class DigitalOcean
5
+ def initialize(token)
6
+ @token = token
7
+ end
8
+
9
+ def droplets
10
+ r = HTTParty.get('https://api.digitalocean.com/v2/droplets',
11
+ headers: { 'Authorization' => "Bearer #{@token}" })
12
+ r = JSON.parse(r.body)
13
+ droplets = {}
14
+ r['droplets'].each do |e|
15
+ e['networks']['v4'].each do |i|
16
+ next if i['type'] == 'private'
17
+ droplets[e['name']] = i['ip_address']
18
+ end
19
+ end
20
+ droplets
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: droptoflare
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Johan Haals
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email: johan@haals.se
29
+ executables:
30
+ - droptoflare
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gemspec
35
+ - .gitignore
36
+ - Gemfile
37
+ - README.md
38
+ - bin/droptoflare
39
+ - lib/droptoflare/cloudflare.rb
40
+ - lib/droptoflare/digitalocean.rb
41
+ homepage: https://github.com/jhaals/droptoflare
42
+ licenses:
43
+ - Apache 2.0
44
+ metadata: {}
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ - bin
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.0.14
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Populate Cloudflare DNS with DigitalOcean droplets
66
+ test_files: []