ruby_api_pack_cloudways 0.3.0 → 0.4.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/lib/ruby_api_pack_cloudways/api/cw_lists.rb +18 -12
- data/lib/ruby_api_pack_cloudways/connection/cw_connect.rb +19 -3
- data/lib/ruby_api_pack_cloudways/connection/cw_token.rb +36 -3
- data/lib/ruby_api_pack_cloudways/handlers/response_validator.rb +29 -0
- data/lib/ruby_api_pack_cloudways/version.rb +1 -1
- data/lib/ruby_api_pack_cloudways.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6765ce6819c078879372426341ea342075ff9affdb4bba5d0b975cb9bb6a9490
|
4
|
+
data.tar.gz: 2686e6ab99b91918efec326913b6e47efc0f6362f783d0e81f96c32d2392fa10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c146cd133b425c9b233b2140d154ec607c7c3cd720466b70300338b22a7f338e934f25cd49633199fe8de3d492f3a0de74d008853780e21f089060843b8266fb
|
7
|
+
data.tar.gz: 4f6a16799faae8d64f844b312cd7b2775fa4428a62c5f1abb3cf193d508873ba31763ae5b3e216ae31f8669ae113e86ef50439386d3dc98b231a4aa18a6f632b
|
@@ -1,15 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'ruby_api_pack_cloudways/handlers/response_validator'
|
4
|
+
|
3
5
|
module RubyApiPackCloudways
|
4
6
|
module Api
|
5
7
|
class CwLists
|
8
|
+
extend RubyApiPackCloudways::Handlers::ResponseValidator
|
9
|
+
|
6
10
|
# List endpoints
|
7
11
|
ENDPOINTS = {
|
8
12
|
apps: '/apps',
|
9
13
|
backup_frequencies: '/backup-frequencies',
|
10
14
|
countries: '/countries',
|
11
|
-
monitor_durations: '/
|
12
|
-
monitor_targets: '/
|
15
|
+
monitor_durations: '/monitor_durations',
|
16
|
+
monitor_targets: '/monitor_targets',
|
13
17
|
packages: '/packages',
|
14
18
|
providers: '/providers',
|
15
19
|
regions: '/regions',
|
@@ -19,52 +23,54 @@ module RubyApiPackCloudways
|
|
19
23
|
|
20
24
|
# Fetch list of applications available
|
21
25
|
def self.app_list
|
22
|
-
fetch_resource(ENDPOINTS[:apps])
|
26
|
+
validate_response(fetch_resource(ENDPOINTS[:apps]), 'apps')
|
23
27
|
end
|
24
28
|
|
25
29
|
# Fetch list of available backup frequencies
|
26
30
|
def self.backup_frequency_list
|
27
|
-
fetch_resource(ENDPOINTS[:backup_frequencies])
|
31
|
+
validate_response(fetch_resource(ENDPOINTS[:backup_frequencies]), 'frequencies')
|
28
32
|
end
|
29
33
|
|
30
34
|
# Fetch list of supported countries
|
31
35
|
def self.country_list
|
32
|
-
fetch_resource(ENDPOINTS[:countries])
|
36
|
+
response = fetch_resource(ENDPOINTS[:countries])
|
37
|
+
wrapped_response = { 'countries' => response } if response.is_a?(Array)
|
38
|
+
validate_response(wrapped_response || response, 'countries')
|
33
39
|
end
|
34
40
|
|
35
41
|
# Fetch list of monitoring durations
|
36
42
|
def self.monitor_duration_list
|
37
|
-
fetch_resource(ENDPOINTS[:monitor_durations])
|
43
|
+
validate_response(fetch_resource(ENDPOINTS[:monitor_durations]), 'durations')
|
38
44
|
end
|
39
45
|
|
40
46
|
# Fetch list of monitoring targets
|
41
47
|
def self.monitor_target_list
|
42
|
-
fetch_resource(ENDPOINTS[:monitor_targets])
|
48
|
+
validate_response(fetch_resource(ENDPOINTS[:monitor_targets]), 'targets')
|
43
49
|
end
|
44
50
|
|
45
51
|
# Fetch list of available packages
|
46
52
|
def self.package_list
|
47
|
-
fetch_resource(ENDPOINTS[:packages])
|
53
|
+
validate_response(fetch_resource(ENDPOINTS[:packages]), 'packages')
|
48
54
|
end
|
49
55
|
|
50
56
|
# Fetch list of providers
|
51
57
|
def self.provider_list
|
52
|
-
fetch_resource(ENDPOINTS[:providers])
|
58
|
+
validate_response(fetch_resource(ENDPOINTS[:providers]), 'providers')
|
53
59
|
end
|
54
60
|
|
55
61
|
# Fetch list of regions
|
56
62
|
def self.region_list
|
57
|
-
fetch_resource(ENDPOINTS[:regions])
|
63
|
+
validate_response(fetch_resource(ENDPOINTS[:regions]), 'regions')
|
58
64
|
end
|
59
65
|
|
60
66
|
# Fetch list of server sizes
|
61
67
|
def self.server_size_list
|
62
|
-
fetch_resource(ENDPOINTS[:server_sizes])
|
68
|
+
validate_response(fetch_resource(ENDPOINTS[:server_sizes]), 'sizes')
|
63
69
|
end
|
64
70
|
|
65
71
|
# Fetch list of available settings
|
66
72
|
def self.setting_list
|
67
|
-
fetch_resource(ENDPOINTS[:settings])
|
73
|
+
validate_response(fetch_resource(ENDPOINTS[:settings]), 'settings')
|
68
74
|
end
|
69
75
|
|
70
76
|
# Private method to fetch resources from a specified endpoint
|
@@ -1,5 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'httparty'
|
4
|
+
require 'oj'
|
5
|
+
require 'openssl'
|
6
|
+
|
3
7
|
module RubyApiPackCloudways
|
4
8
|
module Connection
|
5
9
|
class CwConnect
|
@@ -17,9 +21,16 @@ module RubyApiPackCloudways
|
|
17
21
|
token = CwToken.new.cw_api_token
|
18
22
|
response = HTTParty.get(
|
19
23
|
"#{@cw_api_url_base}#{@cw_api_path}",
|
20
|
-
headers: { 'Authorization' => "Bearer #{token}" }
|
24
|
+
headers: { 'Authorization' => "Bearer #{token}" },
|
25
|
+
ssl_version: :TLSv1_2,
|
26
|
+
debug_output: $stdout
|
21
27
|
)
|
22
28
|
handle_response(response)
|
29
|
+
rescue RuntimeError => e
|
30
|
+
raise unless e.message.include?('Rate limit exceeded')
|
31
|
+
|
32
|
+
sleep(60)
|
33
|
+
retry
|
23
34
|
end
|
24
35
|
|
25
36
|
# POST request to Cloudways API
|
@@ -28,7 +39,9 @@ module RubyApiPackCloudways
|
|
28
39
|
response = HTTParty.post(
|
29
40
|
"#{@cw_api_url_base}#{@cw_api_path}",
|
30
41
|
headers: { 'Authorization' => "Bearer #{token}", 'Content-Type' => 'application/json' },
|
31
|
-
body: params.to_json
|
42
|
+
body: params.to_json,
|
43
|
+
ssl_version: :TLSv1_2,
|
44
|
+
debug_output: $stdout
|
32
45
|
)
|
33
46
|
handle_response(response)
|
34
47
|
end
|
@@ -47,9 +60,12 @@ module RubyApiPackCloudways
|
|
47
60
|
|
48
61
|
# Parse response from Cloudways API
|
49
62
|
def parse_response(response)
|
63
|
+
content_type = response.headers&.fetch('content-type', nil)
|
64
|
+
raise "Unexpected response: #{response.body}" unless content_type&.include?('application/json')
|
65
|
+
|
50
66
|
Oj.load(response.body, mode: :strict)
|
51
67
|
rescue Oj::ParseError => e
|
52
|
-
raise "Error parsing response: #{e.message}"
|
68
|
+
raise "Error parsing response: #{e.message}. Raw body: #{response.body}"
|
53
69
|
end
|
54
70
|
end
|
55
71
|
end
|
@@ -3,6 +3,9 @@
|
|
3
3
|
module RubyApiPackCloudways
|
4
4
|
module Connection
|
5
5
|
class CwToken
|
6
|
+
# Buffer time before token expiration to fetch a new token
|
7
|
+
TOKEN_EXPIRATION_BUFFER = 300
|
8
|
+
|
6
9
|
attr_reader :cw_api_url_base, :cw_url_path_auth, :cw_user_email, :cw_user_key
|
7
10
|
|
8
11
|
def initialize
|
@@ -10,23 +13,53 @@ module RubyApiPackCloudways
|
|
10
13
|
@cw_url_path_auth = RubyApiPackCloudways.configuration.api_path_token
|
11
14
|
@cw_user_email = RubyApiPackCloudways.configuration.api_email
|
12
15
|
@cw_user_key = RubyApiPackCloudways.configuration.api_key
|
16
|
+
@cached_token = nil
|
17
|
+
@token_expiry = nil
|
13
18
|
end
|
14
19
|
|
20
|
+
# Fetch the API token, using caching to avoid unnecessary requests
|
15
21
|
def cw_api_token
|
22
|
+
# Use cached token if valid and not near expiration
|
23
|
+
return @cached_token if valid_cached_token?
|
24
|
+
|
25
|
+
# Fetch a new token
|
16
26
|
response = HTTParty.post(
|
17
27
|
"#{@cw_api_url_base}#{@cw_url_path_auth}",
|
18
28
|
headers: { 'Content-Type' => 'application/x-www-form-urlencoded' },
|
19
|
-
body: { email: @cw_user_email, api_key: @cw_user_key }
|
29
|
+
body: { email: @cw_user_email, api_key: @cw_user_key },
|
30
|
+
debug_output: $stdout # Enable debug output for troubleshooting
|
20
31
|
)
|
21
|
-
|
32
|
+
|
33
|
+
if response.code == 200
|
34
|
+
# Parse the response and cache the token
|
35
|
+
parsed_response = parse_response(response)
|
36
|
+
@cached_token = parsed_response['access_token']
|
37
|
+
@token_expiry = Time.now + parsed_response['expires_in']
|
38
|
+
@cached_token
|
39
|
+
else
|
40
|
+
handle_error_response(response)
|
41
|
+
end
|
22
42
|
end
|
23
43
|
|
24
44
|
private
|
25
45
|
|
46
|
+
# Check if the cached token is still valid
|
47
|
+
def valid_cached_token?
|
48
|
+
@cached_token && @token_expiry && Time.now < (@token_expiry - TOKEN_EXPIRATION_BUFFER)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Parse the API response
|
26
52
|
def parse_response(response)
|
27
53
|
Oj.load(response.body, mode: :strict)
|
28
54
|
rescue Oj::ParseError => e
|
29
|
-
raise "Error parsing response: #{e.message}"
|
55
|
+
raise "Error parsing response: #{e.message}. Raw body: #{response.body}"
|
56
|
+
end
|
57
|
+
|
58
|
+
# Handle non-200 responses
|
59
|
+
def handle_error_response(response)
|
60
|
+
error_message = "Failed to fetch token: #{response.code} - #{response.body}"
|
61
|
+
puts error_message
|
62
|
+
raise error_message
|
30
63
|
end
|
31
64
|
end
|
32
65
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyApiPackCloudways
|
4
|
+
module Handlers
|
5
|
+
module ResponseValidator
|
6
|
+
def validate_response(response, expected_key)
|
7
|
+
raise "Unexpected response format: #{response.inspect}" unless response.is_a?(Hash) && response.key?(expected_key)
|
8
|
+
|
9
|
+
result = response[expected_key]
|
10
|
+
raise "Expected '#{expected_key}' to be an Array, got #{result.class}: #{result.inspect}" unless result.is_a?(Array)
|
11
|
+
|
12
|
+
result
|
13
|
+
rescue StandardError => e
|
14
|
+
log_error("Error validating response: #{e.message}")
|
15
|
+
raise "An error occurred while processing the response: #{e.message}"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def log_error(message)
|
21
|
+
if defined?(Rails)
|
22
|
+
Rails.logger.error(message)
|
23
|
+
else
|
24
|
+
puts "[ERROR] #{message}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -4,6 +4,7 @@ require 'httparty'
|
|
4
4
|
require 'oj'
|
5
5
|
|
6
6
|
require_relative 'ruby_api_pack_cloudways/configuration'
|
7
|
+
require_relative 'ruby_api_pack_cloudways/handlers/response_validator'
|
7
8
|
require_relative 'ruby_api_pack_cloudways/connection/cw_token'
|
8
9
|
require_relative 'ruby_api_pack_cloudways/connection/cw_connect'
|
9
10
|
require_relative 'ruby_api_pack_cloudways/api/cw_lists'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_api_pack_cloudways
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- PHCDevworks
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-11-
|
12
|
+
date: 2024-11-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httparty
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- lib/ruby_api_pack_cloudways/configuration.rb
|
59
59
|
- lib/ruby_api_pack_cloudways/connection/cw_connect.rb
|
60
60
|
- lib/ruby_api_pack_cloudways/connection/cw_token.rb
|
61
|
+
- lib/ruby_api_pack_cloudways/handlers/response_validator.rb
|
61
62
|
- lib/ruby_api_pack_cloudways/version.rb
|
62
63
|
homepage: https://github.com/phcdevworks/ruby_api_pack_cloudways/wiki
|
63
64
|
licenses:
|
@@ -82,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
83
|
- !ruby/object:Gem::Version
|
83
84
|
version: '0'
|
84
85
|
requirements: []
|
85
|
-
rubygems_version: 3.
|
86
|
+
rubygems_version: 3.4.19
|
86
87
|
signing_key:
|
87
88
|
specification_version: 4
|
88
89
|
summary: API Pack for Cloudways
|