kitchen-cloudstack 0.20.2 → 0.20.3

Sign up to get free protection for your applications and to get access to all the features.
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