cloudflare 3.2.1 → 4.0.0
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 +4 -4
- data/.travis.yml +14 -16
- data/README.md +9 -9
- data/Rakefile +10 -8
- data/cloudflare.gemspec +19 -17
- data/lib/cloudflare.rb +20 -5
- data/lib/cloudflare/{response.rb → accounts.rb} +25 -47
- data/lib/cloudflare/connection.rb +31 -52
- data/lib/cloudflare/dns.rb +91 -0
- data/lib/cloudflare/firewall.rb +80 -0
- data/lib/cloudflare/logs.rb +41 -0
- data/lib/cloudflare/paginate.rb +54 -0
- data/lib/cloudflare/representation.rb +94 -0
- data/lib/cloudflare/rspec/connection.rb +18 -11
- data/lib/cloudflare/user.rb +10 -9
- data/lib/cloudflare/version.rb +1 -1
- data/lib/cloudflare/zones.rb +85 -0
- data/spec/cloudflare/dns_spec.rb +32 -0
- data/spec/cloudflare/firewall_spec.rb +48 -0
- data/spec/cloudflare/zone_spec.rb +23 -124
- data/spec/spec_helper.rb +25 -169
- metadata +37 -19
- data/.rubocop.yml +0 -19
- data/.ruby-version +0 -1
- data/lib/cloudflare/zone.rb +0 -202
- data/spec/fake_cloudflare/cloudflare.rb +0 -17
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
require 'cloudflare/rspec/connection'
|
3
|
+
|
4
|
+
RSpec.describe Cloudflare::Firewall, order: :defined, timeout: 30 do
|
5
|
+
include_context Cloudflare::Zone
|
6
|
+
|
7
|
+
let(:notes) {'gemtest'}
|
8
|
+
|
9
|
+
context "with several rules" do
|
10
|
+
let(:allow_ip) {'123.123.123.123'}
|
11
|
+
let(:block_ip) {'123.123.123.124'}
|
12
|
+
|
13
|
+
before do
|
14
|
+
zone.firewall_rules.each do |rule|
|
15
|
+
rule.delete
|
16
|
+
end
|
17
|
+
|
18
|
+
zone.firewall_rules.set('whitelist', allow_ip)
|
19
|
+
zone.firewall_rules.set('block', block_ip)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should get all rules' do
|
23
|
+
rules = zone.firewall_rules.to_a
|
24
|
+
|
25
|
+
expect(rules.size).to be >= 2
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should get rules with specific value' do
|
29
|
+
rules = zone.firewall_rules.each_by_value(allow_ip).to_a
|
30
|
+
|
31
|
+
expect(rules.size).to be == 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
%w[block challenge whitelist].each_with_index do |mode, index|
|
36
|
+
it "should create a #{mode} rule" do
|
37
|
+
value = "123.123.123.#{index}"
|
38
|
+
rule = zone.firewall_rules.set(mode, value, notes: notes)
|
39
|
+
|
40
|
+
expect(rule.mode).to be == mode
|
41
|
+
expect(rule.configuration[:value]).to be == value
|
42
|
+
expect(rule.configuration[:target]).to be == 'ip'
|
43
|
+
expect(rule.notes).to be == notes
|
44
|
+
|
45
|
+
rule.delete
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,126 +1,25 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
1
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
describe Cloudflare::DNSRecords, order: :defined do
|
29
|
-
before(:each) do
|
30
|
-
stub_get_zones
|
31
|
-
stub_get_dns_records
|
32
|
-
stub_create_dns_record
|
33
|
-
stub_delete_dns_record '123123123'
|
34
|
-
stub_find_dns_record_by_id '123123123'
|
35
|
-
end
|
36
|
-
let(:zone) { connection.zones.all.first }
|
37
|
-
|
38
|
-
let(:name) { 'test' }
|
39
|
-
let(:ip) { '123.123.123.123' }
|
40
|
-
|
41
|
-
it 'should get all records' do
|
42
|
-
result = zone.dns_records.all
|
43
|
-
expect(result.size).to be > 0
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'should create dns record' do
|
47
|
-
response = zone.dns_records.post({
|
48
|
-
type: 'A',
|
49
|
-
name: name,
|
50
|
-
content: ip,
|
51
|
-
ttl: 240,
|
52
|
-
proxied: false
|
53
|
-
}.to_json, content_type: 'application/json')
|
54
|
-
|
55
|
-
expect(response).to be_successful
|
56
|
-
|
57
|
-
result = response.result
|
58
|
-
expect(result).to include(:id, :type, :name, :content, :ttl)
|
59
|
-
end
|
60
|
-
|
61
|
-
before do
|
62
|
-
stub_get_dns_record '1231231234'
|
63
|
-
stub_delete_dns_record '1231231234'
|
64
|
-
end
|
65
|
-
it 'should delete dns record' do
|
66
|
-
dns_record = zone.dns_records.find_by_id('1231231234')
|
67
|
-
response = dns_record.delete
|
68
|
-
expect(response).to be_successful
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe Cloudflare::FirewallRules, order: :defined do
|
73
|
-
let(:zone) { connection.zones.all.first }
|
74
|
-
let(:name) { 'test' }
|
75
|
-
let(:ip) { '123.123.123.123' }
|
76
|
-
let(:ip2) { '123.123.123.124' }
|
77
|
-
let(:notes) { 'gemtest' }
|
78
|
-
before do
|
79
|
-
stub_get_zones
|
80
|
-
stub_create_rule 'block', ip2, notes
|
81
|
-
stub_list_access_rules 1, [cf_access_rule('whitelist', ip, notes)]
|
82
|
-
stub_list_access_rules 2, [cf_access_rule('block', ip2, notes)]
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'should get all rules' do
|
86
|
-
result = zone.firewall_rules.all
|
87
|
-
|
88
|
-
puts "===> #{result.size} records returned"
|
89
|
-
expect(result.size).to be > 0
|
90
|
-
end
|
91
|
-
|
92
|
-
%i[block challenge whitelist].each do |mode|
|
93
|
-
it "should create a #{mode} rule" do
|
94
|
-
stub_create_rule mode, ip, notes
|
95
|
-
response = zone.firewall_rules.set(mode, ip, notes)
|
96
|
-
|
97
|
-
expect(response).to be_successful
|
98
|
-
|
99
|
-
result = response.result
|
100
|
-
expect(result).to include(:id, :mode, :notes, :configuration)
|
101
|
-
expect(result[:mode]).to eq mode.to_s
|
102
|
-
end
|
103
|
-
end
|
104
|
-
before do
|
105
|
-
stub_get_access_rule('123123123')
|
106
|
-
stub_delete_access_rule(id: '123123123')
|
107
|
-
end
|
108
|
-
it 'should delete firewall rule by record' do
|
109
|
-
response = zone.firewall_rules.unset('id', '123123123')
|
110
|
-
assert_requested stub_get_access_rule('123123123')
|
111
|
-
assert_requested stub_delete_access_rule(id: '123123123')
|
112
|
-
expect(response).to be_successful
|
113
|
-
end
|
114
|
-
|
115
|
-
before do
|
116
|
-
stub_find_rule_by_value ip: ip2
|
117
|
-
stub_get_access_rule '123123124'
|
118
|
-
stub_delete_access_rule id: '123123124'
|
119
|
-
end
|
120
|
-
it 'should delete firewall rule by ip' do
|
121
|
-
response = zone.firewall_rules.unset('ip', ip2)
|
122
|
-
expect(response).to be_successful
|
123
|
-
end
|
124
|
-
end
|
2
|
+
RSpec.describe Cloudflare::Zones, order: :defined, timeout: 30 do
|
3
|
+
include_context Cloudflare::Zone
|
4
|
+
|
5
|
+
it "can delete existing domain if exists" do
|
6
|
+
if zone = zones.find_by_name(name)
|
7
|
+
expect(zone.delete).to be_success
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "can create zone" do
|
12
|
+
zone = zones.create(name, account)
|
13
|
+
expect(zone.value).to include(:id)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "can list zones" do
|
17
|
+
matching_zones = zones.select{|zone| zone.name == name}
|
18
|
+
expect(matching_zones).to_not be_empty
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can get zone by name" do
|
22
|
+
found_zone = zones.find_by_name(name)
|
23
|
+
expect(found_zone.name).to be == name
|
24
|
+
end
|
125
25
|
end
|
126
|
-
# rubocop:enable Metrics/BlockLength
|
data/spec/spec_helper.rb
CHANGED
@@ -1,177 +1,33 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
1
|
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'simplecov'
|
2
|
+
require 'async/rspec'
|
6
3
|
|
7
|
-
SimpleCov.start do
|
8
|
-
add_filter '/spec/'
|
9
|
-
end
|
10
|
-
rescue LoadError
|
11
|
-
warn "Could not load simplecov: #{$ERROR_INFO}"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
require 'webmock/rspec'
|
16
|
-
WebMock.disable_net_connect!(allow_localhost: true)
|
17
|
-
|
18
|
-
require 'bundler/setup'
|
19
|
-
require 'cloudflare'
|
20
4
|
require 'cloudflare/rspec/connection'
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
def stub_get_dns_records
|
42
|
-
dns_record = {
|
43
|
-
"id": 'b12a037696862c2fc1d45a0e288c82a5',
|
44
|
-
"type": 'A',
|
45
|
-
"name": 'www.example.com',
|
46
|
-
"content": '123.123.123.123',
|
47
|
-
"ttl": 1,
|
48
|
-
"zone_id": zone_id,
|
49
|
-
"zone_name": 'example.com'
|
50
|
-
}
|
51
|
-
stub_request(:get, "#{base_url}/zones/#{zone_id}/dns_records/?page=1&per_page=50&scope_type=organization")
|
52
|
-
.with(cf_headers)
|
53
|
-
.to_return(status: 200,
|
54
|
-
body: cf_results([dns_record]),
|
55
|
-
headers: {})
|
56
|
-
end
|
57
|
-
|
58
|
-
def stub_create_dns_record
|
59
|
-
stub_request(:post, "#{base_url}/zones/#{zone_id}/dns_records")
|
60
|
-
.with(cf_headers('Content-Type': 'application/json'))
|
61
|
-
.with(
|
62
|
-
body: hash_including(:type, :name, :content, :ttl, :proxied)
|
63
|
-
)
|
64
|
-
.to_return(status: 200,
|
65
|
-
body: cf_results(id: '123231123', type: 'A', name: 'test', content: '123.123.123.123', ttl: 240),
|
66
|
-
headers: {})
|
67
|
-
end
|
68
|
-
|
69
|
-
def stub_find_dns_record_by_id(id)
|
70
|
-
stub_request(:get, "#{base_url}/zones/#{zone_id}/dns_records")
|
71
|
-
.with(query: {id: id})
|
72
|
-
.with(cf_headers)
|
73
|
-
.to_return(status: 200,
|
74
|
-
body: cf_results(
|
75
|
-
id: '123231123',
|
76
|
-
type: 'A',
|
77
|
-
name: 'test',
|
78
|
-
content: '123.123.123.123',
|
79
|
-
ttl: 240
|
80
|
-
),
|
81
|
-
headers: {})
|
82
|
-
end
|
83
|
-
|
84
|
-
def stub_get_dns_record(id)
|
85
|
-
stub_request(:get, "#{base_url}/zones/#{zone_id}/dns_records/#{id}")
|
86
|
-
.with(cf_headers)
|
87
|
-
.to_return(status: 200,
|
88
|
-
body: cf_results(
|
89
|
-
id: '123231123',
|
90
|
-
type: 'A',
|
91
|
-
name: 'test',
|
92
|
-
content: '123.123.123.123',
|
93
|
-
ttl: 240
|
94
|
-
),
|
95
|
-
headers: {})
|
96
|
-
end
|
97
|
-
|
98
|
-
def stub_delete_dns_record(id)
|
99
|
-
stub_request(:delete, "#{base_url}/zones/#{zone_id}/dns_records/#{id}")
|
100
|
-
.with(cf_headers)
|
101
|
-
.to_return(status: 200, body: cf_results(id: id), headers: {})
|
102
|
-
end
|
103
|
-
|
104
|
-
def stub_find_rule_by_value(ip:)
|
105
|
-
stub_request(:get, "#{base_url}/zones/#{zone_id}/firewall/access_rules/rules/?configuration_value=#{ip}")
|
106
|
-
.with(cf_headers)
|
107
|
-
.to_return(status: 200,
|
108
|
-
body: cf_results([cf_access_rule('block', '123.123.123.124', 'gemtest')]),
|
109
|
-
headers: {})
|
110
|
-
end
|
111
|
-
|
112
|
-
def stub_list_access_rules(page, rules)
|
113
|
-
query = URI.encode_www_form(page: page, per_page: 50, scope_type: :organization)
|
114
|
-
stub_request(:get, "#{base_url}/zones/#{zone_id}/firewall/access_rules/rules/?#{query}")
|
115
|
-
.with(cf_headers)
|
116
|
-
.to_return(status: 200, body: cf_results(rules), headers: {})
|
117
|
-
end
|
118
|
-
|
119
|
-
def stub_get_access_rule(id)
|
120
|
-
stub_request(:get, "#{base_url}/zones/#{zone_id}/firewall/access_rules/rules/#{id}")
|
121
|
-
.with(cf_headers)
|
122
|
-
.to_return(status: 200,
|
123
|
-
body: cf_results(cf_access_rule('whitelist', '123.123.123.124', 'gemtest', id)),
|
124
|
-
headers: {})
|
125
|
-
end
|
126
|
-
|
127
|
-
def stub_delete_access_rule(id: nil)
|
128
|
-
stub_request(:delete, "#{base_url}/zones/#{zone_id}/firewall/access_rules/rules/#{id}")
|
129
|
-
.with(cf_headers)
|
130
|
-
.to_return(status: 200, body: cf_results(id: id), headers: {})
|
131
|
-
end
|
132
|
-
|
133
|
-
def stub_create_rule(mode, ip, note)
|
134
|
-
notes = "cloudflare gem firewall_rules [#{mode}] #{note} #{Time.now.strftime('%m/%d/%y')}"
|
135
|
-
body = "{\"mode\":\"#{mode}\",\"configuration\":{\"target\":\"ip\",\"value\":\"#{ip}\",\"notes\":\"#{notes}\"}}"
|
136
|
-
stub_request(:post, "https://api.cloudflare.com/client/v4/zones/#{zone_id}/firewall/access_rules/rules")
|
137
|
-
.with(cf_headers(
|
138
|
-
'Content-Length' => body.bytesize,
|
139
|
-
'Content-Type' => 'application/json'
|
140
|
-
))
|
141
|
-
.with(body: body)
|
142
|
-
.to_return(status: 200, body: cf_results(cf_access_rule(mode, ip, notes)), headers: {})
|
143
|
-
end
|
144
|
-
|
145
|
-
def stub_purge_cache
|
146
|
-
stub_request(:post, "#{base_url}/zones/#{zone_id}/purge_cache")
|
147
|
-
.with(cf_headers)
|
148
|
-
.to_return(status: 200, body: cf_results(id: zone_id), headers: {})
|
5
|
+
require 'cloudflare/zones'
|
6
|
+
|
7
|
+
RSpec.shared_context Cloudflare::Zone do
|
8
|
+
include_context Cloudflare::RSpec::Connection
|
9
|
+
|
10
|
+
let(:job_id) {ENV.fetch('TRAVIS_JOB_ID', 0).to_i}
|
11
|
+
let(:names) {['testing', 'horse', 'cat', 'dog', 'fish', 'dolphin', 'lion', 'tiger']}
|
12
|
+
let(:name) {"#{names[job_id % names.size]}.com"}
|
13
|
+
|
14
|
+
let(:account) {connection.accounts.first}
|
15
|
+
let(:zones) {connection.zones}
|
16
|
+
|
17
|
+
let(:zone) {@zone = zones.find_by_name(name) || zones.create(name, account)}
|
18
|
+
|
19
|
+
# after do
|
20
|
+
# if defined? @zone
|
21
|
+
# @zone.delete
|
22
|
+
# end
|
23
|
+
# end
|
149
24
|
end
|
150
25
|
|
151
26
|
RSpec.configure do |config|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
config.expect_with :rspec do |c|
|
156
|
-
c.syntax = :expect
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
def cf_results(result, messages = [], errors = [])
|
161
|
-
{result: result, success: true, messages: messages, errors: errors}.to_json
|
162
|
-
end
|
163
|
-
|
164
|
-
def cf_headers(extra = {})
|
165
|
-
{headers: {
|
166
|
-
'Accept' => '*/*',
|
167
|
-
'Accept-Encoding' => 'gzip, deflate',
|
168
|
-
'Host' => 'api.cloudflare.com',
|
169
|
-
'X-Auth-Email' => 'jake@example.net',
|
170
|
-
'X-Auth-Key' => '5up3rS3cr3tAuthK3y',
|
171
|
-
'X-Auth-User-Service-Key' => ''
|
172
|
-
}.merge(extra)}
|
173
|
-
end
|
27
|
+
# Enable flags like --only-failures and --next-failure
|
28
|
+
config.example_status_persistence_file_path = '.rspec_status'
|
174
29
|
|
175
|
-
|
176
|
-
|
30
|
+
config.expect_with :rspec do |c|
|
31
|
+
c.syntax = :expect
|
32
|
+
end
|
177
33
|
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:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcin Prokop
|
@@ -9,36 +9,50 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-01-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name: rest
|
15
|
+
name: async-rest
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
20
|
+
version: '0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - "
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: async-rspec
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
28
42
|
- !ruby/object:Gem::Dependency
|
29
43
|
name: bundler
|
30
44
|
requirement: !ruby/object:Gem::Requirement
|
31
45
|
requirements:
|
32
|
-
- - "
|
46
|
+
- - ">="
|
33
47
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
48
|
+
version: '0'
|
35
49
|
type: :development
|
36
50
|
prerelease: false
|
37
51
|
version_requirements: !ruby/object:Gem::Requirement
|
38
52
|
requirements:
|
39
|
-
- - "
|
53
|
+
- - ">="
|
40
54
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
55
|
+
version: '0'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
57
|
name: rake
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -77,22 +91,26 @@ extra_rdoc_files: []
|
|
77
91
|
files:
|
78
92
|
- ".gitignore"
|
79
93
|
- ".rspec"
|
80
|
-
- ".rubocop.yml"
|
81
|
-
- ".ruby-version"
|
82
94
|
- ".travis.yml"
|
83
95
|
- Gemfile
|
84
96
|
- README.md
|
85
97
|
- Rakefile
|
86
98
|
- cloudflare.gemspec
|
87
99
|
- lib/cloudflare.rb
|
100
|
+
- lib/cloudflare/accounts.rb
|
88
101
|
- lib/cloudflare/connection.rb
|
89
|
-
- lib/cloudflare/
|
102
|
+
- lib/cloudflare/dns.rb
|
103
|
+
- lib/cloudflare/firewall.rb
|
104
|
+
- lib/cloudflare/logs.rb
|
105
|
+
- lib/cloudflare/paginate.rb
|
106
|
+
- lib/cloudflare/representation.rb
|
90
107
|
- lib/cloudflare/rspec/connection.rb
|
91
108
|
- lib/cloudflare/user.rb
|
92
109
|
- lib/cloudflare/version.rb
|
93
|
-
- lib/cloudflare/
|
110
|
+
- lib/cloudflare/zones.rb
|
111
|
+
- spec/cloudflare/dns_spec.rb
|
112
|
+
- spec/cloudflare/firewall_spec.rb
|
94
113
|
- spec/cloudflare/zone_spec.rb
|
95
|
-
- spec/fake_cloudflare/cloudflare.rb
|
96
114
|
- spec/spec_helper.rb
|
97
115
|
homepage: https://github.com/b4k3r/cloudflare
|
98
116
|
licenses:
|
@@ -113,12 +131,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
131
|
- !ruby/object:Gem::Version
|
114
132
|
version: '0'
|
115
133
|
requirements: []
|
116
|
-
|
117
|
-
rubygems_version: 2.7.6
|
134
|
+
rubygems_version: 3.0.1
|
118
135
|
signing_key:
|
119
136
|
specification_version: 4
|
120
137
|
summary: A Ruby wrapper for the Cloudflare API.
|
121
138
|
test_files:
|
139
|
+
- spec/cloudflare/dns_spec.rb
|
140
|
+
- spec/cloudflare/firewall_spec.rb
|
122
141
|
- spec/cloudflare/zone_spec.rb
|
123
|
-
- spec/fake_cloudflare/cloudflare.rb
|
124
142
|
- spec/spec_helper.rb
|