kitchen-cloudstack 0.20.2 → 0.20.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4aea8ef2bb8e1861c84d98804c3d2dd42b755a37
4
- data.tar.gz: 357e9002fd56121c69cbc2d639a6b184425f3a53
3
+ metadata.gz: ee4d465613811dd5d90ac237c6dedd0c6244af0b
4
+ data.tar.gz: 2e8787096938b70798dc267c0efa47e06d4701bf
5
5
  SHA512:
6
- metadata.gz: a67eaf5ffe6050dcca689a666e016ec9fb33745bc2adefba8c6fe41fcb89612124b1f91f13c43b4c42f76bc31fa4b8bde46eb8d7296ad8fe774d85e6e9d9531e
7
- data.tar.gz: 34a83850f480777e217bb956013f193fed9d707a5366befeacf2434fc3ced5a12303e04af30bbf8631a21932c4a97d036d8a3066e9007ab4a1232d6f3a3b6038
6
+ metadata.gz: dc30e3effe7036cd5a5cd47c3842535cff1691d643694e76d981c531af0c6a1f9745a830ffd5822bbc1afc1b4ac5e99d0e61d8eb6f3fea0555e55dcb9a0aba2a
7
+ data.tar.gz: 01535d54ad3e924f5f192cb3d70c5fa704560948c2347f7fa1920d9e25e4df903da16f6555bcaed417f1497bf81577d327e904840e01269d3ebd889de279e6e0
data/README.md CHANGED
@@ -32,9 +32,10 @@ Then to specify different OS templates,
32
32
  cloudstack_template_id: [INSTANCE TEMPLATE ID]
33
33
  cloudstack_serviceoffering_id: [INSTANCE SERVICE OFFERING ID]
34
34
  cloudstack_zone_id: [INSTANCE ZONE ID]
35
+ OPTIONAL
35
36
  cloudstack_network_id: [NETWORK ID FOR ISOLATED OR VPC NETWORKS]
36
37
  cloudstack_security_group_id: [SECURITY GROUP ID FOR SHARED NETWORKS]
37
- OPTIONAL
38
+ cloudstack_diskoffering_id: [INSTANCE DISK OFFERING ID]
38
39
  cloudstack_ssh_keypair_name: [SSH KEY NAME]
39
40
  cloudstack_sync_time: [NUMBER OF SECONDS TO WAIT FOR CLOUD-SET-GUEST-PASSWORD/SSHKEY]
40
41
  To use the CloudStack public key provider, you need to have the .PEM file located in the same directory as
@@ -24,8 +24,8 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency 'bundler', '~> 1.3'
25
25
  spec.add_development_dependency 'rake', '~> 0'
26
26
 
27
- spec.add_development_dependency 'cane', '~> 0'
28
- spec.add_development_dependency 'tailor', '~> 0'
27
+ spec.add_development_dependency 'cane', '~> 2'
28
+ spec.add_development_dependency 'tailor', '~> 1'
29
29
  spec.add_development_dependency 'countloc', '~> 0'
30
30
  spec.add_development_dependency 'pry', '~> 0'
31
31
  end
@@ -21,12 +21,9 @@ require 'kitchen'
21
21
  require 'fog'
22
22
  require 'socket'
23
23
  require 'openssl'
24
- # require 'pry'
25
24
 
26
25
  module Kitchen
27
-
28
26
  module Driver
29
-
30
27
  # Cloudstack driver for Kitchen.
31
28
  #
32
29
  # @author Jeff Moody <fifthecho@gmail.com>
@@ -35,42 +32,47 @@ module Kitchen
35
32
  default_config :username, 'root'
36
33
  default_config :port, '22'
37
34
  default_config :password, nil
38
-
35
+
39
36
  def compute
40
37
  cloudstack_uri = URI.parse(config[:cloudstack_api_url])
41
38
  connection = Fog::Compute.new(
42
- :provider => :cloudstack,
43
- :cloudstack_api_key => config[:cloudstack_api_key],
44
- :cloudstack_secret_access_key => config[:cloudstack_secret_key],
45
- :cloudstack_host => cloudstack_uri.host,
46
- :cloudstack_port => cloudstack_uri.port,
47
- :cloudstack_path => cloudstack_uri.path,
48
- :cloudstack_scheme => cloudstack_uri.scheme
39
+ :provider => :cloudstack,
40
+ :cloudstack_api_key => config[:cloudstack_api_key],
41
+ :cloudstack_secret_access_key => config[:cloudstack_secret_key],
42
+ :cloudstack_host => cloudstack_uri.host,
43
+ :cloudstack_port => cloudstack_uri.port,
44
+ :cloudstack_path => cloudstack_uri.path,
45
+ :cloudstack_scheme => cloudstack_uri.scheme
49
46
  )
50
47
  end
51
48
 
52
49
  def create_server
53
50
  options = {}
51
+
54
52
  config[:server_name] ||= generate_name(instance.name)
55
53
  options['displayname'] = config[:server_name]
56
- if (!config[:cloudstack_network_id].nil?)
54
+
55
+ if config[:cloudstack_network_id]
57
56
  options['networkids'] = config[:cloudstack_network_id]
58
57
  end
59
58
 
60
- if (!config[:cloudstack_security_group_id].nil?)
59
+ if config[:cloudstack_security_group_id]
61
60
  options['securitygroupids'] = config[:cloudstack_security_group_id]
62
61
  end
63
62
 
64
- if (!config[:cloudstack_ssh_keypair_name].nil?)
63
+ if config[:cloudstack_ssh_keypair_name]
65
64
  options['keypair'] = config[:cloudstack_ssh_keypair_name]
66
65
  end
67
66
 
67
+ if config[:cloudstack_diskoffering_id]
68
+ options['diskofferingid'] = config[:cloudstack_diskoffering_id]
69
+ end
70
+
68
71
  options[:templateid] = config[:cloudstack_template_id]
69
72
  options[:serviceofferingid] = config[:cloudstack_serviceoffering_id]
70
73
  options[:zoneid] = config[:cloudstack_zone_id]
71
74
 
72
75
  debug(options)
73
- # binding.pry
74
76
  compute.deploy_virtual_machine(options)
75
77
  end
76
78
 
@@ -78,22 +80,24 @@ module Kitchen
78
80
  if not config[:name]
79
81
  # Generate what should be a unique server name
80
82
  config[:name] = "#{instance.name}-#{Etc.getlogin}-" +
81
- "#{Socket.gethostname}-#{Array.new(8){rand(36).to_s(36)}.join}"
83
+ "#{Socket.gethostname}-#{Array.new(8){rand(36).to_s(36)}.join}"
82
84
  end
83
85
  if config[:disable_ssl_validation]
84
86
  require 'excon'
85
87
  Excon.defaults[:ssl_verify_peer] = false
86
88
  end
87
89
 
88
-
89
90
  server = create_server
90
91
  debug(server)
91
92
 
92
93
  state[:server_id] = server['deployvirtualmachineresponse'].fetch('id')
93
- start_jobid = {'jobid' => server['deployvirtualmachineresponse'].fetch('jobid')}
94
+ start_jobid = {
95
+ 'jobid' => server['deployvirtualmachineresponse'].fetch('jobid')
96
+ }
94
97
  info("CloudStack instance <#{state[:server_id]}> created.")
95
98
  debug("Job ID #{start_jobid}")
96
- # Cloning the original job id hash because running the query_async_job_result updates the hash to include
99
+ # Cloning the original job id hash because running the
100
+ # query_async_job_result updates the hash to include
97
101
  # more than just the job id (which I could work around, but I'm lazy).
98
102
  jobid = start_jobid.clone
99
103
 
@@ -113,8 +117,12 @@ module Kitchen
113
117
 
114
118
  # jobstatus of 2 is an error response
115
119
  if server_start['queryasyncjobresultresponse'].fetch('jobstatus').to_i == 2
116
- errortext = server_start['queryasyncjobresultresponse'].fetch('jobresult').fetch('errortext')
120
+ errortext = server_start['queryasyncjobresultresponse']
121
+ .fetch('jobresult')
122
+ .fetch('errortext')
123
+
117
124
  error("ERROR! Job failed with #{errortext}")
125
+
118
126
  raise ActionFailed, "Could not create server #{errortext}"
119
127
  end
120
128
 
@@ -124,9 +132,10 @@ module Kitchen
124
132
  debug(server_info)
125
133
  print "(server ready)"
126
134
 
127
-
128
135
  keypair = nil
129
- if ((!config[:keypair_search_directory].nil?) and (File.exist?("#{config[:keypair_search_directory]}/#{config[:cloudstack_ssh_keypair_name]}.pem")))
136
+ if config[:keypair_search_directory] and File.exist?(
137
+ "#{config[:keypair_search_directory]}/#{config[:cloudstack_ssh_keypair_name]}.pem"
138
+ )
130
139
  keypair = "#{config[:keypair_search_directory]}/#{config[:cloudstack_ssh_keypair_name]}.pem"
131
140
  debug("Keypair being used is #{keypair}")
132
141
  elsif File.exist?("./#{config[:cloudstack_ssh_keypair_name]}.pem")
@@ -142,11 +151,9 @@ module Kitchen
142
151
  info("Keypair specified but not found. Using password if enabled.")
143
152
  end
144
153
 
145
- # binding.pry
146
- # debug("Keypair is #{keypair}")
147
154
  state[:hostname] = config[:cloudstack_vm_public_ip] || server_info.fetch('nic').first.fetch('ipaddress')
148
155
 
149
- if (!keypair.nil?)
156
+ if keypair
150
157
  debug("Using keypair: #{keypair}")
151
158
  info("SSH for #{state[:hostname]} with keypair #{config[:cloudstack_ssh_keypair_name]}.")
152
159
  ssh_key = File.read(keypair)
@@ -159,7 +166,7 @@ module Kitchen
159
166
 
160
167
  ssh = Fog::SSH.new(state[:hostname], config[:username], {:keys => keypair})
161
168
  debug("Connecting to : #{state[:hostname]} as #{config[:username]} using keypair #{keypair}.")
162
- elsif (server_info.fetch('passwordenabled') == true)
169
+ elsif server_info.fetch('passwordenabled')
163
170
  password = server_info.fetch('password')
164
171
  config[:password] = password
165
172
  # Print out IP and password so you can record it if you want.
@@ -170,7 +177,7 @@ module Kitchen
170
177
 
171
178
  ssh = Fog::SSH.new(state[:hostname], config[:username], {:password => password})
172
179
  debug("Connecting to : #{state[:hostname]} as #{config[:username]} using password #{password}.")
173
- elsif (!config[:password].nil?)
180
+ elsif config[:password]
174
181
  info("Connecting with user #{config[:username]} with password #{config[:password]}")
175
182
 
176
183
  wait_for_sshd(state[:hostname], config[:username], {:password => config[:password]})
@@ -180,7 +187,6 @@ module Kitchen
180
187
  else
181
188
  info("No keypair specified (or file not found) nor is this a password enabled template. You will have to manually copy your SSH public key to #{state[:hostname]} to use this Kitchen.")
182
189
  end
183
- # binding.pry
184
190
 
185
191
  validate_ssh_connectivity(ssh)
186
192
 
@@ -189,10 +195,10 @@ module Kitchen
189
195
  end
190
196
 
191
197
  def destroy(state)
192
- return if state[:server_id].nil?
198
+ return unless state[:server_id]
193
199
  debug("Destroying #{state[:server_id]}")
194
200
  server = compute.servers.get(state[:server_id])
195
- if not server.nil?
201
+ if server
196
202
  compute.destroy_virtual_machine({'id' => state[:server_id]})
197
203
  end
198
204
  info("CloudStack instance <#{state[:server_id]}> destroyed.")
@@ -201,41 +207,41 @@ module Kitchen
201
207
  end
202
208
 
203
209
  def validate_ssh_connectivity(ssh)
204
- rescue Errno::ETIMEDOUT
205
- debug("SSH connection timed out. Retrying.")
206
- sleep 2
207
- false
208
- rescue Errno::EPERM
209
- debug("SSH connection returned error. Retrying.")
210
- false
211
- rescue Errno::ECONNREFUSED
212
- debug("SSH connection returned connection refused. Retrying.")
213
- sleep 2
214
- false
215
- rescue Errno::EHOSTUNREACH
216
- debug("SSH connection returned host unreachable. Retrying.")
217
- sleep 2
218
- false
219
- rescue Errno::ENETUNREACH
220
- debug("SSH connection returned network unreachable. Retrying.")
221
- sleep 30
222
- false
223
- rescue Net::SSH::Disconnect
224
- debug("SSH connection has been disconnected. Retrying.")
225
- sleep 15
226
- false
227
- rescue Net::SSH::AuthenticationFailed
228
- debug("SSH authentication has failed. Password or Keys may not be in place yet. Retrying.")
229
- sleep 15
230
- false
231
- ensure
232
- sync_time = 0
233
- if (config[:cloudstack_sync_time])
234
- sync_time = config[:cloudstack_sync_time]
235
- end
236
- sleep(sync_time)
237
- debug("Connecting to host and running ls")
238
- ssh.run('ls')
210
+ rescue Errno::ETIMEDOUT
211
+ debug("SSH connection timed out. Retrying.")
212
+ sleep 2
213
+ false
214
+ rescue Errno::EPERM
215
+ debug("SSH connection returned error. Retrying.")
216
+ false
217
+ rescue Errno::ECONNREFUSED
218
+ debug("SSH connection returned connection refused. Retrying.")
219
+ sleep 2
220
+ false
221
+ rescue Errno::EHOSTUNREACH
222
+ debug("SSH connection returned host unreachable. Retrying.")
223
+ sleep 2
224
+ false
225
+ rescue Errno::ENETUNREACH
226
+ debug("SSH connection returned network unreachable. Retrying.")
227
+ sleep 30
228
+ false
229
+ rescue Net::SSH::Disconnect
230
+ debug("SSH connection has been disconnected. Retrying.")
231
+ sleep 15
232
+ false
233
+ rescue Net::SSH::AuthenticationFailed
234
+ debug("SSH authentication has failed. Password or Keys may not be in place yet. Retrying.")
235
+ sleep 15
236
+ false
237
+ ensure
238
+ sync_time = 0
239
+ if (config[:cloudstack_sync_time])
240
+ sync_time = config[:cloudstack_sync_time]
241
+ end
242
+ sleep(sync_time)
243
+ debug("Connecting to host and running ls")
244
+ ssh.run('ls')
239
245
  end
240
246
 
241
247
  def deploy_private_key(ssh)
@@ -250,12 +256,12 @@ module Kitchen
250
256
 
251
257
  if user_public_key
252
258
  ssh.run([
253
- %{mkdir .ssh},
254
- %{echo "#{user_public_key}" >> ~/.ssh/authorized_keys}
255
- ])
259
+ %{mkdir .ssh},
260
+ %{echo "#{user_public_key}" >> ~/.ssh/authorized_keys}
261
+ ])
256
262
  end
257
263
  end
258
-
264
+
259
265
  def generate_name(base)
260
266
  # Generate what should be a unique server name
261
267
  sep = '-'
@@ -276,7 +282,6 @@ module Kitchen
276
282
  end
277
283
  pieces.join sep
278
284
  end
279
-
280
285
  end
281
286
  end
282
287
  end
@@ -21,6 +21,6 @@ module Kitchen
21
21
  module Driver
22
22
 
23
23
  # Version string for Cloudstack Kitchen driver
24
- CLOUDSTACK_VERSION = "0.20.2"
24
+ CLOUDSTACK_VERSION = "0.20.3"
25
25
  end
26
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-cloudstack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.2
4
+ version: 0.20.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Moody
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-09 00:00:00.000000000 Z
11
+ date: 2015-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-kitchen
@@ -84,28 +84,28 @@ dependencies:
84
84
  requirements:
85
85
  - - "~>"
86
86
  - !ruby/object:Gem::Version
87
- version: '0'
87
+ version: '2'
88
88
  type: :development
89
89
  prerelease: false
90
90
  version_requirements: !ruby/object:Gem::Requirement
91
91
  requirements:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: '0'
94
+ version: '2'
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: tailor
97
97
  requirement: !ruby/object:Gem::Requirement
98
98
  requirements:
99
99
  - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: '0'
101
+ version: '1'
102
102
  type: :development
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - "~>"
107
107
  - !ruby/object:Gem::Version
108
- version: '0'
108
+ version: '1'
109
109
  - !ruby/object:Gem::Dependency
110
110
  name: countloc
111
111
  requirement: !ruby/object:Gem::Requirement