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.
- checksums.yaml +13 -5
- data/.travis.yml +14 -1
- data/README.md +117 -67
- data/bin/stacker_bee +4 -3
- data/lib/faraday_middleware/response/graylog.rb +35 -0
- data/lib/stacker_bee/body_parser.rb +11 -1
- data/lib/stacker_bee/client.rb +32 -4
- data/lib/stacker_bee/connection.rb +8 -9
- data/lib/stacker_bee/dictionary_flattener.rb +12 -12
- data/lib/stacker_bee/graylog_faraday_middleware.rb +13 -0
- data/lib/stacker_bee/request_error.rb +1 -1
- data/lib/stacker_bee/version.rb +1 -1
- data/lib/stacker_bee.rb +3 -0
- data/spec/cassettes/A_request_sent_to_CloudStack_for_console_access/returns_html_for_console_access.yml +34 -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/integration/configure_middleware_spec.rb +30 -0
- data/spec/integration/console_spec.rb +23 -0
- data/spec/integration/request_spec.rb +2 -31
- data/spec/spec_helper.rb +4 -0
- data/spec/units/faraday_graylog_middleware_spec.rb +80 -0
- data/spec/units/stacker_bee/client_spec.rb +52 -9
- data/spec/units/stacker_bee/connection_spec.rb +14 -5
- data/spec/units/stacker_bee/console_spec.rb +0 -0
- data/spec/units/stacker_bee/graylog_faraday_middleware_spec.rb +51 -0
- data/spec/units/stacker_bee/request_error_spec.rb +7 -3
- data/spec/units/stacker_bee/response_spec.rb +18 -4
- data/stacker_bee.gemspec +9 -2
- metadata +58 -15
- data/lib/stacker_bee/middleware/logger.rb +0 -47
- data/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_a_Map/object.yml +0 -153
- data/spec/units/stacker_bee/middleware/logger_spec.rb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZmNkOGY0ZGRkY2Y0MjYzZGZmYzJjMWI0MTZjMzU5MTIwNWYyZDY5MA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTBhNzY3NmQ1ODU1MzliZGVmYWE4NWNhNGViMGMyNTdmNWI3NmY1OA==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
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
|
16
|
+
If you are using Bundler add the following to your Gemfile:
|
17
17
|
|
18
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
36
|
+
cloud_stack.list_virtual_machines state: 'Running'
|
37
|
+
# => [ { id: '48b91ab4...', displayName: '...', ... },
|
38
|
+
# { id: '59c02bc5...', displayName: '...', ... },
|
39
|
+
# ... ]
|
37
40
|
|
38
|
-
|
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
|
-
|
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
|
-
|
50
|
-
|
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,
|
60
|
+
For any endpoint requiring a map parameter, pass in a hash.
|
55
61
|
|
56
|
-
|
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
|
-
|
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
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
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
|
-
|
108
|
-
|
110
|
+
```ruby
|
111
|
+
StackerBee::Client.url = 'http://localhost:8080/client/api'
|
109
112
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
113
|
+
user_client = StackerBee::Client.new(
|
114
|
+
api_key: 'USER_API_KEY',
|
115
|
+
secret_key: 'USER_SECRET_KEY'
|
116
|
+
)
|
114
117
|
|
115
|
-
|
116
|
-
|
117
|
-
|
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
|
-
|
128
|
+
```ruby
|
129
|
+
StackerBee::Client.url = 'http://localhost:8080/client/api'
|
130
|
+
```
|
125
131
|
|
126
132
|
Or:
|
127
133
|
|
128
|
-
|
129
|
-
|
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
|
-
|
137
|
-
|
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
|
-
|
142
|
-
|
143
|
-
|
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
|
-
|
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
|
-
|
173
|
+
### Logging
|
149
174
|
|
150
|
-
|
175
|
+
Logging is best handled with Faraday middleware.
|
151
176
|
|
152
|
-
|
177
|
+
#### GELF/Graylog2
|
153
178
|
|
154
|
-
|
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
|
-
|
181
|
+
```ruby
|
182
|
+
logger = GELF::Notifier.new("localhost", 12201)
|
159
183
|
|
160
|
-
|
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
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
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
|
-
|
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)
|
data/lib/stacker_bee/client.rb
CHANGED
@@ -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
|
-
|
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 <
|
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
|
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
|
-
|
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(
|
34
|
-
rescue Faraday::Error::ConnectionFailed
|
35
|
-
raise ConnectionError,
|
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(
|
9
|
+
key.gsub("[", LB).gsub("]", RB)
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.detokenize(key)
|
13
|
-
key.gsub(
|
13
|
+
key.gsub(LB, "[").gsub(RB, "]")
|
14
14
|
end
|
15
15
|
|
16
16
|
def initialize(params)
|
17
|
-
|
17
|
+
self.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 { |_, 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 |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
|
33
|
+
params.delete hash_name
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
def remove_empties(hash)
|
38
|
-
hash.reject{ |
|
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
|
data/lib/stacker_bee/version.rb
CHANGED
data/lib/stacker_bee.rb
CHANGED
@@ -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
|
File without changes
|
@@ -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
|