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.
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