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 +4 -4
- data/.gitignore +6 -0
- data/Gemfile +0 -2
- data/README.md +28 -1
- data/lib/cloudflare/connection.rb +18 -0
- data/lib/cloudflare/version.rb +1 -1
- data/lib/cloudflare/zone.rb +83 -4
- data/spec/cloudflare/zone_spec.rb +65 -14
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7803b3a770a2ca6cfe874d77a7172bce3b0a3016
|
4
|
+
data.tar.gz: 8e97d03f70b94c9c6e5534adeff3fd9258c6a56c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df0801c3eaeca54ebdf36c45eecb85ae27f39eeae1163474ace6fda7211357aae6c9ddefee4f4fa12a45a34d99509011965e9d2af4d9e4139f75dbb7ee68c6d4
|
7
|
+
data.tar.gz: bb7ee1e783f5288612252a2908ef7e1d8b27daa2ba5c96947b09faf35fb6b536c91512d0fda099c6cac3a453ec8db9a8211fa5fcf12069b9a82c382e57b4c562
|
data/.gitignore
ADDED
data/Gemfile
CHANGED
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
|
data/lib/cloudflare/version.rb
CHANGED
data/lib/cloudflare/zone.rb
CHANGED
@@ -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
|
-
|
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
|
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("¬es=#{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
|
-
|
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:
|
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
|
-
|
32
|
-
|
33
|
-
expect(
|
34
|
-
|
35
|
-
|
36
|
-
|
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.
|
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-
|
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.
|
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.
|