stacker_bee 2.0.0.pre178 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.travis.yml +1 -13
- data/README.md +64 -104
- data/bin/stacker_bee +3 -4
- data/lib/stacker_bee/body_parser.rb +1 -11
- data/lib/stacker_bee/client.rb +1 -30
- data/lib/stacker_bee/connection.rb +10 -12
- data/lib/stacker_bee/dictionary_flattener.rb +12 -12
- data/lib/stacker_bee/graylog_faraday_middleware.rb +2 -3
- data/lib/stacker_bee/middleware/logger.rb +47 -0
- data/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/{a_request_parameter_with_a_map → a_request_parameter_with_a_Map}/can_create_an_object.yml +0 -0
- data/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_a_Map/object.yml +153 -0
- data/spec/spec_helper.rb +0 -4
- data/spec/units/faraday_graylog_middleware_spec.rb +1 -1
- data/spec/units/stacker_bee/client_spec.rb +7 -48
- data/spec/units/stacker_bee/connection_spec.rb +7 -32
- data/spec/units/stacker_bee/graylog_faraday_middleware_spec.rb +1 -17
- data/spec/units/stacker_bee/middleware/logger_spec.rb +55 -0
- data/spec/units/stacker_bee/request_error_spec.rb +3 -7
- data/spec/units/stacker_bee/response_spec.rb +4 -18
- data/stacker_bee.gemspec +2 -6
- metadata +23 -30
- data/spec/cassettes/A_request_sent_to_CloudStack_for_console_access/returns_html_for_console_access.yml +0 -34
- data/spec/integration/console_spec.rb +0 -23
- data/spec/units/stacker_bee/console_spec.rb +0 -0
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
Y2IyNGIxYWI1ZTM1ODYwYTNkODM3MTlmMGYyZDZhNGNhYWQwYmU2OA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c61314ae91d1a5401971f178fc31e00cd9b06687
|
4
|
+
data.tar.gz: 48d6f1e0eb6d767fdd42a3de0d1bfef4c6c30e22
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MzVjMWY1YjRlNWJkNTQ1MWE3ZjEyNTcxMWM5YjdmMTNkODg2YTNhMzUzYTUx
|
11
|
-
ZDk5NWY4MjU3ZGRiN2ZkNDNhZGM3MzJlYjliOTk4YjAwMjE0MDM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MWQ5YzMwNmI1ODA0ZjAyZmIzM2M0N2E1MzE3MGFmMjJkOGUxMmU0MDFiNThi
|
14
|
-
YjAxMDJlM2Q0OGU2NzNkZjE5MTViY2ZjOTgyNWZiM2ZiNWIwZWMyMDExZTlh
|
15
|
-
MTZmMDBkYjFmZWQ1ODZjZWVmMmYwYjQ1N2M5Y2JiMGI4NzM4Y2E=
|
6
|
+
metadata.gz: 4acc5d7d764361a10298e3a2cbb95d877f474f3cd4790f7f5bb0799f59c86937bee7762f42e71a048a77894a05ad747b7ea5613b50396eddeec76e0dba4e6fff
|
7
|
+
data.tar.gz: 2d1c306caec103c7b0464fb3d44dbd00571c00031f122acd2a80e83962220286b4a4d1c5498d6bfe8270558b295a41217f0524a6f93e9024bddb35fcb7f61263
|
data/.travis.yml
CHANGED
@@ -1,21 +1,9 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.1.0
|
4
3
|
- 2.0.0
|
5
4
|
- 1.9.3
|
6
5
|
- 1.9.2
|
7
6
|
- jruby-19mode
|
7
|
+
- rbx-19mode
|
8
8
|
- ruby-head
|
9
9
|
- jruby-head
|
10
|
-
matrix:
|
11
|
-
allow_failures:
|
12
|
-
- rvm: ruby-head
|
13
|
-
- rvm: jruby-head
|
14
|
-
deploy:
|
15
|
-
provider: rubygems
|
16
|
-
api_key:
|
17
|
-
secure: d5hC4iuoXOsrQKJRd9GSyZP2UlO2v9HsayhgNk2RlQQJFbqki6TcIlxN6j39/QER3pM3MUZyvCewtvxjrijt4f82xJGHRXaVNZvPSyD91PkGUtOuibLojc+GmwrzzRpu0d3TSEuzeKBSVag7AuJFO3oQnhEyblyZPyqWh1Ii1nM=
|
18
|
-
gem: stacker_bee
|
19
|
-
on:
|
20
|
-
repo: promptworks/stacker_bee
|
21
|
-
ruby: 2.1.0
|
data/README.md
CHANGED
@@ -13,11 +13,9 @@ You can install StackerBee with rubygems:
|
|
13
13
|
|
14
14
|
$ gem install stacker_bee
|
15
15
|
|
16
|
-
If you are using Bundler add the following to your Gemfile:
|
16
|
+
If you are using Bundler simply add the following to your Gemfile:
|
17
17
|
|
18
|
-
|
19
|
-
gem 'stacker_bee'
|
20
|
-
```
|
18
|
+
gem 'stacker_bee'
|
21
19
|
|
22
20
|
And execute:
|
23
21
|
|
@@ -26,42 +24,35 @@ And execute:
|
|
26
24
|
|
27
25
|
## Basic Usage
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
)
|
27
|
+
cloud_stack = StackerBee::Client.new(
|
28
|
+
url: 'http://localhost:8080/client/api',
|
29
|
+
api_key: 'MY_API_KEY',
|
30
|
+
secret_key: 'MY_SECRET_KEY'
|
31
|
+
)
|
35
32
|
|
36
|
-
cloud_stack.list_virtual_machines state: 'Running'
|
37
|
-
# => [ { id: '48b91ab4...', displayName: '...', ... },
|
38
|
-
# { id: '59c02bc5...', displayName: '...', ... },
|
39
|
-
# ... ]
|
33
|
+
cloud_stack.list_virtual_machines state: 'Running'
|
34
|
+
# => [ { id: '48b91ab4...', displayName: '...', ... },
|
35
|
+
# { id: '59c02bc5...', displayName: '...', ... },
|
36
|
+
# ... ]
|
40
37
|
|
41
|
-
cloud_stack.create_volume name: 'MyVolume'
|
42
|
-
```
|
38
|
+
cloud_stack.create_volume name: 'MyVolume'
|
43
39
|
|
44
40
|
## Features
|
45
41
|
|
46
42
|
### Idomatic Ruby formatting for names
|
47
43
|
|
48
|
-
|
44
|
+
You can use `list_virtual_machines` instead of `listVirtualMachines` and
|
49
45
|
`affinity_group_id` instead of `affinitygroupid` (if you want to).
|
50
46
|
|
51
47
|
For example:
|
52
48
|
|
53
|
-
|
54
|
-
vm
|
55
|
-
puts vm[:iso_display_text]
|
56
|
-
```
|
49
|
+
vm = cloud_stack.list_virtual_machines(affinity_group_id: id).first
|
50
|
+
puts vm[:iso_display_text]
|
57
51
|
|
58
52
|
### Handling 'map' parameters
|
59
53
|
|
60
|
-
For any endpoint requiring a map parameter, pass in a hash.
|
61
|
-
|
62
|
-
```ruby
|
63
|
-
cloud_stack.create_tags(tags: { type: 'community' }, resource_type: "Template", resource_ids: id )
|
64
|
-
```
|
54
|
+
For any endpoint requiring a map parameter, simply pass in a hash.
|
55
|
+
create_tags(tags: { type: 'community'}, resource_type: "Template", resource_ids: id )
|
65
56
|
|
66
57
|
This will yield a request with the following query string:
|
67
58
|
|
@@ -72,9 +63,7 @@ This will yield a request with the following query string:
|
|
72
63
|
By default, StackerBee uses the CloudStack 4.2 API, but it doesn't have to.
|
73
64
|
Use a different API version by setting the `api_path` configuration option to the path of a JSON file containing the response from your CloudStack instance's `listApis` command.
|
74
65
|
|
75
|
-
|
76
|
-
StackerBee::Client.api_path = '/path/to/your/listApis/response.json'
|
77
|
-
```
|
66
|
+
StackerBee::Client.api_path = '/path/to/your/listApis/response.json'
|
78
67
|
|
79
68
|
### CloudStack REPL
|
80
69
|
|
@@ -97,76 +86,64 @@ Example:
|
|
97
86
|
|
98
87
|
Configuring a client:
|
99
88
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
)
|
106
|
-
```
|
89
|
+
cloud_stack = StackerBee::Client.new(
|
90
|
+
url: 'http://localhost:8080/client/api'
|
91
|
+
api_key: 'API_KEY',
|
92
|
+
secret_key: 'SECRET_KEY',
|
93
|
+
logger: Rails.logger
|
94
|
+
)
|
107
95
|
|
108
96
|
All configuration parameters set on the `StackerBee::Client` class are used as defaults for `StackerBee::Client` instances.
|
109
97
|
|
110
|
-
|
111
|
-
StackerBee::Client.
|
98
|
+
StackerBee::Client.url = 'http://localhost:8080/client/api'
|
99
|
+
StackerBee::Client.logger = Rails.logger
|
112
100
|
|
113
|
-
user_client = StackerBee::Client.new(
|
114
|
-
|
115
|
-
|
116
|
-
)
|
101
|
+
user_client = StackerBee::Client.new(
|
102
|
+
api_key: 'USER_API_KEY',
|
103
|
+
secret_key: 'USER_SECRET_KEY'
|
104
|
+
)
|
117
105
|
|
118
|
-
root_client = StackerBee::Client.new(
|
119
|
-
|
120
|
-
|
121
|
-
)
|
122
|
-
```
|
106
|
+
root_client = StackerBee::Client.new(
|
107
|
+
api_key: 'ROOT_API_KEY',
|
108
|
+
secret_key: 'ROOT_SECRET_KEY'
|
109
|
+
)
|
123
110
|
|
124
111
|
### URL
|
125
112
|
|
126
113
|
The URL of your CloudStack instance's URL.
|
127
114
|
|
128
|
-
|
129
|
-
StackerBee::Client.url = 'http://localhost:8080/client/api'
|
130
|
-
```
|
115
|
+
StackerBee::Client.url = 'http://localhost:8080/client/api'
|
131
116
|
|
132
117
|
Or:
|
133
118
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
)
|
138
|
-
```
|
119
|
+
my_client = StackerBee::Client.new(
|
120
|
+
url: 'http://localhost:8080/client/api'
|
121
|
+
)
|
139
122
|
|
140
123
|
### Keys
|
141
124
|
|
142
125
|
Your CloudStack credentials, i.e. API key and secret key.
|
143
126
|
|
144
|
-
|
145
|
-
StackerBee::Client.
|
146
|
-
StackerBee::Client.secret_key = 'MY_SECRET_KEY'
|
147
|
-
```
|
127
|
+
StackerBee::Client.api_key = 'MY_API_KEY'
|
128
|
+
StackerBee::Client.secret_key = 'MY_SECRET_KEY'
|
148
129
|
|
149
130
|
Or:
|
150
131
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
)
|
156
|
-
```
|
132
|
+
my_client = StackerBee::Client.new(
|
133
|
+
api_key: 'MY_API_KEY',
|
134
|
+
secret_key: 'MY_SECRET_KEY'
|
135
|
+
)
|
157
136
|
|
158
137
|
### Faraday Middleware
|
159
138
|
|
160
|
-
StackerBee is built on [Faraday](https://github.com/lostisland/faraday) and
|
139
|
+
StackerBee is built on [Faraday](https://github.com/lostisland/faraday) and makes it easy for you to add Faraday middleware. Here's an example of adding your own middleware.
|
161
140
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
}
|
169
|
-
```
|
141
|
+
StackerBee::Client.default_config = {
|
142
|
+
middlewares: ->(faraday) do
|
143
|
+
faraday.use Custom::LoggingMiddleware, Logger.new
|
144
|
+
faraday.use Custom::CachingMiddleware, Rails.cache
|
145
|
+
end
|
146
|
+
}
|
170
147
|
|
171
148
|
StackerBee itself puts some middlewares on Faraday. Any middlewares you add will be placed after these. If you want your middleware to come as the very first, you can use Faraday's builder like `faraday.builder.insert 0, MyMiddleware`.
|
172
149
|
|
@@ -178,35 +155,30 @@ Logging is best handled with Faraday middleware.
|
|
178
155
|
|
179
156
|
If you're using the Graylog2 GELF format, you're in luck because StackerBee currently ships with a Faraday middleware for that. Here's an example of logging to Graylog2:
|
180
157
|
|
181
|
-
|
182
|
-
logger = GELF::Notifier.new("localhost", 12201)
|
158
|
+
logger = GELF::Notifier.new("localhost", 12201)
|
183
159
|
|
184
|
-
StackerBee::Client.
|
185
|
-
|
186
|
-
}
|
187
|
-
```
|
160
|
+
StackerBee::Client.default_config = {
|
161
|
+
middlewares: ->(faraday) { faraday.use faraday.use StackerBee::GraylogFaradayMiddleware, logger }
|
162
|
+
}
|
188
163
|
|
189
164
|
#### Basic logging
|
190
165
|
|
191
166
|
To log to a file or STDOUT, Faraday has a built-in logger. You can use it like so:
|
192
167
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
}
|
197
|
-
```
|
168
|
+
StackerBee::Client.default_config = {
|
169
|
+
middlewares: ->(faraday) { faraday.response :logger }
|
170
|
+
}
|
198
171
|
|
199
172
|
### Bulk Configuration
|
200
173
|
|
201
174
|
The `StackerBee::Client` class can be configured with multiple options at once.
|
202
175
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
}
|
209
|
-
```
|
176
|
+
StackerBee::Client.default_config = {
|
177
|
+
url: 'http://localhost:8080/client/api',
|
178
|
+
logger: Rails.logger,
|
179
|
+
api_key: 'API_KEY',
|
180
|
+
secret_key: 'MY_SECRET_KEY'
|
181
|
+
}
|
210
182
|
|
211
183
|
## Contributing
|
212
184
|
|
@@ -230,18 +202,6 @@ This project uses [Rubocop](https://github.com/bbatsov/rubocop) to enforce code
|
|
230
202
|
|
231
203
|
$ bundle exec rubocop
|
232
204
|
|
233
|
-
### Releasing
|
234
|
-
|
235
|
-
To create a release, first bump the version in `lib/stacker_bee/version.rb`, and commit. Then, build the gem and release it to Rubygems with `rake release`:
|
236
|
-
|
237
|
-
$ rake release
|
238
|
-
stacker_bee 1.2.3 built to pkg/stacker_bee-1.2.3.gem.
|
239
|
-
Tagged v1.2.3.
|
240
|
-
Pushed git commits and tags.
|
241
|
-
Pushed stacker_bee 1.2.3 to rubygems.org.
|
242
|
-
|
243
|
-
We use Bundler's gem tasks to manage releases. See the output of `rake -T` and [Bundler's Rubygems documentation](http://bundler.io/rubygems.html) for more information.
|
244
|
-
|
245
205
|
## Thanks to
|
246
206
|
|
247
207
|
- [Chip Childers](http://github.com/chipchilders) for a [reference implementation of a CloudStack client in Ruby](http://chipchilders.github.io/cloudstack_ruby_client/)
|
data/bin/stacker_bee
CHANGED
@@ -1,7 +1,4 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
|
-
|
3
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
4
|
-
|
5
2
|
require 'optparse'
|
6
3
|
require 'stacker_bee'
|
7
4
|
require 'json'
|
@@ -57,7 +54,7 @@ begin
|
|
57
54
|
options.merge! YAML.load(hash)
|
58
55
|
end
|
59
56
|
unless (%w(api_key secret_key url) - options.keys).empty?
|
60
|
-
puts "Please specify a config file or all of the following: "
|
57
|
+
puts "Please specify a config file or all of the following: " +
|
61
58
|
"--api_key, --secret_key and --url"
|
62
59
|
exit
|
63
60
|
end
|
@@ -71,6 +68,8 @@ if verbose
|
|
71
68
|
puts "StackerBee version #{StackerBee::VERSION}"
|
72
69
|
puts "URL: #{options["url"]}"
|
73
70
|
puts "API key: #{options["api_key"]}"
|
71
|
+
else
|
72
|
+
options['logger'] = Logger.new('/dev/null')
|
74
73
|
end
|
75
74
|
|
76
75
|
client = StackerBee::Client.new(options)
|
@@ -6,17 +6,7 @@ module StackerBee
|
|
6
6
|
attr_reader :body
|
7
7
|
|
8
8
|
def body=(raw_response)
|
9
|
-
|
10
|
-
|
11
|
-
unless html?(raw_response)
|
12
|
-
response_body = parse(response_body)
|
13
|
-
end
|
14
|
-
|
15
|
-
@body = response_body
|
16
|
-
end
|
17
|
-
|
18
|
-
def html?(raw_response)
|
19
|
-
raw_response.headers['content-type'].to_s.match(%r{/html})
|
9
|
+
@body = parse(raw_response.body)
|
20
10
|
end
|
21
11
|
|
22
12
|
def parse(json)
|
data/lib/stacker_bee/client.rb
CHANGED
@@ -7,31 +7,11 @@ require "stacker_bee/dictionary_flattener"
|
|
7
7
|
require "stacker_bee/response"
|
8
8
|
|
9
9
|
module StackerBee
|
10
|
-
module ConsoleAccess
|
11
|
-
ENDPOINT = "consoleAccess"
|
12
|
-
PATH = "/client/console"
|
13
|
-
|
14
|
-
def console_access(options)
|
15
|
-
options.merge!(cmd: 'access')
|
16
|
-
request("consoleAccess", options)
|
17
|
-
end
|
18
|
-
|
19
|
-
def path_for_endpoint(endpoint_name)
|
20
|
-
PATH if endpoint_name == ENDPOINT
|
21
|
-
end
|
22
|
-
|
23
|
-
def endpoint_for(name)
|
24
|
-
name if name == ENDPOINT
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
10
|
class Client
|
29
11
|
DEFAULT_API_PATH = File.join(
|
30
12
|
File.dirname(__FILE__), '../../config/4.2.json'
|
31
13
|
)
|
32
14
|
|
33
|
-
include ConsoleAccess
|
34
|
-
|
35
15
|
extend Forwardable
|
36
16
|
def_delegators :configuration,
|
37
17
|
:url,
|
@@ -88,20 +68,11 @@ module StackerBee
|
|
88
68
|
request = Request.new(endpoint_for(endpoint_name), api_key, params)
|
89
69
|
request.allow_empty_string_params =
|
90
70
|
configuration.allow_empty_string_params
|
91
|
-
|
92
|
-
raw_response = connection.get(request, path)
|
71
|
+
raw_response = connection.get(request)
|
93
72
|
Response.new(raw_response)
|
94
73
|
end
|
95
74
|
|
96
|
-
def path_for_endpoint(endpoint_name)
|
97
|
-
super || URI.parse(configuration.url).path
|
98
|
-
end
|
99
|
-
|
100
75
|
def endpoint_for(name)
|
101
|
-
if result = super
|
102
|
-
return result
|
103
|
-
end
|
104
|
-
|
105
76
|
api = self.class.api[name]
|
106
77
|
api && api["name"]
|
107
78
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "faraday"
|
2
2
|
require "uri"
|
3
3
|
require "stacker_bee/middleware/signed_query"
|
4
|
+
require "stacker_bee/middleware/logger"
|
4
5
|
require "stacker_bee/middleware/detokenizer"
|
5
6
|
|
6
7
|
module StackerBee
|
@@ -12,17 +13,15 @@ module StackerBee
|
|
12
13
|
|
13
14
|
def initialize(configuration)
|
14
15
|
@configuration = configuration
|
15
|
-
uri
|
16
|
+
uri = URI.parse(self.configuration.url)
|
17
|
+
@path = uri.path
|
16
18
|
uri.path = ''
|
17
|
-
ssl_verify = !self.configuration.ssl_verify.nil? ?
|
18
|
-
self.configuration.ssl_verify : true
|
19
19
|
fail ConnectionError, "no protocol specified" unless uri.scheme
|
20
|
-
initialize_faraday(
|
21
|
-
ssl: { verify: ssl_verify })
|
20
|
+
initialize_faraday(uri)
|
22
21
|
end
|
23
22
|
|
24
|
-
def initialize_faraday(
|
25
|
-
@faraday = Faraday.new(
|
23
|
+
def initialize_faraday(uri)
|
24
|
+
@faraday = Faraday.new(url: uri.to_s) do |faraday|
|
26
25
|
faraday.use Middleware::Detokenizer
|
27
26
|
faraday.use Middleware::SignedQuery, configuration.secret_key
|
28
27
|
configuration.middlewares.call faraday
|
@@ -30,11 +29,10 @@ module StackerBee
|
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
33
|
-
def get(request
|
34
|
-
@faraday.get(path, request.query_params)
|
35
|
-
rescue Faraday::Error::ConnectionFailed
|
36
|
-
raise ConnectionError,
|
37
|
-
"Failed to connect to #{configuration.url}, #{error}"
|
32
|
+
def get(request)
|
33
|
+
@faraday.get(@path, request.query_params)
|
34
|
+
rescue Faraday::Error::ConnectionFailed
|
35
|
+
raise ConnectionError, "Failed to connect to #{configuration.url}"
|
38
36
|
end
|
39
37
|
end
|
40
38
|
end
|
@@ -6,36 +6,36 @@ module StackerBee
|
|
6
6
|
attr_accessor :params
|
7
7
|
|
8
8
|
def self.tokenize(key)
|
9
|
-
key.gsub(
|
9
|
+
key.gsub(/\[/, LB).gsub(/\]/, RB)
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.detokenize(key)
|
13
|
-
key.gsub(LB
|
13
|
+
key.gsub(/#{LB}/, "[").gsub(/#{RB}/, "]")
|
14
14
|
end
|
15
15
|
|
16
16
|
def initialize(params)
|
17
|
-
|
17
|
+
@params = params.dup
|
18
18
|
flatten_params
|
19
19
|
end
|
20
20
|
|
21
21
|
def flatten_params
|
22
|
-
hashes = params.select { |
|
23
|
-
flatten_map_values
|
22
|
+
hashes = params.select { |key, val| val.respond_to? :keys }
|
23
|
+
flatten_map_values(params, hashes)
|
24
24
|
end
|
25
25
|
|
26
26
|
def flatten_map_values(params, hashes)
|
27
|
-
hashes.each do |
|
28
|
-
remove_empties(
|
29
|
-
|
30
|
-
params["#{
|
31
|
-
params["#{
|
27
|
+
hashes.each do |outer|
|
28
|
+
remove_empties(outer[1]).each_with_index do |array, index|
|
29
|
+
key = self.class.tokenize("#{outer[0]}[#{index}]")
|
30
|
+
params["#{key}.key"] = params["#{key}.name"] = array[0]
|
31
|
+
params["#{key}.value"] = array[1]
|
32
32
|
end
|
33
|
-
params.delete
|
33
|
+
params.delete outer[0]
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
def remove_empties(hash)
|
38
|
-
hash.reject { |
|
38
|
+
hash.reject { |k, v| v.nil? || v == "" }
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
require "logger"
|
3
|
+
require "pp"
|
4
|
+
|
5
|
+
module StackerBee
|
6
|
+
module Middleware
|
7
|
+
class Logger < Faraday::Response::Middleware
|
8
|
+
extend Forwardable
|
9
|
+
PROGNAME = "StackerBee"
|
10
|
+
|
11
|
+
attr_accessor :logger
|
12
|
+
|
13
|
+
def initialize(app, _logger = nil)
|
14
|
+
super(app)
|
15
|
+
self.logger = _logger
|
16
|
+
logger.progname ||= PROGNAME if logger.respond_to?(:progname=)
|
17
|
+
end
|
18
|
+
|
19
|
+
def logger
|
20
|
+
@logger ||= ::Logger.new($stdout)
|
21
|
+
end
|
22
|
+
|
23
|
+
def_delegators :logger, :debug, :info, :warn, :error, :fatal
|
24
|
+
|
25
|
+
def call(env)
|
26
|
+
log_request(env)
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_complete(env)
|
31
|
+
log_response(env)
|
32
|
+
end
|
33
|
+
|
34
|
+
def log_request(env)
|
35
|
+
info "#{env[:method]} #{env[:url]}"
|
36
|
+
debug env[:request_headers].pretty_inspect
|
37
|
+
end
|
38
|
+
|
39
|
+
def log_response(env)
|
40
|
+
status_message = "Status: #{env[:status]}"
|
41
|
+
env[:status] < 400 ? info(status_message) : error(status_message)
|
42
|
+
debug env[:response_headers].pretty_inspect
|
43
|
+
debug env[:body]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|