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,139 @@
|
|
1
|
+
module CloudstackSpec::Resource
|
2
|
+
class Vpc < Base
|
3
|
+
# do nothing
|
4
|
+
|
5
|
+
def initialize(name='rspec-vpc1', zonename=nil)
|
6
|
+
@name = name
|
7
|
+
@connection = CloudstackSpec::Helper::Api.new.connection
|
8
|
+
@zone = get_zone(zonename)
|
9
|
+
@runner = Specinfra::Runner
|
10
|
+
#vpc = @connection.list_vpcs(listall: true, name: @name)
|
11
|
+
if vpc.empty?
|
12
|
+
@router = nil
|
13
|
+
else
|
14
|
+
@router = @connection.list_routers(vpcid: vpc['id'])['router'].first
|
15
|
+
end
|
16
|
+
$vpc = vpc
|
17
|
+
end
|
18
|
+
|
19
|
+
def exist?
|
20
|
+
if vpc.empty?
|
21
|
+
return false
|
22
|
+
else
|
23
|
+
return true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def ready?
|
28
|
+
begin
|
29
|
+
if @router['state'] == 'Running'
|
30
|
+
if @router['version'] == CloudstackSpec::Helper::Api.new.version
|
31
|
+
return true
|
32
|
+
else
|
33
|
+
return "VR version #{@router['version']}"
|
34
|
+
end
|
35
|
+
else
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
rescue
|
39
|
+
return false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def reachable?(port, proto, timeout)
|
44
|
+
ip = @router['publicip']
|
45
|
+
@runner.check_host_is_reachable(ip, port, proto, timeout)
|
46
|
+
end
|
47
|
+
|
48
|
+
def created?(cidr='10.10.0.0/22')
|
49
|
+
if self.exist?
|
50
|
+
puts " VPC already exist"
|
51
|
+
return true
|
52
|
+
else
|
53
|
+
job = @connection.create_vpc(
|
54
|
+
:name => @name,
|
55
|
+
:displaytext => @name,
|
56
|
+
:cidr => cidr,
|
57
|
+
:vpcofferingid => vpc_offering_id,
|
58
|
+
:zoneid => @zone['id']
|
59
|
+
)
|
60
|
+
job_status = job_status?(job['jobid'])
|
61
|
+
@router = @connection.list_routers(vpcid: vpc['id'])['router'].first
|
62
|
+
$vpc = vpc
|
63
|
+
return job_status
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def destroy?
|
69
|
+
sleep(5)
|
70
|
+
if self.exist?
|
71
|
+
job = @connection.delete_vpc(id: vpc['id'])
|
72
|
+
return job_status?(job['jobid'])
|
73
|
+
else
|
74
|
+
puts " Does not exist"
|
75
|
+
return false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def enable_remote_vpn
|
80
|
+
newvpn = @connection.create_remote_access_vpn(publicipid: publicip_snat_id)
|
81
|
+
job_status?(newvpn['jobid'])
|
82
|
+
vpn = @connection.list_remote_access_vpns(publicipid: publicip_snat_id)
|
83
|
+
vpn = vpn['remoteaccessvpn'].first
|
84
|
+
if ! vpn.empty?
|
85
|
+
return true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def remote_vpn_enabled?
|
90
|
+
a = @connection.list_remote_access_vpns(listall: true, publicipid: publicip_snat_id)
|
91
|
+
if a.empty?
|
92
|
+
false
|
93
|
+
else
|
94
|
+
puts " Pubic IP = #{a['remoteaccessvpn'].first['publicip']}"
|
95
|
+
puts " PreShared Key = #{a['remoteaccessvpn'].first['presharedkey']}"
|
96
|
+
true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def vpc
|
104
|
+
vpc = @connection.list_vpcs(listall: true, name: @name)
|
105
|
+
if vpc.empty?
|
106
|
+
return {}
|
107
|
+
else
|
108
|
+
return vpc['vpc'].first
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def first_vm_id
|
113
|
+
vm = @connection.list_virtual_machines(vpcid: vpc['id'])
|
114
|
+
if vm.empty?
|
115
|
+
return false
|
116
|
+
end
|
117
|
+
vm['virtualmachine'].first['id']
|
118
|
+
end
|
119
|
+
|
120
|
+
def first_tier_id
|
121
|
+
net = @connection.list_vpcs(id: vpc['id'])
|
122
|
+
net = net['vpc'].first['network'].first['id']
|
123
|
+
return net
|
124
|
+
end
|
125
|
+
|
126
|
+
def publicip_snat_id
|
127
|
+
# get the id of the sourceNAT public IP for the current VPC
|
128
|
+
public_ip = @connection.list_public_ip_addresses(vpcid: vpc['id'], issourcenat: true)
|
129
|
+
public_ip = public_ip['publicipaddress'].first
|
130
|
+
return public_ip['id']
|
131
|
+
end
|
132
|
+
|
133
|
+
def vpc_offering_id(offering_name="Default VPC offering")
|
134
|
+
offering = @connection.list_vpc_offerings(name: offering_name)['vpcoffering'].first
|
135
|
+
return offering['id']
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module CloudstackSpec::Resource
|
2
|
+
class VpcTier < Base
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
def initialize(name='tier11', zonename=nil)
|
6
|
+
@name = name
|
7
|
+
@connection = CloudstackSpec::Helper::Api.new.connection
|
8
|
+
@zone = get_zone(zonename)
|
9
|
+
@runner = Specinfra::Runner
|
10
|
+
end
|
11
|
+
|
12
|
+
def exist?
|
13
|
+
begin
|
14
|
+
if !get_tier.empty?
|
15
|
+
return true
|
16
|
+
else
|
17
|
+
return false
|
18
|
+
end
|
19
|
+
rescue Exception => e
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def created?
|
25
|
+
unless self.exist?
|
26
|
+
@connection.create_network(
|
27
|
+
:name => @name,
|
28
|
+
:displaytext => @name,
|
29
|
+
:networkofferingid => get_offering_id,
|
30
|
+
:zoneid => @zone['id'],
|
31
|
+
:vpcid => $vpc['id'],
|
32
|
+
:gateway => '10.10.0.1',
|
33
|
+
:netmask => '255.255.255.0',
|
34
|
+
:aclid => get_acl_id
|
35
|
+
)
|
36
|
+
else
|
37
|
+
print " already exist"
|
38
|
+
return true
|
39
|
+
#return false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy?
|
44
|
+
if self.exist?
|
45
|
+
sleep(5)
|
46
|
+
job = @connection.delete_network(id: get_tier['id'])
|
47
|
+
job_status?(job['jobid'])
|
48
|
+
else
|
49
|
+
puts " Does not exist"
|
50
|
+
return false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def get_tier
|
58
|
+
# CloudStack API does not search by name for networks
|
59
|
+
networks = @connection.list_networks(:listall => true, vpcid: $vpc['id'])
|
60
|
+
networks = networks['network']
|
61
|
+
if networks.nil?
|
62
|
+
return {}
|
63
|
+
else
|
64
|
+
network = networks.select { |net| net['name'] == @name }
|
65
|
+
network = network.first
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_offering_id
|
70
|
+
offering = @connection.list_network_offerings(:name => "DefaultIsolatedNetworkOfferingForVpcNetworks")
|
71
|
+
offering = offering["networkoffering"].first
|
72
|
+
return offering['id']
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_acl_id(name='default_allow')
|
76
|
+
acl = @connection.list_network_a_c_l_lists(name: name)
|
77
|
+
acl = acl['networkacllist'].first
|
78
|
+
return acl['id']
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module CloudstackSpec::Resource
|
2
|
+
class Zone < Base
|
3
|
+
# All about zone...
|
4
|
+
#####
|
5
|
+
def exist?
|
6
|
+
#zone = @connection.list_zone(:name => name)
|
7
|
+
if @zonename.nil?
|
8
|
+
return false
|
9
|
+
else
|
10
|
+
return true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def allocated?
|
15
|
+
if @zonename['allocationstate'] == 'Enabled'
|
16
|
+
return true
|
17
|
+
else
|
18
|
+
return @zonename['allocationstate']
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def local_storage
|
23
|
+
return @zonename['localstorageenabled']
|
24
|
+
end
|
25
|
+
|
26
|
+
def security_group
|
27
|
+
return @zonename['securitygroupsenabled']
|
28
|
+
end
|
29
|
+
|
30
|
+
def network_type
|
31
|
+
# return "Basic" or "Advanced"
|
32
|
+
return @zonename['networktype']
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def this_zone(name)
|
38
|
+
if name.nil?
|
39
|
+
# if zone name not define, thake the first one
|
40
|
+
zone = @connection.list_zones['zone'].first
|
41
|
+
@name = zone['name']
|
42
|
+
else
|
43
|
+
@name = name
|
44
|
+
zone = @connection.list_zones(:name => name)['zone'].first
|
45
|
+
end
|
46
|
+
return zone
|
47
|
+
end
|
48
|
+
|
49
|
+
# end private
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module CloudstackSpec
|
5
|
+
class Setup
|
6
|
+
def self.run
|
7
|
+
|
8
|
+
create_initial
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.create_initial
|
12
|
+
print "Create base for cloudstack_spec? y/n: "
|
13
|
+
auto_config = $stdin.gets.chomp
|
14
|
+
if auto_config =~ (/(true|t|yes|y|1)$/i)
|
15
|
+
[ 'spec', "spec/lib" ].each { |dir| safe_mkdir(dir) }
|
16
|
+
safe_create_config
|
17
|
+
safe_create_spec
|
18
|
+
safe_create_spec_helper
|
19
|
+
# safe_create_rakefile
|
20
|
+
puts "Make sure to Update file: spec/config.yml"
|
21
|
+
else
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.safe_create_config
|
27
|
+
# create config.yml file.
|
28
|
+
content = <<-EOF
|
29
|
+
cloudstack:
|
30
|
+
url: http://127.0.0.1:8080/client/api
|
31
|
+
api_key: c0dD7KjmFF4ixekZyQZJa7xPrW6y5-egZU1FGqq2u0DITs1qSluyP3giLDJ2msg0y1gPeARq4ZyvK-j48QP8hQ
|
32
|
+
secret_key: GYfIZjsjSIHKO_227M6tvLns86QJEzqJVzc8xobqfgg03YeDUYk2QTGBgB6IeaHfSROW61uPm-koO2iDDvq5HQ
|
33
|
+
use_ssl: false
|
34
|
+
|
35
|
+
EOF
|
36
|
+
|
37
|
+
if File.exists? "spec/config.yml"
|
38
|
+
old_content = File.read("spec/config.yml")
|
39
|
+
if old_content != content
|
40
|
+
$stderr.puts "!! spec/config.yml already exists and differs from template"
|
41
|
+
end
|
42
|
+
else
|
43
|
+
File.open("spec/config.yml", 'w') do |f|
|
44
|
+
f.puts content
|
45
|
+
end
|
46
|
+
puts " + spec/config.yml"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.safe_create_spec
|
51
|
+
content = <<-EOF
|
52
|
+
require 'spec_helper'
|
53
|
+
|
54
|
+
describe zone do
|
55
|
+
it { should exist }
|
56
|
+
it { should be_allocated }
|
57
|
+
# its(:local_storage) { should_not be_set }
|
58
|
+
# its(:security_group) { should_not be_set }
|
59
|
+
# its(:network_type) { should match("Advanced") }
|
60
|
+
end
|
61
|
+
|
62
|
+
%w(consoleproxy secondarystoragevm).each do |svm|
|
63
|
+
describe system_vm(svm) do
|
64
|
+
it { should exist }
|
65
|
+
it { should be_running }
|
66
|
+
it { should be_reachable }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
EOF
|
71
|
+
|
72
|
+
if File.exists? "spec/lib/001_zone_spec.rb"
|
73
|
+
old_content = File.read("spec/lib/001_zone_spec.rb")
|
74
|
+
if old_content != content
|
75
|
+
$stderr.puts "!! spec/lib/zone_spec.rb already exists and differs from template"
|
76
|
+
end
|
77
|
+
else
|
78
|
+
File.open("spec/lib/001_zone_spec.rb", 'w') do |f|
|
79
|
+
f.puts content
|
80
|
+
end
|
81
|
+
puts " + spec/lib/001_zone_spec.rb"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.safe_mkdir(dir)
|
86
|
+
if File.exists? dir
|
87
|
+
unless File.directory? dir
|
88
|
+
$stderr.puts "!! #{dir} already exists and is not a directory"
|
89
|
+
end
|
90
|
+
else
|
91
|
+
FileUtils.mkdir dir
|
92
|
+
puts " + #{dir}/"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.safe_create_spec_helper
|
97
|
+
requirements = []
|
98
|
+
content = ERB.new(spec_helper_template, nil, '-').result(binding)
|
99
|
+
if File.exists? 'spec/spec_helper.rb'
|
100
|
+
old_content = File.read('spec/spec_helper.rb')
|
101
|
+
if old_content != content
|
102
|
+
$stderr.puts "!! spec/spec_helper.rb already exists and differs from template"
|
103
|
+
end
|
104
|
+
else
|
105
|
+
File.open('spec/spec_helper.rb', 'w') do |f|
|
106
|
+
f.puts content
|
107
|
+
end
|
108
|
+
puts ' + spec/spec_helper.rb'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.safe_create_rakefile
|
113
|
+
content = <<-EOF
|
114
|
+
require 'rake'
|
115
|
+
require 'rspec/core/rake_task'
|
116
|
+
|
117
|
+
task :spec => 'spec:all'
|
118
|
+
task :default => :spec
|
119
|
+
|
120
|
+
namespace :spec do
|
121
|
+
targets = []
|
122
|
+
Dir.glob('./spec/*').each do |dir|
|
123
|
+
next unless File.directory?(dir)
|
124
|
+
targets << File.basename(dir)
|
125
|
+
end
|
126
|
+
|
127
|
+
task :all => targets
|
128
|
+
task :default => :all
|
129
|
+
|
130
|
+
targets.each do |target|
|
131
|
+
desc "Run serverspec tests to #{target}"
|
132
|
+
RSpec::Core::RakeTask.new(target.to_sym) do |t|
|
133
|
+
ENV['TARGET_HOST'] = target
|
134
|
+
t.pattern = "spec/#{target}/*_spec.rb"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
EOF
|
140
|
+
if File.exists? 'Rakefile'
|
141
|
+
old_content = File.read('Rakefile')
|
142
|
+
if old_content != content
|
143
|
+
$stderr.puts "!! Rakefile already exists and differs from template"
|
144
|
+
end
|
145
|
+
else
|
146
|
+
File.open('Rakefile', 'w') do |f|
|
147
|
+
f.puts content
|
148
|
+
end
|
149
|
+
puts ' + Rakefile'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.spec_helper_template
|
154
|
+
template = <<-EOF
|
155
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
156
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
157
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
158
|
+
# loaded once.
|
159
|
+
#
|
160
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
161
|
+
require 'yaml'
|
162
|
+
require 'cloudstack_ruby_client'
|
163
|
+
require 'uuid'
|
164
|
+
require 'cloudstack_spec'
|
165
|
+
require 'rspec/expectations'
|
166
|
+
|
167
|
+
require 'serverspec'
|
168
|
+
#require 'specinfra'
|
169
|
+
set :backend, :exec
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
RSpec.configure do |config|
|
174
|
+
config.run_all_when_everything_filtered = true
|
175
|
+
# config.filter_run :focus
|
176
|
+
|
177
|
+
# Run specs in random order to surface order dependencies. If you find an
|
178
|
+
# order dependency and want to debug it, you can fix the order by providing
|
179
|
+
# the seed, which is printed after each run.
|
180
|
+
# --seed 1234
|
181
|
+
config.order = 'defined'
|
182
|
+
config.formatter = 'documentation'
|
183
|
+
config.color = true
|
184
|
+
end
|
185
|
+
|
186
|
+
EOF
|
187
|
+
template
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
end
|