cloudstack_spec 0.0.4

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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +13 -0
  5. data/README.md +127 -0
  6. data/Rakefile +2 -0
  7. data/bin/cloudstackspec-init +7 -0
  8. data/cloudstack_spec.gemspec +29 -0
  9. data/examples/output_example.txt +56 -0
  10. data/lib/cloudstack_spec.rb +56 -0
  11. data/lib/cloudstack_spec/helper.rb +9 -0
  12. data/lib/cloudstack_spec/helper/api.rb +40 -0
  13. data/lib/cloudstack_spec/helper/resource.rb +19 -0
  14. data/lib/cloudstack_spec/matcher.rb +12 -0
  15. data/lib/cloudstack_spec/matcher/be_allocated.rb +23 -0
  16. data/lib/cloudstack_spec/matcher/be_created.rb +30 -0
  17. data/lib/cloudstack_spec/matcher/be_ready.rb +17 -0
  18. data/lib/cloudstack_spec/matcher/be_running.rb +17 -0
  19. data/lib/cloudstack_spec/matcher/be_set.rb +18 -0
  20. data/lib/cloudstack_spec/resource.rb +1 -0
  21. data/lib/cloudstack_spec/resource/account.rb +102 -0
  22. data/lib/cloudstack_spec/resource/base.rb +58 -0
  23. data/lib/cloudstack_spec/resource/domain.rb +71 -0
  24. data/lib/cloudstack_spec/resource/network.rb +90 -0
  25. data/lib/cloudstack_spec/resource/project.rb +66 -0
  26. data/lib/cloudstack_spec/resource/snapshot.rb +53 -0
  27. data/lib/cloudstack_spec/resource/system_vm.rb +55 -0
  28. data/lib/cloudstack_spec/resource/template.rb +41 -0
  29. data/lib/cloudstack_spec/resource/template_from_snapshot.rb +73 -0
  30. data/lib/cloudstack_spec/resource/virtual_machine.rb +245 -0
  31. data/lib/cloudstack_spec/resource/vpc.rb +139 -0
  32. data/lib/cloudstack_spec/resource/vpc_tier.rb +81 -0
  33. data/lib/cloudstack_spec/resource/zone.rb +51 -0
  34. data/lib/cloudstack_spec/setup.rb +191 -0
  35. data/lib/cloudstack_spec/version.rb +3 -0
  36. data/spec/config.yml +5 -0
  37. data/spec/lib/1_zone_spec.rb +18 -0
  38. data/spec/lib/domain_spec.rb +20 -0
  39. data/spec/lib/network_spec.rb +45 -0
  40. data/spec/lib/snapshot_spec.rb +41 -0
  41. data/spec/lib/template_spec.rb +11 -0
  42. data/spec/lib/virtual_machine_spec.rb +17 -0
  43. data/spec/lib/vpc_spec.rb +40 -0
  44. data/spec/preprod/001_zone_spec.rb +65 -0
  45. data/spec/preprod/010_domain_spec.rb +18 -0
  46. data/spec/preprod/snapshot_spec.rb +27 -0
  47. data/spec/spec_helper.rb +31 -0
  48. metadata +207 -0
@@ -0,0 +1,53 @@
1
+ module CloudstackSpec::Resource
2
+ class Snapshot < Base
3
+
4
+ def initialize(name='root_disk')
5
+ @volume_name = name
6
+ @connection = CloudstackSpec::Helper::Api.new.connection
7
+ @version = CloudstackSpec::Helper::Api.new.version
8
+ end
9
+
10
+ def exist?
11
+ snapshots = @connection.list_snapshots(volumeid: get_volume_id)
12
+ if ! snapshots.empty?
13
+ if snapshots['count'] >= 1
14
+ return true
15
+ end
16
+ else
17
+ return false
18
+ end
19
+ end
20
+
21
+ def created?
22
+ # start the VM creation job
23
+ # Return {true/false}
24
+ #if self.exist?
25
+ # creation_job = "Already exist"
26
+ # puts " #{creation_job}"
27
+ # return false
28
+ #end
29
+ begin
30
+ newsnap = @connection.create_snapshot(volumeid: get_volume_id)
31
+ creation_job = newsnap['jobid']
32
+ rescue Exception => e
33
+ creation_job = "vm creation fail with #{e.message}"
34
+ end
35
+ if UUID.validate(creation_job) == true
36
+ puts " jobid: #{creation_job}"
37
+ return job_status?(creation_job)
38
+ else
39
+ puts " #{creation_job}"
40
+ return false
41
+ end
42
+ end
43
+
44
+
45
+ private
46
+ def get_volume_id
47
+ vol = @connection.list_volumes(virtualmachineid: $vm['id'])
48
+ vol = vol['volume'].first
49
+ return vol['id']
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,55 @@
1
+ module CloudstackSpec::Resource
2
+ class SystemVm < Base
3
+ # All about system VM...
4
+
5
+ def initialize(name=nil, zonename=nil)
6
+ @name = name
7
+ @connection = CloudstackSpec::Helper::Api.new.connection
8
+
9
+ case @name
10
+ when 'cpvm' && 'consoleproxy'
11
+ @systemvmtype = 'consoleproxy'
12
+ when 'ssvm' && 'secondarystoragevm'
13
+ @systemvmtype = 'secondarystoragevm'
14
+ else
15
+ @systemvmtype = nil
16
+ end
17
+ @zone = get_zone(zonename)
18
+
19
+ @sysvm = @connection.list_system_vms(:systemvmtype => @systemvmtype, zoneid: @zone['id'])
20
+ @vmcount = @sysvm['count']
21
+ @sysvm = @sysvm['systemvm'].first
22
+ @runner = Specinfra::Runner
23
+ end
24
+
25
+ def exist?
26
+ begin
27
+ if @vmcount.nil?
28
+ return false
29
+ else
30
+ return true
31
+ end
32
+ rescue Exception => e
33
+ return false
34
+ end
35
+ end
36
+
37
+ def running?
38
+ begin
39
+ if @sysvm['state'] == 'Running'
40
+ return true
41
+ else
42
+ return false
43
+ end
44
+ rescue
45
+ return false
46
+ end
47
+ end
48
+
49
+ def reachable?(port, proto, timeout)
50
+ ip = @sysvm['publicip']
51
+ @runner.check_host_is_reachable(ip, port, proto, timeout)
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,41 @@
1
+ module CloudstackSpec::Resource
2
+ class Template < Base
3
+ # do nothing
4
+
5
+ def tpl
6
+ @connection.list_templates(:templatefilter => "all", :name => name)
7
+ end
8
+
9
+ def exist?
10
+ begin
11
+ if tpl['count'].nil?
12
+ return false
13
+ else
14
+ return true
15
+ end
16
+ rescue Exception => e
17
+ return false
18
+ end
19
+ end
20
+
21
+ def ready?
22
+ if ! tpl["count"].nil?
23
+ isready = tpl["template"].first["isready"]
24
+ if isready
25
+ return true
26
+ else
27
+ return tpl["template"].first["status"]
28
+ end
29
+ else
30
+ return "#{name}: not found"
31
+ #return false
32
+ end
33
+ end
34
+
35
+ def create_from_vm(origin_vm)
36
+ origin_vm
37
+ end
38
+
39
+
40
+ end
41
+ end
@@ -0,0 +1,73 @@
1
+ module CloudstackSpec::Resource
2
+ class TemplateFromSnapshot < Base
3
+ # do nothing
4
+
5
+ def tpl
6
+ @connection.list_templates(:templatefilter => "all", :name => name)
7
+ end
8
+
9
+ def exist?
10
+ begin
11
+ if tpl['count'].nil?
12
+ return false
13
+ else
14
+ return true
15
+ end
16
+ rescue Exception => e
17
+ return false
18
+ end
19
+ end
20
+
21
+ def ready?
22
+ if ! tpl["count"].nil?
23
+ isready = tpl["template"].first["isready"]
24
+ if isready
25
+ return true
26
+ else
27
+ return tpl["template"].first["status"]
28
+ end
29
+ else
30
+ return "#{name}: not found"
31
+ #return false
32
+ end
33
+ end
34
+
35
+ def created?
36
+ if self.exist?
37
+ return 'template already exist'
38
+ else
39
+ snapshot = get_snapshot
40
+ if ! snapshot.empty?
41
+ new_template = @connection.create_template(
42
+ name: @name,
43
+ displaytext: @name,
44
+ ostypeid: get_vm['ostypeid'],
45
+ passwordenabled: 'true',
46
+ snapshotid: get_snapshot['id']
47
+ )
48
+ creation_job = new_template['jobid']
49
+ end
50
+ end
51
+ end
52
+
53
+
54
+ private
55
+
56
+ def get_vm
57
+ vm = @connection.list_virtual_machines(name: @name)
58
+ vm = vm['virtualmachine'].first
59
+ return vm
60
+ end
61
+
62
+ def get_volume
63
+ vol = @connection.list_volumes(virtualmachineid: get_vm['id'])
64
+ return vol['volume'].first
65
+ end
66
+
67
+ def get_snapshot
68
+ snapshot = @connection.list_snapshots(volumeid: get_volume['id'])
69
+ return snapshot['snapshot'].first
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,245 @@
1
+ module CloudstackSpec::Resource
2
+ class VirtualMachine < Base
3
+ # do nothing
4
+ attr_reader :name, :template_name, :zonename
5
+
6
+ def initialize(name='rspec-test1', zonename=nil)
7
+ @name = name
8
+ @template_name = ''
9
+ @connection = CloudstackSpec::Helper::Api.new.connection
10
+ @zone = get_zone(zonename)
11
+ @runner = Specinfra::Runner
12
+ end
13
+
14
+ def exist?
15
+ begin
16
+ if vm.empty?
17
+ return false
18
+ else
19
+ return true
20
+ end
21
+ rescue Exception => e
22
+ return false
23
+ end
24
+ end
25
+
26
+ def running?
27
+ begin
28
+ if vm['state'] == 'Running'
29
+ return true
30
+ else
31
+ return false
32
+ end
33
+ rescue
34
+ return false
35
+ end
36
+ end
37
+
38
+ def reachable?(port, proto, timeout)
39
+ pf_rule = get_pf_rule
40
+ if pf_rule.empty?
41
+ ip = vm['nic'].first['ipaddress']
42
+ else
43
+ ip = pf_rule['ipaddress']
44
+ port = pf_rule['publicport']
45
+ proto = pf_rule['protocol']
46
+ end
47
+ @runner.check_host_is_reachable(ip, port, proto, timeout)
48
+ end
49
+
50
+ def created?
51
+ # start the VM creation job
52
+ # Return {true/false}
53
+ if self.exist?
54
+ creation_job = "Already exist"
55
+ puts " #{creation_job}"
56
+ return false
57
+ end
58
+
59
+ if ! self.template_name.nil?
60
+ if validate_template_status == false
61
+ puts " Template not valid"
62
+ end
63
+ end
64
+ begin
65
+ newvm = create_virtual_machine(@name)
66
+ creation_job = newvm['jobid']
67
+ rescue Exception => exception
68
+ creation_job = "vm creation fail with #{exception.message}"
69
+ end
70
+ if UUID.validate(creation_job) == true
71
+ return job_status?(creation_job)
72
+ else
73
+ puts " #{creation_job}"
74
+ return false
75
+ end
76
+ end
77
+
78
+ def destroy?
79
+ if self.exist?
80
+ job = @connection.destroy_virtual_machine(id: vm['id'], expunge: true)
81
+ job_status?(job['jobid'])
82
+ else
83
+ puts " Does not exist"
84
+ return false
85
+ end
86
+ end
87
+
88
+ def open_pf_ssh
89
+ # open port forwarding for ssh (tcp:22)
90
+ port = 22
91
+ proto = 'tcp'
92
+ sleep(5) # give move time to the vm to complete booting.
93
+ if get_pf_rule.empty?
94
+ new_rule = @connection.create_port_forwarding_rule(
95
+ ipaddressid: publicip_id,
96
+ virtualmachineid: vm['id'],
97
+ privateport: port,
98
+ publicport: port,
99
+ networkid: vm['nic'].first['networkid'],
100
+ protocol: proto )
101
+ else
102
+ #puts " Port Forwarging rule already exist"
103
+ end
104
+ return true
105
+
106
+ end
107
+
108
+
109
+ private
110
+
111
+ def validate_template_status
112
+ # if template_name define
113
+ # make sure the template is ready otherwise, wait.
114
+ # puts get_template
115
+ if get_template['isready']
116
+ template_status = true
117
+ else
118
+ until get_template['isready']
119
+ if get_template['status'].nil?
120
+ puts " Template not ready: #{get_template['name']}"
121
+ puts " ERROR in CloudStack: status is empty"
122
+ print " Template download in progress..."
123
+ until ! get_template['status'].nil?
124
+ print '.'
125
+ sleep 5
126
+ end # end loop
127
+ end
128
+ if get_template['status'].include? "%"
129
+ puts " Template not ready: #{get_template['name']}"
130
+ print " Template download in progress..."
131
+ until ! get_template['status'].include? "%"
132
+ print '.'
133
+ sleep 5
134
+ end # end loop
135
+ elsif get_template['status'].include? "Installing"
136
+ puts " Template not ready: #{get_template['name']}"
137
+ print " Template is installing..."
138
+ until ! get_template['status'].include? "Installing"
139
+ print '.'
140
+ sleep 5
141
+ end # end loop
142
+ else
143
+ template_status = false
144
+ break
145
+ end
146
+ end # end loop
147
+ if get_template['isready']
148
+ template_status = true
149
+ end
150
+ end
151
+ return template_status
152
+ end
153
+
154
+
155
+ def vm
156
+ vm = @connection.list_virtual_machines(name: @name, zoneid: @zone['id'])
157
+ if vm.empty?
158
+ $vm = {}
159
+ return {}
160
+ else
161
+ $vm = vm['virtualmachine'].first
162
+ return vm['virtualmachine'].first
163
+ end
164
+ end
165
+
166
+ def get_template
167
+ tpl = @connection.list_templates(:templatefilter => "featured", id: get_template_id)
168
+ tpl = tpl['template'].first
169
+ return tpl
170
+ end
171
+
172
+ def get_template_id
173
+ if self.template_name.empty?
174
+ tpl = @connection.list_templates(:templatefilter => "featured", :zoneid => @zone['id'])
175
+ else
176
+ tpl = @connection.list_templates(:name => self.template_name, :templatefilter => "all", :zoneid => @zone['id'])
177
+ end
178
+ if ! tpl.empty?
179
+ tpl = tpl['template'].first['id']
180
+ return tpl
181
+ else
182
+ return 'no featured template found'
183
+ end
184
+ end
185
+
186
+ def get_network_id(network_name)
187
+ # CloudStack API does not search by name for networks
188
+ networks = @connection.list_networks(zoneid: @zone['id'])['network']
189
+ return "NO NETWORK FOUND" if networks.nil?
190
+ networks = networks.select { |net| net['name'] == network_name }
191
+ return networks.first['id']
192
+ end
193
+
194
+ def get_systemoffering_id(offering_name=nil)
195
+ if offering_name.nil?
196
+ systemofferingid = @connection.list_service_offerings()['serviceoffering'].first['id']
197
+ else
198
+ systemofferingid = @connection.list_service_offerings(:name => offering_name)['serviceoffering'].first['id']
199
+ end
200
+ if UUID.validate(systemofferingid)
201
+ return systemofferingid
202
+ else
203
+ return "invalid systemoffering"
204
+ end
205
+ end
206
+
207
+ def create_virtual_machine(name='rspec-test1',network_name='tier11',offering_name=nil)
208
+ networkid = get_network_id(network_name)
209
+ jobid = @connection.deploy_virtual_machine(
210
+ zoneid: @zone['id'],
211
+ serviceofferingid: get_systemoffering_id,
212
+ templateid: get_template_id,
213
+ name: name,
214
+ displayname: name,
215
+ networkids: networkid
216
+ )
217
+ end
218
+
219
+ def publicip_id
220
+ # public ip not used for SourceNAT
221
+ public_ip = @connection.list_public_ip_addresses(vpcid: $vpc['id'], issourcenat: false)
222
+ if public_ip.empty?
223
+ puts " Associating Public IP to VPC"
224
+ newip = @connection.associate_ip_address(vpcid: $vpc['id'])
225
+ sleep 5
226
+ public_ip = @connection.list_public_ip_addresses(vpcid: $vpc['id'], issourcenat: false)
227
+ end
228
+ public_ip = public_ip['publicipaddress'].first
229
+ return public_ip['id']
230
+ end
231
+
232
+ def get_pf_rule
233
+ # retrieve Port Forwarding Rule for the VM if it exist
234
+ pf_rules = @connection.list_port_forwarding_rules
235
+ pf_rules = pf_rules['portforwardingrule']
236
+ if pf_rules.nil?
237
+ return {}
238
+ else
239
+ pf_rule = pf_rules.select { |rule| rule['virtualmachineid'] == vm['id'] }
240
+ pf_rule.first
241
+ end
242
+ end
243
+
244
+ end
245
+ end