vcloud-core 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +9 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.md +103 -0
  5. data/Rakefile +18 -0
  6. data/bin/vcloud-query +84 -0
  7. data/jenkins.sh +10 -0
  8. data/lib/vcloud/core.rb +23 -0
  9. data/lib/vcloud/core/compute_metadata.rb +13 -0
  10. data/lib/vcloud/core/edge_gateway.rb +46 -0
  11. data/lib/vcloud/core/entity.rb +23 -0
  12. data/lib/vcloud/core/metadata_helper.rb +29 -0
  13. data/lib/vcloud/core/org_vdc_network.rb +102 -0
  14. data/lib/vcloud/core/query.rb +142 -0
  15. data/lib/vcloud/core/vapp.rb +118 -0
  16. data/lib/vcloud/core/vapp_template.rb +39 -0
  17. data/lib/vcloud/core/vdc.rb +37 -0
  18. data/lib/vcloud/core/version.rb +5 -0
  19. data/lib/vcloud/core/vm.rb +162 -0
  20. data/lib/vcloud/fog.rb +5 -0
  21. data/lib/vcloud/fog/content_types.rb +20 -0
  22. data/lib/vcloud/fog/model_interface.rb +33 -0
  23. data/lib/vcloud/fog/relation.rb +8 -0
  24. data/lib/vcloud/fog/service_interface.rb +257 -0
  25. data/spec/spec_helper.rb +26 -0
  26. data/spec/support/stub_fog_interface.rb +59 -0
  27. data/spec/vcloud/core/edge_gateway_spec.rb +79 -0
  28. data/spec/vcloud/core/metadata_helper_spec.rb +89 -0
  29. data/spec/vcloud/core/org_vdc_network_spec.rb +257 -0
  30. data/spec/vcloud/core/query_spec.rb +111 -0
  31. data/spec/vcloud/core/vapp_spec.rb +173 -0
  32. data/spec/vcloud/core/vapp_template_spec.rb +77 -0
  33. data/spec/vcloud/core/vdc_spec.rb +68 -0
  34. data/spec/vcloud/core/vm_spec.rb +290 -0
  35. data/spec/vcloud/data/basic_preamble_test.erb +8 -0
  36. data/spec/vcloud/data/basic_preamble_test.erb.OUT +8 -0
  37. data/spec/vcloud/fog/fog_model_interface_spec.rb +25 -0
  38. data/spec/vcloud/fog/service_interface_spec.rb +30 -0
  39. data/vcloud-core.gemspec +30 -0
  40. metadata +198 -0
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ module Vcloud
4
+ module Core
5
+ describe MetadataHelper do
6
+ context "get_metadata" do
7
+
8
+ it "should process valid metadata types" do
9
+ metadata_entries = [
10
+ {
11
+ :type => Fog::ContentTypes::METADATA,
12
+ :Key => 'role_name',
13
+ :TypedValue => {
14
+ :xsi_type => 'MetadataStringValue',
15
+ :Value => 'james-bond'
16
+ }},
17
+ {
18
+ :type => Fog::ContentTypes::METADATA,
19
+ :Key => "server_number",
20
+ :TypedValue => {:xsi_type => "MetadataNumberValue", :Value => "-10"}
21
+ },
22
+ {
23
+ :type => Fog::ContentTypes::METADATA,
24
+ :Key => "created_at",
25
+ :TypedValue => {:xsi_type => "MetadataDateTimeValue", :Value => "2013-12-16T14:30:05.000Z"}
26
+ },
27
+ {
28
+ :type => Fog::ContentTypes::METADATA,
29
+ :Key => "daily_shutdown",
30
+ :TypedValue => {:xsi_type => "MetadataBooleanValue", :Value => "false"}
31
+ }
32
+ ]
33
+ metadata = MetadataHelper.extract_metadata(metadata_entries)
34
+ metadata.count.should == 4
35
+ metadata[:role_name].should == 'james-bond'
36
+ metadata[:server_number].should == -10
37
+ metadata[:created_at].should == DateTime.parse("2013-12-16T14:30:05.000Z")
38
+ metadata[:daily_shutdown].should == false
39
+ end
40
+
41
+ it "should skip metadata entry if entry type is not application/vnd.vmware.vcloud.metadata.value+xml" do
42
+ metadata_entries = [
43
+ {
44
+ :type => Fog::ContentTypes::METADATA,
45
+ :Key => 'role_name',
46
+ :TypedValue => {
47
+ :xsi_type => 'MetadataStringValue',
48
+ :Value => 'james-bond'
49
+ }},
50
+ {
51
+ :Key => "untyped_key",
52
+ :TypedValue => {:xsi_type => "MetadataNumberValue", :Value => "-10"}
53
+ },
54
+
55
+ ]
56
+ metadata = MetadataHelper.extract_metadata(metadata_entries)
57
+ metadata.count.should == 1
58
+ metadata.keys.should_not include :untyped_key
59
+ end
60
+
61
+ it "should include unrecognized metadata types" do
62
+ metadata_entries = [
63
+ {
64
+ :type => Fog::ContentTypes::METADATA,
65
+ :Key => 'role_name',
66
+ :TypedValue => {
67
+ :xsi_type => 'MetadataStringValue',
68
+ :Value => 'james-bond'
69
+ }},
70
+ {
71
+ :type => Fog::ContentTypes::METADATA,
72
+ :Key => "unrecognized_type_key",
73
+ :TypedValue => {:xsi_type => "MetadataWholeNumberValue", :Value => "-10"}
74
+ },
75
+
76
+ ]
77
+ metadata = MetadataHelper.extract_metadata(metadata_entries)
78
+ metadata.count.should == 2
79
+ metadata.keys.should include :unrecognized_type_key
80
+ end
81
+
82
+
83
+ end
84
+
85
+
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,257 @@
1
+ require 'spec_helper'
2
+
3
+ module Vcloud
4
+ module Core
5
+ describe OrgVdcNetwork do
6
+
7
+ before (:each) do
8
+ @vdc_id = '12345678-1234-1234-1234-000000111111'
9
+ @edgegw_id = '12345678-1234-1234-1234-000000222222'
10
+ @net_id = '12345678-1234-1234-1234-000000333333'
11
+ @vdc_name = 'test-vdc-1'
12
+ @net_name = 'test-net-1'
13
+ @mock_fog_interface = StubFogInterface.new
14
+ Vcloud::Fog::ServiceInterface.stub(:new).and_return(@mock_fog_interface)
15
+ Vdc.any_instance.stub(:id).and_return(@vdc_id)
16
+ @mock_vdc = double(:vdc, :id => @vdc_id)
17
+ Vdc.stub(:get_by_name).and_return(@mock_vdc)
18
+ end
19
+
20
+ context "Class public interface" do
21
+ it { OrgVdcNetwork.should respond_to(:provision) }
22
+ end
23
+
24
+ context "Object public interface" do
25
+ subject { OrgVdcNetwork.new(@net_id) }
26
+ it { should respond_to(:id) }
27
+ it { should respond_to(:name) }
28
+ it { should respond_to(:href) }
29
+ it { should respond_to(:delete) }
30
+ end
31
+
32
+ context "#initialize" do
33
+
34
+ it "should be constructable from just an id reference" do
35
+ obj = OrgVdcNetwork.new(@net_id)
36
+ expect(obj.class).to be(Vcloud::Core::OrgVdcNetwork)
37
+ end
38
+
39
+ it "should store the id specified" do
40
+ obj = OrgVdcNetwork.new(@net_id)
41
+ expect(obj.id) == @net_id
42
+ end
43
+
44
+ it "should raise error if id is not in correct format" do
45
+ bogus_id = '123123-bogus-id-123445'
46
+ expect{ OrgVdcNetwork.new(bogus_id) }.
47
+ to raise_error("orgVdcNetwork id : #{bogus_id} is not in correct format" )
48
+ end
49
+
50
+ end
51
+
52
+ context "#delete" do
53
+ it "should call down to Fog::ServiceInterface.delete_network with the correct id" do
54
+ @mock_fog_interface.should_receive(:delete_network).with(@net_id)
55
+ OrgVdcNetwork.new(@net_id).delete
56
+ end
57
+ end
58
+
59
+ context "#provision" do
60
+
61
+ before(:each) do
62
+ @mock_vdc = double(
63
+ :vdc,
64
+ :id => @vdc_id,
65
+ :href => "/#{@vdc_id}",
66
+ :name => @vdc_name
67
+ )
68
+ Vdc.stub(:get_by_name).and_return(@mock_vdc)
69
+ end
70
+
71
+ context "should fail gracefully on bad input" do
72
+
73
+ before(:each) do
74
+ @config = {
75
+ :name => @net_name,
76
+ :vdc_name => @vdc_name,
77
+ :fence_mode => 'isolated'
78
+ }
79
+ end
80
+
81
+ it "should fail if :name is not set" do
82
+ @config.delete(:name)
83
+ expect { Vcloud::Core::OrgVdcNetwork.provision(@config) }.
84
+ to raise_exception(RuntimeError)
85
+ end
86
+
87
+ it "should fail if :vdc_name is not set" do
88
+ @config.delete(:vdc_name)
89
+ expect { Vcloud::Core::OrgVdcNetwork.provision(@config) }.
90
+ to raise_exception(RuntimeError)
91
+ end
92
+
93
+ it "should fail if :fence_mode is not set" do
94
+ @config.delete(:fence_mode)
95
+ expect { Vcloud::Core::OrgVdcNetwork.provision(@config) }.
96
+ to raise_exception(RuntimeError)
97
+ end
98
+
99
+ it "should fail if :fence_mode is not 'isolated' or 'natRouted'" do
100
+ @config[:fence_mode] = 'testfail'
101
+ expect { Vcloud::Core::OrgVdcNetwork.provision(@config) }.
102
+ to raise_exception(RuntimeError)
103
+ end
104
+
105
+ end
106
+
107
+ context "isolated orgVdcNetwork" do
108
+
109
+ before(:each) do
110
+ q_results = [
111
+ { :name => @net_name, :href => "/#{@net_id}" }
112
+ ]
113
+ @mock_net_query = double(:query, :get_all_results => q_results)
114
+ @config = {
115
+ :name => @net_name,
116
+ :vdc_name => @vdc_name,
117
+ :fence_mode => 'isolated'
118
+ }
119
+ end
120
+
121
+ it "should create an OrgVdcNetwork with minimal config" do
122
+ expected_vcloud_attrs = {
123
+ :IsShared => false,
124
+ :Configuration => {
125
+ :FenceMode => 'isolated',
126
+ :IpScopes => {
127
+ :IpScope => {
128
+ :IsInherited => false,
129
+ :IsEnabled => true
130
+ }
131
+ }
132
+ },
133
+ }
134
+ Vcloud::Core.logger.should_receive(:info)
135
+ @mock_fog_interface.should_receive(:post_create_org_vdc_network).
136
+ with(@vdc_id, @config[:name], expected_vcloud_attrs).
137
+ and_return({ :href => "/#{@net_id}" })
138
+ obj = Vcloud::Core::OrgVdcNetwork.provision(@config)
139
+ expect(obj.id) == @net_id
140
+ end
141
+
142
+ it "should handle specification of one ip_ranges" do
143
+ @config[:ip_ranges] = [
144
+ { :start_address => '10.53.53.100', :end_address => '10.53.53.110' }
145
+ ]
146
+ expected_vcloud_attrs = {
147
+ :IsShared => false,
148
+ :Configuration => {
149
+ :FenceMode => 'isolated',
150
+ :IpScopes => {
151
+ :IpScope => {
152
+ :IsInherited => false,
153
+ :IsEnabled => true,
154
+ :IpRanges => [{
155
+ :IpRange => {
156
+ :StartAddress => '10.53.53.100',
157
+ :EndAddress => '10.53.53.110'
158
+ },
159
+ }],
160
+ }
161
+ }
162
+ }
163
+ }
164
+ Vcloud::Core.logger.should_receive(:info)
165
+ @mock_fog_interface.should_receive(:post_create_org_vdc_network).
166
+ with(@vdc_id, @config[:name], expected_vcloud_attrs).
167
+ and_return({ :href => "/#{@net_id}" })
168
+ obj = Vcloud::Core::OrgVdcNetwork.provision(@config)
169
+ end
170
+
171
+ it "should handle specification of two ip_ranges" do
172
+ @config[:ip_ranges] = [
173
+ { :start_address => '10.53.53.100', :end_address => '10.53.53.110' },
174
+ { :start_address => '10.53.53.120', :end_address => '10.53.53.130' },
175
+ ]
176
+ expected_vcloud_attrs = {
177
+ :IsShared => false,
178
+ :Configuration => {
179
+ :FenceMode => 'isolated',
180
+ :IpScopes => {
181
+ :IpScope => {
182
+ :IsInherited => false,
183
+ :IsEnabled => true,
184
+ :IpRanges => [
185
+ { :IpRange =>
186
+ {
187
+ :StartAddress => '10.53.53.100',
188
+ :EndAddress => '10.53.53.110'
189
+ }
190
+ },
191
+ { :IpRange =>
192
+ {
193
+ :StartAddress => '10.53.53.120',
194
+ :EndAddress => '10.53.53.130'
195
+ }
196
+ },
197
+ ]
198
+ }
199
+ }
200
+ },
201
+ }
202
+ Vcloud::Core.logger.should_receive(:info)
203
+ @mock_fog_interface.should_receive(:post_create_org_vdc_network).
204
+ with(@vdc_id, @config[:name], expected_vcloud_attrs).
205
+ and_return({ :href => "/#{@net_id}" })
206
+ obj = Vcloud::Core::OrgVdcNetwork.provision(@config)
207
+ end
208
+
209
+ end
210
+
211
+ context "natRouted orgVdcNetwork" do
212
+
213
+ before(:each) do
214
+ @config = {
215
+ :name => @net_name,
216
+ :vdc_name => @vdc_name,
217
+ :fence_mode => 'natRouted'
218
+ }
219
+ end
220
+
221
+ it "should fail if an edge_gateway is not supplied" do
222
+ expect{ Vcloud::Core::OrgVdcNetwork.provision(@config) }.
223
+ to raise_exception(RuntimeError)
224
+ end
225
+
226
+ it "should handle lack of ip_ranges on natRouted networks" do
227
+ @config[:edge_gateway] = 'test gateway'
228
+ mock_edgegw = Vcloud::Core::EdgeGateway.new(@edgegw_id)
229
+ Vcloud::Core::EdgeGateway.stub(:get_by_name).and_return(mock_edgegw)
230
+
231
+ expected_vcloud_attrs = {
232
+ :IsShared => false,
233
+ :Configuration => {
234
+ :FenceMode => 'natRouted',
235
+ :IpScopes => {
236
+ :IpScope => {
237
+ :IsInherited => false,
238
+ :IsEnabled => true
239
+ }
240
+ }
241
+ },
242
+ :EdgeGateway => { :href => "/#{@edgegw_id}" },
243
+ }
244
+ Vcloud::Core.logger.should_receive(:info)
245
+ @mock_fog_interface.should_receive(:post_create_org_vdc_network).
246
+ with(@vdc_id, @config[:name], expected_vcloud_attrs).
247
+ and_return({ :href => "/#{@net_id}" })
248
+ obj = Vcloud::Core::OrgVdcNetwork.provision(@config)
249
+ end
250
+
251
+ end
252
+
253
+ end
254
+
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe Vcloud::Query do
4
+ context "attributes" do
5
+
6
+ context "our object should have methods" do
7
+ before(:each) do
8
+ @mock_fog_interface = StubFogInterface.new
9
+ Vcloud::Fog::ServiceInterface.stub(:new).and_return(@mock_fog_interface)
10
+ @query = Vcloud::Query.new()
11
+ end
12
+ it { @query.should respond_to(:run) }
13
+ end
14
+
15
+ context "#run with no type set" do
16
+
17
+ before(:each) do
18
+ @mock_fog_interface = StubFogInterface.new
19
+ Vcloud::Fog::ServiceInterface.stub(:new).and_return(@mock_fog_interface)
20
+ @query = @query = Vcloud::Query.new()
21
+ end
22
+
23
+ it "should call output_potential_query_types when run not provided with a type" do
24
+ @query.should_receive(:output_potential_query_types)
25
+ @query.run()
26
+ end
27
+
28
+ it "should output viable types when run not provided with a type" do
29
+ @mock_fog_interface.stub(:get_execute_query).and_return(
30
+ { :Link => [
31
+ {:rel=>"down",
32
+ :href=>"query?type=alice&format=references"},
33
+ {:rel=>"down",
34
+ :href=>"query?type=alice&format=records"},
35
+ {:rel=>"down",
36
+ :href=>"query?type=bob&format=records"},
37
+ ]})
38
+
39
+ @query.should_receive(:puts).with("alice records,references")
40
+ @query.should_receive(:puts).with("bob records")
41
+
42
+ @query.run
43
+ end
44
+
45
+ end
46
+
47
+ context "gracefully handle zero results" do
48
+ before(:each) do
49
+ @mock_fog_interface = StubFogInterface.new
50
+ Vcloud::Fog::ServiceInterface.stub(:new).and_return(@mock_fog_interface)
51
+ @query = Vcloud::Query.new('bob')
52
+ @mock_fog_interface.stub(:get_execute_query).and_return({})
53
+ end
54
+
55
+ it "should not output when given tsv output_format" do
56
+ @query = Vcloud::Query.new('bob', :output_format => 'tsv')
57
+ @query.should_not_receive(:puts)
58
+ @query.run()
59
+ end
60
+
61
+ it "should not output when given csv output_format" do
62
+ @query = Vcloud::Query.new('bob', :output_format => 'csv')
63
+ @query.should_not_receive(:puts)
64
+ @query.run()
65
+ end
66
+
67
+ end
68
+
69
+ context "get results with a single response page" do
70
+
71
+ before(:each) do
72
+ @mock_fog_interface = StubFogInterface.new
73
+ Vcloud::Fog::ServiceInterface.stub(:new).and_return(@mock_fog_interface)
74
+ @query = Vcloud::Query.new('bob')
75
+ @mock_fog_interface.stub(:get_execute_query).and_return( {
76
+ :WibbleRecord=>
77
+ [{:field1=>"Stuff 1",
78
+ :field2=>"Stuff 2",
79
+ :field3=>"Stuff 3",
80
+ },
81
+ {:field1=>"More Stuff 1",
82
+ :field2=>"More Stuff 2",
83
+ :field3=>"More Stuff 3",
84
+ },
85
+ ]
86
+ } )
87
+ end
88
+
89
+ it "should output a query in tsv when run with a type" do
90
+ @query = Vcloud::Query.new('bob', :output_format => 'tsv')
91
+ @query.should_receive(:puts).with("field1\tfield2\tfield3")
92
+ @query.should_receive(:puts).with("Stuff 1\tStuff 2\tStuff 3")
93
+ @query.should_receive(:puts).with("More Stuff 1\tMore Stuff 2\tMore Stuff 3")
94
+ @query.run()
95
+ end
96
+
97
+ it "should output a query in csv when run with a type" do
98
+ @query = Vcloud::Query.new('bob', :output_format => 'csv')
99
+ @query.should_receive(:puts).with("field1,field2,field3\n")
100
+ @query.should_receive(:puts).with("Stuff 1,Stuff 2,Stuff 3\nMore Stuff 1,More Stuff 2,More Stuff 3\n")
101
+ @query.run()
102
+ end
103
+
104
+ # it "should output a query in yaml when run with a type"
105
+
106
+ end
107
+
108
+ end
109
+
110
+ end
111
+