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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YjhmNmYwOWEwNDE5NmViNTkxMTZiZTIxNmQwNjA0NmFlMjUzOTk4OQ==
5
- data.tar.gz: !binary |-
6
- Y2IyNGIxYWI1ZTM1ODYwYTNkODM3MTlmMGYyZDZhNGNhYWQwYmU2OA==
2
+ SHA1:
3
+ metadata.gz: c61314ae91d1a5401971f178fc31e00cd9b06687
4
+ data.tar.gz: 48d6f1e0eb6d767fdd42a3de0d1bfef4c6c30e22
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- Yzc3ZDZhNDIzNjcyNTdiYTFhNjcxMTE4NTRhZjRmNzk3ZmZiZDYzY2UyZTBm
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
- ```ruby
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
- ```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
- )
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
- For example, you can use `list_virtual_machines` instead of `listVirtualMachines` and
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
- ```ruby
54
- vm = cloud_stack.list_virtual_machines(affinity_group_id: id).first
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
- ```ruby
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
- ```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
- ```
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
- ```ruby
111
- StackerBee::Client.url = 'http://localhost:8080/client/api'
98
+ StackerBee::Client.url = 'http://localhost:8080/client/api'
99
+ StackerBee::Client.logger = Rails.logger
112
100
 
113
- user_client = StackerBee::Client.new(
114
- api_key: 'USER_API_KEY',
115
- secret_key: 'USER_SECRET_KEY'
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
- api_key: 'ROOT_API_KEY',
120
- secret_key: 'ROOT_SECRET_KEY'
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
- ```ruby
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
- ```ruby
135
- my_client = StackerBee::Client.new(
136
- url: 'http://localhost:8080/client/api'
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
- ```ruby
145
- StackerBee::Client.api_key = 'MY_API_KEY'
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
- ```ruby
152
- my_client = StackerBee::Client.new(
153
- api_key: 'MY_API_KEY',
154
- secret_key: 'MY_SECRET_KEY'
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 allows you to add Faraday middleware. Here's an example of adding your own middleware.
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
- ```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
- ```
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
- ```ruby
182
- logger = GELF::Notifier.new("localhost", 12201)
158
+ logger = GELF::Notifier.new("localhost", 12201)
183
159
 
184
- StackerBee::Client.configuration = {
185
- middlewares: ->(faraday) { faraday.use StackerBee::GraylogFaradayMiddleware, logger }
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
- ```ruby
194
- StackerBee::Client.configuration = {
195
- middlewares: ->(faraday) { faraday.response :logger }
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
- ```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
- ```
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
- 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})
9
+ @body = parse(raw_response.body)
20
10
  end
21
11
 
22
12
  def parse(json)
@@ -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
- path = path_for_endpoint(endpoint_name)
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 = URI.parse(self.configuration.url)
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(url: uri.to_s,
21
- ssl: { verify: ssl_verify })
20
+ initialize_faraday(uri)
22
21
  end
23
22
 
24
- def initialize_faraday(options)
25
- @faraday = Faraday.new(options) do |faraday|
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, path)
34
- @faraday.get(path, request.query_params)
35
- rescue Faraday::Error::ConnectionFailed => error
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("[", 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
- self.params = params.dup
17
+ @params = params.dup
18
18
  flatten_params
19
19
  end
20
20
 
21
21
  def flatten_params
22
- hashes = params.select { |_, val| val.respond_to?(:keys) }
23
- flatten_map_values params, hashes
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 |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
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 hash_name
33
+ params.delete outer[0]
34
34
  end
35
35
  end
36
36
 
37
37
  def remove_empties(hash)
38
- hash.reject { |_, v| v.nil? || v == "" }
38
+ hash.reject { |k, v| v.nil? || v == "" }
39
39
  end
40
40
  end
41
41
  end
@@ -5,9 +5,8 @@ module StackerBee
5
5
  end
6
6
 
7
7
  def short_message(env)
8
- message = env[:url].query.scan(/&command=([^&]*)/).join(' ')
9
-
10
- "StackerBee #{message}".strip
8
+ message = env[:url].query.match(/&command=([^&]*)/)[1]
9
+ "StackerBee #{message}"
11
10
  end
12
11
  end
13
12
  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