stacker_bee 1.0.1 → 2.0.0.pre.pre164

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +13 -5
  2. data/.travis.yml +14 -1
  3. data/README.md +117 -67
  4. data/bin/stacker_bee +4 -3
  5. data/lib/faraday_middleware/response/graylog.rb +35 -0
  6. data/lib/stacker_bee/body_parser.rb +11 -1
  7. data/lib/stacker_bee/client.rb +32 -4
  8. data/lib/stacker_bee/connection.rb +8 -9
  9. data/lib/stacker_bee/dictionary_flattener.rb +12 -12
  10. data/lib/stacker_bee/graylog_faraday_middleware.rb +13 -0
  11. data/lib/stacker_bee/request_error.rb +1 -1
  12. data/lib/stacker_bee/version.rb +1 -1
  13. data/lib/stacker_bee.rb +3 -0
  14. data/spec/cassettes/A_request_sent_to_CloudStack_for_console_access/returns_html_for_console_access.yml +34 -0
  15. 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
  16. data/spec/integration/configure_middleware_spec.rb +30 -0
  17. data/spec/integration/console_spec.rb +23 -0
  18. data/spec/integration/request_spec.rb +2 -31
  19. data/spec/spec_helper.rb +4 -0
  20. data/spec/units/faraday_graylog_middleware_spec.rb +80 -0
  21. data/spec/units/stacker_bee/client_spec.rb +52 -9
  22. data/spec/units/stacker_bee/connection_spec.rb +14 -5
  23. data/spec/units/stacker_bee/console_spec.rb +0 -0
  24. data/spec/units/stacker_bee/graylog_faraday_middleware_spec.rb +51 -0
  25. data/spec/units/stacker_bee/request_error_spec.rb +7 -3
  26. data/spec/units/stacker_bee/response_spec.rb +18 -4
  27. data/stacker_bee.gemspec +9 -2
  28. metadata +58 -15
  29. data/lib/stacker_bee/middleware/logger.rb +0 -47
  30. data/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_a_Map/object.yml +0 -153
  31. data/spec/units/stacker_bee/middleware/logger_spec.rb +0 -55
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 113d9dc3b7034e99f4fa25d03b558de6f6a71c67
4
- data.tar.gz: 3ec61352a7c75f6cdf92fbe7bd628fd2d3890d15
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZmNkOGY0ZGRkY2Y0MjYzZGZmYzJjMWI0MTZjMzU5MTIwNWYyZDY5MA==
5
+ data.tar.gz: !binary |-
6
+ OTBhNzY3NmQ1ODU1MzliZGVmYWE4NWNhNGViMGMyNTdmNWI3NmY1OA==
5
7
  SHA512:
6
- metadata.gz: 3583805c59178743eba73e67477b1d7a47e47dbd57e76248e2ab90ba398ebf2c452601c7c7b431039b22d612414d4c7fa874fec74ecea333ca0feceae53e21f0
7
- data.tar.gz: e5bd192f9e42c7d9a6facca1fed0ab07339a089e329e41aaf6257516ede551e50f51e79963ede771ba183f8a8951a4b0bfc0919391c9ba5af9a5530905869739
8
+ metadata.gz: !binary |-
9
+ NmRlNzQ2MGU1ZjBlODlmYzJmZTFjY2Y5MjcyNWY5ZDI2MmFhNWQzODM4YjZm
10
+ NTZkZTZjZTQxNzI4NzFkOTFiMDVmYTdmZWQ3MDc3YjVjZGZkMDZhZmZjMjQ5
11
+ NzYxMmZmOWEzYWIyODZlOTZlOGZjYmE1ZDYwY2ViMjA1YzkzNzk=
12
+ data.tar.gz: !binary |-
13
+ ODNlNzY5MmJmZWE1MDhlNzkxZjYxNGZkNWU4Y2ExZGU5NmUzMjZmOWFiZTY1
14
+ NzM5ODBhYjgyZGY2MGI4NTkxM2UxYTZhNDE2NzAxYmQ5MDJkMWVkZGIxNzNh
15
+ NmIwZGI4MWE2MTQ1NTY1YTg1YWFkNGZmMjgxY2EzYjQxNWFmNTg=
data/.travis.yml CHANGED
@@ -1,9 +1,22 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.1.0
3
4
  - 2.0.0
4
5
  - 1.9.3
5
6
  - 1.9.2
6
7
  - 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
+ all_branches: true
21
+ repo: promptworks/stacker_bee
22
+ ruby: 2.1.0
data/README.md CHANGED
@@ -13,9 +13,11 @@ You can install StackerBee with rubygems:
13
13
 
14
14
  $ gem install stacker_bee
15
15
 
16
- If you are using Bundler simply add the following to your Gemfile:
16
+ If you are using Bundler add the following to your Gemfile:
17
17
 
18
- gem 'stacker_bee'
18
+ ```ruby
19
+ gem 'stacker_bee'
20
+ ```
19
21
 
20
22
  And execute:
21
23
 
@@ -24,55 +26,55 @@ And execute:
24
26
 
25
27
  ## Basic Usage
26
28
 
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
- )
29
+ ```ruby
30
+ cloud_stack = StackerBee::Client.new(
31
+ url: 'http://localhost:8080/client/api',
32
+ api_key: 'MY_API_KEY',
33
+ secret_key: 'MY_SECRET_KEY'
34
+ )
32
35
 
33
- cloud_stack.list_virtual_machines state: 'Running'
34
- # => [ { id: '48b91ab4...', displayName: '...', ... },
35
- # { id: '59c02bc5...', displayName: '...', ... },
36
- # ... ]
36
+ cloud_stack.list_virtual_machines state: 'Running'
37
+ # => [ { id: '48b91ab4...', displayName: '...', ... },
38
+ # { id: '59c02bc5...', displayName: '...', ... },
39
+ # ... ]
37
40
 
38
- cloud_stack.create_volume name: 'MyVolume'
41
+ cloud_stack.create_volume name: 'MyVolume'
42
+ ```
39
43
 
40
44
  ## Features
41
45
 
42
46
  ### Idomatic Ruby formatting for names
43
47
 
44
- You can use `list_virtual_machines` instead of `listVirtualMachines` and
48
+ For example, you can use `list_virtual_machines` instead of `listVirtualMachines` and
45
49
  `affinity_group_id` instead of `affinitygroupid` (if you want to).
46
50
 
47
51
  For example:
48
52
 
49
- vm = cloud_stack.list_virtual_machines(affinity_group_id: id).first
50
- puts vm[:iso_display_text]
53
+ ```ruby
54
+ vm = cloud_stack.list_virtual_machines(affinity_group_id: id).first
55
+ puts vm[:iso_display_text]
56
+ ```
51
57
 
52
58
  ### Handling 'map' parameters
53
59
 
54
- For any endpoint requiring a map parameter, simply pass in a hash.
60
+ For any endpoint requiring a map parameter, pass in a hash.
55
61
 
56
- create_tags(tags: { type: 'community'}, resource_type: "Template", resource_ids: id )
62
+ ```ruby
63
+ cloud_stack.create_tags(tags: { type: 'community' }, resource_type: "Template", resource_ids: id )
64
+ ```
57
65
 
58
66
  This will yield a request with the following query string:
59
67
 
60
68
  ...&tags[0].key=type&tags[0].name=type&tags[0].value=community
61
69
 
62
- ### Configurable Logger
63
-
64
- StackerBee::Client.logger = Rails.logger
65
-
66
- Or
67
-
68
- StackerBee::Client.logger = Logger.new
69
-
70
70
  ### Configurable API Version
71
71
 
72
72
  By default, StackerBee uses the CloudStack 4.2 API, but it doesn't have to.
73
73
  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
74
 
75
- StackerBee::Client.api_path = '/path/to/your/listApis/response.json'
75
+ ```ruby
76
+ StackerBee::Client.api_path = '/path/to/your/listApis/response.json'
77
+ ```
76
78
 
77
79
  ### CloudStack REPL
78
80
 
@@ -95,80 +97,116 @@ Example:
95
97
 
96
98
  Configuring a client:
97
99
 
98
- cloud_stack = StackerBee::Client.new(
99
- url: 'http://localhost:8080/client/api'
100
- api_key: 'API_KEY',
101
- secret_key: 'SECRET_KEY',
102
- logger: Rails.logger
103
- )
100
+ ```ruby
101
+ cloud_stack = StackerBee::Client.new(
102
+ url: 'http://localhost:8080/client/api',
103
+ api_key: 'API_KEY',
104
+ secret_key: 'SECRET_KEY'
105
+ )
106
+ ```
104
107
 
105
108
  All configuration parameters set on the `StackerBee::Client` class are used as defaults for `StackerBee::Client` instances.
106
109
 
107
- StackerBee::Client.url = 'http://localhost:8080/client/api'
108
- StackerBee::Client.logger = Rails.logger
110
+ ```ruby
111
+ StackerBee::Client.url = 'http://localhost:8080/client/api'
109
112
 
110
- user_client = StackerBee::Client.new(
111
- api_key: 'USER_API_KEY',
112
- secret_key: 'USER_SECRET_KEY'
113
- )
113
+ user_client = StackerBee::Client.new(
114
+ api_key: 'USER_API_KEY',
115
+ secret_key: 'USER_SECRET_KEY'
116
+ )
114
117
 
115
- root_client = StackerBee::Client.new(
116
- api_key: 'ROOT_API_KEY',
117
- secret_key: 'ROOT_SECRET_KEY'
118
- )
118
+ root_client = StackerBee::Client.new(
119
+ api_key: 'ROOT_API_KEY',
120
+ secret_key: 'ROOT_SECRET_KEY'
121
+ )
122
+ ```
119
123
 
120
124
  ### URL
121
125
 
122
126
  The URL of your CloudStack instance's URL.
123
127
 
124
- StackerBee::Client.url = 'http://localhost:8080/client/api'
128
+ ```ruby
129
+ StackerBee::Client.url = 'http://localhost:8080/client/api'
130
+ ```
125
131
 
126
132
  Or:
127
133
 
128
- my_client = StackerBee::Client.new(
129
- url: 'http://localhost:8080/client/api'
130
- )
134
+ ```ruby
135
+ my_client = StackerBee::Client.new(
136
+ url: 'http://localhost:8080/client/api'
137
+ )
138
+ ```
131
139
 
132
140
  ### Keys
133
141
 
134
142
  Your CloudStack credentials, i.e. API key and secret key.
135
143
 
136
- StackerBee::Client.api_key = 'MY_API_KEY'
137
- StackerBee::Client.secret_key = 'MY_SECRET_KEY'
144
+ ```ruby
145
+ StackerBee::Client.api_key = 'MY_API_KEY'
146
+ StackerBee::Client.secret_key = 'MY_SECRET_KEY'
147
+ ```
138
148
 
139
149
  Or:
140
150
 
141
- my_client = StackerBee::Client.new(
142
- api_key: 'MY_API_KEY',
143
- secret_key: 'MY_SECRET_KEY'
144
- )
151
+ ```ruby
152
+ my_client = StackerBee::Client.new(
153
+ api_key: 'MY_API_KEY',
154
+ secret_key: 'MY_SECRET_KEY'
155
+ )
156
+ ```
157
+
158
+ ### Faraday Middleware
159
+
160
+ StackerBee is built on [Faraday](https://github.com/lostisland/faraday) and allows you to add Faraday middleware. Here's an example of adding your own middleware.
161
+
162
+ ```ruby
163
+ StackerBee::Client.configuration = {
164
+ middlewares: ->(faraday) do
165
+ faraday.use Custom::LoggingMiddleware, Logger.new
166
+ faraday.use Custom::CachingMiddleware, Rails.cache
167
+ end
168
+ }
169
+ ```
145
170
 
146
- ### Logger
171
+ 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`.
147
172
 
148
- StackerBee can be configured with a custom `Logger`.
173
+ ### Logging
149
174
 
150
- StackerBee::Client.logger = Logger.new
175
+ Logging is best handled with Faraday middleware.
151
176
 
152
- Or
177
+ #### GELF/Graylog2
153
178
 
154
- my_client = StackerBee::Client.new(
155
- logger: Logger.new
156
- )
179
+ 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:
157
180
 
158
- For Rails apps, it's sometimes convenient to use Rail's logger:
181
+ ```ruby
182
+ logger = GELF::Notifier.new("localhost", 12201)
159
183
 
160
- StackerBee::Client.logger = Rails.logger
184
+ StackerBee::Client.configuration = {
185
+ middlewares: ->(faraday) { faraday.use StackerBee::GraylogFaradayMiddleware, logger }
186
+ }
187
+ ```
188
+
189
+ #### Basic logging
190
+
191
+ To log to a file or STDOUT, Faraday has a built-in logger. You can use it like so:
192
+
193
+ ```ruby
194
+ StackerBee::Client.configuration = {
195
+ middlewares: ->(faraday) { faraday.response :logger }
196
+ }
197
+ ```
161
198
 
162
199
  ### Bulk Configuration
163
200
 
164
201
  The `StackerBee::Client` class can be configured with multiple options at once.
165
202
 
166
- StackerBee::Client.default_config = {
167
- url: 'http://localhost:8080/client/api',
168
- logger: Rails.logger,
169
- api_key: 'API_KEY',
170
- secret_key: 'MY_SECRET_KEY'
171
- }
203
+ ```ruby
204
+ StackerBee::Client.configuration = {
205
+ url: 'http://localhost:8080/client/api',
206
+ api_key: 'API_KEY',
207
+ secret_key: 'MY_SECRET_KEY'
208
+ }
209
+ ```
172
210
 
173
211
  ## Contributing
174
212
 
@@ -192,6 +230,18 @@ This project uses [Rubocop](https://github.com/bbatsov/rubocop) to enforce code
192
230
 
193
231
  $ bundle exec rubocop
194
232
 
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
+
195
245
  ## Thanks to
196
246
 
197
247
  - [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,4 +1,7 @@
1
1
  #! /usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
4
+
2
5
  require 'optparse'
3
6
  require 'stacker_bee'
4
7
  require 'json'
@@ -54,7 +57,7 @@ begin
54
57
  options.merge! YAML.load(hash)
55
58
  end
56
59
  unless (%w(api_key secret_key url) - options.keys).empty?
57
- puts "Please specify a config file or all of the following: " +
60
+ puts "Please specify a config file or all of the following: " \
58
61
  "--api_key, --secret_key and --url"
59
62
  exit
60
63
  end
@@ -68,8 +71,6 @@ if verbose
68
71
  puts "StackerBee version #{StackerBee::VERSION}"
69
72
  puts "URL: #{options["url"]}"
70
73
  puts "API key: #{options["api_key"]}"
71
- else
72
- options['logger'] = Logger.new('/dev/null')
73
74
  end
74
75
 
75
76
  client = StackerBee::Client.new(options)
@@ -0,0 +1,35 @@
1
+ require 'faraday_middleware'
2
+ require 'faraday_middleware/response_middleware'
3
+
4
+ module FaradayMiddleware
5
+ class Graylog < ResponseMiddleware
6
+ INFO = 1
7
+ ERROR = 3
8
+
9
+ attr_accessor :facility
10
+
11
+ def initialize(app, logger, options = {})
12
+ @logger = logger
13
+ self.facility = options[:facility] || "faraday-middleware-graylog"
14
+
15
+ super app, options
16
+ end
17
+
18
+ def process_response(env)
19
+ @logger.notify(
20
+ facility: facility,
21
+ short_message: short_message(env),
22
+ level: level(env),
23
+ _data: env.dup.tap { |e| e.delete(:response) }
24
+ )
25
+ end
26
+
27
+ def short_message(env)
28
+ facility + " Request"
29
+ end
30
+
31
+ def level(env)
32
+ env[:status] < 400 ? INFO : ERROR
33
+ end
34
+ end
35
+ end
@@ -6,7 +6,17 @@ module StackerBee
6
6
  attr_reader :body
7
7
 
8
8
  def body=(raw_response)
9
- @body = parse(raw_response.body)
9
+ response_body = raw_response.body
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})
10
20
  end
11
21
 
12
22
  def parse(json)
@@ -7,15 +7,33 @@ 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
+
10
28
  class Client
11
29
  DEFAULT_API_PATH = File.join(
12
30
  File.dirname(__FILE__), '../../config/4.2.json'
13
31
  )
14
32
 
33
+ include ConsoleAccess
34
+
15
35
  extend Forwardable
16
36
  def_delegators :configuration,
17
- :logger,
18
- :logger=,
19
37
  :url,
20
38
  :url=,
21
39
  :api_key,
@@ -30,7 +48,8 @@ module StackerBee
30
48
 
31
49
  def default_config
32
50
  @default_config ||= {
33
- allow_empty_string_params: false
51
+ allow_empty_string_params: false,
52
+ middlewares: ->(*) {}
34
53
  }
35
54
  end
36
55
 
@@ -69,11 +88,20 @@ module StackerBee
69
88
  request = Request.new(endpoint_for(endpoint_name), api_key, params)
70
89
  request.allow_empty_string_params =
71
90
  configuration.allow_empty_string_params
72
- raw_response = connection.get(request)
91
+ path = path_for_endpoint(endpoint_name)
92
+ raw_response = connection.get(request, path)
73
93
  Response.new(raw_response)
74
94
  end
75
95
 
96
+ def path_for_endpoint(endpoint_name)
97
+ super || URI.parse(configuration.url).path
98
+ end
99
+
76
100
  def endpoint_for(name)
101
+ if result = super
102
+ return result
103
+ end
104
+
77
105
  api = self.class.api[name]
78
106
  api && api["name"]
79
107
  end
@@ -1,11 +1,10 @@
1
1
  require "faraday"
2
2
  require "uri"
3
3
  require "stacker_bee/middleware/signed_query"
4
- require "stacker_bee/middleware/logger"
5
4
  require "stacker_bee/middleware/detokenizer"
6
5
 
7
6
  module StackerBee
8
- class ConnectionError < Exception
7
+ class ConnectionError < StandardError
9
8
  end
10
9
 
11
10
  class Connection
@@ -13,8 +12,7 @@ module StackerBee
13
12
 
14
13
  def initialize(configuration)
15
14
  @configuration = configuration
16
- uri = URI.parse(self.configuration.url)
17
- @path = uri.path
15
+ uri = URI.parse(self.configuration.url)
18
16
  uri.path = ''
19
17
  fail ConnectionError, "no protocol specified" unless uri.scheme
20
18
  initialize_faraday(uri)
@@ -24,15 +22,16 @@ module StackerBee
24
22
  @faraday = Faraday.new(url: uri.to_s) do |faraday|
25
23
  faraday.use Middleware::Detokenizer
26
24
  faraday.use Middleware::SignedQuery, configuration.secret_key
27
- faraday.use Middleware::Logger, configuration.logger
25
+ configuration.middlewares.call faraday
28
26
  faraday.adapter Faraday.default_adapter # Net::HTTP
29
27
  end
30
28
  end
31
29
 
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}"
30
+ def get(request, path)
31
+ @faraday.get(path, request.query_params)
32
+ rescue Faraday::Error::ConnectionFailed => error
33
+ raise ConnectionError,
34
+ "Failed to connect to #{configuration.url}, #{error}"
36
35
  end
37
36
  end
38
37
  end
@@ -6,36 +6,36 @@ module StackerBee
6
6
  attr_accessor :params
7
7
 
8
8
  def self.tokenize(key)
9
- key.gsub(/\[/, LB).gsub(/\]/, RB)
9
+ key.gsub("[", LB).gsub("]", RB)
10
10
  end
11
11
 
12
12
  def self.detokenize(key)
13
- key.gsub(/#{LB}/, "[").gsub(/#{RB}/, "]")
13
+ key.gsub(LB, "[").gsub(RB, "]")
14
14
  end
15
15
 
16
16
  def initialize(params)
17
- @params = params.dup
17
+ self.params = params.dup
18
18
  flatten_params
19
19
  end
20
20
 
21
21
  def flatten_params
22
- hashes = params.select { |key, val| val.respond_to? :keys }
23
- flatten_map_values(params, hashes)
22
+ hashes = params.select { |_, 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 |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]
27
+ hashes.each do |hash_name, hash|
28
+ remove_empties(hash).each_with_index do |(key, value), index|
29
+ hash_url_key = self.class.tokenize("#{hash_name}[#{index}]")
30
+ params["#{hash_url_key}.key"] = params["#{hash_url_key}.name"] = key
31
+ params["#{hash_url_key}.value"] = value
32
32
  end
33
- params.delete outer[0]
33
+ params.delete hash_name
34
34
  end
35
35
  end
36
36
 
37
37
  def remove_empties(hash)
38
- hash.reject{ |k, v| v.nil? || v == "" }
38
+ hash.reject { |_, v| v.nil? || v == "" }
39
39
  end
40
40
  end
41
41
  end
@@ -0,0 +1,13 @@
1
+ module StackerBee
2
+ class GraylogFaradayMiddleware < FaradayMiddleware::Graylog
3
+ def facility
4
+ 'stacker-bee'
5
+ end
6
+
7
+ def short_message(env)
8
+ message = env[:url].query.scan(/&command=([^&]*)/).join(' ')
9
+
10
+ "StackerBee #{message}".strip
11
+ end
12
+ end
13
+ end
@@ -1,7 +1,7 @@
1
1
  require "stacker_bee/body_parser"
2
2
 
3
3
  module StackerBee
4
- class RequestError < Exception
4
+ class RequestError < StandardError
5
5
  include BodyParser
6
6
 
7
7
  def initialize(raw_body)
@@ -1,3 +1,3 @@
1
1
  module StackerBee
2
- VERSION = "1.0.1"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/stacker_bee.rb CHANGED
@@ -1,2 +1,5 @@
1
1
  require_relative "stacker_bee/version"
2
2
  require_relative "stacker_bee/client"
3
+
4
+ require_relative "faraday_middleware/response/graylog"
5
+ require_relative "stacker_bee/graylog_faraday_middleware"
@@ -0,0 +1,34 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: "<CLOUD_STACK_HOST>/client/console?apiKey=<CLOUD_STACK_API_KEY>&cmd=access&command=consoleAccess&response=json&signature=DsI/kxaNO7AgzDCgE1j/3rtq3xU&vm=36f9c08b-f17a-4d0e-ac9b-d45ce2d34fcd"
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.9
12
+ Accept-Encoding:
13
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
14
+ Accept:
15
+ - "*/*"
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - Apache-Coyote/1.1
23
+ Content-Type:
24
+ - text/html
25
+ Content-Length:
26
+ - '616'
27
+ Date:
28
+ - Tue, 11 Feb 2014 19:33:34 GMT
29
+ body:
30
+ encoding: UTF-8
31
+ string: "<html><title>console2</title><frameset><frame src=\"https://207-19-99-5.realhostip.com/ajax?token=FAKE_TOKEN\"></frame></frameset></html>"
32
+ http_version:
33
+ recorded_at: Tue, 11 Feb 2014 19:34:25 GMT
34
+ recorded_with: VCR 2.8.0
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Client initialization configures the middleware" do
4
+
5
+ context "pass a new middleware to the client" do
6
+ subject { StackerBee::Client.new(configuration) }
7
+
8
+ let(:configuration) do
9
+ {
10
+ url: "http://garbagestring",
11
+ api_key: "HI!",
12
+ secret_key: "SECRETT",
13
+ middlewares: ->(faraday) { faraday.use middleware_class }
14
+ }
15
+ end
16
+
17
+ let(:middleware_class) do
18
+ Class.new(Faraday::Middleware) do
19
+ def call(env)
20
+ fail "MiddlewareUsed"
21
+ end
22
+ end
23
+ end
24
+
25
+ it "uses the middle ware" do
26
+ expect { subject.list_virtual_machines }
27
+ .to raise_exception "MiddlewareUsed"
28
+ end
29
+ end
30
+ end