stacker_bee 1.0.0 → 1.0.1
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 +4 -4
- data/.gitignore +1 -0
- data/README.md +127 -38
- data/lib/stacker_bee.rb +2 -16
- data/lib/stacker_bee/client.rb +2 -2
- data/lib/stacker_bee/connection.rb +9 -2
- data/lib/stacker_bee/dictionary_flattener.rb +41 -0
- data/lib/stacker_bee/middleware/detokenizer.rb +17 -0
- data/lib/stacker_bee/middleware/logger.rb +3 -4
- data/lib/stacker_bee/rash.rb +1 -1
- data/lib/stacker_bee/request.rb +12 -7
- data/lib/stacker_bee/response.rb +1 -1
- data/lib/stacker_bee/utilities.rb +4 -2
- data/lib/stacker_bee/version.rb +1 -1
- data/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_a_Map/can_create_an_object.yml +183 -0
- data/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_a_Map/object.yml +153 -0
- data/spec/integration/request_spec.rb +32 -4
- data/spec/units/stacker_bee/dictionary_flattener_spec.rb +51 -0
- data/spec/units/stacker_bee/request_spec.rb +13 -11
- data/spec/units/stacker_bee/utilities_spec.rb +2 -0
- data/stacker_bee.gemspec +3 -2
- metadata +26 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 113d9dc3b7034e99f4fa25d03b558de6f6a71c67
|
4
|
+
data.tar.gz: 3ec61352a7c75f6cdf92fbe7bd628fd2d3890d15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3583805c59178743eba73e67477b1d7a47e47dbd57e76248e2ab90ba398ebf2c452601c7c7b431039b22d612414d4c7fa874fec74ecea333ca0feceae53e21f0
|
7
|
+
data.tar.gz: e5bd192f9e42c7d9a6facca1fed0ab07339a089e329e41aaf6257516ede551e50f51e79963ede771ba183f8a8951a4b0bfc0919391c9ba5af9a5530905869739
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
[](https://codeclimate.com/github/promptworks/stacker_bee)
|
4
4
|
[](https://gemnasium.com/promptworks/stacker_bee)
|
5
5
|
[](https://travis-ci.org/promptworks/stacker_bee)
|
6
|
+
[](http://badge.fury.io/rb/stacker_bee)
|
6
7
|
|
7
8
|
The unofficial CloudStack client for Ruby.
|
8
9
|
|
@@ -20,71 +21,66 @@ And execute:
|
|
20
21
|
|
21
22
|
$ bundle install
|
22
23
|
|
24
|
+
|
23
25
|
## Basic Usage
|
24
26
|
|
25
|
-
|
27
|
+
cloud_stack = StackerBee::Client.new(
|
26
28
|
url: 'http://localhost:8080/client/api',
|
27
29
|
api_key: 'MY_API_KEY',
|
28
30
|
secret_key: 'MY_SECRET_KEY'
|
29
|
-
|
30
|
-
|
31
|
-
my_client.list_virtual_machines
|
32
|
-
|
33
|
-
my_client.create_volume name: "MyVolume"
|
34
|
-
|
35
|
-
## Basic Configuration
|
31
|
+
)
|
36
32
|
|
37
|
-
|
33
|
+
cloud_stack.list_virtual_machines state: 'Running'
|
34
|
+
# => [ { id: '48b91ab4...', displayName: '...', ... },
|
35
|
+
# { id: '59c02bc5...', displayName: '...', ... },
|
36
|
+
# ... ]
|
38
37
|
|
39
|
-
|
38
|
+
cloud_stack.create_volume name: 'MyVolume'
|
40
39
|
|
41
|
-
|
40
|
+
## Features
|
42
41
|
|
43
|
-
|
42
|
+
### Idomatic Ruby formatting for names
|
44
43
|
|
45
|
-
|
44
|
+
You can use `list_virtual_machines` instead of `listVirtualMachines` and
|
45
|
+
`affinity_group_id` instead of `affinitygroupid` (if you want to).
|
46
46
|
|
47
|
-
|
48
|
-
url: 'http://localhost:8080/client/api'
|
49
|
-
})
|
47
|
+
For example:
|
50
48
|
|
51
|
-
|
49
|
+
vm = cloud_stack.list_virtual_machines(affinity_group_id: id).first
|
50
|
+
puts vm[:iso_display_text]
|
52
51
|
|
53
|
-
|
52
|
+
### Handling 'map' parameters
|
54
53
|
|
55
|
-
|
56
|
-
StackerBee::Client.secret_key = "MY_SECRET_KEY"
|
54
|
+
For any endpoint requiring a map parameter, simply pass in a hash.
|
57
55
|
|
58
|
-
|
56
|
+
create_tags(tags: { type: 'community'}, resource_type: "Template", resource_ids: id )
|
59
57
|
|
60
|
-
|
61
|
-
api_key: 'MY_API_KEY',
|
62
|
-
secret_key: 'MY_SECRET_KEY'
|
63
|
-
})
|
58
|
+
This will yield a request with the following query string:
|
64
59
|
|
65
|
-
|
60
|
+
...&tags[0].key=type&tags[0].name=type&tags[0].value=community
|
66
61
|
|
67
|
-
|
62
|
+
### Configurable Logger
|
68
63
|
|
69
64
|
StackerBee::Client.logger = Rails.logger
|
70
65
|
|
71
|
-
Or
|
66
|
+
Or
|
72
67
|
|
73
|
-
|
74
|
-
logger: Rails.logger
|
75
|
-
})
|
68
|
+
StackerBee::Client.logger = Logger.new
|
76
69
|
|
77
|
-
|
70
|
+
### Configurable API Version
|
78
71
|
|
79
|
-
|
72
|
+
By default, StackerBee uses the CloudStack 4.2 API, but it doesn't have to.
|
73
|
+
Use a different API version by setting the `api_path` configuration option to the path of a JSON file containing the response from your CloudStack instance's `listApis` command.
|
80
74
|
|
81
|
-
|
75
|
+
StackerBee::Client.api_path = '/path/to/your/listApis/response.json'
|
76
|
+
|
77
|
+
### CloudStack REPL
|
82
78
|
|
83
79
|
Usage:
|
84
80
|
|
85
81
|
$ stacker_bee [OPTIONS]
|
86
82
|
|
87
|
-
|
83
|
+
Example:
|
88
84
|
|
89
85
|
$ stacker_bee -u http://localhost:8080/client/api -a MY_API_KEY -s MY_SECRET_KEY
|
90
86
|
StackerBee CloudStack REPL
|
@@ -95,17 +91,110 @@ Examples:
|
|
95
91
|
...
|
96
92
|
>>
|
97
93
|
|
94
|
+
## Configuration
|
95
|
+
|
96
|
+
Configuring a client:
|
97
|
+
|
98
|
+
cloud_stack = StackerBee::Client.new(
|
99
|
+
url: 'http://localhost:8080/client/api'
|
100
|
+
api_key: 'API_KEY',
|
101
|
+
secret_key: 'SECRET_KEY',
|
102
|
+
logger: Rails.logger
|
103
|
+
)
|
104
|
+
|
105
|
+
All configuration parameters set on the `StackerBee::Client` class are used as defaults for `StackerBee::Client` instances.
|
106
|
+
|
107
|
+
StackerBee::Client.url = 'http://localhost:8080/client/api'
|
108
|
+
StackerBee::Client.logger = Rails.logger
|
109
|
+
|
110
|
+
user_client = StackerBee::Client.new(
|
111
|
+
api_key: 'USER_API_KEY',
|
112
|
+
secret_key: 'USER_SECRET_KEY'
|
113
|
+
)
|
114
|
+
|
115
|
+
root_client = StackerBee::Client.new(
|
116
|
+
api_key: 'ROOT_API_KEY',
|
117
|
+
secret_key: 'ROOT_SECRET_KEY'
|
118
|
+
)
|
119
|
+
|
120
|
+
### URL
|
121
|
+
|
122
|
+
The URL of your CloudStack instance's URL.
|
123
|
+
|
124
|
+
StackerBee::Client.url = 'http://localhost:8080/client/api'
|
125
|
+
|
126
|
+
Or:
|
127
|
+
|
128
|
+
my_client = StackerBee::Client.new(
|
129
|
+
url: 'http://localhost:8080/client/api'
|
130
|
+
)
|
131
|
+
|
132
|
+
### Keys
|
133
|
+
|
134
|
+
Your CloudStack credentials, i.e. API key and secret key.
|
135
|
+
|
136
|
+
StackerBee::Client.api_key = 'MY_API_KEY'
|
137
|
+
StackerBee::Client.secret_key = 'MY_SECRET_KEY'
|
138
|
+
|
139
|
+
Or:
|
140
|
+
|
141
|
+
my_client = StackerBee::Client.new(
|
142
|
+
api_key: 'MY_API_KEY',
|
143
|
+
secret_key: 'MY_SECRET_KEY'
|
144
|
+
)
|
145
|
+
|
146
|
+
### Logger
|
147
|
+
|
148
|
+
StackerBee can be configured with a custom `Logger`.
|
149
|
+
|
150
|
+
StackerBee::Client.logger = Logger.new
|
151
|
+
|
152
|
+
Or
|
153
|
+
|
154
|
+
my_client = StackerBee::Client.new(
|
155
|
+
logger: Logger.new
|
156
|
+
)
|
157
|
+
|
158
|
+
For Rails apps, it's sometimes convenient to use Rail's logger:
|
159
|
+
|
160
|
+
StackerBee::Client.logger = Rails.logger
|
161
|
+
|
162
|
+
### Bulk Configuration
|
163
|
+
|
164
|
+
The `StackerBee::Client` class can be configured with multiple options at once.
|
165
|
+
|
166
|
+
StackerBee::Client.default_config = {
|
167
|
+
url: 'http://localhost:8080/client/api',
|
168
|
+
logger: Rails.logger,
|
169
|
+
api_key: 'API_KEY',
|
170
|
+
secret_key: 'MY_SECRET_KEY'
|
171
|
+
}
|
172
|
+
|
98
173
|
## Contributing
|
99
174
|
|
175
|
+
### Testing
|
176
|
+
|
100
177
|
Running the tests:
|
101
178
|
|
102
|
-
$ rake
|
179
|
+
$ bundle exec rake
|
180
|
+
|
181
|
+
### Testing against CloudStack
|
103
182
|
|
104
|
-
To interact with a real CloudStack server:
|
183
|
+
To interact with a real CloudStack server, instead of the recorded responses:
|
105
184
|
|
106
185
|
$ cp config.default.yml config.yml
|
107
186
|
|
108
|
-
And edit `config.yml`, specifying the URL and credentials for your CloudStack server. This file is ignored by git.
|
187
|
+
And edit `config.yml`, specifying the URL and credentials for your CloudStack server. This file is used by the test suite if it exists, but is ignored by git.
|
188
|
+
|
189
|
+
### Coding Style
|
190
|
+
|
191
|
+
This project uses [Rubocop](https://github.com/bbatsov/rubocop) to enforce code style.
|
192
|
+
|
193
|
+
$ bundle exec rubocop
|
194
|
+
|
195
|
+
## Thanks to
|
196
|
+
|
197
|
+
- [Chip Childers](http://github.com/chipchilders) for a [reference implementation of a CloudStack client in Ruby](http://chipchilders.github.io/cloudstack_ruby_client/)
|
109
198
|
|
110
199
|
## License
|
111
200
|
|
data/lib/stacker_bee.rb
CHANGED
@@ -1,16 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require_relative path
|
4
|
-
end
|
5
|
-
else # for 1.8.7
|
6
|
-
lambda do |path|
|
7
|
-
require "stacker_bee/#{path}"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
%w(
|
12
|
-
version
|
13
|
-
client
|
14
|
-
).each do |file_name|
|
15
|
-
require_stacker_bee["stacker_bee/#{file_name}"]
|
16
|
-
end
|
1
|
+
require_relative "stacker_bee/version"
|
2
|
+
require_relative "stacker_bee/client"
|
data/lib/stacker_bee/client.rb
CHANGED
@@ -3,6 +3,7 @@ require "stacker_bee/configuration"
|
|
3
3
|
require "stacker_bee/api"
|
4
4
|
require "stacker_bee/connection"
|
5
5
|
require "stacker_bee/request"
|
6
|
+
require "stacker_bee/dictionary_flattener"
|
6
7
|
require "stacker_bee/response"
|
7
8
|
|
8
9
|
module StackerBee
|
@@ -23,7 +24,6 @@ module StackerBee
|
|
23
24
|
:secret_key=
|
24
25
|
|
25
26
|
class << self
|
26
|
-
|
27
27
|
def reset!
|
28
28
|
@api, @api_path, @default_config = nil
|
29
29
|
end
|
@@ -66,7 +66,7 @@ module StackerBee
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def request(endpoint_name, params = {})
|
69
|
-
request
|
69
|
+
request = Request.new(endpoint_for(endpoint_name), api_key, params)
|
70
70
|
request.allow_empty_string_params =
|
71
71
|
configuration.allow_empty_string_params
|
72
72
|
raw_response = connection.get(request)
|
@@ -2,6 +2,7 @@ require "faraday"
|
|
2
2
|
require "uri"
|
3
3
|
require "stacker_bee/middleware/signed_query"
|
4
4
|
require "stacker_bee/middleware/logger"
|
5
|
+
require "stacker_bee/middleware/detokenizer"
|
5
6
|
|
6
7
|
module StackerBee
|
7
8
|
class ConnectionError < Exception
|
@@ -9,15 +10,21 @@ module StackerBee
|
|
9
10
|
|
10
11
|
class Connection
|
11
12
|
attr_accessor :configuration
|
13
|
+
|
12
14
|
def initialize(configuration)
|
13
15
|
@configuration = configuration
|
14
16
|
uri = URI.parse(self.configuration.url)
|
15
17
|
@path = uri.path
|
16
18
|
uri.path = ''
|
17
19
|
fail ConnectionError, "no protocol specified" unless uri.scheme
|
20
|
+
initialize_faraday(uri)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize_faraday(uri)
|
18
24
|
@faraday = Faraday.new(url: uri.to_s) do |faraday|
|
19
|
-
faraday.use Middleware::
|
20
|
-
faraday.use Middleware::
|
25
|
+
faraday.use Middleware::Detokenizer
|
26
|
+
faraday.use Middleware::SignedQuery, configuration.secret_key
|
27
|
+
faraday.use Middleware::Logger, configuration.logger
|
21
28
|
faraday.adapter Faraday.default_adapter # Net::HTTP
|
22
29
|
end
|
23
30
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module StackerBee
|
2
|
+
class DictionaryFlattener
|
3
|
+
LB = "SBLEFTBRACKET"
|
4
|
+
RB = "SBRIGHTBRACKET"
|
5
|
+
|
6
|
+
attr_accessor :params
|
7
|
+
|
8
|
+
def self.tokenize(key)
|
9
|
+
key.gsub(/\[/, LB).gsub(/\]/, RB)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.detokenize(key)
|
13
|
+
key.gsub(/#{LB}/, "[").gsub(/#{RB}/, "]")
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(params)
|
17
|
+
@params = params.dup
|
18
|
+
flatten_params
|
19
|
+
end
|
20
|
+
|
21
|
+
def flatten_params
|
22
|
+
hashes = params.select { |key, 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 |outer|
|
28
|
+
remove_empties(outer[1]).each_with_index do |array, index|
|
29
|
+
key = self.class.tokenize("#{outer[0]}[#{index}]")
|
30
|
+
params["#{key}.key"] = params["#{key}.name"] = array[0]
|
31
|
+
params["#{key}.value"] = array[1]
|
32
|
+
end
|
33
|
+
params.delete outer[0]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_empties(hash)
|
38
|
+
hash.reject{ |k, v| v.nil? || v == "" }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require "base64"
|
3
|
+
|
4
|
+
module StackerBee
|
5
|
+
module Middleware
|
6
|
+
class Detokenizer < Faraday::Middleware
|
7
|
+
def call(env)
|
8
|
+
detokenize(env[:url])
|
9
|
+
@app.call(env)
|
10
|
+
end
|
11
|
+
|
12
|
+
def detokenize(uri)
|
13
|
+
uri.query = StackerBee::DictionaryFlattener.detokenize uri.query
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "forwardable"
|
2
|
+
require "logger"
|
3
|
+
require "pp"
|
4
4
|
|
5
5
|
module StackerBee
|
6
6
|
module Middleware
|
@@ -42,7 +42,6 @@ module StackerBee
|
|
42
42
|
debug env[:response_headers].pretty_inspect
|
43
43
|
debug env[:body]
|
44
44
|
end
|
45
|
-
|
46
45
|
end
|
47
46
|
end
|
48
47
|
end
|
data/lib/stacker_bee/rash.rb
CHANGED
data/lib/stacker_bee/request.rb
CHANGED
@@ -6,21 +6,26 @@ module StackerBee
|
|
6
6
|
|
7
7
|
RESPONSE_TYPE = "json"
|
8
8
|
|
9
|
-
attr_accessor :params
|
10
9
|
attr_writer :allow_empty_string_params
|
10
|
+
attr_accessor :endpoint, :api_key
|
11
11
|
|
12
12
|
def initialize(endpoint, api_key, params = {})
|
13
|
-
params
|
14
|
-
|
15
|
-
|
16
|
-
self.params = params
|
13
|
+
@params = params
|
14
|
+
self.endpoint = endpoint
|
15
|
+
self.api_key = api_key
|
17
16
|
end
|
18
17
|
|
19
18
|
def query_params
|
20
|
-
params
|
19
|
+
flat_params = DictionaryFlattener.new(@params).params
|
20
|
+
|
21
|
+
flat_params[:api_key] = api_key
|
22
|
+
flat_params[:command] = endpoint
|
23
|
+
flat_params[:response] = RESPONSE_TYPE
|
24
|
+
|
25
|
+
flat_params
|
21
26
|
.reject { |key, val| val.nil? }
|
22
27
|
.reject { |key, val| !allow_empty_string_params && val == '' }
|
23
|
-
.
|
28
|
+
.sort_by { |key, val| key.to_s }
|
24
29
|
.map { |(key, val)| [cloud_stack_key(key), cloud_stack_value(val)] }
|
25
30
|
end
|
26
31
|
|
data/lib/stacker_bee/response.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
module StackerBee
|
2
2
|
module Utilities
|
3
|
+
REGEX = /\s|-|_/
|
4
|
+
|
3
5
|
def uncase(string)
|
4
|
-
string.to_s.downcase.gsub(
|
6
|
+
string.to_s.downcase.gsub(REGEX, '')
|
5
7
|
end
|
6
8
|
|
7
9
|
def snake_case(string)
|
@@ -9,7 +11,7 @@ module StackerBee
|
|
9
11
|
end
|
10
12
|
|
11
13
|
def camel_case(string, lower = false)
|
12
|
-
string.to_s.split(
|
14
|
+
string.to_s.split(REGEX).each_with_object('') do |word, memo|
|
13
15
|
memo << (memo.empty? && lower ? word[0].downcase : word[0].upcase)
|
14
16
|
memo << word[1..-1]
|
15
17
|
end
|
data/lib/stacker_bee/version.rb
CHANGED
@@ -0,0 +1,183 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=listZones&response=json&signature=/MnHgTBKGc%2BXx0Z8KwMllvw92vg=
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.8.8
|
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
|
+
- '403'
|
25
|
+
Server:
|
26
|
+
- Jetty(6.1.26)
|
27
|
+
body:
|
28
|
+
encoding: UTF-8
|
29
|
+
string: '{ "listzonesresponse" : { "count":1 ,"zone" : [ {"id":"39e9e31e-925c-4b55-8d33-f99912b73dfc","name":"Sandbox-simulator","dns1":"10.147.28.6","internaldns1":"10.147.28.6","guestcidraddress":"10.1.1.0/24","networktype":"Advanced","securitygroupsenabled":false,"allocationstate":"Enabled","zonetoken":"ea3acbc4-cae8-3b82-b42f-7492ddfede00","dhcpprovider":"VirtualRouter","localstorageenabled":false}
|
30
|
+
] } }'
|
31
|
+
http_version:
|
32
|
+
recorded_at: Thu, 19 Dec 2013 17:34:44 GMT
|
33
|
+
- request:
|
34
|
+
method: get
|
35
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=listNetworkOfferings&response=json&signature=BAdYatJ5Rjcffi6sU8P%2BZtLhSF8=&supportedServices=sourcenat&type=isolated
|
36
|
+
body:
|
37
|
+
encoding: US-ASCII
|
38
|
+
string: ''
|
39
|
+
headers:
|
40
|
+
User-Agent:
|
41
|
+
- Faraday v0.8.8
|
42
|
+
Accept-Encoding:
|
43
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
44
|
+
Accept:
|
45
|
+
- '*/*'
|
46
|
+
response:
|
47
|
+
status:
|
48
|
+
code: 200
|
49
|
+
message: OK
|
50
|
+
headers:
|
51
|
+
Content-Type:
|
52
|
+
- text/javascript; charset=UTF-8
|
53
|
+
Content-Length:
|
54
|
+
- '6006'
|
55
|
+
Server:
|
56
|
+
- Jetty(6.1.26)
|
57
|
+
body:
|
58
|
+
encoding: UTF-8
|
59
|
+
string: '{ "listnetworkofferingsresponse" : { "count":4 ,"networkoffering" :
|
60
|
+
[ {"id":"fa126319-f822-4786-9cd3-30bd0c55ca94","name":"DefaultIsolatedNetworkOfferingWithSourceNatService","displaytext":"Offering
|
61
|
+
for Isolated networks with Source Nat service enabled","traffictype":"Guest","isdefault":true,"specifyvlan":false,"conservemode":true,"specifyipranges":false,"availability":"Required","networkrate":200,"state":"Enabled","guestiptype":"Isolated","serviceofferingid":"983410fa-b51b-439c-b8ba-be973804c38f","service":[{"name":"PortForwarding","provider":[{"name":"VirtualRouter"}]},{"name":"StaticNat","provider":[{"name":"VirtualRouter"}],"capability":[{"name":"ElasticIp","value":"false","canchooseservicecapability":false},{"name":"AssociatePublicIP","value":"true","canchooseservicecapability":false}]},{"name":"Dhcp","provider":[{"name":"VirtualRouter"}]},{"name":"Firewall","provider":[{"name":"VirtualRouter"}]},{"name":"Lb","provider":[{"name":"VirtualRouter"}],"capability":[{"name":"SupportedLBIsolation","value":"dedicated","canchooseservicecapability":false},{"name":"ElasticLb","value":"false","canchooseservicecapability":false},{"name":"InlineMode","value":"false","canchooseservicecapability":false}]},{"name":"UserData","provider":[{"name":"VirtualRouter"}]},{"name":"Dns","provider":[{"name":"VirtualRouter"}]},{"name":"SourceNat","provider":[{"name":"VirtualRouter"}],"capability":[{"name":"SupportedSourceNatTypes","value":"peraccount","canchooseservicecapability":false},{"name":"RedundantRouter","value":"false","canchooseservicecapability":false}]},{"name":"Vpn","provider":[{"name":"VirtualRouter"}]}],"forvpc":false,"ispersistent":false,"egressdefaultpolicy":false},
|
62
|
+
{"id":"7e70b3b5-5e2c-42cb-9b49-93a87c13a675","name":"DefaultIsolatedNetworkOfferingForVpcNetworks","displaytext":"Offering
|
63
|
+
for Isolated Vpc networks with Source Nat service enabled","traffictype":"Guest","isdefault":true,"specifyvlan":false,"conservemode":false,"specifyipranges":false,"availability":"Optional","networkrate":200,"state":"Enabled","guestiptype":"Isolated","serviceofferingid":"983410fa-b51b-439c-b8ba-be973804c38f","service":[{"name":"PortForwarding","provider":[{"name":"VpcVirtualRouter"}]},{"name":"StaticNat","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"ElasticIp","value":"false","canchooseservicecapability":false},{"name":"AssociatePublicIP","value":"true","canchooseservicecapability":false}]},{"name":"Dhcp","provider":[{"name":"VpcVirtualRouter"}]},{"name":"NetworkACL","provider":[{"name":"VpcVirtualRouter"}]},{"name":"Lb","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"SupportedLBIsolation","value":"dedicated","canchooseservicecapability":false},{"name":"ElasticLb","value":"false","canchooseservicecapability":false},{"name":"InlineMode","value":"false","canchooseservicecapability":false}]},{"name":"UserData","provider":[{"name":"VpcVirtualRouter"}]},{"name":"Dns","provider":[{"name":"VpcVirtualRouter"}]},{"name":"SourceNat","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"SupportedSourceNatTypes","value":"peraccount","canchooseservicecapability":false},{"name":"RedundantRouter","value":"false","canchooseservicecapability":false}]},{"name":"Vpn","provider":[{"name":"VpcVirtualRouter"}]}],"forvpc":true,"ispersistent":false,"egressdefaultpolicy":false},
|
64
|
+
{"id":"a9d78d52-f306-44c5-bb6d-c121a507db05","name":"DefaultIsolatedNetworkOfferingForVpcNetworksNoLB","displaytext":"Offering
|
65
|
+
for Isolated Vpc networks with Source Nat service enabled and LB service Disabled","traffictype":"Guest","isdefault":true,"specifyvlan":false,"conservemode":false,"specifyipranges":false,"availability":"Optional","networkrate":200,"state":"Enabled","guestiptype":"Isolated","serviceofferingid":"983410fa-b51b-439c-b8ba-be973804c38f","service":[{"name":"PortForwarding","provider":[{"name":"VpcVirtualRouter"}]},{"name":"StaticNat","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"ElasticIp","value":"false","canchooseservicecapability":false},{"name":"AssociatePublicIP","value":"true","canchooseservicecapability":false}]},{"name":"Dhcp","provider":[{"name":"VpcVirtualRouter"}]},{"name":"NetworkACL","provider":[{"name":"VpcVirtualRouter"}]},{"name":"UserData","provider":[{"name":"VpcVirtualRouter"}]},{"name":"Dns","provider":[{"name":"VpcVirtualRouter"}]},{"name":"SourceNat","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"SupportedSourceNatTypes","value":"peraccount","canchooseservicecapability":false},{"name":"RedundantRouter","value":"false","canchooseservicecapability":false}]},{"name":"Vpn","provider":[{"name":"VpcVirtualRouter"}]}],"forvpc":true,"ispersistent":false,"egressdefaultpolicy":false},
|
66
|
+
{"id":"f9a7b0d0-ce61-4f8d-a360-be1040d67287","name":"DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB","displaytext":"Offering
|
67
|
+
for Isolated Vpc networks with Internal LB support","traffictype":"Guest","isdefault":true,"specifyvlan":false,"conservemode":false,"specifyipranges":false,"availability":"Optional","networkrate":200,"state":"Enabled","guestiptype":"Isolated","serviceofferingid":"983410fa-b51b-439c-b8ba-be973804c38f","service":[{"name":"Dhcp","provider":[{"name":"VpcVirtualRouter"}]},{"name":"NetworkACL","provider":[{"name":"VpcVirtualRouter"}]},{"name":"Lb","provider":[{"name":"InternalLbVm"}],"capability":[{"name":"SupportedLBIsolation","value":"dedicated","canchooseservicecapability":false},{"name":"ElasticLb","value":"false","canchooseservicecapability":false},{"name":"InlineMode","value":"false","canchooseservicecapability":false}]},{"name":"UserData","provider":[{"name":"VpcVirtualRouter"}]},{"name":"Dns","provider":[{"name":"VpcVirtualRouter"}]},{"name":"SourceNat","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"SupportedSourceNatTypes","value":"peraccount","canchooseservicecapability":false},{"name":"RedundantRouter","value":"false","canchooseservicecapability":false}]}],"forvpc":true,"ispersistent":false,"egressdefaultpolicy":false}
|
68
|
+
] } }'
|
69
|
+
http_version:
|
70
|
+
recorded_at: Thu, 19 Dec 2013 17:34:44 GMT
|
71
|
+
- request:
|
72
|
+
method: get
|
73
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=createNetwork&displaytext=John&name=John&networkOfferingId=fa126319-f822-4786-9cd3-30bd0c55ca94&response=json&signature=UDcfFqlzwpHJib/9kLKzR0%2BCbyc=&zoneId=39e9e31e-925c-4b55-8d33-f99912b73dfc
|
74
|
+
body:
|
75
|
+
encoding: US-ASCII
|
76
|
+
string: ''
|
77
|
+
headers:
|
78
|
+
User-Agent:
|
79
|
+
- Faraday v0.8.8
|
80
|
+
Accept-Encoding:
|
81
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
82
|
+
Accept:
|
83
|
+
- '*/*'
|
84
|
+
response:
|
85
|
+
status:
|
86
|
+
code: 200
|
87
|
+
message: OK
|
88
|
+
headers:
|
89
|
+
Content-Type:
|
90
|
+
- text/javascript; charset=UTF-8
|
91
|
+
Content-Length:
|
92
|
+
- '4441'
|
93
|
+
Server:
|
94
|
+
- Jetty(6.1.26)
|
95
|
+
body:
|
96
|
+
encoding: UTF-8
|
97
|
+
string: '{ "createnetworkresponse" : { "network" : {"id":"18772181-9674-4a30-81e7-99ebb6a5baed","name":"John","displaytext":"John","broadcastdomaintype":"Vlan","traffictype":"Guest","gateway":"10.1.1.1","netmask":"255.255.255.0","cidr":"10.1.1.0/24","zoneid":"39e9e31e-925c-4b55-8d33-f99912b73dfc","zonename":"Sandbox-simulator","networkofferingid":"fa126319-f822-4786-9cd3-30bd0c55ca94","networkofferingname":"DefaultIsolatedNetworkOfferingWithSourceNatService","networkofferingdisplaytext":"Offering
|
98
|
+
for Isolated networks with Source Nat service enabled","networkofferingconservemode":true,"networkofferingavailability":"Required","issystem":false,"state":"Allocated","related":"18772181-9674-4a30-81e7-99ebb6a5baed","dns1":"10.147.28.6","type":"Isolated","acltype":"Account","account":"admin","domainid":"ce4585b8-41f5-11e3-aaa7-d6558ad1fb9f","domain":"ROOT","service":[{"name":"PortForwarding"},{"name":"StaticNat"},{"name":"Dhcp","capability":[{"name":"DhcpAccrossMultipleSubnets","value":"true","canchooseservicecapability":false}]},{"name":"Firewall","capability":[{"name":"TrafficStatistics","value":"per
|
99
|
+
public ip","canchooseservicecapability":false},{"name":"SupportedTrafficDirection","value":"ingress,
|
100
|
+
egress","canchooseservicecapability":false},{"name":"SupportedEgressProtocols","value":"tcp,udp,icmp,
|
101
|
+
all","canchooseservicecapability":false},{"name":"SupportedProtocols","value":"tcp,udp,icmp","canchooseservicecapability":false},{"name":"MultipleIps","value":"true","canchooseservicecapability":false}]},{"name":"Lb","capability":[{"name":"SupportedLbAlgorithms","value":"roundrobin,leastconn,source","canchooseservicecapability":false},{"name":"SupportedLBIsolation","value":"dedicated","canchooseservicecapability":false},{"name":"SupportedStickinessMethods","value":"[{\"methodname\":\"LbCookie\",\"paramlist\":[{\"paramname\":\"cookie-name\",\"required\":false,\"isflag\":false,\"description\":\"
|
102
|
+
\"},{\"paramname\":\"mode\",\"required\":false,\"isflag\":false,\"description\":\"
|
103
|
+
\"},{\"paramname\":\"nocache\",\"required\":false,\"isflag\":true,\"description\":\"
|
104
|
+
\"},{\"paramname\":\"indirect\",\"required\":false,\"isflag\":true,\"description\":\"
|
105
|
+
\"},{\"paramname\":\"postonly\",\"required\":false,\"isflag\":true,\"description\":\"
|
106
|
+
\"},{\"paramname\":\"domain\",\"required\":false,\"isflag\":false,\"description\":\"
|
107
|
+
\"}],\"description\":\"This is loadbalancer cookie based stickiness method.\"},{\"methodname\":\"AppCookie\",\"paramlist\":[{\"paramname\":\"cookie-name\",\"required\":false,\"isflag\":false,\"description\":\"
|
108
|
+
\"},{\"paramname\":\"length\",\"required\":false,\"isflag\":false,\"description\":\"
|
109
|
+
\"},{\"paramname\":\"holdtime\",\"required\":false,\"isflag\":false,\"description\":\"
|
110
|
+
\"},{\"paramname\":\"request-learn\",\"required\":false,\"isflag\":true,\"description\":\"
|
111
|
+
\"},{\"paramname\":\"prefix\",\"required\":false,\"isflag\":true,\"description\":\"
|
112
|
+
\"},{\"paramname\":\"mode\",\"required\":false,\"isflag\":false,\"description\":\"
|
113
|
+
\"}],\"description\":\"This is App session based sticky method. Define session
|
114
|
+
stickiness on an existing application cookie. It can be used only for a specific
|
115
|
+
http traffic\"},{\"methodname\":\"SourceBased\",\"paramlist\":[{\"paramname\":\"tablesize\",\"required\":false,\"isflag\":false,\"description\":\"
|
116
|
+
\"},{\"paramname\":\"expire\",\"required\":false,\"isflag\":false,\"description\":\"
|
117
|
+
\"}],\"description\":\"This is source based Stickiness method, it can be used
|
118
|
+
for any type of protocol.\"}]","canchooseservicecapability":false},{"name":"LbSchemes","value":"Public","canchooseservicecapability":false},{"name":"SupportedProtocols","value":"tcp,
|
119
|
+
udp","canchooseservicecapability":false}]},{"name":"UserData"},{"name":"Dns","capability":[{"name":"AllowDnsSuffixModification","value":"true","canchooseservicecapability":false}]},{"name":"SourceNat","capability":[{"name":"RedundantRouter","value":"true","canchooseservicecapability":false},{"name":"SupportedSourceNatTypes","value":"peraccount","canchooseservicecapability":false}]},{"name":"Vpn","capability":[{"name":"SupportedVpnTypes","value":"pptp,l2tp,ipsec","canchooseservicecapability":false},{"name":"VpnTypes","value":"removeaccessvpn","canchooseservicecapability":false}]}],"networkdomain":"cs2sandbox.simulator","physicalnetworkid":"46d08659-81e9-4f31-a589-a15aca972af0","restartrequired":false,"specifyipranges":false,"canusefordeploy":true,"ispersistent":false,"tags":[],"displaynetwork":true}
|
120
|
+
} }'
|
121
|
+
http_version:
|
122
|
+
recorded_at: Thu, 19 Dec 2013 17:34:44 GMT
|
123
|
+
- request:
|
124
|
+
method: get
|
125
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=createTags&resourceIds=18772181-9674-4a30-81e7-99ebb6a5baed&resourceType=Network&response=json&signature=xFXocwxqx4V1VH1EGVtjwdGZ0Yw=&tags%5B0%5D%5B%7D.key%5D=speed%20%5Blab%5D&tags%5B0%5D%5B%7D.name%5D=speed%20%5Blab%5D&tags%5B0%5D%5B%7D.value%5D=real%20fast!
|
126
|
+
body:
|
127
|
+
encoding: US-ASCII
|
128
|
+
string: ''
|
129
|
+
headers:
|
130
|
+
User-Agent:
|
131
|
+
- Faraday v0.8.8
|
132
|
+
Accept-Encoding:
|
133
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
134
|
+
Accept:
|
135
|
+
- '*/*'
|
136
|
+
response:
|
137
|
+
status:
|
138
|
+
code: 401
|
139
|
+
message: Unauthorized
|
140
|
+
headers:
|
141
|
+
Content-Type:
|
142
|
+
- text/javascript; charset=UTF-8
|
143
|
+
Content-Length:
|
144
|
+
- '131'
|
145
|
+
Server:
|
146
|
+
- Jetty(6.1.26)
|
147
|
+
body:
|
148
|
+
encoding: UTF-8
|
149
|
+
string: '{ "createtagsresponse" : {"uuidList":[],"errorcode":401,"errortext":"unable
|
150
|
+
to verify user credentials and/or request signature"} }'
|
151
|
+
http_version:
|
152
|
+
recorded_at: Thu, 19 Dec 2013 17:34:44 GMT
|
153
|
+
- request:
|
154
|
+
method: get
|
155
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=createTags&resourceIds=18772181-9674-4a30-81e7-99ebb6a5baed&resourceType=Network&response=json&signature=IqPennOpZ2NWFlJIBomJG9Ys9Zg=&tags%5B0%5D%5B.key%5D=speed%20%5Blab%5D&tags%5B0%5D%5B.name%5D=speed%20%5Blab%5D&tags%5B0%5D%5B.value%5D=real%20fast!
|
156
|
+
body:
|
157
|
+
encoding: US-ASCII
|
158
|
+
string: ''
|
159
|
+
headers:
|
160
|
+
User-Agent:
|
161
|
+
- Faraday v0.8.8
|
162
|
+
Accept-Encoding:
|
163
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
164
|
+
Accept:
|
165
|
+
- '*/*'
|
166
|
+
response:
|
167
|
+
status:
|
168
|
+
code: 200
|
169
|
+
message: OK
|
170
|
+
headers:
|
171
|
+
Content-Type:
|
172
|
+
- text/javascript; charset=UTF-8
|
173
|
+
Content-Length:
|
174
|
+
- '75'
|
175
|
+
Server:
|
176
|
+
- Jetty(6.1.26)
|
177
|
+
body:
|
178
|
+
encoding: UTF-8
|
179
|
+
string: '{ "createtagsresponse" : {"jobid":"7f37bba8-dd8e-4ba2-b5a4-bb97f3cf0cab"}
|
180
|
+
}'
|
181
|
+
http_version:
|
182
|
+
recorded_at: Thu, 19 Dec 2013 17:42:02 GMT
|
183
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,153 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=listZones&response=json&signature=/MnHgTBKGc%2BXx0Z8KwMllvw92vg=
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.8.8
|
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
|
+
- '403'
|
25
|
+
Server:
|
26
|
+
- Jetty(6.1.26)
|
27
|
+
body:
|
28
|
+
encoding: US-ASCII
|
29
|
+
string: ! '{ "listzonesresponse" : { "count":1 ,"zone" : [ {"id":"39e9e31e-925c-4b55-8d33-f99912b73dfc","name":"Sandbox-simulator","dns1":"10.147.28.6","internaldns1":"10.147.28.6","guestcidraddress":"10.1.1.0/24","networktype":"Advanced","securitygroupsenabled":false,"allocationstate":"Enabled","zonetoken":"ea3acbc4-cae8-3b82-b42f-7492ddfede00","dhcpprovider":"VirtualRouter","localstorageenabled":false}
|
30
|
+
] } }'
|
31
|
+
http_version:
|
32
|
+
recorded_at: Wed, 18 Dec 2013 21:25:06 GMT
|
33
|
+
- request:
|
34
|
+
method: get
|
35
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=listNetworkOfferings&response=json&signature=BAdYatJ5Rjcffi6sU8P%2BZtLhSF8=&supportedServices=sourcenat&type=isolated
|
36
|
+
body:
|
37
|
+
encoding: US-ASCII
|
38
|
+
string: ''
|
39
|
+
headers:
|
40
|
+
User-Agent:
|
41
|
+
- Faraday v0.8.8
|
42
|
+
Accept-Encoding:
|
43
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
44
|
+
Accept:
|
45
|
+
- ! '*/*'
|
46
|
+
response:
|
47
|
+
status:
|
48
|
+
code: 200
|
49
|
+
message: OK
|
50
|
+
headers:
|
51
|
+
Content-Type:
|
52
|
+
- text/javascript; charset=UTF-8
|
53
|
+
Content-Length:
|
54
|
+
- '6006'
|
55
|
+
Server:
|
56
|
+
- Jetty(6.1.26)
|
57
|
+
body:
|
58
|
+
encoding: US-ASCII
|
59
|
+
string: ! '{ "listnetworkofferingsresponse" : { "count":4 ,"networkoffering"
|
60
|
+
: [ {"id":"fa126319-f822-4786-9cd3-30bd0c55ca94","name":"DefaultIsolatedNetworkOfferingWithSourceNatService","displaytext":"Offering
|
61
|
+
for Isolated networks with Source Nat service enabled","traffictype":"Guest","isdefault":true,"specifyvlan":false,"conservemode":true,"specifyipranges":false,"availability":"Required","networkrate":200,"state":"Enabled","guestiptype":"Isolated","serviceofferingid":"983410fa-b51b-439c-b8ba-be973804c38f","service":[{"name":"SourceNat","provider":[{"name":"VirtualRouter"}],"capability":[{"name":"SupportedSourceNatTypes","value":"peraccount","canchooseservicecapability":false},{"name":"RedundantRouter","value":"false","canchooseservicecapability":false}]},{"name":"Dns","provider":[{"name":"VirtualRouter"}]},{"name":"UserData","provider":[{"name":"VirtualRouter"}]},{"name":"PortForwarding","provider":[{"name":"VirtualRouter"}]},{"name":"Firewall","provider":[{"name":"VirtualRouter"}]},{"name":"Lb","provider":[{"name":"VirtualRouter"}],"capability":[{"name":"SupportedLBIsolation","value":"dedicated","canchooseservicecapability":false},{"name":"ElasticLb","value":"false","canchooseservicecapability":false},{"name":"InlineMode","value":"false","canchooseservicecapability":false}]},{"name":"Dhcp","provider":[{"name":"VirtualRouter"}]},{"name":"Vpn","provider":[{"name":"VirtualRouter"}]},{"name":"StaticNat","provider":[{"name":"VirtualRouter"}],"capability":[{"name":"ElasticIp","value":"false","canchooseservicecapability":false},{"name":"AssociatePublicIP","value":"true","canchooseservicecapability":false}]}],"forvpc":false,"ispersistent":false,"egressdefaultpolicy":false},
|
62
|
+
{"id":"7e70b3b5-5e2c-42cb-9b49-93a87c13a675","name":"DefaultIsolatedNetworkOfferingForVpcNetworks","displaytext":"Offering
|
63
|
+
for Isolated Vpc networks with Source Nat service enabled","traffictype":"Guest","isdefault":true,"specifyvlan":false,"conservemode":false,"specifyipranges":false,"availability":"Optional","networkrate":200,"state":"Enabled","guestiptype":"Isolated","serviceofferingid":"983410fa-b51b-439c-b8ba-be973804c38f","service":[{"name":"SourceNat","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"SupportedSourceNatTypes","value":"peraccount","canchooseservicecapability":false},{"name":"RedundantRouter","value":"false","canchooseservicecapability":false}]},{"name":"Dns","provider":[{"name":"VpcVirtualRouter"}]},{"name":"UserData","provider":[{"name":"VpcVirtualRouter"}]},{"name":"PortForwarding","provider":[{"name":"VpcVirtualRouter"}]},{"name":"Lb","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"SupportedLBIsolation","value":"dedicated","canchooseservicecapability":false},{"name":"ElasticLb","value":"false","canchooseservicecapability":false},{"name":"InlineMode","value":"false","canchooseservicecapability":false}]},{"name":"Dhcp","provider":[{"name":"VpcVirtualRouter"}]},{"name":"Vpn","provider":[{"name":"VpcVirtualRouter"}]},{"name":"StaticNat","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"ElasticIp","value":"false","canchooseservicecapability":false},{"name":"AssociatePublicIP","value":"true","canchooseservicecapability":false}]},{"name":"NetworkACL","provider":[{"name":"VpcVirtualRouter"}]}],"forvpc":true,"ispersistent":false,"egressdefaultpolicy":false},
|
64
|
+
{"id":"a9d78d52-f306-44c5-bb6d-c121a507db05","name":"DefaultIsolatedNetworkOfferingForVpcNetworksNoLB","displaytext":"Offering
|
65
|
+
for Isolated Vpc networks with Source Nat service enabled and LB service Disabled","traffictype":"Guest","isdefault":true,"specifyvlan":false,"conservemode":false,"specifyipranges":false,"availability":"Optional","networkrate":200,"state":"Enabled","guestiptype":"Isolated","serviceofferingid":"983410fa-b51b-439c-b8ba-be973804c38f","service":[{"name":"SourceNat","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"SupportedSourceNatTypes","value":"peraccount","canchooseservicecapability":false},{"name":"RedundantRouter","value":"false","canchooseservicecapability":false}]},{"name":"Dns","provider":[{"name":"VpcVirtualRouter"}]},{"name":"UserData","provider":[{"name":"VpcVirtualRouter"}]},{"name":"PortForwarding","provider":[{"name":"VpcVirtualRouter"}]},{"name":"Dhcp","provider":[{"name":"VpcVirtualRouter"}]},{"name":"Vpn","provider":[{"name":"VpcVirtualRouter"}]},{"name":"StaticNat","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"ElasticIp","value":"false","canchooseservicecapability":false},{"name":"AssociatePublicIP","value":"true","canchooseservicecapability":false}]},{"name":"NetworkACL","provider":[{"name":"VpcVirtualRouter"}]}],"forvpc":true,"ispersistent":false,"egressdefaultpolicy":false},
|
66
|
+
{"id":"f9a7b0d0-ce61-4f8d-a360-be1040d67287","name":"DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB","displaytext":"Offering
|
67
|
+
for Isolated Vpc networks with Internal LB support","traffictype":"Guest","isdefault":true,"specifyvlan":false,"conservemode":false,"specifyipranges":false,"availability":"Optional","networkrate":200,"state":"Enabled","guestiptype":"Isolated","serviceofferingid":"983410fa-b51b-439c-b8ba-be973804c38f","service":[{"name":"SourceNat","provider":[{"name":"VpcVirtualRouter"}],"capability":[{"name":"SupportedSourceNatTypes","value":"peraccount","canchooseservicecapability":false},{"name":"RedundantRouter","value":"false","canchooseservicecapability":false}]},{"name":"Dns","provider":[{"name":"VpcVirtualRouter"}]},{"name":"UserData","provider":[{"name":"VpcVirtualRouter"}]},{"name":"Lb","provider":[{"name":"InternalLbVm"}],"capability":[{"name":"SupportedLBIsolation","value":"dedicated","canchooseservicecapability":false},{"name":"ElasticLb","value":"false","canchooseservicecapability":false},{"name":"InlineMode","value":"false","canchooseservicecapability":false}]},{"name":"Dhcp","provider":[{"name":"VpcVirtualRouter"}]},{"name":"NetworkACL","provider":[{"name":"VpcVirtualRouter"}]}],"forvpc":true,"ispersistent":false,"egressdefaultpolicy":false}
|
68
|
+
] } }'
|
69
|
+
http_version:
|
70
|
+
recorded_at: Wed, 18 Dec 2013 21:25:06 GMT
|
71
|
+
- request:
|
72
|
+
method: get
|
73
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=createNetwork&displaytext=John&name=John&networkOfferingId=fa126319-f822-4786-9cd3-30bd0c55ca94&response=json&signature=UDcfFqlzwpHJib/9kLKzR0%2BCbyc=&zoneId=39e9e31e-925c-4b55-8d33-f99912b73dfc
|
74
|
+
body:
|
75
|
+
encoding: US-ASCII
|
76
|
+
string: ''
|
77
|
+
headers:
|
78
|
+
User-Agent:
|
79
|
+
- Faraday v0.8.8
|
80
|
+
Accept-Encoding:
|
81
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
82
|
+
Accept:
|
83
|
+
- ! '*/*'
|
84
|
+
response:
|
85
|
+
status:
|
86
|
+
code: 200
|
87
|
+
message: OK
|
88
|
+
headers:
|
89
|
+
Content-Type:
|
90
|
+
- text/javascript; charset=UTF-8
|
91
|
+
Content-Length:
|
92
|
+
- '4441'
|
93
|
+
Server:
|
94
|
+
- Jetty(6.1.26)
|
95
|
+
body:
|
96
|
+
encoding: US-ASCII
|
97
|
+
string: ! '{ "createnetworkresponse" : { "network" : {"id":"02e5fd84-e9ea-49f7-ba6a-6d63ea23a27f","name":"John","displaytext":"John","broadcastdomaintype":"Vlan","traffictype":"Guest","gateway":"10.1.1.1","netmask":"255.255.255.0","cidr":"10.1.1.0/24","zoneid":"39e9e31e-925c-4b55-8d33-f99912b73dfc","zonename":"Sandbox-simulator","networkofferingid":"fa126319-f822-4786-9cd3-30bd0c55ca94","networkofferingname":"DefaultIsolatedNetworkOfferingWithSourceNatService","networkofferingdisplaytext":"Offering
|
98
|
+
for Isolated networks with Source Nat service enabled","networkofferingconservemode":true,"networkofferingavailability":"Required","issystem":false,"state":"Allocated","related":"02e5fd84-e9ea-49f7-ba6a-6d63ea23a27f","dns1":"10.147.28.6","type":"Isolated","acltype":"Account","account":"admin","domainid":"ce4585b8-41f5-11e3-aaa7-d6558ad1fb9f","domain":"ROOT","service":[{"name":"SourceNat","capability":[{"name":"SupportedSourceNatTypes","value":"peraccount","canchooseservicecapability":false},{"name":"RedundantRouter","value":"true","canchooseservicecapability":false}]},{"name":"Dns","capability":[{"name":"AllowDnsSuffixModification","value":"true","canchooseservicecapability":false}]},{"name":"UserData"},{"name":"PortForwarding"},{"name":"Firewall","capability":[{"name":"TrafficStatistics","value":"per
|
99
|
+
public ip","canchooseservicecapability":false},{"name":"SupportedTrafficDirection","value":"ingress,
|
100
|
+
egress","canchooseservicecapability":false},{"name":"SupportedProtocols","value":"tcp,udp,icmp","canchooseservicecapability":false},{"name":"MultipleIps","value":"true","canchooseservicecapability":false},{"name":"SupportedEgressProtocols","value":"tcp,udp,icmp,
|
101
|
+
all","canchooseservicecapability":false}]},{"name":"Lb","capability":[{"name":"SupportedLbAlgorithms","value":"roundrobin,leastconn,source","canchooseservicecapability":false},{"name":"LbSchemes","value":"Public","canchooseservicecapability":false},{"name":"SupportedStickinessMethods","value":"[{\"methodname\":\"LbCookie\",\"paramlist\":[{\"paramname\":\"cookie-name\",\"required\":false,\"isflag\":false,\"description\":\"
|
102
|
+
\"},{\"paramname\":\"mode\",\"required\":false,\"isflag\":false,\"description\":\"
|
103
|
+
\"},{\"paramname\":\"nocache\",\"required\":false,\"isflag\":true,\"description\":\"
|
104
|
+
\"},{\"paramname\":\"indirect\",\"required\":false,\"isflag\":true,\"description\":\"
|
105
|
+
\"},{\"paramname\":\"postonly\",\"required\":false,\"isflag\":true,\"description\":\"
|
106
|
+
\"},{\"paramname\":\"domain\",\"required\":false,\"isflag\":false,\"description\":\"
|
107
|
+
\"}],\"description\":\"This is loadbalancer cookie based stickiness method.\"},{\"methodname\":\"AppCookie\",\"paramlist\":[{\"paramname\":\"cookie-name\",\"required\":false,\"isflag\":false,\"description\":\"
|
108
|
+
\"},{\"paramname\":\"length\",\"required\":false,\"isflag\":false,\"description\":\"
|
109
|
+
\"},{\"paramname\":\"holdtime\",\"required\":false,\"isflag\":false,\"description\":\"
|
110
|
+
\"},{\"paramname\":\"request-learn\",\"required\":false,\"isflag\":true,\"description\":\"
|
111
|
+
\"},{\"paramname\":\"prefix\",\"required\":false,\"isflag\":true,\"description\":\"
|
112
|
+
\"},{\"paramname\":\"mode\",\"required\":false,\"isflag\":false,\"description\":\"
|
113
|
+
\"}],\"description\":\"This is App session based sticky method. Define session
|
114
|
+
stickiness on an existing application cookie. It can be used only for a specific
|
115
|
+
http traffic\"},{\"methodname\":\"SourceBased\",\"paramlist\":[{\"paramname\":\"tablesize\",\"required\":false,\"isflag\":false,\"description\":\"
|
116
|
+
\"},{\"paramname\":\"expire\",\"required\":false,\"isflag\":false,\"description\":\"
|
117
|
+
\"}],\"description\":\"This is source based Stickiness method, it can be used
|
118
|
+
for any type of protocol.\"}]","canchooseservicecapability":false},{"name":"SupportedProtocols","value":"tcp,
|
119
|
+
udp","canchooseservicecapability":false},{"name":"SupportedLBIsolation","value":"dedicated","canchooseservicecapability":false}]},{"name":"Dhcp","capability":[{"name":"DhcpAccrossMultipleSubnets","value":"true","canchooseservicecapability":false}]},{"name":"Vpn","capability":[{"name":"SupportedVpnTypes","value":"pptp,l2tp,ipsec","canchooseservicecapability":false},{"name":"VpnTypes","value":"removeaccessvpn","canchooseservicecapability":false}]},{"name":"StaticNat"}],"networkdomain":"cs2sandbox.simulator","physicalnetworkid":"46d08659-81e9-4f31-a589-a15aca972af0","restartrequired":false,"specifyipranges":false,"canusefordeploy":true,"ispersistent":false,"tags":[],"displaynetwork":true}
|
120
|
+
} }'
|
121
|
+
http_version:
|
122
|
+
recorded_at: Wed, 18 Dec 2013 21:25:06 GMT
|
123
|
+
- request:
|
124
|
+
method: get
|
125
|
+
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=createTags&resourceIds=02e5fd84-e9ea-49f7-ba6a-6d63ea23a27f&resourceType=Network&response=json&signature=KnWoymoA3Q34Iz%2BZ9iFEc8R0lEo=&tags%5B0%5D%5B.key%5D=speed&tags%5B0%5D%5B.name%5D=speed&tags%5B0%5D%5B.value%5D=fast
|
126
|
+
body:
|
127
|
+
encoding: US-ASCII
|
128
|
+
string: ''
|
129
|
+
headers:
|
130
|
+
User-Agent:
|
131
|
+
- Faraday v0.8.8
|
132
|
+
Accept-Encoding:
|
133
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
134
|
+
Accept:
|
135
|
+
- ! '*/*'
|
136
|
+
response:
|
137
|
+
status:
|
138
|
+
code: 200
|
139
|
+
message: OK
|
140
|
+
headers:
|
141
|
+
Content-Type:
|
142
|
+
- text/javascript; charset=UTF-8
|
143
|
+
Content-Length:
|
144
|
+
- '75'
|
145
|
+
Server:
|
146
|
+
- Jetty(6.1.26)
|
147
|
+
body:
|
148
|
+
encoding: US-ASCII
|
149
|
+
string: ! '{ "createtagsresponse" : {"jobid":"90bdb3e9-dcd5-4aac-9aa9-1879863082cc"}
|
150
|
+
}'
|
151
|
+
http_version:
|
152
|
+
recorded_at: Wed, 18 Dec 2013 21:25:07 GMT
|
153
|
+
recorded_with: VCR 2.8.0
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "spec_helper"
|
2
|
+
require "logger"
|
3
3
|
|
4
4
|
describe "A response to a request sent to the CloudStack API", :vcr do
|
5
5
|
let(:io) { StringIO.new }
|
@@ -15,9 +15,11 @@ describe "A response to a request sent to the CloudStack API", :vcr do
|
|
15
15
|
apis_path: File.join(File.dirname(__FILE__), '../fixtures/4.2.json')
|
16
16
|
}
|
17
17
|
end
|
18
|
+
|
18
19
|
let(:client) do
|
19
20
|
StackerBee::Client.new(config_hash)
|
20
21
|
end
|
22
|
+
|
21
23
|
subject { client.list_accounts }
|
22
24
|
|
23
25
|
it { should_not be_empty }
|
@@ -55,10 +57,10 @@ describe "A response to a request sent to the CloudStack API", :vcr do
|
|
55
57
|
end
|
56
58
|
|
57
59
|
context "failing to connect" do
|
58
|
-
let(:url) { "http://127.0.0.1:
|
60
|
+
let(:url) { "http://127.0.0.1:666/client/api" }
|
59
61
|
it "should raise helpful exception" do
|
60
62
|
klass = StackerBee::ConnectionError
|
61
|
-
expect
|
63
|
+
expect{ subject }.to raise_error klass, /#{url}/
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
@@ -113,4 +115,30 @@ describe "A response to a request sent to the CloudStack API", :vcr do
|
|
113
115
|
it { should include "events" }
|
114
116
|
it { should_not include "cpuallocated" }
|
115
117
|
end
|
118
|
+
|
119
|
+
context "a request parameter with a map" do
|
120
|
+
let(:zone_id) { client.list_zones.first["id"] }
|
121
|
+
|
122
|
+
let(:service_offering_id) do
|
123
|
+
client.list_network_offerings(
|
124
|
+
supported_services: 'sourcenat',
|
125
|
+
type: 'isolated').first["id"]
|
126
|
+
end
|
127
|
+
|
128
|
+
let(:network) do
|
129
|
+
client.create_network(zone_id: zone_id,
|
130
|
+
network_offering_id: service_offering_id,
|
131
|
+
name: "John", displaytext: "John")
|
132
|
+
end
|
133
|
+
|
134
|
+
let(:tag) do
|
135
|
+
client.create_tags(resource_type: "Network",
|
136
|
+
resource_ids: network["id"],
|
137
|
+
tags: { "speed [lab]" => 'real fast!' })
|
138
|
+
end
|
139
|
+
|
140
|
+
it "can create an object" do
|
141
|
+
tag.should_not be_nil
|
142
|
+
end
|
143
|
+
end
|
116
144
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe StackerBee::DictionaryFlattener do
|
4
|
+
let(:lb) { StackerBee::DictionaryFlattener::LB }
|
5
|
+
let(:rb) { StackerBee::DictionaryFlattener::RB }
|
6
|
+
let(:string) { "cool[0].name%21" }
|
7
|
+
let(:tokenized_string) { "cool#{lb}0#{rb}.name%21" }
|
8
|
+
|
9
|
+
describe ".detokenize" do
|
10
|
+
subject { StackerBee::DictionaryFlattener.detokenize(tokenized_string) }
|
11
|
+
it { should eq string }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ".tokenize" do
|
15
|
+
subject { StackerBee::DictionaryFlattener.tokenize(string) }
|
16
|
+
it { should eq tokenized_string }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".new" do
|
20
|
+
def prefix(number)
|
21
|
+
StackerBee::DictionaryFlattener.tokenize "rebels[#{number}]"
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:params) do
|
25
|
+
{ "time" => "long ago",
|
26
|
+
"rebels" => { "r2" => "d2", "r1" => "", "father" => false } }
|
27
|
+
end
|
28
|
+
|
29
|
+
subject do
|
30
|
+
StackerBee::DictionaryFlattener.new(params).params
|
31
|
+
end
|
32
|
+
|
33
|
+
it "flattens objects in the manner that cloudstack expects" do
|
34
|
+
subject["#{prefix(0)}.name"].should eq "r2"
|
35
|
+
subject["#{prefix(0)}.key"].should eq "r2"
|
36
|
+
subject["#{prefix(0)}.value"].should eq "d2"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "doesnt flatten empty hashes" do
|
40
|
+
subject.should_not have_key "#{prefix(2)}.name"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "handles booleans" do
|
44
|
+
subject["#{prefix(1)}.name"].should eq "father"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "removes original map params" do
|
48
|
+
subject.should_not have_key "rebels"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -8,33 +8,35 @@ describe StackerBee::Request do
|
|
8
8
|
list: :all,
|
9
9
|
nothing: nil,
|
10
10
|
deets: [:things, :stuff],
|
11
|
+
settings: { cookiename: "Fred", something: "cool" },
|
11
12
|
blank: ''
|
12
13
|
}
|
13
14
|
end
|
15
|
+
|
14
16
|
let(:request) { StackerBee::Request.new endpoint, api_key, params }
|
15
17
|
subject { request }
|
16
|
-
its(:params) do
|
17
|
-
should == {
|
18
|
-
list: :all,
|
19
|
-
api_key: api_key,
|
20
|
-
command: "listStuff",
|
21
|
-
nothing: nil,
|
22
|
-
blank: '',
|
23
|
-
deets: [:things, :stuff],
|
24
|
-
response: "json"
|
25
|
-
}
|
26
|
-
end
|
27
18
|
|
28
19
|
describe "#query_params" do
|
20
|
+
let(:new_params) { params.merge("settings[1].name" => "cool") }
|
21
|
+
let(:flattener) { double(new: double(params: new_params)) }
|
22
|
+
|
23
|
+
before do
|
24
|
+
stub_const "StackerBee::DictionaryFlattener", flattener
|
25
|
+
end
|
26
|
+
|
29
27
|
subject { request.query_params }
|
28
|
+
|
29
|
+
it { should include ["settings[1].name", "cool"] }
|
30
30
|
it { should include ["list", :all] }
|
31
31
|
it { should include %W(apiKey #{api_key}) }
|
32
32
|
it { should include %w(command listStuff) }
|
33
33
|
it { should include %w(response json) }
|
34
34
|
it { should include %w(deets things,stuff) }
|
35
|
+
|
35
36
|
it "removes params with nil values" do
|
36
37
|
subject.map(&:first).should_not include "nothing"
|
37
38
|
end
|
39
|
+
|
38
40
|
it "removes params with blank values" do
|
39
41
|
subject.map(&:first).should_not include "blank"
|
40
42
|
end
|
@@ -6,6 +6,7 @@ describe StackerBee::Utilities, "#uncase" do
|
|
6
6
|
it { uncase("foo_bar").should eq "foobar" }
|
7
7
|
it { uncase("foo-bar").should eq "foobar" }
|
8
8
|
it { uncase("fooBar").should eq "foobar" }
|
9
|
+
it { uncase("foo[0].Bar").should eq "foo[0].bar" }
|
9
10
|
|
10
11
|
it { snake_case("Foo Bar").should eq "foo_bar" }
|
11
12
|
it { snake_case("foo_bar").should eq "foo_bar" }
|
@@ -22,4 +23,5 @@ describe StackerBee::Utilities, "#uncase" do
|
|
22
23
|
it { camel_case("foo-bar", true).should eq "fooBar" }
|
23
24
|
it { camel_case("fooBar", true).should eq "fooBar" }
|
24
25
|
it { camel_case("fooBar", false).should eq "FooBar" }
|
26
|
+
it { camel_case("foo[0].Bar", false).should eq "Foo[0].Bar" }
|
25
27
|
end
|
data/stacker_bee.gemspec
CHANGED
@@ -7,8 +7,8 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "stacker_bee"
|
8
8
|
spec.version = StackerBee::VERSION
|
9
9
|
spec.platform = Gem::Platform::RUBY
|
10
|
-
spec.authors = ["Greg Sterndale"]
|
11
|
-
spec.email = ["
|
10
|
+
spec.authors = ["Greg Sterndale", "Mike Nicholaides"]
|
11
|
+
spec.email = ["team@promptworks.com"]
|
12
12
|
spec.summary = %q{Ruby CloudStack client}
|
13
13
|
spec.description = %q{Ruby CloudStack client and CLI}
|
14
14
|
spec.homepage = "http://github.com/promptworks/stacker_bee"
|
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency "rspec", "~> 2.1"
|
28
28
|
spec.add_development_dependency "webmock", "~> 1.15"
|
29
29
|
spec.add_development_dependency "vcr", "~> 2.6"
|
30
|
+
spec.add_development_dependency "rubocop"
|
30
31
|
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stacker_bee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg Sterndale
|
8
|
+
- Mike Nicholaides
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-
|
12
|
+
date: 2013-12-31 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: faraday
|
@@ -108,9 +109,23 @@ dependencies:
|
|
108
109
|
- - ~>
|
109
110
|
- !ruby/object:Gem::Version
|
110
111
|
version: '2.6'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: rubocop
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
111
126
|
description: Ruby CloudStack client and CLI
|
112
127
|
email:
|
113
|
-
-
|
128
|
+
- team@promptworks.com
|
114
129
|
executables:
|
115
130
|
- stacker_bee
|
116
131
|
extensions: []
|
@@ -133,6 +148,8 @@ files:
|
|
133
148
|
- lib/stacker_bee/client.rb
|
134
149
|
- lib/stacker_bee/configuration.rb
|
135
150
|
- lib/stacker_bee/connection.rb
|
151
|
+
- lib/stacker_bee/dictionary_flattener.rb
|
152
|
+
- lib/stacker_bee/middleware/detokenizer.rb
|
136
153
|
- lib/stacker_bee/middleware/logger.rb
|
137
154
|
- lib/stacker_bee/middleware/signed_query.rb
|
138
155
|
- lib/stacker_bee/rash.rb
|
@@ -143,6 +160,8 @@ files:
|
|
143
160
|
- lib/stacker_bee/version.rb
|
144
161
|
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/.yml
|
145
162
|
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_nil_request_parameter/properly_executes_the_request.yml
|
163
|
+
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_a_Map/can_create_an_object.yml
|
164
|
+
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_a_Map/object.yml
|
146
165
|
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_an_Array/.yml
|
147
166
|
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_and_empty_string/properly_executes_the_request.yml
|
148
167
|
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/containing_an_error/.yml
|
@@ -162,6 +181,7 @@ files:
|
|
162
181
|
- spec/units/stacker_bee/client_spec.rb
|
163
182
|
- spec/units/stacker_bee/configuration_spec.rb
|
164
183
|
- spec/units/stacker_bee/connection_spec.rb
|
184
|
+
- spec/units/stacker_bee/dictionary_flattener_spec.rb
|
165
185
|
- spec/units/stacker_bee/middleware/logger_spec.rb
|
166
186
|
- spec/units/stacker_bee/rash_spec.rb
|
167
187
|
- spec/units/stacker_bee/request_error_spec.rb
|
@@ -197,6 +217,8 @@ summary: Ruby CloudStack client
|
|
197
217
|
test_files:
|
198
218
|
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/.yml
|
199
219
|
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_nil_request_parameter/properly_executes_the_request.yml
|
220
|
+
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_a_Map/can_create_an_object.yml
|
221
|
+
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_a_Map/object.yml
|
200
222
|
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_an_Array/.yml
|
201
223
|
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/a_request_parameter_with_and_empty_string/properly_executes_the_request.yml
|
202
224
|
- spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/containing_an_error/.yml
|
@@ -216,6 +238,7 @@ test_files:
|
|
216
238
|
- spec/units/stacker_bee/client_spec.rb
|
217
239
|
- spec/units/stacker_bee/configuration_spec.rb
|
218
240
|
- spec/units/stacker_bee/connection_spec.rb
|
241
|
+
- spec/units/stacker_bee/dictionary_flattener_spec.rb
|
219
242
|
- spec/units/stacker_bee/middleware/logger_spec.rb
|
220
243
|
- spec/units/stacker_bee/rash_spec.rb
|
221
244
|
- spec/units/stacker_bee/request_error_spec.rb
|