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.
Files changed (73) hide show
  1. checksums.yaml +13 -5
  2. data/.travis.yml +13 -1
  3. data/README.md +134 -64
  4. data/bin/stacker_bee +4 -3
  5. data/config.default.yml +1 -1
  6. data/lib/stacker_bee/api.rb +2 -3
  7. data/lib/stacker_bee/client.rb +101 -19
  8. data/lib/stacker_bee/connection.rb +31 -16
  9. data/lib/stacker_bee/{middleware → http_middleware}/detokenizer.rb +3 -2
  10. data/lib/stacker_bee/http_middleware/graylog.rb +14 -0
  11. data/lib/stacker_bee/{middleware → http_middleware}/signed_query.rb +1 -1
  12. data/lib/stacker_bee/middleware/adapter.rb +16 -0
  13. data/lib/stacker_bee/middleware/base.rb +33 -0
  14. data/lib/stacker_bee/middleware/clean_response.rb +42 -0
  15. data/lib/stacker_bee/middleware/cloud_stack_api.rb +17 -0
  16. data/lib/stacker_bee/middleware/console_access.rb +38 -0
  17. data/lib/stacker_bee/middleware/de_namespace.rb +15 -0
  18. data/lib/stacker_bee/middleware/dictionary_flattener.rb +44 -0
  19. data/lib/stacker_bee/middleware/endpoint_normalizer.rb +23 -0
  20. data/lib/stacker_bee/middleware/environment.rb +23 -0
  21. data/lib/stacker_bee/middleware/format_keys.rb +13 -0
  22. data/lib/stacker_bee/middleware/format_values.rb +13 -0
  23. data/lib/stacker_bee/middleware/http_status.rb +14 -0
  24. data/lib/stacker_bee/middleware/json_body.rb +14 -0
  25. data/lib/stacker_bee/middleware/raise_on_http_error.rb +11 -0
  26. data/lib/stacker_bee/middleware/rashify_response.rb +21 -0
  27. data/lib/stacker_bee/middleware/remove_empty_strings.rb +11 -0
  28. data/lib/stacker_bee/middleware/remove_nils.rb +9 -0
  29. data/lib/stacker_bee/request_error.rb +8 -16
  30. data/lib/stacker_bee/utilities.rb +30 -0
  31. data/lib/stacker_bee/version.rb +1 -1
  32. data/lib/stacker_bee.rb +1 -1
  33. data/spec/cassettes/A_request_sent_to_CloudStack_for_console_access/returns_html_for_console_access.yml +33 -0
  34. 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
  35. 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
  36. 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
  37. 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
  38. data/spec/integration/check_spec.rb +48 -0
  39. data/spec/integration/configure_middleware_spec.rb +54 -16
  40. data/spec/integration/console_spec.rb +21 -0
  41. data/spec/integration/request_spec.rb +57 -2
  42. data/spec/spec_helper.rb +11 -1
  43. data/spec/units/faraday_graylog_middleware_spec.rb +1 -1
  44. data/spec/units/stacker_bee/client_spec.rb +47 -78
  45. data/spec/units/stacker_bee/connection_spec.rb +34 -11
  46. data/spec/units/stacker_bee/console_spec.rb +0 -0
  47. data/spec/units/stacker_bee/{graylog_faraday_middleware_spec.rb → http_middleware/graylog_spec.rb} +18 -2
  48. data/spec/units/stacker_bee/middleware/adapter_spec.rb +54 -0
  49. data/spec/units/stacker_bee/middleware/base_spec.rb +128 -0
  50. data/spec/units/stacker_bee/middleware/cloudstack_api_spec.rb +37 -0
  51. data/spec/units/stacker_bee/middleware/console_access_spec.rb +59 -0
  52. data/spec/units/stacker_bee/{dictionary_flattener_spec.rb → middleware/dictionary_flattener_spec.rb} +7 -7
  53. data/spec/units/stacker_bee/middleware/endpoint_normalizer_spec.rb +36 -0
  54. data/spec/units/stacker_bee/middleware/format_keys_spec.rb +18 -0
  55. data/spec/units/stacker_bee/middleware/format_values_spec.rb +15 -0
  56. data/spec/units/stacker_bee/middleware/http_status_spec.rb +34 -0
  57. data/spec/units/stacker_bee/middleware/raise_on_http_errors_spec.rb +5 -0
  58. data/spec/units/stacker_bee/middleware/remove_empty_strings_spec.rb +54 -0
  59. data/spec/units/stacker_bee/middleware/remove_nils_spec.rb +8 -0
  60. data/spec/units/stacker_bee/request_error_spec.rb +25 -37
  61. data/spec/units/stacker_bee/utilities_spec.rb +26 -0
  62. data/stacker_bee.gemspec +6 -2
  63. metadata +84 -38
  64. data/lib/stacker_bee/body_parser.rb +0 -23
  65. data/lib/stacker_bee/dictionary_flattener.rb +0 -41
  66. data/lib/stacker_bee/graylog_faraday_middleware.rb +0 -12
  67. data/lib/stacker_bee/middleware/logger.rb +0 -47
  68. data/lib/stacker_bee/request.rb +0 -46
  69. data/lib/stacker_bee/response.rb +0 -29
  70. data/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_a_Map/object.yml +0 -153
  71. data/spec/units/stacker_bee/middleware/logger_spec.rb +0 -55
  72. data/spec/units/stacker_bee/request_spec.rb +0 -51
  73. 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,13 @@
1
+ module StackerBee
2
+ module Middleware
3
+ class FormatKeys < Base
4
+ include Utilities
5
+
6
+ def params(params)
7
+ transform_hash_keys(params) do |key|
8
+ camel_case(key, true)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module StackerBee
2
+ module Middleware
3
+ class FormatValues < Base
4
+ include Utilities
5
+
6
+ def params(params)
7
+ transform_hash_values(params) do |value|
8
+ value.respond_to?(:join) ? value.join(',') : value.to_s
9
+ end
10
+ end
11
+ end
12
+ end
13
+ 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,11 @@
1
+ require "stacker_bee/request_error"
2
+
3
+ module StackerBee
4
+ module Middleware
5
+ class RaiseOnHTTPError < Base
6
+ def after(env)
7
+ fail RequestError.for(env) unless env.raw_response.success?
8
+ end
9
+ end
10
+ end
11
+ 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
@@ -0,0 +1,11 @@
1
+ module StackerBee
2
+ module Middleware
3
+ class RemoveEmptyStrings < Base
4
+ def before(env)
5
+ Utilities.hash_deeply(env.request.params) do |hash|
6
+ hash.delete_if { |_, val| val == '' }
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module StackerBee
2
+ module Middleware
3
+ class RemoveNils < Base
4
+ def params(params)
5
+ params.reject { |key, val| val.nil? }
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,30 +1,22 @@
1
- require "stacker_bee/body_parser"
2
-
3
1
  module StackerBee
4
2
  class RequestError < StandardError
5
- include BodyParser
3
+ attr_accessor :env, :status
6
4
 
7
- def initialize(raw_body)
8
- self.body = raw_body
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(raw_response)
12
- klass = case raw_response.status
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(raw_response)
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
@@ -1,3 +1,3 @@
1
1
  module StackerBee
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
data/lib/stacker_bee.rb CHANGED
@@ -2,4 +2,4 @@ require_relative "stacker_bee/version"
2
2
  require_relative "stacker_bee/client"
3
3
 
4
4
  require_relative "faraday_middleware/response/graylog"
5
- require_relative "stacker_bee/graylog_faraday_middleware"
5
+ require_relative "stacker_bee/http_middleware/graylog"
@@ -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
@@ -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