vcloud-core 0.0.1

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 (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
+