stacker_bee 2.0.0 → 2.1.0.pre180
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|