cloud_party 0.1.1.pre.alpha.1 → 0.1.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +1 -1
  4. data/.rubocop_config.yml +2 -1
  5. data/.travis.yml +11 -6
  6. data/README.md +17 -8
  7. data/Rakefile +1 -1
  8. data/cloud_party.gemspec +27 -25
  9. data/lib/cloud_party/context.rb +5 -7
  10. data/lib/cloud_party/exception.rb +28 -54
  11. data/lib/cloud_party/exceptions/request_errors/bad_request_error.rb +26 -0
  12. data/lib/cloud_party/exceptions/request_errors/forbidden_error.rb +26 -0
  13. data/lib/cloud_party/exceptions/request_errors/method_not_allowed_error.rb +27 -0
  14. data/lib/cloud_party/exceptions/request_errors/not_found_error.rb +26 -0
  15. data/lib/cloud_party/exceptions/request_errors/too_many_requests_error.rb +27 -0
  16. data/lib/cloud_party/exceptions/request_errors/unauthorized_error.rb +26 -0
  17. data/lib/cloud_party/exceptions/request_errors/unsupported_media_type_error.rb +27 -0
  18. data/lib/cloud_party/exceptions/request_errors.rb +25 -0
  19. data/lib/cloud_party/exceptions/un_recognized_endpoint_error.rb +20 -0
  20. data/lib/cloud_party/exceptions/un_recognized_result_type_error.rb +14 -0
  21. data/lib/cloud_party/exceptions.rb +42 -1
  22. data/lib/cloud_party/nodes/accounts.rb +26 -0
  23. data/lib/cloud_party/nodes/ips.rb +5 -3
  24. data/lib/cloud_party/nodes/memberships.rb +6 -6
  25. data/lib/cloud_party/nodes/zones.rb +30 -0
  26. data/lib/cloud_party/nodes.rb +2 -0
  27. data/lib/cloud_party/response.rb +17 -3
  28. data/lib/cloud_party/responses/accounts.rb +148 -0
  29. data/lib/cloud_party/responses/ips.rb +3 -6
  30. data/lib/cloud_party/responses/memberships.rb +1 -0
  31. data/lib/cloud_party/responses/nodes/accounts.rb +3 -0
  32. data/lib/cloud_party/responses/nodes/zones/account.rb +30 -0
  33. data/lib/cloud_party/responses/nodes/zones/permissions.rb +33 -0
  34. data/lib/cloud_party/responses/nodes/zones/plan.rb +25 -0
  35. data/lib/cloud_party/responses/nodes/zones/plan_pending.rb +27 -0
  36. data/lib/cloud_party/responses/nodes/zones.rb +6 -0
  37. data/lib/cloud_party/responses/nodes.rb +7 -2
  38. data/lib/cloud_party/responses/zones.rb +150 -0
  39. data/lib/cloud_party/responses.rb +11 -0
  40. data/lib/cloud_party/version.rb +1 -1
  41. data/lib/cloud_party.rb +5 -1
  42. data/sonar-project.properties +9 -0
  43. metadata +55 -37
  44. data/lib/cloud_party/exceptions/bad_request_400.rb +0 -24
@@ -4,18 +4,20 @@ require 'cloud_party/context'
4
4
  require 'cloud_party/responses'
5
5
  module CloudParty
6
6
  module Nodes
7
- class IPs < CloudParty::Context
7
+ class IPs
8
+ include CloudParty::Context
8
9
  include HTTParty
9
10
  base_uri 'api.cloudflare.com:443/client/v4'
10
11
  headers 'X-Auth-Email' => cfg.email,
11
- 'X-Auth-Key' => cfg.api_key,
12
+ 'X-Auth-Key' => cfg.api_key,
12
13
  'Content-Type' => 'application/json',
13
- 'User-Agent' => "CloudParty/#{CloudParty::VERSION}"
14
+ 'User-Agent' => "CloudParty/#{CloudParty::VERSION}"
14
15
 
15
16
  def initialize(options = nil)
16
17
  super()
17
18
  @options = options
18
19
  end
20
+
19
21
  def list
20
22
  CloudParty::Responses::IPs.new(:get, '/ips', self.class.get('/ips'), @options)
21
23
  end
@@ -4,13 +4,14 @@ require 'cloud_party/context'
4
4
  require 'cloud_party/responses'
5
5
  module CloudParty
6
6
  module Nodes
7
- class Memberships < CloudParty::Context
7
+ class Memberships
8
+ include CloudParty::Context
8
9
  include HTTParty
9
10
  base_uri 'api.cloudflare.com:443/client/v4'
10
11
  headers 'X-Auth-Email' => cfg.email,
11
- 'X-Auth-Key' => cfg.api_key,
12
+ 'X-Auth-Key' => cfg.api_key,
12
13
  'Content-Type' => 'application/json',
13
- 'User-Agent' => "CloudParty/#{CloudParty::VERSION}"
14
+ 'User-Agent' => "CloudParty/#{CloudParty::VERSION}"
14
15
 
15
16
  def initialize(options)
16
17
  super()
@@ -19,9 +20,8 @@ module CloudParty
19
20
 
20
21
  def list
21
22
  CloudParty::Responses::Memberships.new(:get, '/memberships', self.class.get('/memberships', @options))
22
- rescue APIError => e
23
- puts e.message
24
- puts e.response
23
+ rescue APIError
24
+ raise
25
25
  end
26
26
  end
27
27
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cloud_party/context'
4
+ require 'cloud_party/responses'
5
+ module CloudParty
6
+ module Nodes
7
+ class Zones
8
+ include CloudParty::Context
9
+ include HTTParty
10
+ base_uri 'api.cloudflare.com:443/client/v4'
11
+ headers 'X-Auth-Email' => cfg.email,
12
+ 'X-Auth-Key' => cfg.api_key,
13
+ 'Content-Type' => 'application/json',
14
+ 'User-Agent' => "CloudParty/#{CloudParty::VERSION}"
15
+
16
+ def initialize(options = nil)
17
+ super()
18
+ @options = options
19
+ end
20
+
21
+ def list
22
+ CloudParty::Responses::Zones.new(:get, '/zones', self.class.get('/zones'), @options)
23
+ end
24
+
25
+ def get(id)
26
+ CloudParty::Responses::Zones.new(:get, '/zones/:id', self.class.get("/zones/#{id}"), @options)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -2,7 +2,9 @@
2
2
 
3
3
  module CloudParty
4
4
  module Nodes
5
+ autoload :Accounts, 'cloud_party/nodes/accounts'
5
6
  autoload :Memberships, 'cloud_party/nodes/memberships'
6
7
  autoload :IPs, 'cloud_party/nodes/ips'
8
+ autoload :Zones, 'cloud_party/nodes/zones'
7
9
  end
8
10
  end
@@ -1,11 +1,25 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  module CloudParty
3
+
4
4
  module Response
5
5
  def self.included(base)
6
- # if base.def
6
+ base.include CloudParty::Responses::ResponseMethods
7
+ base.attr_reader :body, :parsed_response, :code, :errors, :messages, :results, :result
7
8
  end
8
9
 
9
- def initialize(self_object, method_name, endpoint, response); end
10
+ def filter_by_account(account)
11
+ # blah
12
+ end
13
+ # @param [Result] result_json_object check result type for parsing
14
+ # @raise [UnRecognizedResultTypeError] when the result type is neither Hash nor Array
15
+ def check_result_type(result_json_object)
16
+ if result_json_object.is_a?(Hash)
17
+ 'Hash'
18
+ elsif result_json_object.is_a?(Array)
19
+ 'Array'
20
+ else
21
+ raise UnRecognizedResultTypeError, result_json_object.class
22
+ end
23
+ end
10
24
  end
11
25
  end
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cloud_party/responses/nodes/accounts'
4
+ module CloudParty
5
+ module Responses
6
+ class Accounts
7
+ include CloudParty::Response
8
+ def initialize(method_name, endpoint, response)
9
+ @code = response.code
10
+ @body = JSON.parse(response.body, symbolize_names: true)
11
+ @success = @body[:success]
12
+ unless successful?
13
+ message = <<~MESSAGE
14
+ Unable to #{method_name.to_s.upcase} to endpoint:
15
+ #{endpoint}. Inspect CloudParty::APIError#response
16
+ for further details
17
+ MESSAGE
18
+ raise CloudParty::APIError.new(message, response)
19
+ end
20
+
21
+ @results = []
22
+ @body[:result].each do |res|
23
+ @results << CloudParty::Responses::Result.new(res)
24
+ end
25
+ @errors = []
26
+ @body[:errors].each do |err|
27
+ @errors << CloudParty::Responses::Error.new(err)
28
+ end
29
+ @messages = []
30
+ @body[:messages].each do |msg|
31
+ @messages << CloudParty::Responses::Message.new(msg)
32
+ end
33
+ end
34
+
35
+ def successful?
36
+ @success
37
+ end
38
+ alias success successful?
39
+ attr_reader :messages
40
+
41
+ def result
42
+ @results.first
43
+ end
44
+
45
+ attr_reader :results
46
+
47
+ def inspect
48
+ wanted_methods = %i[errors messages success results result]
49
+ our_methods = methods.select do |m|
50
+ wanted_methods.include? m
51
+ end
52
+ outputs = []
53
+ our_methods.each do |m|
54
+ outputs << "#{m}=#{send(m)}"
55
+ end
56
+ "#<Response: #{outputs.join(', ')}>"
57
+ end
58
+
59
+ def to_s
60
+ inspect
61
+ end
62
+ end
63
+ class Result
64
+ def initialize(result)
65
+ @result = result
66
+ @result.each do |k, v|
67
+ next if k == :permissions
68
+ next if k == :account
69
+
70
+ instance_variable_set(:"@#{k}", v)
71
+ end
72
+ end
73
+
74
+ def account
75
+ CloudParty::Responses::Node::Account.new(@result[:account])
76
+ end
77
+
78
+ def permissions
79
+ CloudParty::Responses::Node::Permissions.new(@result[:permissions])
80
+ end
81
+
82
+ def status
83
+ @status
84
+ end
85
+
86
+ def roles
87
+ @roles
88
+ end
89
+
90
+ def id
91
+ @id
92
+ end
93
+
94
+ def inspect
95
+ wanted = %i[permissions account status roles id]
96
+ outputs = []
97
+ wanted.each do |m|
98
+ outputs << "#{m.to_s}=#{send(m)}"
99
+ end
100
+ "#<Result #{outputs.join(', ')}>"
101
+ end
102
+
103
+ def to_s
104
+ inspect
105
+ end
106
+ end
107
+ class Error
108
+ def initialize(error)
109
+ @error = error
110
+ @code = error.fetch(:code, nil)
111
+ @message = error.fetch(:message, nil)
112
+ end
113
+
114
+ attr_reader :code
115
+
116
+ attr_reader :message
117
+
118
+ def inspect
119
+ to_s
120
+ end
121
+
122
+ def to_s
123
+ wanted_methods = %i[code message]
124
+ our_methods = methods.select do |m|
125
+ wanted_methods.include? m
126
+ end
127
+ outputs = []
128
+ our_methods.each do |m|
129
+ outputs << "#{m}=#{send(m)}"
130
+ end
131
+ "#<Error: #{output.join(', ')}>"
132
+ end
133
+ end
134
+ class Message
135
+ def initialize(message)
136
+ @message = message
137
+ end
138
+
139
+ def inspect
140
+ to_s
141
+ end
142
+
143
+ def to_s
144
+ @messages.join(', ')
145
+ end
146
+ end
147
+ end
148
+ end
@@ -5,6 +5,7 @@ module CloudParty
5
5
  module Responses
6
6
  #
7
7
  class IPs
8
+ include CloudParty::Response
8
9
  def initialize(method_name, endpoint, response, options)
9
10
  @code = response.code
10
11
  @body = JSON.parse(response.body, symbolize_names: true)
@@ -66,6 +67,7 @@ module CloudParty
66
67
  end
67
68
  end
68
69
  class Result
70
+ attr_reader :ipv4_cidrs, :ipv6_cidrs
69
71
  def initialize(result)
70
72
  @result = result
71
73
  @result.each do |k, v|
@@ -73,12 +75,7 @@ module CloudParty
73
75
  end
74
76
  end
75
77
 
76
- def ipv4_cidrs
77
- @ipv4_cidrs
78
- end
79
- def ipv6_cidrs
80
- @ipv6_cidrs
81
- end
78
+
82
79
 
83
80
  def inspect
84
81
  wanted = %i[ipv4_cidrs ipv6_cidrs]
@@ -4,6 +4,7 @@ require 'cloud_party/responses/nodes/memberships'
4
4
  module CloudParty
5
5
  module Responses
6
6
  class Memberships
7
+ include CloudParty::Response
7
8
  def initialize(method_name, endpoint, response)
8
9
  @code = response.code
9
10
  @body = JSON.parse(response.body, symbolize_names: true)
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloudParty
4
+ module Responses
5
+ module Node
6
+ class Account
7
+ def initialize(account_hsh)
8
+ @account = account_hsh
9
+ @name = @account[:name]
10
+ @id = @account[:id]
11
+ end
12
+
13
+ attr_reader :name
14
+ attr_reader :id
15
+
16
+ def inspect
17
+ outputs = []
18
+ %i[id name].each do |var|
19
+ outputs << "#{var}=#{send(var)}"
20
+ end
21
+ "#<Account #{outputs.join(', ')}>"
22
+ end
23
+
24
+ def to_s
25
+ inspect
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloudParty
4
+ module Responses
5
+ module Node
6
+ class Permissions
7
+ def initialize(array)
8
+ @perms = {}
9
+ array.each do |perm|
10
+ perm_obj = parse_perm(perm)
11
+ @perms[perm_obj[:perm_name]] ||= []
12
+ @perms[perm_obj[:perm_name]] << perm_obj[:perm_value]
13
+ end
14
+ end
15
+
16
+ def parse_perm(perm)
17
+ pattern = /\#(?<perm_name>.+):(?<perm_value>.+)/
18
+ pattern.match(perm)
19
+ end
20
+
21
+ attr_reader :perms
22
+
23
+ def to_s
24
+ "#<Permissions: #{perms}>"
25
+ end
26
+
27
+ def inspect
28
+ to_s
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloudParty
4
+ module Responses
5
+ module Node
6
+ class Plan
7
+ def initialize(hsh)
8
+ hsh.each do |name, value|
9
+ instance_variable_set(:"@#{name}", value)
10
+ end
11
+ end
12
+
13
+ attr_reader :list
14
+
15
+ def to_s
16
+ "#<Plan: #{list}>"
17
+ end
18
+
19
+ def inspect
20
+ to_s
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloudParty
4
+ module Responses
5
+ module Node
6
+ class PlanPending
7
+ def initialize(hsh)
8
+ if hsh.nil?
9
+ @list = nil
10
+ else
11
+ hsh.each do |name, value|
12
+ instance_variable_set(:"@#{name}", value)
13
+ end
14
+ end
15
+ end
16
+
17
+ def to_s
18
+ "#<PlanPending: #{list}>"
19
+ end
20
+
21
+ def inspect
22
+ to_s
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cloud_party/responses/nodes/zones/account'
4
+ require 'cloud_party/responses/nodes/zones/plan'
5
+ require 'cloud_party/responses/nodes/zones/plan_pending'
6
+ require 'cloud_party/responses/nodes/zones/permissions'
@@ -2,9 +2,14 @@
2
2
 
3
3
  module CloudParty
4
4
  module Responses
5
+ # Response Node
6
+ #
7
+ # This module is to be first ancestor of each node's response objects.
8
+ #
9
+ # This being in some way a Permissions class is to be
10
+ # formed as CloudParty::Responses::Node::Permissions
11
+ # instead of CloudParty::Responses::ENDPOINT::Permissions
5
12
  module Node
6
- autoload :Account, 'cloud_party/responses/nodes/account'
7
- autoload :Permissions, 'cloud_party/responses/nodes/permissions'
8
13
  end
9
14
  end
10
15
  end
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cloud_party/responses/nodes/zones'
4
+ module CloudParty
5
+ module Responses
6
+ include CloudParty::Response
7
+ # '/zones' endpoint response object
8
+ class Zones
9
+ # @raise [CloudParty::APIError] if the library encountered
10
+ # an error and {#successful?} is false
11
+ # @raise [CloudParty::UnRecognizedEndpointError] if the library encountered
12
+ # an unknown endpoint for this class
13
+ def initialize(method_name, endpoint, response, options)
14
+ @code = response.code
15
+ @body = JSON.parse(response.body, symbolize_names: true)
16
+ @parsed_response = response.parsed_response
17
+ @success = @body[:success]
18
+ unless successful?
19
+ message = <<~MESSAGE
20
+ Unable to #{method_name.to_s.upcase} to endpoint:
21
+ #{endpoint}. Inspect CloudParty::APIError#response
22
+ for further details
23
+ MESSAGE
24
+ raise CloudParty::APIError.new(message, response)
25
+ end
26
+ @results = []
27
+ case endpoint
28
+ when '/zones'
29
+
30
+ @body[:result].each do |res|
31
+ @results << CloudParty::Responses::Result.new(res)
32
+ end
33
+ when '/zones/:id'
34
+ @result = CloudParty::Responses::Result.new(@body[:result])
35
+ @results << @result
36
+ else
37
+ raise UnRecognizedEndpointError.new(endpoint, self.class)
38
+ end
39
+
40
+ @errors = []
41
+ @body[:errors].each do |err|
42
+ @errors << CloudParty::Responses::Error.new(err)
43
+ end
44
+ @messages = []
45
+ @body[:messages].each do |msg|
46
+ @messages << CloudParty::Responses::Message.new(msg)
47
+ end
48
+
49
+ end
50
+ attr_reader :errors
51
+ attr_reader :messages
52
+ attr_reader :results
53
+ def successful?
54
+ @success
55
+ end
56
+ alias success successful?
57
+
58
+
59
+ def result
60
+ @body[:result]
61
+ end
62
+
63
+
64
+
65
+ def inspect
66
+ wanted_methods = %i[success messages errors results]
67
+ our_methods = methods.select do |m|
68
+ wanted_methods.include? m
69
+ end
70
+ outputs = []
71
+ our_methods.sort.each do |m|
72
+ outputs << "#{m}=#{send(m)}"
73
+ end
74
+ "#<Response: #{outputs.join(', ')}>"
75
+ end
76
+
77
+ def to_s
78
+ inspect
79
+ end
80
+ end
81
+ class Result
82
+ attr_reader :id, :name, :development_mode, :original_registar, :original_dnshost, :status, :paused, :type, :permissions
83
+ def initialize(result)
84
+ @result = result
85
+ @result.each do |k, v|
86
+ @plan = CloudParty::Responses::Node::Plan.new(@result.dig(:plan))
87
+ @plan_pending = CloudParty::Responses::Node::PlanPending.new(@result.dig(:plan_pending))
88
+ @account = CloudParty::Responses::Node::Account.new(@result.dig(:account))
89
+ @permissions = CloudParty::Responses::Node::Permissions.new(@result.dig(:permissions))
90
+ instance_variable_set(:"@#{k}", v) unless %i[plan plan_pending account permissions].include?(k)
91
+ end
92
+ end
93
+
94
+
95
+
96
+ def inspect
97
+ wanted = %i[id name development_mode original_registar original_dnshost status paused type permissions]
98
+ outputs = []
99
+ wanted.each do |m|
100
+ outputs << "#{m}=#{send(m)}"
101
+ end
102
+ "#<Result #{outputs.join(', ')}>"
103
+ end
104
+
105
+ def to_s
106
+ inspect
107
+ end
108
+ end
109
+ class Error
110
+ def initialize(error)
111
+ @error = error
112
+ @code = error.fetch(:code, nil)
113
+ @message = error.fetch(:message, nil)
114
+ end
115
+
116
+ attr_reader :code
117
+
118
+ attr_reader :message
119
+
120
+ def inspect
121
+ to_s
122
+ end
123
+
124
+ def to_s
125
+ wanted_methods = %i[code message]
126
+ our_methods = methods.select do |m|
127
+ wanted_methods.include? m
128
+ end
129
+ outputs = []
130
+ our_methods.each do |m|
131
+ outputs << "#{m}=#{send(m)}"
132
+ end
133
+ "#<Error: #{output.join(', ')}>"
134
+ end
135
+ end
136
+ class Message
137
+ def initialize(message)
138
+ @message = message
139
+ end
140
+
141
+ def inspect
142
+ to_s
143
+ end
144
+
145
+ def to_s
146
+ @messages.join(', ')
147
+ end
148
+ end
149
+ end
150
+ end
@@ -1,8 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudParty
4
+ # base module to have responses from the API be parents of,
5
+ # all response nodes (read: endpoints) are to have their own autoload line
6
+ # if an endpoint has numerous uses, like Zones and its dns_records endpoint
7
+ # a sane class is to be used instead, e.g. .../zones/#!{zone_id}/dns_records ->
8
+ # {Responses::DnsRecords} or {Responses::Zones_DnsRecords}
4
9
  module Responses
5
10
  autoload :Memberships, 'cloud_party/responses/memberships'
6
11
  autoload :IPs, 'cloud_party/responses/ips'
12
+ autoload :Zones, 'cloud_party/responses/zones'
13
+
14
+ module ResponseMethods
15
+
16
+ end
7
17
  end
18
+
8
19
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudParty
4
- VERSION = '0.1.1-alpha.1'
4
+ VERSION = '0.1.1'
5
5
  end
data/lib/cloud_party.rb CHANGED
@@ -31,10 +31,14 @@ class String
31
31
  end
32
32
  end
33
33
  module CloudParty
34
+ autoload :Errors, 'cloud_party/exceptions'
35
+ class Connection
36
+ include CloudParty::Context
37
+ end
34
38
  def self.simple_connect
35
39
  CloudParty::Simple.new.connect
36
40
  end
37
41
  def self.context_connect
38
- CloudParty::Context.new
42
+ Connection.new
39
43
  end
40
44
  end
@@ -0,0 +1,9 @@
1
+ sonar.projectKey=iotaspencer_gem_cloud_party
2
+ sonar.projectName=Cloud Party
3
+ sonar.projectVersion=0.0.0
4
+ sonar.sources=.
5
+ sonar.host.url=https://sonarcloud.io
6
+ sonar.links.homepage=https://iotaspencer.me/projects/cloud_party
7
+ sonar.links.ci=https://travis-ci.org/IotaSpencer/cloud_party
8
+ sonar.links.scm=https://github.com/ElectroCode-Gems/cloud_party
9
+ sonar.tests=tests