Class: Jets::Api::Client
Constant Summary
collapse
- NETWORK_ERRORS =
[
Errno::ECONNREFUSED,
Errno::ECONNRESET,
Errno::EHOSTUNREACH,
Errno::ETIMEDOUT,
Jets::Api::Error::Maintenance,
Jets::Api::Error::ServiceUnavailable, Net::HTTPServiceUnavailable, Net::OpenTimeout,
Net::ReadTimeout,
OpenSSL::SSL::SSLError,
OpenURI::HTTPError,
SocketError
]
- @@max_retries =
3
Instance Method Summary
collapse
-
#account ⇒ Object
-
#api_key ⇒ Object
-
#build_request(klass, url, data = {}, headers = {}) ⇒ Object
-
#command ⇒ Object
-
#delete(path, data = {}) ⇒ Object
-
#endpoint ⇒ Object
-
#execute_request(klass, path, data = {}, headers = {}) ⇒ Object
-
#get(path, data = {}) ⇒ Object
-
#global_params(path) ⇒ Object
-
#http ⇒ Object
-
#http_request(req, retries = 0) ⇒ Object
-
#maintenance_mode?(body) ⇒ Boolean
-
#patch(path, data = {}) ⇒ Object
-
#path_with_query(path, query = {}) ⇒ Object
-
#post(path, data = {}) ⇒ Object
-
#processable?(http_code) ⇒ Boolean
422 Unprocessable Entity: Server understands the content type of the request entity, and the syntax of the request entity is correct, but it was unable to process the contained instructions.
-
#put(path, data = {}) ⇒ Object
-
#puts_debug_request(data) ⇒ Object
-
#puts_debug_resp(url, resp) ⇒ Object
-
#reraise_error_from_503!(req, resp) ⇒ Object
For some reason, rescue Net::HTTPServiceUnavailable is not being caught.
-
#session ⇒ Object
-
#set_headers!(req, headers = {}) ⇒ Object
-
#sts ⇒ Object
-
#url(path) ⇒ Object
API does not include the /.
#log
#general_api_error, #handle_as_error?, #handle_error_response!, #specific_api_error
Instance Method Details
#account ⇒ Object
205
206
207
208
209
|
# File 'lib/jets/api/client.rb', line 205
def account
sts.get_caller_identity.account
rescue
nil
end
|
#api_key ⇒ Object
181
182
183
|
# File 'lib/jets/api/client.rb', line 181
def api_key
Jets::Api.api_key
end
|
#build_request(klass, url, data = {}, headers = {}) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
|
# File 'lib/jets/api/client.rb', line 34
def build_request(klass, url, data = {}, = {})
req = klass.new(url) (req)
if [Net::HTTP::Delete, Net::HTTP::Patch, Net::HTTP::Post, Net::HTTP::Put].include?(klass)
text = JSON.dump(data)
puts_debug_request(data)
req.body = text
req.content_length = text.bytesize
req.content_type = "application/json"
end
req
end
|
#command ⇒ Object
136
137
138
139
140
141
142
143
|
# File 'lib/jets/api/client.rb', line 136
def command
args = ARGV.reject { |arg| arg.include?("-") }
if args.first == "rollback" args.first
else
args.join(":")
end
end
|
#delete(path, data = {}) ⇒ Object
201
202
203
|
# File 'lib/jets/api/client.rb', line 201
def delete(path, data = {})
execute_request(Net::HTTP::Delete, path, data)
end
|
#endpoint ⇒ Object
217
218
219
220
221
222
223
224
225
226
|
# File 'lib/jets/api/client.rb', line 217
def endpoint
return ENV["JETS_API"] if ENV["JETS_API"]
major = Jets::VERSION.split(".").first.to_i
if major >= 6
"https://api.rubyonjets.com/v2"
else
"https://api.rubyonjets.com/v1"
end
end
|
#execute_request(klass, path, data = {}, headers = {}) ⇒ Object
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
# File 'lib/jets/api/client.rb', line 12
def execute_request(klass, path, data = {}, = {})
data = global_params(path).merge(data)
if klass == Net::HTTP::Get
path = path_with_query(path, data)
data = {}
end
url = url(path)
req = build_request(klass, url, data, )
http_resp = http_request(req)
resp = Jets::Api::Response.new(http_resp)
puts_debug_resp(url, resp)
if handle_as_error?(resp.http_status)
handle_error_response!(resp)
end
resp.data end
|
#get(path, data = {}) ⇒ Object
185
186
187
|
# File 'lib/jets/api/client.rb', line 185
def get(path, data = {})
execute_request(Net::HTTP::Get, path, data)
end
|
#global_params(path) ⇒ Object
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
# File 'lib/jets/api/client.rb', line 114
def global_params(path)
args = ARGV.reject { |arg| arg.include?("-") }
params = {
account: Jets.aws.account,
command: command,
jets_env: Jets.env.to_s,
jets_extra: Jets.,
jets_go_version: ENV["JETS_GO_VERSION"],
jets_remote_version: ENV["JETS_REMOTE_VERSION"],
jets_version: Jets::VERSION,
region: Jets.aws.region,
ruby_version: RUBY_VERSION
}
if Jets::Thor::ProjectCheck.new(args).project? || command == "delete"
params[:project_namespace] = Jets.project.namespace
params[:project_name] = Jets.project.name
end
params.delete_if { |k, v| v.nil? }
params
end
|
#http ⇒ Object
105
106
107
108
109
110
111
|
# File 'lib/jets/api/client.rb', line 105
def http
uri = URI(endpoint)
http = Net::HTTP.new(uri.host, uri.port)
http.open_timeout = http.read_timeout = 30
http.use_ssl = true if uri.scheme == "https"
http
end
|
#http_request(req, retries = 0) ⇒ Object
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/jets/api/client.rb', line 62
def http_request(req, retries = 0)
resp = http.request(req) reraise_error_from_503!(req, resp)
resp
rescue *NETWORK_ERRORS => error
if retries < @@max_retries
delay = 2**retries
log.debug "Error: #{error.class} #{error.message} retrying after #{delay} seconds..."
sleep delay
retries += 1
retry
elsif error.is_a?(Jets::Api::Error::Maintenance)
log.info error.message exit 1
else
message = "Unexpected error #{error.class.name} communicating with the Jets API. "
message += " Request was attempted #{retries + 1} times."
raise Jets::Api::Error::Connection, message + "\nNetwork error: #{error.message}"
end
end
|
#maintenance_mode?(body) ⇒ Boolean
98
99
100
101
102
103
|
# File 'lib/jets/api/client.rb', line 98
def maintenance_mode?(body)
payload = JSON.parse(body)
payload["status"] == "maintenance"
rescue JSON::ParserError
false
end
|
#patch(path, data = {}) ⇒ Object
197
198
199
|
# File 'lib/jets/api/client.rb', line 197
def patch(path, data = {})
execute_request(Net::HTTP::Patch, path, data)
end
|
#path_with_query(path, query = {}) ⇒ Object
151
152
153
154
155
|
# File 'lib/jets/api/client.rb', line 151
def path_with_query(path, query = {})
return path if query.empty?
separator = path.include?("?") ? "&" : "?"
"#{path}#{separator}#{query.to_query}"
end
|
#post(path, data = {}) ⇒ Object
189
190
191
|
# File 'lib/jets/api/client.rb', line 189
def post(path, data = {})
execute_request(Net::HTTP::Post, path, data)
end
|
#processable?(http_code) ⇒ Boolean
422 Unprocessable Entity: Server understands the content type of the request entity, and the syntax of the request entity is correct, but it was unable to process the contained instructions. TODO: remove? or rename to ha
169
170
171
|
# File 'lib/jets/api/client.rb', line 169
def processable?(http_code)
http_code =~ /^2/ || http_code =~ /^4/
end
|
#put(path, data = {}) ⇒ Object
193
194
195
|
# File 'lib/jets/api/client.rb', line 193
def put(path, data = {})
execute_request(Net::HTTP::Put, path, data)
end
|
#puts_debug_request(data) ⇒ Object
240
241
242
243
244
|
# File 'lib/jets/api/client.rb', line 240
def puts_debug_request(data)
return unless ENV["JETS_DEBUG_API"]
log.info "POST data:"
log.info JSON.pretty_generate(data)
end
|
#puts_debug_resp(url, resp) ⇒ Object
229
230
231
232
233
234
235
236
237
238
|
# File 'lib/jets/api/client.rb', line 229
def puts_debug_resp(url, resp)
return unless ENV["JETS_DEBUG_API"]
puts "API Response for url #{url}"
begin
puts JSON.pretty_generate(resp.data)
rescue
puts "Cannot JSON pretty_generate resp #{resp.inspect}"
nil
end
end
|
#reraise_error_from_503!(req, resp) ⇒ Object
For some reason, rescue Net::HTTPServiceUnavailable is not being caught. So mimic it. Can reproduce by using local Jets API service and not starting it up
87
88
89
90
91
92
93
94
95
96
|
# File 'lib/jets/api/client.rb', line 87
def reraise_error_from_503!(req, resp)
return unless resp.code == "503"
if maintenance_mode?(resp.body)
payload = JSON.parse(resp.body)
raise Jets::Api::Error::Maintenance, payload["message"]
else
raise Jets::Api::Error::ServiceUnavailable, "Request #{req.path}"
end
end
|
#session ⇒ Object
173
174
175
176
177
178
179
|
# File 'lib/jets/api/client.rb', line 173
def session
session_path = "#{ENV["HOME"]}/.jets/session.yml"
if File.exist?(session_path)
data = YAML.load_file(session_path)
data["secret_token"]
end
end
|
157
158
159
160
161
162
163
|
# File 'lib/jets/api/client.rb', line 157
def (req, = {})
.each { |k, v| req[k] = v }
req["Authorization"] = api_key if api_key
req["x-account"] = account if account
req["x-session"] = session if session
req
end
|
#sts ⇒ Object
212
213
214
|
# File 'lib/jets/api/client.rb', line 212
def sts
Aws::STS::Client.new
end
|
#url(path) ⇒ Object
146
147
148
149
|
# File 'lib/jets/api/client.rb', line 146
def url(path)
path = "/#{path}" unless path.starts_with?("/")
"#{endpoint}#{path}"
end
|