stacker_bee 2.0.0 → 2.1.0.pre180
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/.travis.yml +13 -1
- data/README.md +134 -64
- data/bin/stacker_bee +4 -3
- data/config.default.yml +1 -1
- data/lib/stacker_bee/api.rb +2 -3
- data/lib/stacker_bee/client.rb +101 -19
- data/lib/stacker_bee/connection.rb +31 -16
- data/lib/stacker_bee/{middleware → http_middleware}/detokenizer.rb +3 -2
- data/lib/stacker_bee/http_middleware/graylog.rb +14 -0
- data/lib/stacker_bee/{middleware → http_middleware}/signed_query.rb +1 -1
- data/lib/stacker_bee/middleware/adapter.rb +16 -0
- data/lib/stacker_bee/middleware/base.rb +33 -0
- data/lib/stacker_bee/middleware/clean_response.rb +42 -0
- data/lib/stacker_bee/middleware/cloud_stack_api.rb +17 -0
- data/lib/stacker_bee/middleware/console_access.rb +38 -0
- data/lib/stacker_bee/middleware/de_namespace.rb +15 -0
- data/lib/stacker_bee/middleware/dictionary_flattener.rb +44 -0
- data/lib/stacker_bee/middleware/endpoint_normalizer.rb +23 -0
- data/lib/stacker_bee/middleware/environment.rb +23 -0
- data/lib/stacker_bee/middleware/format_keys.rb +13 -0
- data/lib/stacker_bee/middleware/format_values.rb +13 -0
- data/lib/stacker_bee/middleware/http_status.rb +14 -0
- data/lib/stacker_bee/middleware/json_body.rb +14 -0
- data/lib/stacker_bee/middleware/raise_on_http_error.rb +11 -0
- data/lib/stacker_bee/middleware/rashify_response.rb +21 -0
- data/lib/stacker_bee/middleware/remove_empty_strings.rb +11 -0
- data/lib/stacker_bee/middleware/remove_nils.rb +9 -0
- data/lib/stacker_bee/request_error.rb +8 -16
- data/lib/stacker_bee/utilities.rb +30 -0
- data/lib/stacker_bee/version.rb +1 -1
- data/lib/stacker_bee.rb +1 -1
- data/spec/cassettes/A_request_sent_to_CloudStack_for_console_access/returns_html_for_console_access.yml +33 -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_that_triggers_an_error/properly_signs_the_request.yml +35 -0
- data/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/middleware/a_middleware_that_doesn_t_match_the_content_type/uses_the_middleware.yml +33 -0
- data/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/middleware/a_middleware_that_matches_the_content_type/uses_the_middleware.yml +33 -0
- data/spec/integration/check_spec.rb +48 -0
- data/spec/integration/configure_middleware_spec.rb +54 -16
- data/spec/integration/console_spec.rb +21 -0
- data/spec/integration/request_spec.rb +57 -2
- data/spec/spec_helper.rb +11 -1
- data/spec/units/faraday_graylog_middleware_spec.rb +1 -1
- data/spec/units/stacker_bee/client_spec.rb +47 -78
- data/spec/units/stacker_bee/connection_spec.rb +34 -11
- data/spec/units/stacker_bee/console_spec.rb +0 -0
- data/spec/units/stacker_bee/{graylog_faraday_middleware_spec.rb → http_middleware/graylog_spec.rb} +18 -2
- data/spec/units/stacker_bee/middleware/adapter_spec.rb +54 -0
- data/spec/units/stacker_bee/middleware/base_spec.rb +128 -0
- data/spec/units/stacker_bee/middleware/cloudstack_api_spec.rb +37 -0
- data/spec/units/stacker_bee/middleware/console_access_spec.rb +59 -0
- data/spec/units/stacker_bee/{dictionary_flattener_spec.rb → middleware/dictionary_flattener_spec.rb} +7 -7
- data/spec/units/stacker_bee/middleware/endpoint_normalizer_spec.rb +36 -0
- data/spec/units/stacker_bee/middleware/format_keys_spec.rb +18 -0
- data/spec/units/stacker_bee/middleware/format_values_spec.rb +15 -0
- data/spec/units/stacker_bee/middleware/http_status_spec.rb +34 -0
- data/spec/units/stacker_bee/middleware/raise_on_http_errors_spec.rb +5 -0
- data/spec/units/stacker_bee/middleware/remove_empty_strings_spec.rb +54 -0
- data/spec/units/stacker_bee/middleware/remove_nils_spec.rb +8 -0
- data/spec/units/stacker_bee/request_error_spec.rb +25 -37
- data/spec/units/stacker_bee/utilities_spec.rb +26 -0
- data/stacker_bee.gemspec +6 -2
- metadata +84 -38
- data/lib/stacker_bee/body_parser.rb +0 -23
- data/lib/stacker_bee/dictionary_flattener.rb +0 -41
- data/lib/stacker_bee/graylog_faraday_middleware.rb +0 -12
- data/lib/stacker_bee/middleware/logger.rb +0 -47
- data/lib/stacker_bee/request.rb +0 -46
- data/lib/stacker_bee/response.rb +0 -29
- 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
- data/spec/units/stacker_bee/request_spec.rb +0 -51
- data/spec/units/stacker_bee/response_spec.rb +0 -79
@@ -0,0 +1,33 @@
|
|
1
|
+
module StackerBee
|
2
|
+
module Middleware
|
3
|
+
class Base < OpenStruct
|
4
|
+
def call(env)
|
5
|
+
before env
|
6
|
+
app.call env
|
7
|
+
after env if matches_content_type?(env)
|
8
|
+
end
|
9
|
+
|
10
|
+
def matches_content_type?(env)
|
11
|
+
content_types.nil? || content_types =~ env.response.content_type
|
12
|
+
end
|
13
|
+
|
14
|
+
def content_types
|
15
|
+
end
|
16
|
+
|
17
|
+
def before(env)
|
18
|
+
env.request.params = params(env.request.params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def after(env)
|
22
|
+
end
|
23
|
+
|
24
|
+
def params(params)
|
25
|
+
params
|
26
|
+
end
|
27
|
+
|
28
|
+
def endpoint_name_for(endpoint_name)
|
29
|
+
app.endpoint_name_for(endpoint_name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module StackerBee
|
2
|
+
module Middleware
|
3
|
+
class CleanResponse < Base
|
4
|
+
def after(env)
|
5
|
+
body = env.response.body
|
6
|
+
|
7
|
+
return if !is_hash?(body)
|
8
|
+
|
9
|
+
if has_count?(body)
|
10
|
+
env.response.body =remove_count(body)
|
11
|
+
elsif single_hash?(body)
|
12
|
+
env.response.body = first_hash(body)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def is_hash?(body)
|
17
|
+
body.respond_to?(:keys)
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_count?(body)
|
21
|
+
body.size == 2 && body.key?("count")
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove_count(body)
|
25
|
+
body.reject { |key, val| key == "count" }.values.first
|
26
|
+
end
|
27
|
+
|
28
|
+
def single_hash?(body)
|
29
|
+
body.size == 1 && body.values.first.respond_to?(:keys)
|
30
|
+
end
|
31
|
+
|
32
|
+
def first_hash(body)
|
33
|
+
body.values.first
|
34
|
+
end
|
35
|
+
|
36
|
+
def content_types
|
37
|
+
/javascript/
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module StackerBee
|
2
|
+
module Middleware
|
3
|
+
class CloudStackAPI < Base
|
4
|
+
RESPONSE_TYPE = "json"
|
5
|
+
DEFAULT_PATH = "/client/api/"
|
6
|
+
|
7
|
+
def before(env)
|
8
|
+
env.request.params.merge!(
|
9
|
+
api_key: api_key,
|
10
|
+
command: env.request.endpoint_name,
|
11
|
+
response: RESPONSE_TYPE
|
12
|
+
)
|
13
|
+
env.request.path ||= DEFAULT_PATH
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module StackerBee
|
2
|
+
module Middleware
|
3
|
+
class ConsoleAccess < Base
|
4
|
+
include Utilities
|
5
|
+
|
6
|
+
ENDPOINT = 'consoleAccess'
|
7
|
+
PATH = '/client/console'
|
8
|
+
PARAMS = { cmd: 'access' }
|
9
|
+
|
10
|
+
def before(env)
|
11
|
+
return unless matches_endpoint?(env.request.endpoint_name)
|
12
|
+
super
|
13
|
+
env.request.path = PATH
|
14
|
+
env.request.endpoint_name = ENDPOINT
|
15
|
+
end
|
16
|
+
|
17
|
+
def params(params)
|
18
|
+
params.merge(PARAMS)
|
19
|
+
end
|
20
|
+
|
21
|
+
def content_types
|
22
|
+
/html/
|
23
|
+
end
|
24
|
+
|
25
|
+
def endpoint_name_for(name)
|
26
|
+
matches_endpoint?(name) ? ENDPOINT : super
|
27
|
+
end
|
28
|
+
|
29
|
+
def matches_endpoint?(name)
|
30
|
+
uncase(name) == uncased_endpoint
|
31
|
+
end
|
32
|
+
|
33
|
+
def uncased_endpoint
|
34
|
+
@uncased_endpoint ||= uncase(ENDPOINT)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module StackerBee
|
2
|
+
module Middleware
|
3
|
+
class DeNamespace < Base
|
4
|
+
def after(env)
|
5
|
+
body = env.response.body
|
6
|
+
fail "Cannot determine response key in #{body.keys}" if body.size > 1
|
7
|
+
env.response.body = body.values.first
|
8
|
+
end
|
9
|
+
|
10
|
+
def content_types
|
11
|
+
/javascript/
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module StackerBee
|
2
|
+
module Middleware
|
3
|
+
class DictionaryFlattener < Base
|
4
|
+
LB = "SBLEFTBRACKET"
|
5
|
+
RB = "SBRIGHTBRACKET"
|
6
|
+
|
7
|
+
# TODO: should the tokenizing be separate from the flattener?
|
8
|
+
# it could be a middleware that finds [] in the keys and replaces them
|
9
|
+
def self.tokenize(key)
|
10
|
+
key.gsub('[', LB).gsub(']', RB)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.detokenize(key)
|
14
|
+
key.gsub(LB, '[').gsub(RB, ']')
|
15
|
+
end
|
16
|
+
|
17
|
+
def params(original)
|
18
|
+
original.dup.tap { |params| flatten_params(params) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def flatten_params(params)
|
22
|
+
hashes = params.select { |_, val| val.respond_to?(:keys) }
|
23
|
+
flatten_map_values params, hashes
|
24
|
+
end
|
25
|
+
|
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
|
32
|
+
end
|
33
|
+
params.delete hash_name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# TODO: isn't this done with the RemoveEmptyStrings middleware?
|
38
|
+
def remove_empties(hash)
|
39
|
+
hash.reject { |_, v| v.nil? || v == "" }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module StackerBee
|
2
|
+
module Middleware
|
3
|
+
class EndpointNormalizer < Base
|
4
|
+
def before(env)
|
5
|
+
new_endpoint_name = endpoint_name_for(env.request.endpoint_name)
|
6
|
+
if new_endpoint_name
|
7
|
+
env.request.endpoint_name = new_endpoint_name
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def endpoint_name_for(name)
|
12
|
+
# TODO: shouldn't this be in the base endpoint?
|
13
|
+
fail "API required" unless api
|
14
|
+
endpoint_description = api[name]
|
15
|
+
if endpoint_description
|
16
|
+
endpoint_description.fetch("name")
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module StackerBee
|
2
|
+
module Middleware
|
3
|
+
class Environment < OpenStruct
|
4
|
+
def initialize(request_attributes = {})
|
5
|
+
super()
|
6
|
+
|
7
|
+
defaults = { params: {} }
|
8
|
+
self.request = Request.new(defaults.merge(request_attributes))
|
9
|
+
|
10
|
+
self.response = Response.new
|
11
|
+
end
|
12
|
+
|
13
|
+
class Request < OpenStruct
|
14
|
+
end
|
15
|
+
|
16
|
+
class Response < OpenStruct
|
17
|
+
def success?
|
18
|
+
!!success
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module StackerBee
|
2
|
+
module Middleware
|
3
|
+
class HTTPStatus < Base
|
4
|
+
def after(env)
|
5
|
+
env.response.status = env.raw_response.status
|
6
|
+
env.response.success = env.raw_response.success?
|
7
|
+
|
8
|
+
unless env.response.success?
|
9
|
+
env.response.error = env.response.body[:errortext]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module StackerBee
|
2
|
+
module Middleware
|
3
|
+
class JSONBody < Base
|
4
|
+
def after(env)
|
5
|
+
env.response.raw_body = env.raw_response.body
|
6
|
+
env.response.body = MultiJson.load(env.response.raw_body)
|
7
|
+
end
|
8
|
+
|
9
|
+
def content_types
|
10
|
+
/javascript/
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'stacker_bee/rash'
|
2
|
+
|
3
|
+
module StackerBee
|
4
|
+
module Middleware
|
5
|
+
class RashifyResponse < Base
|
6
|
+
def after(env)
|
7
|
+
body = env.response.body
|
8
|
+
env.response.body = case body
|
9
|
+
when Hash then Rash.new(body)
|
10
|
+
when Array then body.map { |item| Rash.new(item) }
|
11
|
+
else
|
12
|
+
body
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def content_types
|
17
|
+
/javascript/
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,30 +1,22 @@
|
|
1
|
-
require "stacker_bee/body_parser"
|
2
|
-
|
3
1
|
module StackerBee
|
4
2
|
class RequestError < StandardError
|
5
|
-
|
3
|
+
attr_accessor :env, :status
|
6
4
|
|
7
|
-
def initialize(
|
8
|
-
self.
|
5
|
+
def initialize(env)
|
6
|
+
self.env = env
|
7
|
+
self.status = env.response.status
|
8
|
+
super(env.response.error)
|
9
9
|
end
|
10
10
|
|
11
|
-
def self.for(
|
12
|
-
klass = case
|
11
|
+
def self.for(env)
|
12
|
+
klass = case env.response.status
|
13
13
|
when 401 then AuthenticationError
|
14
14
|
when 400..499 then ClientError
|
15
15
|
when 500..599 then ServerError
|
16
16
|
else
|
17
17
|
self
|
18
18
|
end
|
19
|
-
klass.new(
|
20
|
-
end
|
21
|
-
|
22
|
-
def status
|
23
|
-
body["errorcode"]
|
24
|
-
end
|
25
|
-
|
26
|
-
def to_s
|
27
|
-
body["errortext"]
|
19
|
+
klass.new(env)
|
28
20
|
end
|
29
21
|
end
|
30
22
|
|
@@ -2,6 +2,8 @@ module StackerBee
|
|
2
2
|
module Utilities
|
3
3
|
REGEX = /\s|-|_/
|
4
4
|
|
5
|
+
module_function
|
6
|
+
|
5
7
|
def uncase(string)
|
6
8
|
string.to_s.downcase.gsub(REGEX, '')
|
7
9
|
end
|
@@ -10,11 +12,39 @@ module StackerBee
|
|
10
12
|
string.to_s.gsub(/(.)([A-Z])/, '\1_\2').gsub(/(\W|_)+/, '_').downcase
|
11
13
|
end
|
12
14
|
|
15
|
+
# TODO: avoid flag arguments
|
13
16
|
def camel_case(string, lower = false)
|
14
17
|
string.to_s.split(REGEX).each_with_object('') do |word, memo|
|
15
18
|
memo << (memo.empty? && lower ? word[0].downcase : word[0].upcase)
|
16
19
|
memo << word[1..-1]
|
17
20
|
end
|
18
21
|
end
|
22
|
+
|
23
|
+
def hash_deeply(hash, &block)
|
24
|
+
block.call hash
|
25
|
+
|
26
|
+
hash.values
|
27
|
+
.select { |val| val.respond_to?(:to_hash) }
|
28
|
+
.each { |val| hash_deeply val, &block }
|
29
|
+
end
|
30
|
+
|
31
|
+
def map_a_hash(hash)
|
32
|
+
hash.each_with_object({}) do |pair, new_hash|
|
33
|
+
key, value = yield(*pair)
|
34
|
+
new_hash[key] = value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def transform_hash_values(hash)
|
39
|
+
map_a_hash(hash) do |key, val|
|
40
|
+
[key, yield(val)]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def transform_hash_keys(hash)
|
45
|
+
map_a_hash(hash) do |key, val|
|
46
|
+
[yield(key), val]
|
47
|
+
end
|
48
|
+
end
|
19
49
|
end
|
20
50
|
end
|
data/lib/stacker_bee/version.rb
CHANGED
data/lib/stacker_bee.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
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
|
File without changes
|
@@ -0,0 +1,35 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=listAccounts&domainId=666&response=json&signature=xsXEaSNzlFQjI3%2B4EVBOV%2BwFrbM=
|
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: 431
|
19
|
+
message: '431'
|
20
|
+
headers:
|
21
|
+
X-Description:
|
22
|
+
- Domain id=666 doesn't exist
|
23
|
+
Content-Type:
|
24
|
+
- text/javascript; charset=UTF-8
|
25
|
+
Content-Length:
|
26
|
+
- '121'
|
27
|
+
Server:
|
28
|
+
- Jetty(6.1.26)
|
29
|
+
body:
|
30
|
+
encoding: UTF-8
|
31
|
+
string: '{ "listaccountsresponse" : {"uuidList":[],"errorcode":431,"cserrorcode":4350,"errortext":"Domain
|
32
|
+
id=666 doesn''t exist"} }'
|
33
|
+
http_version:
|
34
|
+
recorded_at: Tue, 11 Feb 2014 02:48:17 GMT
|
35
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,33 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=listAccounts&response=json&signature=oftBcJm8kFc%2Buxul8pAL2%2Bh0bdU=
|
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
|
+
Content-Type:
|
22
|
+
- text/javascript; charset=UTF-8
|
23
|
+
Content-Length:
|
24
|
+
- '1727'
|
25
|
+
Server:
|
26
|
+
- Jetty(6.1.26)
|
27
|
+
body:
|
28
|
+
encoding: UTF-8
|
29
|
+
string: '{ "listaccountsresponse" : { "count":1 ,"account" : [ {"id":"ce45d9a0-41f5-11e3-aaa7-d6558ad1fb9f","name":"admin","accounttype":1,"domainid":"ce4585b8-41f5-11e3-aaa7-d6558ad1fb9f","domain":"ROOT","vmlimit":"Unlimited","vmtotal":0,"vmavailable":"Unlimited","iplimit":"Unlimited","iptotal":0,"ipavailable":"Unlimited","volumelimit":"Unlimited","volumetotal":0,"volumeavailable":"Unlimited","snapshotlimit":"Unlimited","snapshottotal":0,"snapshotavailable":"Unlimited","templatelimit":"Unlimited","templatetotal":0,"templateavailable":"Unlimited","projectlimit":"Unlimited","projecttotal":0,"projectavailable":"Unlimited","networklimit":"Unlimited","networktotal":0,"networkavailable":"Unlimited","vpclimit":"Unlimited","vpctotal":0,"vpcavailable":"Unlimited","cpulimit":"Unlimited","cputotal":0,"cpuavailable":"Unlimited","memorylimit":"Unlimited","memorytotal":0,"memoryavailable":"Unlimited","primarystoragelimit":"Unlimited","primarystoragetotal":0,"primarystorageavailable":"Unlimited","secondarystoragelimit":"Unlimited","secondarystoragetotal":0,"secondarystorageavailable":"Unlimited","state":"enabled","user":[{"id":"ce46057e-41f5-11e3-aaa7-d6558ad1fb9f","username":"admin","firstname":"Admin","lastname":"User","email":"admin@mailprovider.com","created":"2013-10-30T22:29:33-0400","state":"enabled","account":"admin","accounttype":1,"domainid":"ce4585b8-41f5-11e3-aaa7-d6558ad1fb9f","domain":"ROOT","apikey":"<CLOUD_STACK_API_KEY>","secretkey":"<CLOUD_STACK_SECRET_KEY>","accountid":"ce45d9a0-41f5-11e3-aaa7-d6558ad1fb9f","iscallerchilddomain":false,"isdefault":true}],"isdefault":true}
|
30
|
+
] } }'
|
31
|
+
http_version:
|
32
|
+
recorded_at: Sat, 15 Feb 2014 20:42:23 GMT
|
33
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,33 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=listAccounts&response=json&signature=oftBcJm8kFc%2Buxul8pAL2%2Bh0bdU=
|
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
|
+
Content-Type:
|
22
|
+
- text/javascript; charset=UTF-8
|
23
|
+
Content-Length:
|
24
|
+
- '1727'
|
25
|
+
Server:
|
26
|
+
- Jetty(6.1.26)
|
27
|
+
body:
|
28
|
+
encoding: UTF-8
|
29
|
+
string: '{ "listaccountsresponse" : { "count":1 ,"account" : [ {"id":"ce45d9a0-41f5-11e3-aaa7-d6558ad1fb9f","name":"admin","accounttype":1,"domainid":"ce4585b8-41f5-11e3-aaa7-d6558ad1fb9f","domain":"ROOT","vmlimit":"Unlimited","vmtotal":0,"vmavailable":"Unlimited","iplimit":"Unlimited","iptotal":0,"ipavailable":"Unlimited","volumelimit":"Unlimited","volumetotal":0,"volumeavailable":"Unlimited","snapshotlimit":"Unlimited","snapshottotal":0,"snapshotavailable":"Unlimited","templatelimit":"Unlimited","templatetotal":0,"templateavailable":"Unlimited","projectlimit":"Unlimited","projecttotal":0,"projectavailable":"Unlimited","networklimit":"Unlimited","networktotal":0,"networkavailable":"Unlimited","vpclimit":"Unlimited","vpctotal":0,"vpcavailable":"Unlimited","cpulimit":"Unlimited","cputotal":0,"cpuavailable":"Unlimited","memorylimit":"Unlimited","memorytotal":0,"memoryavailable":"Unlimited","primarystoragelimit":"Unlimited","primarystoragetotal":0,"primarystorageavailable":"Unlimited","secondarystoragelimit":"Unlimited","secondarystoragetotal":0,"secondarystorageavailable":"Unlimited","state":"enabled","user":[{"id":"ce46057e-41f5-11e3-aaa7-d6558ad1fb9f","username":"admin","firstname":"Admin","lastname":"User","email":"admin@mailprovider.com","created":"2013-10-30T22:29:33-0400","state":"enabled","account":"admin","accounttype":1,"domainid":"ce4585b8-41f5-11e3-aaa7-d6558ad1fb9f","domain":"ROOT","apikey":"<CLOUD_STACK_API_KEY>","secretkey":"<CLOUD_STACK_SECRET_KEY>","accountid":"ce45d9a0-41f5-11e3-aaa7-d6558ad1fb9f","iscallerchilddomain":false,"isdefault":true}],"isdefault":true}
|
30
|
+
] } }'
|
31
|
+
http_version:
|
32
|
+
recorded_at: Sat, 15 Feb 2014 20:39:56 GMT
|
33
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,48 @@
|
|
1
|
+
if false
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe "Client initialization configures the middleware" do
|
5
|
+
context "pass a new middleware to the client" do
|
6
|
+
subject { StackerBee::Client.new(config_hash) }
|
7
|
+
|
8
|
+
let(:url) { CONFIG["url"] }
|
9
|
+
let(:config_hash) do
|
10
|
+
{
|
11
|
+
url: url,
|
12
|
+
api_key: api_key,
|
13
|
+
secret_key: secret_key,
|
14
|
+
apis_path: File.join(File.dirname(__FILE__), '../fixtures/4.2.json'),
|
15
|
+
faraday_middlewares: ->(faraday) { faraday.use middleware_class }
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:middleware_class) do
|
20
|
+
Class.new(Faraday::Middleware) do
|
21
|
+
def call(env)
|
22
|
+
$query = env[:url].query
|
23
|
+
fail "MiddlewareUsed"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
before do
|
29
|
+
$query = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
data = JSON.parse(File.read("/Users/mike/Desktop/stuff.json"))
|
33
|
+
data.each do |request|
|
34
|
+
context "something" do
|
35
|
+
let(:api_key) { request["config"]["api_key"] }
|
36
|
+
let(:secret_key) { request["config"]["secret_key"] }
|
37
|
+
it do
|
38
|
+
expect {
|
39
|
+
subject.request(*request["input"])
|
40
|
+
}.to raise_exception "MiddlewareUsed"
|
41
|
+
|
42
|
+
$query.should == request["query"]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|