cloudflair 0.0.7 → 0.0.8
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/README.md +23 -9
- data/bin/cloudflair +24 -0
- data/cloudflair.gemspec +2 -1
- data/lib/cloudflair/api/railguns.rb +24 -0
- data/lib/cloudflair/api/zone/analytics.rb +25 -0
- data/lib/cloudflair/api/zone/dns_record.rb +16 -0
- data/lib/cloudflair/api/zone/railgun.rb +22 -0
- data/lib/cloudflair/api/zone.rb +7 -8
- data/lib/cloudflair/api/zone__available_plans.rb +19 -0
- data/lib/cloudflair/api/zone__dns_records.rb +29 -0
- data/lib/cloudflair/api/zone__railguns.rb +19 -0
- data/lib/cloudflair/api.rb +16 -1
- data/lib/cloudflair/communication.rb +16 -0
- data/lib/cloudflair/connection.rb +5 -2
- data/lib/cloudflair/entity.rb +0 -10
- data/lib/cloudflair/error/cloudflare_error.rb +2 -0
- data/lib/cloudflair/version.rb +1 -1
- metadata +25 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67a0d783e6d7240e8f30e85be978a8627fe4c6b0
|
4
|
+
data.tar.gz: ec8881baddadb7e284d235a94c2f1652d2b06235
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24335795c9cb61c816efd5afa6d1e1e9ec915ce9642ad2601b6f0e65141fc13d4f3bad3f784f1e16ae032f65d8ce67e0f463dc5d8bc02074cb17779717a4cace
|
7
|
+
data.tar.gz: ff1fa5d1789e5db5c3c2dae30d556242b8e8b0b83f113b7359f8cbf76d293142ee0da42a6a9b72616c465c728580d0cdda39fde591112c42118693134c1e5d4d
|
data/README.md
CHANGED
@@ -55,14 +55,24 @@ This gem is organized along the URL schema of CloudFlare.
|
|
55
55
|
```ruby
|
56
56
|
require 'cloudflair'
|
57
57
|
|
58
|
-
# https://api.cloudflare.com/client/v4/zones/cd7d068de3012345da9420df9514dad0
|
58
|
+
# GET https://api.cloudflare.com/client/v4/zones/cd7d068de3012345da9420df9514dad0
|
59
59
|
Cloudflair.zone('023e105f4ecef8ad9ca31a8372d0c353').name
|
60
|
-
#
|
60
|
+
# => "blog.example.com"
|
61
61
|
|
62
|
-
# https://api.cloudflare.com/client/v4/zones/cd7d068de3012345da9420df9514dad0/settings/development_mode
|
62
|
+
# GET https://api.cloudflare.com/client/v4/zones/cd7d068de3012345da9420df9514dad0/settings/development_mode
|
63
63
|
Cloudflair.zone('023e105f4ecef8ad9ca31a8372d0c353').settings.development_mode.value
|
64
|
-
#
|
65
|
-
#
|
64
|
+
# => "on"
|
65
|
+
# => "off"
|
66
|
+
|
67
|
+
# PATCH https://api.cloudflare.com/client/v4/zones/cd7d068de3012345da9420df9514dad0/settings/development_mode
|
68
|
+
# {"value"="on"}
|
69
|
+
Cloudflair.zone('023e105f4ecef8ad9ca31a8372d0c353').settings.development_mode.tap do |dm|
|
70
|
+
dm.value = 'on'
|
71
|
+
dm.save
|
72
|
+
end
|
73
|
+
|
74
|
+
# GET https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records/372e67954025e0ba6aaa6d586b9e0b59
|
75
|
+
Cloudflair.zone('023e105f4ecef8ad9ca31a8372d0c353').dns_record('372e67954025e0ba6aaa6d586b9e0b59').name
|
66
76
|
```
|
67
77
|
|
68
78
|
You can use any field that Cloudflare's API returns. If a field is covered by some internal field, use `_field`.
|
@@ -85,11 +95,15 @@ The gem is available as open source under the terms of the [MIT License](http://
|
|
85
95
|
|
86
96
|
## Roadmap
|
87
97
|
|
88
|
-
* Pull Zone Information
|
89
|
-
* Zone Name to Zone ID Lookup
|
90
|
-
* Developer Mode, Cache Purge, Selective Cache Purge
|
91
|
-
* Airbrake error reporting
|
98
|
+
* ~~Pull Zone Information~~ ✅
|
99
|
+
* ~~Zone Name to Zone ID Lookup~~ ✅
|
100
|
+
* ~~Developer Mode, Cache Purge, Selective Cache Purge~~ ✅
|
101
|
+
* ~~Airbrake error reporting~~ ❌ (It's the responsibility of the application, not the Gem)
|
102
|
+
* Full read-only `/zones` API support
|
92
103
|
* Full API support
|
104
|
+
|
105
|
+
### Whishlist
|
106
|
+
|
93
107
|
* Metrics reporting
|
94
108
|
* Rate Limit Tracking
|
95
109
|
* (Global) Rate Limit Tracking (redis?)
|
data/bin/cloudflair
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'cloudflair'
|
5
|
+
require 'dotenv'
|
6
|
+
|
7
|
+
Dotenv.load
|
8
|
+
|
9
|
+
Cloudflair.configure do |c|
|
10
|
+
c.cloudflare.auth.key = ENV['AUTH_KEY']
|
11
|
+
c.cloudflare.auth.email = ENV['AUTH_MAIL']
|
12
|
+
c.faraday.logger = :detailed_logger
|
13
|
+
end
|
14
|
+
|
15
|
+
if ENV['CF_ZONE']
|
16
|
+
def z
|
17
|
+
@z ||= Cloudflair.zone ENV['CF_ZONE']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
#p.everything true
|
22
|
+
|
23
|
+
require 'irb'
|
24
|
+
IRB.start
|
data/cloudflair.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = %w(christian.maeder@nine.ch)
|
11
11
|
|
12
12
|
spec.summary = "Wrapper to CloudFlare's v4 REST API."
|
13
|
-
spec.description =
|
13
|
+
spec.description = "Cloudflair aims to provide easy access to CloudFlare's public API."
|
14
14
|
spec.homepage = 'https://github.com/ninech/cloudflair'
|
15
15
|
spec.license = 'MIT'
|
16
16
|
|
@@ -29,4 +29,5 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_development_dependency 'bundler', '~> 1.12'
|
30
30
|
spec.add_development_dependency 'rake', '~> 10.0'
|
31
31
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
32
|
+
spec.add_development_dependency 'dotenv', '~> 2.1'
|
32
33
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'cloudflair/entity'
|
2
|
+
|
3
|
+
module Cloudflair
|
4
|
+
class Railguns
|
5
|
+
include Cloudflair::Entity
|
6
|
+
|
7
|
+
attr_reader :railgun_id
|
8
|
+
patchable_fields :enabled
|
9
|
+
deletable true
|
10
|
+
path 'railguns/:railgun_id'
|
11
|
+
|
12
|
+
def initialize(railgun_id)
|
13
|
+
@railgun_id = railgun_id
|
14
|
+
end
|
15
|
+
|
16
|
+
def zones
|
17
|
+
raw_response = connection.get "#{path}/zones"
|
18
|
+
parsed_responses = response raw_response
|
19
|
+
parsed_responses.map do |parsed_response|
|
20
|
+
hash_to_object parsed_response
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'cloudflair/entity'
|
2
|
+
|
3
|
+
module Cloudflair
|
4
|
+
class Analytics
|
5
|
+
include Cloudflair::Communication
|
6
|
+
|
7
|
+
def initialize(zone_id)
|
8
|
+
@path = "zones/#{zone_id}/analytics"
|
9
|
+
end
|
10
|
+
|
11
|
+
def dashboard(filter = {})
|
12
|
+
raw_response = connection.get "#{@path}/dashboard", filter
|
13
|
+
parsed_response = response raw_response
|
14
|
+
hash_to_object parsed_response
|
15
|
+
end
|
16
|
+
|
17
|
+
def colos(filter = {})
|
18
|
+
raw_response = connection.get "#{@path}/colos", filter
|
19
|
+
parsed_responses = response raw_response
|
20
|
+
parsed_responses.map do |parsed_response|
|
21
|
+
hash_to_object parsed_response
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'cloudflair/entity'
|
2
|
+
|
3
|
+
module Cloudflair
|
4
|
+
class DnsRecord
|
5
|
+
include Cloudflair::Entity
|
6
|
+
|
7
|
+
attr_reader :zone_id, :record_id
|
8
|
+
deletable true
|
9
|
+
path 'zones/:zone_id/dns_records/:record_id'
|
10
|
+
|
11
|
+
def initialize(zone_id, record_id)
|
12
|
+
@zone_id = zone_id
|
13
|
+
@record_id = record_id
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'cloudflair/entity'
|
2
|
+
|
3
|
+
module Cloudflair
|
4
|
+
class Railgun
|
5
|
+
include Cloudflair::Entity
|
6
|
+
|
7
|
+
attr_reader :zone_id, :railgun_id
|
8
|
+
patchable_fields :connected
|
9
|
+
path 'zones/:zone_id/railguns/:railgun_id'
|
10
|
+
|
11
|
+
def initialize(zone_id, railgun_id)
|
12
|
+
@zone_id = zone_id
|
13
|
+
@railgun_id = railgun_id
|
14
|
+
end
|
15
|
+
|
16
|
+
def diagnose
|
17
|
+
raw_response = connection.get "#{path}/diagnose"
|
18
|
+
parsed_response = response raw_response
|
19
|
+
hash_to_object parsed_response
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/cloudflair/api/zone.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'cloudflair/api/zone/analytics'
|
1
2
|
require 'cloudflair/api/zone/available_plan'
|
2
3
|
require 'cloudflair/api/zone/available_rate_plan'
|
3
4
|
require 'cloudflair/api/zone/purge_cache'
|
@@ -8,6 +9,10 @@ module Cloudflair
|
|
8
9
|
class Zone
|
9
10
|
include Cloudflair::Entity
|
10
11
|
|
12
|
+
require 'cloudflair/api/zone__dns_records'
|
13
|
+
require 'cloudflair/api/zone__available_plans'
|
14
|
+
require 'cloudflair/api/zone__railguns'
|
15
|
+
|
11
16
|
attr_reader :zone_id
|
12
17
|
|
13
18
|
patchable_fields :paused, :vanity_name_servers, :plan
|
@@ -31,14 +36,8 @@ module Cloudflair
|
|
31
36
|
Cloudflair::AvailableRatePlan.new zone_id
|
32
37
|
end
|
33
38
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
raw_plans.map do |raw_plan|
|
38
|
-
zone = Cloudflair::AvailablePlan.new(zone_id, raw_plan['id'])
|
39
|
-
zone.data = raw_plan
|
40
|
-
zone
|
41
|
-
end
|
39
|
+
def analytics
|
40
|
+
Cloudflair::Analytics.new zone_id
|
42
41
|
end
|
43
42
|
end
|
44
43
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'cloudflair/api/zone/available_plan'
|
2
|
+
|
3
|
+
module Cloudflair
|
4
|
+
class Zone
|
5
|
+
def available_plans
|
6
|
+
raw_plans = response connection.get("#{path}/available_plans")
|
7
|
+
|
8
|
+
raw_plans.map do |raw_plan|
|
9
|
+
zone = available_plan raw_plan['id']
|
10
|
+
zone.data = raw_plan
|
11
|
+
zone
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def available_plan(plan_id)
|
16
|
+
Cloudflair::AvailablePlan.new zone_id, plan_id
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'cloudflair/api/zone/dns_record'
|
2
|
+
|
3
|
+
module Cloudflair
|
4
|
+
class Zone
|
5
|
+
def dns_records(filter={})
|
6
|
+
raw_records = response connection.get("#{path}/dns_records", filter)
|
7
|
+
|
8
|
+
raw_records.map { |raw_record| build_dns_record(raw_record) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def dns_record(record_id)
|
12
|
+
Cloudflair::DnsRecord.new zone_id, record_id
|
13
|
+
end
|
14
|
+
|
15
|
+
def new_dns_record(record_data)
|
16
|
+
raw_record = response connection.post("#{path}/dns_records", record_data)
|
17
|
+
|
18
|
+
build_dns_record raw_record
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def build_dns_record(raw_record)
|
24
|
+
record = dns_record raw_record['id']
|
25
|
+
record.data = raw_record
|
26
|
+
record
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'cloudflair/api/zone/railgun'
|
2
|
+
|
3
|
+
module Cloudflair
|
4
|
+
class Zone
|
5
|
+
def railguns(filter={})
|
6
|
+
raw_railguns = response connection.get("#{path}/railguns", filter)
|
7
|
+
|
8
|
+
raw_railguns.map do |raw_railgun|
|
9
|
+
railgun = railgun raw_railgun['id']
|
10
|
+
railgun.data = raw_railgun
|
11
|
+
railgun
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def railgun(railgun_id)
|
16
|
+
Cloudflair::Railgun.new zone_id, railgun_id
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/cloudflair/api.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'cloudflair/api/zone'
|
2
|
+
require 'cloudflair/api/railguns'
|
2
3
|
require 'cloudflair/communication'
|
3
4
|
|
4
5
|
module Cloudflair
|
@@ -9,7 +10,7 @@ module Cloudflair
|
|
9
10
|
end
|
10
11
|
|
11
12
|
def self.zones(filter = {})
|
12
|
-
raw_zones = response connection.get
|
13
|
+
raw_zones = response connection.get 'zones', filter
|
13
14
|
|
14
15
|
raw_zones.map do |raw_zone|
|
15
16
|
zone = Zone.new(raw_zone['id'])
|
@@ -17,4 +18,18 @@ module Cloudflair
|
|
17
18
|
zone
|
18
19
|
end
|
19
20
|
end
|
21
|
+
|
22
|
+
def self.railgun(railgun_id)
|
23
|
+
Railguns.new railgun_id
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.railguns(filter = {})
|
27
|
+
raw_railguns = response connection.get 'railguns', filter
|
28
|
+
|
29
|
+
raw_railguns.map do |raw_railgun|
|
30
|
+
railgun = Railguns.new(raw_railgun['id'])
|
31
|
+
railgun.data = raw_railgun
|
32
|
+
railgun
|
33
|
+
end
|
34
|
+
end
|
20
35
|
end
|
@@ -16,6 +16,18 @@ module Cloudflair
|
|
16
16
|
Cloudflair::Connection.new
|
17
17
|
end
|
18
18
|
|
19
|
+
def hash_to_object(hash)
|
20
|
+
objectified = (Class.new).new
|
21
|
+
hash.each do |k, v|
|
22
|
+
variable_name = sanitize_variable_name(k)
|
23
|
+
variable_name = "_#{variable_name}" if objectified.methods.map(&:to_s).include?(variable_name)
|
24
|
+
|
25
|
+
objectified.instance_variable_set("@#{variable_name}", v)
|
26
|
+
objectified.class.send :define_method, variable_name, proc { self.instance_variable_get("@#{variable_name}") }
|
27
|
+
end
|
28
|
+
objectified
|
29
|
+
end
|
30
|
+
|
19
31
|
private
|
20
32
|
|
21
33
|
def read(response)
|
@@ -59,5 +71,9 @@ module Cloudflair
|
|
59
71
|
fail Cloudflair::CloudflairError, "#{status} Request Error"
|
60
72
|
end
|
61
73
|
end
|
74
|
+
|
75
|
+
def sanitize_variable_name(raw_name)
|
76
|
+
raw_name.gsub /[^a-zA-Z0-9_]/, '_'
|
77
|
+
end
|
62
78
|
end
|
63
79
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'faraday'
|
2
2
|
require 'faraday_middleware'
|
3
3
|
require 'faraday/detailed_logger'
|
4
|
+
require 'cloudflair/error/cloudflair_error'
|
4
5
|
|
5
6
|
module Cloudflair
|
6
7
|
class Connection
|
@@ -13,11 +14,13 @@ module Cloudflair
|
|
13
14
|
def self.headers
|
14
15
|
headers = {}
|
15
16
|
cloudflare_auth_config = Cloudflair.config.cloudflare.auth
|
16
|
-
if cloudflare_auth_config.
|
17
|
+
if !(cloudflare_auth_config.key.nil? || cloudflare_auth_config.email.nil?)
|
17
18
|
headers['X-Auth-Key'] = cloudflare_auth_config.key
|
18
19
|
headers['X-Auth-Email'] = cloudflare_auth_config.email
|
19
|
-
|
20
|
+
elsif !cloudflare_auth_config.user_service_key.nil?
|
20
21
|
headers['X-Auth-User-Service-Key'] = cloudflare_auth_config.user_service_key
|
22
|
+
else
|
23
|
+
raise CloudflairError, 'Neither email & key nor user_service_key have been defined.'
|
21
24
|
end
|
22
25
|
headers
|
23
26
|
end
|
data/lib/cloudflair/entity.rb
CHANGED
@@ -211,16 +211,6 @@ module Cloudflair
|
|
211
211
|
def objectify(name)
|
212
212
|
hash_to_object data[name]
|
213
213
|
end
|
214
|
-
|
215
|
-
def hash_to_object(hash)
|
216
|
-
objectified = Class.new
|
217
|
-
hash.each do |k, v|
|
218
|
-
objectified.instance_variable_set("@#{k}", v)
|
219
|
-
objectified.class.send(:define_method, k, proc { self.instance_variable_get("@#{k}") })
|
220
|
-
end
|
221
|
-
objectified
|
222
|
-
end
|
223
|
-
|
224
214
|
def arrayify(name, klass_or_proc=nil)
|
225
215
|
data[name].map do |data|
|
226
216
|
if klass_or_proc.nil?
|
@@ -9,6 +9,8 @@ module Cloudflair
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def to_s
|
12
|
+
return '[ "An error happened, but no error message/code was given by CloudFlare." (Code: 0000) ]' if cloudflare_errors.empty?
|
13
|
+
|
12
14
|
strings = cloudflare_errors.map { |cf_e| "\"#{cf_e[:message]}\" (Code: #{cf_e[:code]})" }
|
13
15
|
"[ #{strings.join ', '} ]"
|
14
16
|
end
|
data/lib/cloudflair/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudflair
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Mäder
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -108,7 +108,21 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '3.0'
|
111
|
-
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: dotenv
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.1'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2.1'
|
125
|
+
description: Cloudflair aims to provide easy access to CloudFlare's public API.
|
112
126
|
email:
|
113
127
|
- christian.maeder@nine.ch
|
114
128
|
executables: []
|
@@ -123,15 +137,20 @@ files:
|
|
123
137
|
- LICENSE.txt
|
124
138
|
- README.md
|
125
139
|
- Rakefile
|
140
|
+
- bin/cloudflair
|
126
141
|
- bin/console
|
127
142
|
- bin/setup
|
128
143
|
- cloudflair.gemspec
|
129
144
|
- lib/cloudflair.rb
|
130
145
|
- lib/cloudflair/api.rb
|
146
|
+
- lib/cloudflair/api/railguns.rb
|
131
147
|
- lib/cloudflair/api/zone.rb
|
148
|
+
- lib/cloudflair/api/zone/analytics.rb
|
132
149
|
- lib/cloudflair/api/zone/available_plan.rb
|
133
150
|
- lib/cloudflair/api/zone/available_rate_plan.rb
|
151
|
+
- lib/cloudflair/api/zone/dns_record.rb
|
134
152
|
- lib/cloudflair/api/zone/purge_cache.rb
|
153
|
+
- lib/cloudflair/api/zone/railgun.rb
|
135
154
|
- lib/cloudflair/api/zone/settings.rb
|
136
155
|
- lib/cloudflair/api/zone/settings/advanced_ddos.rb
|
137
156
|
- lib/cloudflair/api/zone/settings/always_online.rb
|
@@ -163,6 +182,9 @@ files:
|
|
163
182
|
- lib/cloudflair/api/zone/settings/true_client_ip_header.rb
|
164
183
|
- lib/cloudflair/api/zone/settings/waf.rb
|
165
184
|
- lib/cloudflair/api/zone/settings/websockets.rb
|
185
|
+
- lib/cloudflair/api/zone__available_plans.rb
|
186
|
+
- lib/cloudflair/api/zone__dns_records.rb
|
187
|
+
- lib/cloudflair/api/zone__railguns.rb
|
166
188
|
- lib/cloudflair/communication.rb
|
167
189
|
- lib/cloudflair/connection.rb
|
168
190
|
- lib/cloudflair/entity.rb
|