cloudflare 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9a110e823c75c13f404a65302681c7dfa94259b7
4
- data.tar.gz: 9124f505ca1db512e237515ffb5936921a2981b6
3
+ metadata.gz: 7803b3a770a2ca6cfe874d77a7172bce3b0a3016
4
+ data.tar.gz: 8e97d03f70b94c9c6e5534adeff3fd9258c6a56c
5
5
  SHA512:
6
- metadata.gz: 45ece12909dddffe400565bad14412a58d33d1e062a4744676a4b1a6cc3e33a959aa56ee8a6d5f022c34fa31909edc46a3a9b3f7e56e84a2b4d6fb0d4fe22da2
7
- data.tar.gz: 7190a218eeb9dd39b2dc43c1ce4c8ed7b9a5bd20aefdfbd3be583886f16d601360d53eb58d4fd5e4d0f1f92910cbefc9c1372785c4799ecbaac83603502f76e5
6
+ metadata.gz: df0801c3eaeca54ebdf36c45eecb85ae27f39eeae1163474ace6fda7211357aae6c9ddefee4f4fa12a45a34d99509011965e9d2af4d9e4139f75dbb7ee68c6d4
7
+ data.tar.gz: bb7ee1e783f5288612252a2908ef7e1d8b27daa2ba5c96947b09faf35fb6b536c91512d0fda099c6cac3a453ec8db9a8211fa5fcf12069b9a82c382e57b4c562
@@ -0,0 +1,6 @@
1
+ t/
2
+ Gemfile*
3
+ *.gem
4
+ tags
5
+ .byebug_history
6
+ .rspec_status
data/Gemfile CHANGED
@@ -6,8 +6,6 @@ gemspec
6
6
  group :development do
7
7
  gem 'pry'
8
8
  gem 'pry-coolline'
9
-
10
- gem 'tty-prompt'
11
9
  end
12
10
 
13
11
  group :test do
data/README.md CHANGED
@@ -66,6 +66,29 @@ puts records.first.record[:name]
66
66
  puts records
67
67
  ```
68
68
 
69
+ Get firewall rules:
70
+
71
+ ```ruby
72
+ all_rules = zones.first.firewall_rules.all
73
+ block_rules = zones.first.firewall_rules.all("block") # or "whitelist" or "challenge"
74
+ ```
75
+
76
+ Get blocked ips:
77
+
78
+ ```ruby
79
+ block_rules = zones.first.firewall_rules.all("block")
80
+ blocked_ips = zones.first.firewall_rules.firewalled_ips(block_rules)
81
+ ```
82
+
83
+ Block an ip:
84
+
85
+ ```ruby
86
+ # ip = "nnn.nnn.nnn.nnn"
87
+ # note: "some note about the block"
88
+ data = {"mode":"block","configuration":{"target":"ip","value":"#{ip}"},"notes":"#{note} #{Time.now.strftime("%m/%d/%y")} "}
89
+ response = zones.first.firewall_rules.post(data.to_json, content_type: 'application/json')
90
+ ```
91
+
69
92
  ## Contributing
70
93
 
71
94
  1. Fork it
@@ -84,7 +107,8 @@ puts records
84
107
  Released under the MIT license.
85
108
 
86
109
  Copyright, 2012, 2014, by [Marcin Prokop](https://github.com/b4k3r).
87
- Copyright, 2017, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
110
+ Copyright, 2017, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
111
+ Copyright, 2017, by [David Rosenbloom](http://artifactory.com).
88
112
 
89
113
  Permission is hereby granted, free of charge, to any person obtaining a copy
90
114
  of this software and associated documentation files (the "Software"), to deal
@@ -103,3 +127,6 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
103
127
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
104
128
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
105
129
  THE SOFTWARE.
130
+
131
+
132
+
@@ -31,6 +31,8 @@ module Cloudflare
31
31
  TIMEOUT = 10 # Default is 5 seconds
32
32
 
33
33
  class Resource < RestClient::Resource
34
+ include Enumerable
35
+
34
36
  # @param api_key [String] `X-Auth-Key` or `X-Auth-User-Service-Key` if no email provided.
35
37
  # @param email [String] `X-Auth-Email`, your email address for the account.
36
38
  def initialize(url = DEFAULT_URL, key: nil, email: nil, **options)
@@ -48,6 +50,22 @@ module Cloudflare
48
50
  Response.new(response.request.url, response.body)
49
51
  end
50
52
  end
53
+
54
+ def paginate(obj, url, url_args = "")
55
+ page = 1
56
+ page_size = 100
57
+ results = []
58
+
59
+ # fetch and aggregate all pages
60
+ loop do
61
+ rules = obj.new(concat_urls(url, "?scope_type=organization#{url_args}&per_page=#{page_size}&page=#{page}"), self, **options)
62
+ results += rules.get.results
63
+ break if results.size % page_size != 0
64
+ page += 1
65
+ end
66
+
67
+ return results
68
+ end
51
69
  end
52
70
 
53
71
  class Connection < Resource
@@ -20,5 +20,5 @@
20
20
  # THE SOFTWARE.
21
21
 
22
22
  module Cloudflare
23
- VERSION = '3.0.0'
23
+ VERSION = '3.1.0'
24
24
  end
@@ -1,5 +1,6 @@
1
1
  # Copyright, 2012, by Marcin Prokop.
2
2
  # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
3
+ # Copyright, 2017, by David Rosenbloom. <http://artifactory.com>
3
4
  #
4
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -34,7 +35,12 @@ module Cloudflare
34
35
 
35
36
  @record = record || self.get.result
36
37
  end
37
-
38
+
39
+ def update_content(content)
40
+ response = self.put({type: @record[:type], name: @record[:name], content: content}.to_json, content_type: 'application/json')
41
+ response.successful?
42
+ end
43
+
38
44
  attr :record
39
45
 
40
46
  def to_s
@@ -52,7 +58,8 @@ module Cloudflare
52
58
  attr :zone
53
59
 
54
60
  def all
55
- self.get.results.map{|record| DNSRecord.new(concat_urls(url, record[:id]), record, **options)}
61
+ results = paginate(DNSRecords, url)
62
+ results.map{|record| DNSRecord.new(concat_urls(url, record[:id]), record, **options)}
56
63
  end
57
64
 
58
65
  def find_by_name(name)
@@ -70,10 +77,78 @@ module Cloudflare
70
77
  end
71
78
  end
72
79
 
73
- class Zone < Resource
80
+ class FirewallRule < Resource
74
81
  def initialize(url, record = nil, **options)
75
82
  super(url, **options)
83
+
84
+ @record = record || self.get.result
85
+ end
86
+
87
+ attr :record
88
+
89
+ def to_s
90
+ "#{@record[:configuration][:value]} - #{@record[:mode]} - #{@record[:notes]}"
91
+ end
92
+ end
93
+
94
+ class FirewallRules < Resource
95
+ def initialize(url, zone, **options)
96
+ super(url, **options)
97
+
98
+ @zone = zone
99
+ end
100
+
101
+ attr :zone
102
+
103
+ def all(mode = nil, ip = nil, notes = nil)
104
+ url_args = ""
105
+ url_args.concat("&mode=#{mode}") if mode
106
+ url_args.concat("&configuration_value=#{ip}") if ip
107
+ url_args.concat("&notes=#{notes}") if notes
108
+
109
+ results = paginate(FirewallRules, url, url_args)
110
+ results.map{|record| FirewallRule.new(concat_urls(url, record[:id]), record, **options)}
111
+ end
112
+
113
+ def firewalled_ips(rules)
114
+ rules.collect {|r| r.record[:configuration][:value]}
115
+ end
116
+
117
+ def blocked_ips
118
+ firewalled_ips(all("block"))
119
+ end
120
+
121
+ def set(mode, ip, note)
122
+ data = {
123
+ mode: mode.to_s,
124
+ configuration: {
125
+ target: "ip",
126
+ value: ip.to_s,
127
+ notes: "cloudflare gem firewall_rules [#{mode}] #{note} #{Time.now.strftime("%m/%d/%y")}"
128
+ }
129
+ }
76
130
 
131
+ post(data.to_json, content_type: 'application/json')
132
+ end
133
+
134
+ def unset(mode, value)
135
+ rule = send("find_by_#{mode}", value)
136
+ rule.delete
137
+ end
138
+
139
+ def find_by_id(id)
140
+ FirewallRule.new(concat_urls(url, id), **options)
141
+ end
142
+
143
+ def find_by_ip(ip)
144
+ rule = FirewallRule.new(concat_urls(url, "?configuration_value=#{ip}"), **options)
145
+ FirewallRule.new(concat_urls(url, rule.record.first[:id]), **options)
146
+ end
147
+ end
148
+
149
+ class Zone < Resource
150
+ def initialize(url, record = nil, **options)
151
+ super(url, **options)
77
152
  @record = record || self.get.result
78
153
  end
79
154
 
@@ -83,6 +158,10 @@ module Cloudflare
83
158
  @dns_records ||= DNSRecords.new(concat_urls(url, 'dns_records'), self, **options)
84
159
  end
85
160
 
161
+ def firewall_rules
162
+ @firewall_rules ||= FirewallRules.new(concat_urls(url, "firewall/access_rules/rules"), self, **options)
163
+ end
164
+
86
165
  def to_s
87
166
  @record[:name]
88
167
  end
@@ -94,7 +173,7 @@ module Cloudflare
94
173
  end
95
174
 
96
175
  def find_by_name(name)
97
- record = self.get(params: {name: name}).result
176
+ response = self.get(params: {name: name})
98
177
 
99
178
  unless response.empty?
100
179
  record = response.results.first
@@ -1,41 +1,92 @@
1
1
 
2
2
  RSpec.describe "Cloudflare DNS Zones" do
3
3
  include_context Cloudflare::RSpec::Connection
4
-
4
+
5
5
  it "should list zones" do
6
6
  zones = connection.zones.all
7
-
7
+
8
8
  expect(zones).to be_any
9
9
  end
10
-
10
+
11
11
  describe Cloudflare::DNSRecords, order: :defined do
12
12
  let(:zone) {connection.zones.all.first}
13
+
13
14
  let(:name) {"test"}
14
-
15
+ let(:ip) {"123.123.123.123"}
16
+ record = nil
17
+
18
+ it "should get all records" do
19
+ result = zone.dns_records.all
20
+
21
+ puts "===> #{result.size} records returned"
22
+ expect(result.size).to be > 0
23
+ end
24
+
25
+
15
26
  it "should create dns record" do
16
27
  response = zone.dns_records.post({
17
28
  type: "A",
18
29
  name: name,
19
- content: "127.0.0.1",
30
+ content: ip,
20
31
  ttl: 240,
21
32
  proxied: false
22
33
  }.to_json, content_type: 'application/json')
23
-
34
+
24
35
  expect(response).to be_successful
25
-
36
+
26
37
  result = response.result
27
38
  expect(result).to include(:id, :type, :name, :content, :ttl)
39
+ record = result
28
40
  end
29
-
41
+
30
42
  it "should delete dns record" do
31
- dns_records = zone.dns_records.all
32
-
33
- expect(dns_records).to be_any
34
-
35
- dns_records.each do |record|
36
- response = record.delete
43
+ dns_record = zone.dns_records.find_by_id(record[:id])
44
+ response = dns_record.delete
45
+ expect(response).to be_successful
46
+ end
47
+ end
48
+
49
+ describe Cloudflare::FirewallRules, order: :defined do
50
+ let(:zone) {connection.zones.all.first}
51
+ let(:name) {"test"}
52
+ let(:ip) {'123.123.123.123'}
53
+ let(:ip2) {'123.123.123.124'}
54
+ let(:notes) {"gemtest"}
55
+ record = nil
56
+ before do
57
+ response = zone.firewall_rules.set('block', ip2, notes)
58
+ end
59
+
60
+ it "should get all rules" do
61
+ result = zone.firewall_rules.all
62
+
63
+ puts "===> #{result.size} records returned"
64
+ expect(result.size).to be > 0
65
+ end
66
+
67
+ it "should create firewall rules for 'block', 'challenge', 'whitelist'" do
68
+
69
+ [:block, :challenge, :whitelist].each do |mode|
70
+ response = zone.firewall_rules.set(mode, ip, notes)
37
71
  expect(response).to be_successful
72
+
73
+ result = response.result
74
+ expect(result).to include(:id, :mode, :notes, :configuration)
75
+ expect(result[:mode]).to eq mode.to_s
76
+ record = result
38
77
  end
39
78
  end
79
+
80
+ it "should delete firewall rule by record" do
81
+ response = zone.firewall_rules.unset('id', record[:id])
82
+
83
+ expect(response).to be_successful
84
+ end
85
+
86
+ it "should delete firewall rule by ip" do
87
+ response = zone.firewall_rules.unset('ip', ip2)
88
+
89
+ expect(response).to be_successful
90
+ end
40
91
  end
41
92
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudflare
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcin Prokop
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-05-25 00:00:00.000000000 Z
12
+ date: 2017-08-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -75,6 +75,7 @@ executables: []
75
75
  extensions: []
76
76
  extra_rdoc_files: []
77
77
  files:
78
+ - ".gitignore"
78
79
  - ".rspec"
79
80
  - ".travis.yml"
80
81
  - Gemfile
@@ -110,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
111
  version: '0'
111
112
  requirements: []
112
113
  rubyforge_project:
113
- rubygems_version: 2.6.10
114
+ rubygems_version: 2.6.12
114
115
  signing_key:
115
116
  specification_version: 4
116
117
  summary: A Ruby wrapper for the Cloudflare API.