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,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