opennebula_nagios_probe 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +5 -0
  3. data/.rubocop.yml +6 -0
  4. data/.travis.yml +10 -0
  5. data/Gemfile +18 -0
  6. data/Gemfile.lock +87 -0
  7. data/README.md +36 -0
  8. data/Rakefile +65 -0
  9. data/bin/check_opennebula +70 -0
  10. data/conf/opennebula.cfg.erb +32 -0
  11. data/lib/opennebula_nagios_probe.rb +29 -0
  12. data/lib/probe/occi/client.rb +50 -0
  13. data/lib/probe/occi/nocci/compute.rb +20 -0
  14. data/lib/probe/occi/nocci/network.rb +21 -0
  15. data/lib/probe/occi/nocci/resource.rb +96 -0
  16. data/lib/probe/occi/nocci/storage.rb +22 -0
  17. data/lib/probe/occi/rocci/compute.rb +70 -0
  18. data/lib/probe/occi/rocci/network.rb +21 -0
  19. data/lib/probe/occi/rocci/resource.rb +62 -0
  20. data/lib/probe/occi/rocci/storage.rb +22 -0
  21. data/lib/probe/opennebula_econe_probe.rb +108 -0
  22. data/lib/probe/opennebula_occi_probe.rb +126 -0
  23. data/lib/probe/opennebula_oned_probe.rb +101 -0
  24. data/lib/probe/opennebula_probe.rb +97 -0
  25. data/lib/probe/optparse_nagios_probe.rb +174 -0
  26. data/opennebula_nagios_probe.gemspec +32 -0
  27. data/spec/probe/fixtures/cassettes/econe/econe_critical_existing_resources.yml +75 -0
  28. data/spec/probe/fixtures/cassettes/econe/econe_critical_no_resources.yml +75 -0
  29. data/spec/probe/fixtures/cassettes/econe/econe_critical_nonexisting_resources.yml +75 -0
  30. data/spec/probe/fixtures/cassettes/econe/econe_warning_existing_resources.yml +75 -0
  31. data/spec/probe/fixtures/cassettes/econe/econe_warning_nonexisting_resources.yml +40 -0
  32. data/spec/probe/fixtures/cassettes/occi/occi_critical_existing_resources.yml +143 -0
  33. data/spec/probe/fixtures/cassettes/occi/occi_critical_no_resources.yml +143 -0
  34. data/spec/probe/fixtures/cassettes/occi/occi_critical_nonexisting_resources.yml +143 -0
  35. data/spec/probe/fixtures/cassettes/occi/occi_warning_existing_resources.yml +230 -0
  36. data/spec/probe/fixtures/cassettes/occi/occi_warning_nonexisting_resources.yml +49 -0
  37. data/spec/probe/fixtures/cassettes/oned/oned_critical_existing_resources.yml +131 -0
  38. data/spec/probe/fixtures/cassettes/oned/oned_critical_no_resources.yml +131 -0
  39. data/spec/probe/fixtures/cassettes/oned/oned_critical_nonexisting_resources.yml +131 -0
  40. data/spec/probe/fixtures/cassettes/oned/oned_warning_existing_resources.yml +671 -0
  41. data/spec/probe/fixtures/cassettes/oned/oned_warning_nonexisting_resources.yml +130 -0
  42. data/spec/probe/fixtures/cassettes/rocci/rocci_critical_existing_resources.yml +1220 -0
  43. data/spec/probe/fixtures/cassettes/rocci/rocci_critical_no_resources.yml +1220 -0
  44. data/spec/probe/fixtures/cassettes/rocci/rocci_critical_nonexisting_resources.yml +1220 -0
  45. data/spec/probe/fixtures/cassettes/rocci/rocci_warning_existing_resources.yml +817 -0
  46. data/spec/probe/fixtures/cassettes/rocci/rocci_warning_no_resources.yml +591 -0
  47. data/spec/probe/fixtures/cassettes/rocci/rocci_warning_nonexisting_resources.yml +640 -0
  48. data/spec/probe/opennebula_econe_probe_spec.rb +150 -0
  49. data/spec/probe/opennebula_occi_probe_spec.rb +149 -0
  50. data/spec/probe/opennebula_oned_probe_spec.rb +154 -0
  51. data/spec/probe/opennebula_rocci_probe_spec.rb +156 -0
  52. metadata +280 -0
@@ -0,0 +1,101 @@
1
+ # encoding: UTF-8
2
+ ###########################################################################
3
+ ## Licensed under the Apache License, Version 2.0 (the "License");
4
+ ## you may not use this file except in compliance with the License.
5
+ ## You may obtain a copy of the License at
6
+ ##
7
+ ## http://www.apache.org/licenses/LICENSE-2.0
8
+ ##
9
+ ## Unless required by applicable law or agreed to in writing, software
10
+ ## distributed under the License is distributed on an "AS IS" BASIS,
11
+ ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ ## See the License for the specific language governing permissions and
13
+ ## limitations under the License.
14
+ ###########################################################################
15
+
16
+ require 'opennebula_probe'
17
+ require 'opennebula'
18
+
19
+ include OpenNebula
20
+
21
+ # OpenNebulaOnedProbe - XML-RPC ONED client query service implementation.
22
+
23
+ class OpenNebulaOnedProbe < OpennebulaProbe
24
+ FAILED_CONNECTIVITY = 'Failed to check connectivity: '
25
+ FAILED_RESOURCE = 'Failed to check resource availability: '
26
+
27
+ def initialize(opts)
28
+ super(opts)
29
+
30
+ # OpenNebula credentials
31
+ @credentials = "#{@opts.username}:#{@opts.password}"
32
+ @client = Client.new(@credentials, @endpoint)
33
+ end
34
+
35
+ def check_pool(pool, msg)
36
+ rc = pool.info
37
+ fail "#{msg} #{rc.message}" if OpenNebula.is_error?(rc)
38
+ end
39
+
40
+ def check_crit
41
+ @logger.info "Checking for basic connectivity at #{@endpoint}"
42
+
43
+ pool_class_array = [VirtualNetworkPool, ImagePool, VirtualMachinePool]
44
+ pool_class_array.each do |pool_class|
45
+ pool = pool_class.new(@client, -1)
46
+ check_pool(pool, FAILED_CONNECTIVITY)
47
+ end
48
+
49
+ false
50
+
51
+ rescue StandardError => e
52
+ @logger.error "Failed to check basic connectivity: #{e.message}"
53
+ @logger.debug "#{e.backtrace.join("\n")}"
54
+ return true
55
+ end
56
+
57
+ def check_resources(resources)
58
+ if resources.map { |x| x[:resource] }.reduce(true) { |product, resource| product && resource.nil? }
59
+ @logger.info 'There are no resources to check, for details on how to specify resources see --help'
60
+ return false
61
+ end
62
+
63
+ resources.each do |resource_hash|
64
+ resource = resource_hash[:resource]
65
+
66
+ next unless resource
67
+
68
+ @logger.info "Looking for #{resource_hash[:resource_string]}s: #{resource.inspect}"
69
+ pool = resource_hash[:resource_pool].new(@client, -1)
70
+ check_pool(pool, FAILED_RESOURCE)
71
+
72
+ resource.each do |resource_to_look_for|
73
+ found = false
74
+
75
+ pool.each do |res|
76
+ check_pool(res, FAILED_RESOURCE)
77
+ found = true if res.id.to_s == resource_to_look_for
78
+ end
79
+ fail "#{resource_hash[:resource_string].capitalize} #{resource_to_look_for} not found" unless found
80
+ end
81
+ end
82
+
83
+ false
84
+ end
85
+
86
+ def check_warn
87
+ @logger.info "Checking for resource availability at #{@endpoint}"
88
+
89
+ resources = []
90
+ resources << { resource: @opts.storage, resource_string: 'image', resource_pool: ImagePool }
91
+ resources << { resource: @opts.compute, resource_string: 'compute instance', resource_pool: VirtualMachinePool }
92
+ resources << { resource: @opts.network, resource_string: 'network', resource_pool: VirtualNetworkPool }
93
+
94
+ check_resources(resources)
95
+
96
+ rescue StandardError => e
97
+ @logger.error "Failed to check resource availability: #{e.message}"
98
+ @logger.debug "#{e.backtrace.join("\n")}"
99
+ return true
100
+ end
101
+ end
@@ -0,0 +1,97 @@
1
+ # encoding: UTF-8
2
+ ###########################################################################
3
+ ## Licensed under the Apache License, Version 2.0 (the "License");
4
+ ## you may not use this file except in compliance with the License.
5
+ ## You may obtain a copy of the License at
6
+ ##
7
+ ## http://www.apache.org/licenses/LICENSE-2.0
8
+ ##
9
+ ## Unless required by applicable law or agreed to in writing, software
10
+ ## distributed under the License is distributed on an "AS IS" BASIS,
11
+ ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ ## See the License for the specific language governing permissions and
13
+ ## limitations under the License.
14
+ ###########################################################################
15
+
16
+ ###########################################################################
17
+ # Nagios code explanation (source: https://www.nagios-plugins.org/doc/guidelines.html, q. 11-26-2013)
18
+ #
19
+ # OK/UP - The plugin was able to check the service and it appeared to be functioning properly
20
+ # WARNING - The plugin was able to check the service, but it appeared to be above some "warning"
21
+ # threshold or did not appear to be working properly
22
+ # CRITICAL/DOWN - The plugin detected that either the service was not running or it was above
23
+ # some "critical" threshold
24
+ # UNKNOWN - Invalid command line arguments were supplied to the plugin or low-level failures internal to the plugin
25
+ # (such as unable to fork, or open a tcp socket) that prevent it from performing the specified operation.
26
+ # Higher-level errors (such as name resolution errors, socket timeouts, etc) are outside of the control of plugins
27
+ # and should generally NOT be reported as UNKNOWN states.
28
+ ###########################################################################
29
+
30
+ OK = 0
31
+ WARNING = 1
32
+ CRITICAL = 2
33
+ UNKNOWN = 3
34
+
35
+ # OpennebulaProbe covers generic implementation of subprobes.
36
+ # ==== Attributes
37
+ # * logger - Logger connector.
38
+ # * message - Resulting message.
39
+ # * retval - Probe status constant.
40
+ # * endpoint - Server URI.
41
+ #
42
+ # ==== Options
43
+ # * opts - Hash with parsed command line arguments.
44
+ #
45
+ # ==== Examples
46
+ # Instance is initialized from child class
47
+
48
+ class OpennebulaProbe
49
+ OK_MSG = 'Remote resources successfully queried!'
50
+ WARN_MSG = 'Failed to query specified remote resources!'
51
+ CRIT_MSG = 'Failed to establish connection with the remote server!'
52
+ UNKWN_MSG = 'An exception or error occured!'
53
+
54
+ attr_reader :retval, :message
55
+ attr_writer :logger
56
+
57
+ def initialize(opts = {})
58
+ @opts = opts
59
+ @retval = UNKNOWN
60
+ @logger = nil
61
+ @message = "#{UNKWN_MSG}"
62
+ @endpoint = "#{@opts.protocol.to_s}://#{@opts.hostname}:#{@opts.port.to_s}#{@opts.path}"
63
+ end
64
+
65
+ def check_crit
66
+ # overridden in child class
67
+ true
68
+ end
69
+
70
+ def check_warn
71
+ # overridden in child class
72
+ true
73
+ end
74
+
75
+ def crit?
76
+ return false unless check_crit
77
+ @retval = CRITICAL
78
+ @message = "CRITICAL: #{CRIT_MSG}"
79
+ true
80
+ end
81
+
82
+ def warn?
83
+ return false unless check_warn
84
+ @retval = WARNING
85
+ @message = "WARNING: #{WARN_MSG}"
86
+ true
87
+ end
88
+
89
+ def run
90
+ unless crit?
91
+ unless warn?
92
+ @retval = OK
93
+ @message = "#{OK_MSG}"
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,174 @@
1
+ # encoding: UTF-8
2
+ ###########################################################################
3
+ ## Licensed under the Apache License, Version 2.0 (the "License");
4
+ ## you may not use this file except in compliance with the License.
5
+ ## You may obtain a copy of the License at
6
+ ##
7
+ ## http://www.apache.org/licenses/LICENSE-2.0
8
+ ##
9
+ ## Unless required by applicable law or agreed to in writing, software
10
+ ## distributed under the License is distributed on an "AS IS" BASIS,
11
+ ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ ## See the License for the specific language governing permissions and
13
+ ## limitations under the License.
14
+ ###########################################################################
15
+
16
+ require 'optparse'
17
+ require 'ostruct'
18
+
19
+ # OptparseNagiosProbe - opennebula-nagios probes ARGV parser class.
20
+
21
+ class OptparseNagiosProbe
22
+ VERSION = 0.99
23
+
24
+ def self.parse(args)
25
+ options = OpenStruct.new
26
+
27
+ options.debuglevel = 0
28
+
29
+ options.hostname = 'localhost'
30
+ options.port = 2633
31
+ options.path = '/'
32
+ options.protocol = :http
33
+ options.username = 'oneadmin'
34
+ options.password = 'onepass'
35
+
36
+ options.service = :oned
37
+ options.occi = :occi
38
+
39
+ options.timeout = 60
40
+
41
+ options.user_cred = nil
42
+ options.voms = false
43
+
44
+ opts_ = OptionParser.new do |opts|
45
+ opts.banner = 'Usage: check_opennebula.rb [options]'
46
+
47
+ opts.separator ''
48
+ opts.separator 'Connection options:'
49
+
50
+ opts.on('--protocol [http|https]', [:http, :https], "Protocol to use, defaults to 'http'") do |protocol|
51
+ options.protocol = protocol
52
+ end
53
+
54
+ opts.on('--hostname [HOSTNAME]', String, "Host to be queried, defaults to 'localhost'") do |hostname|
55
+ options.hostname = hostname
56
+ end
57
+
58
+ opts.on('--port [PORT_NUMBER]', Integer, "Port to be queried, defaults to '2633'") do |port|
59
+ options.port = port
60
+ end
61
+
62
+ opts.on('--path [PATH]', String, 'Path to the service endpoint'\
63
+ + "(the last part of the URI, should always start with a slash), defaults to '/'") do |path|
64
+ options.path = path
65
+ end
66
+
67
+ opts.on('--username [USERNAME]', String, 'Username for authentication purposes, '\
68
+ + "defaults to 'oneadmin'") do |username|
69
+ options.username = username
70
+ end
71
+
72
+ opts.on('--password [PASSWORD]', String, 'Password for authentication purposes, '\
73
+ + "defaults to 'onepass'") do |password|
74
+ options.password = password
75
+ end
76
+
77
+ opts.separator ''
78
+ opts.separator 'Session options:'
79
+
80
+ opts.on('--timeout [SECONDS]', Integer, "Timeout time in seconds, defaults to '60'") do |timeout|
81
+ options.timeout = timeout
82
+ end
83
+
84
+ opts.separator ''
85
+ opts.separator 'Service options:'
86
+
87
+ opts.on('--service [SERVICE_NAME]', [:oned, :occi, :econe, :rocci], 'Name of the cloud service'\
88
+ + " to check [oned, occi, rocci, econe], defaults to 'oned'") do |service|
89
+ options.service = service
90
+ end
91
+
92
+ opts.on("--check-network [ID'S]", Array, 'Comma separated list of network IDs to check') do |network|
93
+ options.network = network
94
+ end
95
+
96
+ opts.on("--check-storage [ID'S]", Array, 'Comma separated list of storage IDs to check') do |storage|
97
+ options.storage = storage
98
+ end
99
+
100
+ opts.on("--check-compute [ID'S]", Array, 'Comma separated list of VM IDs to check') do |compute|
101
+ options.compute = compute
102
+ end
103
+
104
+ opts.on('--createvm [TEMPLATE_UUID]', String, 'rOCCI template uuid') do |tmpl|
105
+ options.template_uuid = tmpl
106
+ end
107
+
108
+ opts.on('--name [NAME]', String, 'Name for VM instantiated from template') do |vmname|
109
+ options.vmname = vmname
110
+ end
111
+
112
+ opts.separator ''
113
+ opts.separator 'X.509 options:'
114
+
115
+ opts.on('--user-cred [PATH]', String, "Path to user's X.509 credentials, defaults to ~/.globus/usercred.pem'")\
116
+ do |ucred|
117
+ options.user_cred = ucred
118
+ end
119
+
120
+ opts.on('--ca-file [PATH]', String, 'Path to CA certificates bundle in a file') do |cafile|
121
+ options.ca_file = cafile
122
+ end
123
+
124
+ opts.on('--ca-path [PATH]', String, 'Path to CA certificates directory, defaults to "/etc/grid-security/certificates"')\
125
+ do |capath|
126
+ options.ca_path = capath
127
+ end
128
+
129
+ opts.on('--voms', '--[no-]voms', 'Enable VOMS credentials; modifies behavior of the X.509 authN module')\
130
+ do |voms|
131
+ options.voms = voms
132
+ end
133
+
134
+ opts.separator ''
135
+ opts.separator 'Common options:'
136
+
137
+ opts.on('--debuglevel [NUMBER]', Integer, "Run with debugging mode on certain level, defaults to '0'") do |debug|
138
+ if !debug
139
+ options.debug_level = 1
140
+ else
141
+ options.debug_level = debug
142
+ end
143
+
144
+ # Param. correction - normalize debug level to max 2, minus sign interpreted as switch, no problem there
145
+ options.debug_level %= 3
146
+ end
147
+
148
+ opts.on_tail('-h', '--help', 'Show this message') do
149
+ puts opts
150
+ exit!
151
+ end
152
+
153
+ opts.on_tail('--version', 'Show version') do
154
+ puts VERSION
155
+ exit!
156
+ end
157
+
158
+ end
159
+
160
+ opts_.parse!(args)
161
+
162
+ # Emphasize required fields
163
+ mandatory = [:protocol, :hostname, :port, :path, :service, :password]
164
+ mandatory << :username unless options.user_cred
165
+
166
+ options_hash = options.marshal_dump
167
+
168
+ # Bug here, i am not sure the mandatory params working
169
+ missing = mandatory.select { |param| options_hash[param].nil? }
170
+ fail StandardError, "Missing required arguments #{missing.join(', ')}" unless missing.empty?
171
+
172
+ options
173
+ end
174
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'opennebula_nagios_probe'
5
+ gem.version = '1.0.0'
6
+ gem.authors = ['Boris Parak', 'Filip Hubik', 'Michal Kimle' ]
7
+ gem.email = ['parak@cesnet.cz', 'hubik@ics.muni.cz', 'kimle.michal@gmail.com']
8
+ gem.description = %q{This gem is collection of nagios probes (one, econe, occi, rocci) for OpenNebula cloud platform}
9
+ gem.summary = %q{OpenNebula nagios probes}
10
+ gem.homepage = 'https://github.com/arax/opennebula-nagios-probes'
11
+ gem.license = 'Apache License, Version 2.0'
12
+
13
+ gem.files = `git ls-files`.split("\n")
14
+ gem.test_files = `git ls-files -- {test,spec}/*`.split("\n")
15
+ gem.require_paths = ['lib']
16
+ gem.executables = ['check_opennebula']
17
+
18
+ gem.add_dependency 'nagios-probe', '~> 0.1'
19
+ gem.add_dependency 'log4r', '~> 1.1'
20
+ gem.add_dependency 'amazon-ec2', '~> 0.9'
21
+ gem.add_dependency 'occi-cli', '~> 4.2'
22
+ gem.add_dependency 'opennebula-oca', '~> 4.4'
23
+ gem.add_dependency 'occi-api', '~> 4.2'
24
+
25
+ gem.add_development_dependency 'rspec', '~> 2.14'
26
+ gem.add_development_dependency 'webmock', '~> 1.9'
27
+ gem.add_development_dependency 'vcr', '~> 2.8'
28
+ gem.add_development_dependency 'rake', '~> 10.1'
29
+ gem.add_development_dependency 'bundler', '~> 1.3'
30
+
31
+ gem.required_ruby_version = '>= 1.9.3'
32
+ end
@@ -0,0 +1,75 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://localhost:2345/
6
+ body:
7
+ encoding: US-ASCII
8
+ string: AWSAccessKeyId=nagios-probes-test&Action=DescribeImages&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2013-04-18T11%3A44%3A03Z&Version=2010-08-31&Signature=yUyjdPgO3iXIfZrj%2FtbiO8lM2qrZ2ZOc%2FbjvfzJ5Jxo%3D
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - github-amazon-ec2-ruby-gem
14
+ Content-Type:
15
+ - application/x-www-form-urlencoded
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Date:
22
+ - Thu, 18 Apr 2013 11:44:03 GMT
23
+ Server:
24
+ - thin 1.3.1 codename Triple Espresso
25
+ X-Frame-Options:
26
+ - sameorigin
27
+ X-Xss-Protection:
28
+ - 1; mode=block
29
+ Content-Type:
30
+ - application/xml
31
+ Content-Length:
32
+ - '880'
33
+ body:
34
+ encoding: US-ASCII
35
+ string: <?xml version="1.0"?><DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2010-08-31/"><requestId>783c292a-71db-4fa9-9028-4576aaf983d5</requestId><imagesSet><item><name>ttylinux
36
+ - kvm</name><description>ttylinux</description><imageId>ami-00000006</imageId><imageLocation>7ba83cabcea65882790fbe449d25e4ca</imageLocation><imageState>available</imageState><imageOwnerId>nagios-probes-test</imageOwnerId><isPublic>false</isPublic><architecture>i386</architecture><imageType>machine</imageType></item><item><name>ttylinux
37
+ - kvm2</name><description>ttylinux</description><imageId>ami-00000007</imageId><imageLocation>07193573e51336e1bce9aedc2492bbc6</imageLocation><imageState>available</imageState><imageOwnerId>nagios-probes-test</imageOwnerId><isPublic>false</isPublic><architecture>i386</architecture><imageType>machine</imageType></item></imagesSet></DescribeImagesResponse>
38
+ http_version:
39
+ recorded_at: Thu, 18 Apr 2013 11:44:03 GMT
40
+ - request:
41
+ method: post
42
+ uri: https://localhost:2345/
43
+ body:
44
+ encoding: US-ASCII
45
+ string: AWSAccessKeyId=nagios-probes-test&Action=DescribeInstances&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2013-04-18T11%3A44%3A03Z&Version=2010-08-31&Signature=pVdE33jTb1CpxwbzvB1%2F65LUc6eD6WFEfRx%2B0qXLIuw%3D
46
+ headers:
47
+ Accept:
48
+ - ! '*/*'
49
+ User-Agent:
50
+ - github-amazon-ec2-ruby-gem
51
+ Content-Type:
52
+ - application/x-www-form-urlencoded
53
+ response:
54
+ status:
55
+ code: 200
56
+ message: OK
57
+ headers:
58
+ Date:
59
+ - Thu, 18 Apr 2013 11:44:03 GMT
60
+ Server:
61
+ - thin 1.3.1 codename Triple Espresso
62
+ X-Frame-Options:
63
+ - sameorigin
64
+ X-Xss-Protection:
65
+ - 1; mode=block
66
+ Content-Type:
67
+ - application/xml
68
+ Content-Length:
69
+ - '1785'
70
+ body:
71
+ encoding: US-ASCII
72
+ string: <?xml version="1.0"?><DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2010-08-31/"><requestId>a8784da1-e29c-4220-8602-ced606d12702</requestId><reservationSet><item><reservationId>default</reservationId><ownerId>nagios-probes-test</ownerId><groupSet><item><groupId>default</groupId></item></groupSet><instancesSet><item><instanceId>i-00000009</instanceId><imageId></imageId><instanceState><code>0</code><name>pending</name></instanceState><keyName>none</keyName><productCodes/><instanceType></instanceType><launchTime>2013-04-04T13:29:49+02:00</launchTime><placement><availabilityZone>default</availabilityZone></placement><amiLaunchIndex>9</amiLaunchIndex><kernelId>eki-EA801065</kernelId><ramdiskId>eri-1FEE1144</ramdiskId><monitoring><state>false</state></monitoring></item><item><instanceId>i-00000010</instanceId><imageId></imageId><instanceState><code>0</code><name>pending</name></instanceState><keyName>none</keyName><productCodes/><instanceType></instanceType><launchTime>2013-04-04T13:29:49+02:00</launchTime><placement><availabilityZone>default</availabilityZone></placement><amiLaunchIndex>10</amiLaunchIndex><kernelId>eki-EA801065</kernelId><ramdiskId>eri-1FEE1144</ramdiskId><monitoring><state>false</state></monitoring></item><item><instanceId>i-00000011</instanceId><imageId></imageId><instanceState><code>0</code><name>pending</name></instanceState><keyName>none</keyName><productCodes/><instanceType></instanceType><launchTime>2013-04-04T13:30:33+02:00</launchTime><placement><availabilityZone>default</availabilityZone></placement><amiLaunchIndex>11</amiLaunchIndex><kernelId>eki-EA801065</kernelId><ramdiskId>eri-1FEE1144</ramdiskId><monitoring><state>false</state></monitoring></item></instancesSet></item></reservationSet></DescribeInstancesResponse>
73
+ http_version:
74
+ recorded_at: Thu, 18 Apr 2013 11:44:03 GMT
75
+ recorded_with: VCR 2.4.0