cloudstack_spec 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +127 -0
- data/Rakefile +2 -0
- data/bin/cloudstackspec-init +7 -0
- data/cloudstack_spec.gemspec +29 -0
- data/examples/output_example.txt +56 -0
- data/lib/cloudstack_spec.rb +56 -0
- data/lib/cloudstack_spec/helper.rb +9 -0
- data/lib/cloudstack_spec/helper/api.rb +40 -0
- data/lib/cloudstack_spec/helper/resource.rb +19 -0
- data/lib/cloudstack_spec/matcher.rb +12 -0
- data/lib/cloudstack_spec/matcher/be_allocated.rb +23 -0
- data/lib/cloudstack_spec/matcher/be_created.rb +30 -0
- data/lib/cloudstack_spec/matcher/be_ready.rb +17 -0
- data/lib/cloudstack_spec/matcher/be_running.rb +17 -0
- data/lib/cloudstack_spec/matcher/be_set.rb +18 -0
- data/lib/cloudstack_spec/resource.rb +1 -0
- data/lib/cloudstack_spec/resource/account.rb +102 -0
- data/lib/cloudstack_spec/resource/base.rb +58 -0
- data/lib/cloudstack_spec/resource/domain.rb +71 -0
- data/lib/cloudstack_spec/resource/network.rb +90 -0
- data/lib/cloudstack_spec/resource/project.rb +66 -0
- data/lib/cloudstack_spec/resource/snapshot.rb +53 -0
- data/lib/cloudstack_spec/resource/system_vm.rb +55 -0
- data/lib/cloudstack_spec/resource/template.rb +41 -0
- data/lib/cloudstack_spec/resource/template_from_snapshot.rb +73 -0
- data/lib/cloudstack_spec/resource/virtual_machine.rb +245 -0
- data/lib/cloudstack_spec/resource/vpc.rb +139 -0
- data/lib/cloudstack_spec/resource/vpc_tier.rb +81 -0
- data/lib/cloudstack_spec/resource/zone.rb +51 -0
- data/lib/cloudstack_spec/setup.rb +191 -0
- data/lib/cloudstack_spec/version.rb +3 -0
- data/spec/config.yml +5 -0
- data/spec/lib/1_zone_spec.rb +18 -0
- data/spec/lib/domain_spec.rb +20 -0
- data/spec/lib/network_spec.rb +45 -0
- data/spec/lib/snapshot_spec.rb +41 -0
- data/spec/lib/template_spec.rb +11 -0
- data/spec/lib/virtual_machine_spec.rb +17 -0
- data/spec/lib/vpc_spec.rb +40 -0
- data/spec/preprod/001_zone_spec.rb +65 -0
- data/spec/preprod/010_domain_spec.rb +18 -0
- data/spec/preprod/snapshot_spec.rb +27 -0
- data/spec/spec_helper.rb +31 -0
- metadata +207 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
RSpec::Matchers.define :be_ready do |expected|
|
2
|
+
match do |actual|
|
3
|
+
actual.ready? == true
|
4
|
+
end
|
5
|
+
|
6
|
+
failure_message do |actual|
|
7
|
+
"status: #{actual.ready?}"
|
8
|
+
end
|
9
|
+
|
10
|
+
description do
|
11
|
+
"be ready"
|
12
|
+
end
|
13
|
+
|
14
|
+
# failure_message_when_negated do |actual|
|
15
|
+
# "template status: #{actual}"
|
16
|
+
# end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
RSpec::Matchers.define :be_running do |expected|
|
2
|
+
match do |actual|
|
3
|
+
actual.running? == true
|
4
|
+
end
|
5
|
+
|
6
|
+
failure_message do |actual|
|
7
|
+
"#{actual} status: #{actual.ready?}"
|
8
|
+
end
|
9
|
+
|
10
|
+
description do
|
11
|
+
"be running"
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_when_negated do |actual|
|
15
|
+
"not be running"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
RSpec::Matchers.define :be_set do
|
2
|
+
match do |actual|
|
3
|
+
actual == true
|
4
|
+
end
|
5
|
+
|
6
|
+
failure_message do |actual|
|
7
|
+
"be enabled, return: #{actual}"
|
8
|
+
end
|
9
|
+
|
10
|
+
description do
|
11
|
+
"be enabled"
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_when_negated do |actual|
|
15
|
+
"not be enabled"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'cloudstack_spec/resource/base'
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module CloudstackSpec::Resource
|
2
|
+
class Account < Base
|
3
|
+
# handle domain objects.
|
4
|
+
|
5
|
+
def exist?
|
6
|
+
begin
|
7
|
+
if account.empty?
|
8
|
+
return false
|
9
|
+
else
|
10
|
+
return true
|
11
|
+
end
|
12
|
+
rescue Exception => e
|
13
|
+
return false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def created?
|
18
|
+
if self.exist?
|
19
|
+
puts " Account already exist"
|
20
|
+
return true
|
21
|
+
else
|
22
|
+
account = @connection.create_account(
|
23
|
+
accounttype: 0,
|
24
|
+
email: 'nothing@apache.org',
|
25
|
+
firstname: 'cloudstack_spec',
|
26
|
+
lastname: 'cloudstack_spec',
|
27
|
+
password: 'password',
|
28
|
+
domainid: $domainid ,
|
29
|
+
username: @name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy?
|
34
|
+
sleep(5)
|
35
|
+
if self.exist?
|
36
|
+
job = @connection.delete_account(id: account_id)
|
37
|
+
return job_status?(job['jobid'])
|
38
|
+
else
|
39
|
+
puts " Account does not exist"
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def registerUserKeys
|
46
|
+
keys = user_keys
|
47
|
+
puts " apikey = #{keys['apikey']}"
|
48
|
+
puts " secretkey = #{keys['secretkey']}"
|
49
|
+
return true
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def account
|
57
|
+
accounts = @connection.list_accounts(listall: true, name: @name)
|
58
|
+
accounts = accounts['account'].first
|
59
|
+
if accounts.nil?
|
60
|
+
return {}
|
61
|
+
else
|
62
|
+
return accounts
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def account_id
|
67
|
+
account = @connection.list_accounts(listall: true, name: @name)
|
68
|
+
if account.nil?
|
69
|
+
return ""
|
70
|
+
else
|
71
|
+
return account['account'].first['id']
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def user_keys
|
76
|
+
user = account
|
77
|
+
if user.empty?
|
78
|
+
return ''
|
79
|
+
else
|
80
|
+
user = user['user'].first
|
81
|
+
if user['apikey'].nil? or user['apikey'].empty?
|
82
|
+
keys = @connection.register_user_keys(id: user_id)
|
83
|
+
keys = keys['userkeys']
|
84
|
+
else
|
85
|
+
keys = {'apikey' => user['apikey'], 'secretkey' => user['secretkey']}
|
86
|
+
end
|
87
|
+
return keys
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def user_id
|
92
|
+
if self.exist?
|
93
|
+
userid = @connection.list_accounts(listall: true, name: @name)
|
94
|
+
userid = userid['account'].first['user'].first['id']
|
95
|
+
return userid
|
96
|
+
else
|
97
|
+
return ""
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module CloudstackSpec::Resource
|
2
|
+
class Base
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
def initialize(name=nil)
|
6
|
+
@name = name
|
7
|
+
@connection = CloudstackSpec::Helper::Api.new.connection
|
8
|
+
|
9
|
+
if self.class.name == "CloudstackSpec::Resource::Zone"
|
10
|
+
@zonename = this_zone(name)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
type = self.class.name.split(':')[-1]
|
16
|
+
type.gsub!(/([a-z\d])([A-Z])/, '\1 \2')
|
17
|
+
#type.capitalize!
|
18
|
+
%Q!#{type} "#{@name}"!
|
19
|
+
end
|
20
|
+
|
21
|
+
def inspect
|
22
|
+
to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_ary
|
26
|
+
to_s.split(" ")
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_zone(zonename=nil)
|
30
|
+
if zonename.nil?
|
31
|
+
zone = @connection.list_zones['zone'].first
|
32
|
+
#zonename = zonename['name']
|
33
|
+
else
|
34
|
+
#zonename = zonename
|
35
|
+
zone = @connection.list_zones(:name => zonename)['zone'].first
|
36
|
+
end
|
37
|
+
return zone
|
38
|
+
end
|
39
|
+
|
40
|
+
def job_status?(jobid)
|
41
|
+
job = @connection.query_async_job_result(jobid: jobid)
|
42
|
+
print " async job in progress..."
|
43
|
+
until job['jobstatus'] != 0
|
44
|
+
print '.'
|
45
|
+
job = @connection.query_async_job_result(jobid: jobid)
|
46
|
+
sleep(5)
|
47
|
+
end
|
48
|
+
puts ''
|
49
|
+
if job['jobresultcode'] == 0
|
50
|
+
sleep(5)
|
51
|
+
return true
|
52
|
+
else
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module CloudstackSpec::Resource
|
2
|
+
class Domain < Base
|
3
|
+
# handle domain objects.
|
4
|
+
|
5
|
+
def initialize(name=nil)
|
6
|
+
@name = name
|
7
|
+
@connection = CloudstackSpec::Helper::Api.new.connection
|
8
|
+
|
9
|
+
$domainid = domain_id
|
10
|
+
end
|
11
|
+
|
12
|
+
def exist?
|
13
|
+
begin
|
14
|
+
if domain.empty?
|
15
|
+
return false
|
16
|
+
else
|
17
|
+
return true
|
18
|
+
end
|
19
|
+
rescue Exception => e
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def created?
|
25
|
+
if self.exist?
|
26
|
+
puts " Domain already exist"
|
27
|
+
return true
|
28
|
+
else
|
29
|
+
domain = @connection.create_domain(name: @name)
|
30
|
+
$domainid = domain_id
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy?
|
35
|
+
sleep(5)
|
36
|
+
if self.exist?
|
37
|
+
job = @connection.delete_domain(id: domain_id)
|
38
|
+
return job_status?(job['jobid'])
|
39
|
+
else
|
40
|
+
puts " Domain does not exist"
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def domain
|
50
|
+
domains = @connection.list_domains(listall: true, name: @name)
|
51
|
+
domain = domains['domain'].first
|
52
|
+
if domain.nil?
|
53
|
+
return {}
|
54
|
+
else
|
55
|
+
return domain
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def domain_id
|
60
|
+
domain = @connection.list_domains(listall: true, name: @name)
|
61
|
+
if domain.nil? || domain.empty?
|
62
|
+
return ""
|
63
|
+
else
|
64
|
+
domain['domain'].first['id']
|
65
|
+
return domain['domain'].first['id']
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module CloudstackSpec::Resource
|
2
|
+
class Network < Base
|
3
|
+
# do nothing
|
4
|
+
attr_reader :vpcname, :zonename
|
5
|
+
|
6
|
+
def initialize(name='rspec-net1', vpcname=nil, zonename=nil)
|
7
|
+
@name = name
|
8
|
+
@vpcname = ""
|
9
|
+
@connection = CloudstackSpec::Helper::Api.new.connection
|
10
|
+
@version = CloudstackSpec::Helper::Api.new.version
|
11
|
+
@zone = get_zone(zonename)
|
12
|
+
unless vpcname.nil?
|
13
|
+
vpc = @connection.list_vpcs(listall: true, name: vpcname)
|
14
|
+
end
|
15
|
+
if vpc.nil? || vpc.empty?
|
16
|
+
@vpc = nil
|
17
|
+
else
|
18
|
+
@vpc = vpc['vpc'].first
|
19
|
+
router = @connection.list_routers(vpcid: @vpc['id'])
|
20
|
+
if ! router.empty?
|
21
|
+
@router = router['router'].first
|
22
|
+
end
|
23
|
+
end
|
24
|
+
# @network = @connection.list_networks(:name => @name, zoneid: @zone['id'])
|
25
|
+
end
|
26
|
+
|
27
|
+
def exist?
|
28
|
+
# puts "vpc = #{$vpc}"
|
29
|
+
# puts "vpc= #{@vpcname}, network name = #{@name}"
|
30
|
+
#puts CloudstackSpec::Resource::Vpc('patate').name
|
31
|
+
begin
|
32
|
+
if network.count >= 1
|
33
|
+
return true
|
34
|
+
else
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
rescue Exception => e
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def ready?
|
43
|
+
#
|
44
|
+
# verify the VR is running for this network and run the proper version.
|
45
|
+
vr = @connection.list_routers(:guestnetworkid => state = network.first['id'])['router'].first
|
46
|
+
if ! vr.nil?
|
47
|
+
if vr['state'] == 'Running'
|
48
|
+
if vr['version'] == @version
|
49
|
+
return true
|
50
|
+
else
|
51
|
+
return "VR version #{vr['version']}"
|
52
|
+
end
|
53
|
+
else
|
54
|
+
return "VR state: #{vr['state']}"
|
55
|
+
end
|
56
|
+
else
|
57
|
+
return "vr not found for network #{name}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def create
|
62
|
+
if network.count >= 1
|
63
|
+
offering_id = @connection.list_network_offerings(:name => "DefaultIsolatedNetworkOfferingWithSourceNatService")["networkoffering"].first['id']
|
64
|
+
newnetwork = @connection.create_network(
|
65
|
+
:name => @name,
|
66
|
+
:displaytext => @name,
|
67
|
+
:networkofferingid => offering_id,
|
68
|
+
:zoneid => @zone['id']
|
69
|
+
)
|
70
|
+
else
|
71
|
+
return "network already exist"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def network
|
79
|
+
# CloudStack API does not search by name for networks
|
80
|
+
# networks = @connection.list_networks(zoneid: @zone['id'])['network']
|
81
|
+
networks = @connection.list_networks(:listall => true)['network']
|
82
|
+
if networks.nil?
|
83
|
+
return {}
|
84
|
+
else
|
85
|
+
networks = networks.select { |net| net['name'] == @name }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module CloudstackSpec::Resource
|
2
|
+
class Project < Base
|
3
|
+
# handle domain objects.
|
4
|
+
|
5
|
+
def exist?
|
6
|
+
begin
|
7
|
+
if project.empty?
|
8
|
+
return false
|
9
|
+
else
|
10
|
+
return true
|
11
|
+
end
|
12
|
+
rescue Exception => e
|
13
|
+
return false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def created?
|
18
|
+
if self.exist?
|
19
|
+
puts " Project already exist"
|
20
|
+
return true
|
21
|
+
else
|
22
|
+
project = @connection.create_project(
|
23
|
+
displaytext: @name,
|
24
|
+
name: @name)
|
25
|
+
job_status?(project['jobid'])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def destroy?
|
30
|
+
sleep(5)
|
31
|
+
if self.exist?
|
32
|
+
job = @connection.delete_account(id: account_id)
|
33
|
+
return job_status?(job['jobid'])
|
34
|
+
else
|
35
|
+
puts " Account does not exist"
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def project
|
46
|
+
projects = @connection.list_projects(listall: true, name: @name)
|
47
|
+
project = projects['project'].first
|
48
|
+
if project.nil?
|
49
|
+
return {}
|
50
|
+
else
|
51
|
+
return project
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def project_id
|
56
|
+
proj = project
|
57
|
+
if proj.nil?
|
58
|
+
return ""
|
59
|
+
else
|
60
|
+
return proj['project'].first['id']
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|