foreman_google 3.0.8 → 3.1.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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/foreman_google/locale/cs_CZ/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/de/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/el/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/en/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/en_GB/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/es/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/fr/foreman_google.js +8 -2
- data/app/assets/javascripts/foreman_google/locale/it/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/ja/foreman_google.js +8 -2
- data/app/assets/javascripts/foreman_google/locale/ka/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/ko/foreman_google.js +8 -2
- data/app/assets/javascripts/foreman_google/locale/pl/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/pt_BR/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/ru/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/sv_SE/foreman_google.js +7 -1
- data/app/assets/javascripts/foreman_google/locale/zh_CN/foreman_google.js +8 -2
- data/app/assets/javascripts/foreman_google/locale/zh_TW/foreman_google.js +7 -1
- data/app/lib/google_cloud_compute/compute_attributes.rb +3 -1
- data/app/models/foreman_google/gce.rb +2 -4
- data/app/models/foreman_google/google_compute.rb +2 -2
- data/lib/foreman_google/engine.rb +1 -1
- data/lib/foreman_google/version.rb +1 -1
- data/locale/cs_CZ/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/cs_CZ/foreman_google.po +7 -1
- data/locale/de/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/de/foreman_google.po +7 -1
- data/locale/el/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/el/foreman_google.po +7 -1
- data/locale/en/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/en/foreman_google.po +7 -1
- data/locale/en_GB/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/en_GB/foreman_google.po +7 -1
- data/locale/es/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/es/foreman_google.po +7 -1
- data/locale/foreman_google.pot +12 -4
- data/locale/fr/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/fr/foreman_google.po +9 -3
- data/locale/it/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/it/foreman_google.po +7 -1
- data/locale/ja/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/ja/foreman_google.po +9 -3
- data/locale/ka/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/ka/foreman_google.po +7 -1
- data/locale/ko/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/ko/foreman_google.po +9 -3
- data/locale/pl/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/pl/foreman_google.po +7 -1
- data/locale/pt_BR/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/pt_BR/foreman_google.po +7 -1
- data/locale/ru/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/ru/foreman_google.po +7 -1
- data/locale/sv_SE/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/sv_SE/foreman_google.po +7 -1
- data/locale/zh_CN/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/zh_CN/foreman_google.po +9 -3
- data/locale/zh_TW/LC_MESSAGES/foreman_google.mo +0 -0
- data/locale/zh_TW/foreman_google.po +7 -1
- data/test/controllers/foreman_google/api/v2/compute_resources_extensions_test.rb +71 -0
- data/test/models/concerns/foreman_google/host_managed_extensions_test.rb +46 -0
- data/test/models/foreman_google/gce_test.rb +275 -3
- data/test/models/foreman_google/google_compute_test.rb +193 -4
- data/test/unit/foreman_google/google_compute_adapter_test.rb +59 -7
- data/test/unit/google_cloud_compute/compute_attributes_test.rb +235 -0
- data/test/unit/google_cloud_compute/compute_collection_test.rb +78 -0
- data/test/unit/google_extensions/attached_disk_test.rb +35 -0
- metadata +10 -2
|
@@ -2,7 +2,7 @@ require 'test_google_helper'
|
|
|
2
2
|
|
|
3
3
|
module ForemanGoogle
|
|
4
4
|
class GCETest < GoogleTestCase
|
|
5
|
-
subject { ForemanGoogle::GCE.new(zone: '
|
|
5
|
+
subject { ForemanGoogle::GCE.new(zone: 'us-east1-b', password: gauth_json) }
|
|
6
6
|
let(:service) { mock('GoogleAdapter') }
|
|
7
7
|
|
|
8
8
|
let(:instance_args) do
|
|
@@ -18,6 +18,142 @@ module ForemanGoogle
|
|
|
18
18
|
service.stubs(:project_id).returns('project_id')
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
describe '#to_label' do
|
|
22
|
+
it 'includes name, zone, and provider' do
|
|
23
|
+
subject.name = 'my-gce'
|
|
24
|
+
expected = 'my-gce (us-east1-b-Google)'
|
|
25
|
+
assert_equal expected, subject.to_label
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe '#capabilities' do
|
|
30
|
+
it 'returns image and new_volume' do
|
|
31
|
+
assert_equal %i[image new_volume], subject.capabilities
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe '#provided_attributes' do
|
|
36
|
+
it 'includes ip mapped to vm_ip_address' do
|
|
37
|
+
attrs = subject.provided_attributes
|
|
38
|
+
assert_equal :vm_ip_address, attrs[:ip]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe '#user_data_supported?' do
|
|
43
|
+
it 'returns true' do
|
|
44
|
+
assert subject.user_data_supported?
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe '#zone' do
|
|
49
|
+
it 'reads from url attribute' do
|
|
50
|
+
subject.url = 'us-central1-a'
|
|
51
|
+
assert_equal 'us-central1-a', subject.zone
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe '#zone=' do
|
|
56
|
+
it 'writes to url attribute' do
|
|
57
|
+
subject.zone = 'europe-west1-b'
|
|
58
|
+
assert_equal 'europe-west1-b', subject.url
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe 'validations' do
|
|
63
|
+
it 'is valid with name, zone, and password' do
|
|
64
|
+
subject.name = 'test-gce'
|
|
65
|
+
assert subject.valid?, "Expected subject to be valid, got errors: #{subject.errors.full_messages}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'requires password' do
|
|
69
|
+
cr = ForemanGoogle::GCE.new(zone: 'us-east1-b', password: nil)
|
|
70
|
+
assert_not cr.valid?
|
|
71
|
+
assert_includes cr.errors.attribute_names, :password
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'requires zone' do
|
|
75
|
+
cr = ForemanGoogle::GCE.new(zone: nil, password: gauth_json)
|
|
76
|
+
assert_not cr.valid?
|
|
77
|
+
assert_includes cr.errors.attribute_names, :zone
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'requires name' do
|
|
81
|
+
cr = ForemanGoogle::GCE.new(name: nil, zone: 'us-east1-b', password: gauth_json)
|
|
82
|
+
assert_not cr.valid?
|
|
83
|
+
assert_includes cr.errors.attribute_names, :name
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe '#zones' do
|
|
88
|
+
it 'returns zone names from client' do
|
|
89
|
+
zones = [OpenStruct.new(name: 'us-east1-b'), OpenStruct.new(name: 'us-west1-a')]
|
|
90
|
+
service.expects(:zones).returns(zones)
|
|
91
|
+
assert_equal %w[us-east1-b us-west1-a], subject.zones
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'is aliased as available_zones' do
|
|
95
|
+
zones = [OpenStruct.new(name: 'us-east1-b')]
|
|
96
|
+
service.expects(:zones).returns(zones)
|
|
97
|
+
assert_equal %w[us-east1-b], subject.available_zones
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe '#networks' do
|
|
102
|
+
it 'returns network names from client' do
|
|
103
|
+
networks = [OpenStruct.new(name: 'default'), OpenStruct.new(name: 'custom')]
|
|
104
|
+
service.expects(:networks).returns(networks)
|
|
105
|
+
assert_equal %w[default custom], subject.networks
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
describe '#available_networks' do
|
|
110
|
+
it 'returns full network objects from client' do
|
|
111
|
+
network_objects = [OpenStruct.new(name: 'default')]
|
|
112
|
+
service.expects(:networks).returns(network_objects)
|
|
113
|
+
assert_equal network_objects, subject.available_networks
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
describe '#machine_types' do
|
|
118
|
+
it 'returns machine types for the zone from client' do
|
|
119
|
+
types = [OpenStruct.new(name: 'e2-micro')]
|
|
120
|
+
service.expects(:machine_types).with('us-east1-b').returns(types)
|
|
121
|
+
assert_equal types, subject.machine_types
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'is aliased as available_flavors' do
|
|
125
|
+
types = [OpenStruct.new(name: 'n1-standard-1')]
|
|
126
|
+
service.expects(:machine_types).with('us-east1-b').returns(types)
|
|
127
|
+
assert_equal types, subject.available_flavors
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe '#available_images' do
|
|
132
|
+
it 'delegates to client.images with filter' do
|
|
133
|
+
images = [OpenStruct.new(name: 'centos-7')]
|
|
134
|
+
service.expects(:images).with(filter: nil).returns(images)
|
|
135
|
+
assert_equal images, subject.available_images
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it 'passes custom filter to client' do
|
|
139
|
+
images = [OpenStruct.new(name: 'centos-7')]
|
|
140
|
+
service.expects(:images).with(filter: 'name = "centos"').returns(images)
|
|
141
|
+
assert_equal images, subject.available_images(filter: 'name = "centos"')
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
describe '#filter_for_images' do
|
|
146
|
+
it 'defaults to nil' do
|
|
147
|
+
assert_nil subject.filter_for_images
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
describe '#google_project_id' do
|
|
152
|
+
it 'delegates to client' do
|
|
153
|
+
assert_equal 'project_id', subject.google_project_id
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
21
157
|
describe '#find_vm_by_uuid' do
|
|
22
158
|
it 'does query gce' do
|
|
23
159
|
instance = OpenStruct.new(**instance_args)
|
|
@@ -48,11 +184,29 @@ module ForemanGoogle
|
|
|
48
184
|
end
|
|
49
185
|
|
|
50
186
|
it 'iteration over the vms array' do
|
|
51
|
-
subject.vms.each_with_index { |instance, i|
|
|
187
|
+
subject.vms.each_with_index { |instance, i| assert_equal instances[i].name, instance.name }
|
|
52
188
|
end
|
|
53
189
|
|
|
54
190
|
it 'all method' do
|
|
55
|
-
subject.vms.all.each_with_index { |instance, i|
|
|
191
|
+
subject.vms.all.each_with_index { |instance, i| assert_equal instances[i].name, instance.name }
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
describe '#new_vm' do
|
|
196
|
+
it 'assigns provided attributes' do
|
|
197
|
+
vm = subject.new_vm(name: 'test-vm', machine_type: 'e2-micro')
|
|
198
|
+
assert_equal 'test-vm', vm.name
|
|
199
|
+
assert_equal 'e2-micro', vm.machine_type
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it 'converts volumes_attributes nested hash' do
|
|
203
|
+
attrs = {
|
|
204
|
+
'name' => 'test-vm',
|
|
205
|
+
'volumes_attributes' => { '0' => { 'size_gb' => '20' } },
|
|
206
|
+
}
|
|
207
|
+
vm = subject.new_vm(attrs)
|
|
208
|
+
assert_equal 1, vm.volumes.size
|
|
209
|
+
assert_equal 20, vm.volumes.first.size_gb
|
|
56
210
|
end
|
|
57
211
|
end
|
|
58
212
|
|
|
@@ -65,5 +219,123 @@ module ForemanGoogle
|
|
|
65
219
|
value { subject.create_vm({ image_id: 0 }) }.must_raise(::Foreman::Exception)
|
|
66
220
|
end
|
|
67
221
|
end
|
|
222
|
+
|
|
223
|
+
describe '#create_vm success path' do
|
|
224
|
+
let(:os_image) { OpenStruct.new(username: 'gce_user', name: 'centos-7') }
|
|
225
|
+
let(:gce_image) { OpenStruct.new(id: 42, self_link: 'image-link') }
|
|
226
|
+
let(:key_pair_obj) { OpenStruct.new(public: 'ssh-rsa AAAA') }
|
|
227
|
+
let(:vm) { mock('GoogleCompute') }
|
|
228
|
+
|
|
229
|
+
setup do
|
|
230
|
+
service.stubs(:image).returns(gce_image)
|
|
231
|
+
service.stubs(:instance)
|
|
232
|
+
subject.stubs(:images).returns(stub(find_by: os_image))
|
|
233
|
+
subject.stubs(:key_pair).returns(key_pair_obj)
|
|
234
|
+
subject.stubs(:new_vm).returns(vm)
|
|
235
|
+
vm.stubs(:hostname).returns('test-vm')
|
|
236
|
+
|
|
237
|
+
vm.expects(:create_volumes)
|
|
238
|
+
vm.expects(:create_instance)
|
|
239
|
+
vm.expects(:set_disk_auto_delete)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'creates volumes, instance, and sets auto-delete' do
|
|
243
|
+
result = subject.create_vm({ image_id: 42 })
|
|
244
|
+
assert_kind_of ForemanGoogle::GoogleCompute, result
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
describe '#create_vm rollback on error' do
|
|
249
|
+
let(:os_image) { OpenStruct.new(username: 'gce_user', name: 'centos-7') }
|
|
250
|
+
let(:gce_image) { OpenStruct.new(id: 42, self_link: 'image-link') }
|
|
251
|
+
let(:key_pair_obj) { OpenStruct.new(public: 'ssh-rsa AAAA') }
|
|
252
|
+
let(:vm) { mock('GoogleCompute') }
|
|
253
|
+
|
|
254
|
+
setup do
|
|
255
|
+
subject.stubs(:images).returns(stub(find_by: os_image))
|
|
256
|
+
service.stubs(:image).returns(gce_image)
|
|
257
|
+
subject.stubs(:key_pair).returns(key_pair_obj)
|
|
258
|
+
subject.stubs(:new_vm).returns(vm)
|
|
259
|
+
vm.stubs(:create_volumes).raises(::Google::Cloud::Error.new('quota exceeded'))
|
|
260
|
+
|
|
261
|
+
vm.expects(:destroy_volumes)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it 'destroys volumes and raises WrappedException' do
|
|
265
|
+
assert_raises(Foreman::WrappedException) { subject.create_vm({ image_id: 42 }) }
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
describe '#destroy_vm' do
|
|
270
|
+
it 'calls set_disk_auto_delete and delete_instance' do
|
|
271
|
+
service.expects(:set_disk_auto_delete).with('us-east1-b', 'vm-uuid')
|
|
272
|
+
service.expects(:delete_instance).with('us-east1-b', 'vm-uuid')
|
|
273
|
+
subject.destroy_vm('vm-uuid')
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it 'returns true when VM not found' do
|
|
277
|
+
service.expects(:set_disk_auto_delete).raises(ActiveRecord::RecordNotFound)
|
|
278
|
+
assert subject.destroy_vm('missing-vm')
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
describe '#new_volume' do
|
|
283
|
+
it 'returns an AttachedDisk with 20 GB default' do
|
|
284
|
+
vol = subject.new_volume
|
|
285
|
+
assert_kind_of Google::Cloud::Compute::V1::AttachedDisk, vol
|
|
286
|
+
assert_equal 20, vol.disk_size_gb
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
it 'merges provided attributes' do
|
|
290
|
+
vol = subject.new_volume(device_name: 'boot-disk')
|
|
291
|
+
assert_equal 'boot-disk', vol.device_name
|
|
292
|
+
assert_equal 20, vol.disk_size_gb
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
describe '#console' do
|
|
297
|
+
let(:vm) { mock('GoogleCompute') }
|
|
298
|
+
|
|
299
|
+
setup do
|
|
300
|
+
subject.stubs(:find_vm_by_uuid).returns(vm)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it 'returns serial output when VM is ready' do
|
|
304
|
+
vm.stubs(:ready?).returns(true)
|
|
305
|
+
vm.stubs(:serial_port_output).returns('boot log...')
|
|
306
|
+
vm.stubs(:name).returns('test-vm')
|
|
307
|
+
|
|
308
|
+
result = subject.console('test-vm')
|
|
309
|
+
assert_equal 'boot log...', result['output']
|
|
310
|
+
assert_equal 'log', result[:type]
|
|
311
|
+
assert_equal 'test-vm', result[:name]
|
|
312
|
+
assert result['timestamp'].is_a?(Time)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
it 'raises when VM is not ready' do
|
|
316
|
+
vm.stubs(:ready?).returns(false)
|
|
317
|
+
assert_raises(::Foreman::Exception) { subject.console('test-vm') }
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
describe '#associated_host' do
|
|
322
|
+
it 'calls associate_by with ip addresses' do
|
|
323
|
+
vm = OpenStruct.new(public_ip_address: '1.2.3.4', private_ip_address: '10.0.0.1')
|
|
324
|
+
subject.expects(:associate_by).with('ip', ['1.2.3.4', '10.0.0.1'])
|
|
325
|
+
subject.associated_host(vm)
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
describe '#vm_ready' do
|
|
330
|
+
it 'polls until vm is ready' do
|
|
331
|
+
vm = mock('GoogleCompute')
|
|
332
|
+
vm.stubs(:reload).returns(vm)
|
|
333
|
+
vm.stubs(:ready?).returns(false, true)
|
|
334
|
+
vm.stubs(:wait_for).yields.returns({ duration: 2 })
|
|
335
|
+
|
|
336
|
+
result = subject.vm_ready(vm)
|
|
337
|
+
assert_equal({ duration: 2 }, result)
|
|
338
|
+
end
|
|
339
|
+
end
|
|
68
340
|
end
|
|
69
341
|
end
|
|
@@ -194,20 +194,209 @@ module ForemanGoogle
|
|
|
194
194
|
|
|
195
195
|
it '@network' do
|
|
196
196
|
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
|
|
197
|
-
|
|
197
|
+
assert_equal 'default', cr.network
|
|
198
198
|
|
|
199
199
|
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: { network: 'my-network' })
|
|
200
|
-
|
|
200
|
+
assert_equal 'my-network', cr.network
|
|
201
201
|
end
|
|
202
202
|
|
|
203
203
|
it '@zone' do
|
|
204
204
|
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
|
|
205
|
-
|
|
205
|
+
assert_equal zone, cr.zone
|
|
206
206
|
end
|
|
207
207
|
|
|
208
208
|
it '@zone_name' do
|
|
209
209
|
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: instance)
|
|
210
|
-
|
|
210
|
+
assert_equal zone, cr.zone_name
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
describe '#status' do
|
|
214
|
+
it 'returns status when persisted' do
|
|
215
|
+
instance.status = 'RUNNING'
|
|
216
|
+
client.expects(:instance).with(zone, identity).returns(instance)
|
|
217
|
+
assert_equal 'RUNNING', subject.status
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
it 'returns false when not persisted' do
|
|
221
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
|
|
222
|
+
assert_not cr.status
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
describe '#state' do
|
|
227
|
+
it 'is an alias for status' do
|
|
228
|
+
instance.status = 'TERMINATED'
|
|
229
|
+
client.expects(:instance).with(zone, identity).returns(instance)
|
|
230
|
+
assert_equal subject.status, subject.state
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
describe '#start' do
|
|
235
|
+
it 'delegates to client.start when persisted' do
|
|
236
|
+
client.stubs(:instance).with(zone, identity).returns(instance)
|
|
237
|
+
client.expects(:start).with(zone, identity).returns(true)
|
|
238
|
+
subject.start
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it 'raises when not persisted' do
|
|
242
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
|
|
243
|
+
assert_raises(Foreman::Exception) { cr.start }
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
describe '#stop' do
|
|
248
|
+
it 'delegates to client.stop when persisted' do
|
|
249
|
+
client.stubs(:instance).with(zone, identity).returns(instance)
|
|
250
|
+
client.expects(:stop).with(zone, identity).returns(true)
|
|
251
|
+
subject.stop
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it 'raises when not persisted' do
|
|
255
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
|
|
256
|
+
assert_raises(Foreman::Exception) { cr.stop }
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
describe '#to_s' do
|
|
261
|
+
it 'returns the name' do
|
|
262
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: { name: 'my-vm' })
|
|
263
|
+
assert_equal 'my-vm', cr.to_s
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
describe '#interfaces' do
|
|
268
|
+
it 'returns network_interfaces' do
|
|
269
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
|
|
270
|
+
assert_equal cr.network_interfaces, cr.interfaces
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
describe '#vm_description' do
|
|
275
|
+
it 'delegates to pretty_machine_type' do
|
|
276
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: instance)
|
|
277
|
+
assert_equal cr.pretty_machine_type, cr.vm_description
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
describe '#vm_ip_address - no network interfaces' do
|
|
282
|
+
it 'returns nil' do
|
|
283
|
+
empty_instance = OpenStruct.new(
|
|
284
|
+
name: 'instance', network_interfaces: [],
|
|
285
|
+
creation_timestamp: Time.zone.now, zone: zone,
|
|
286
|
+
machine_type: 'machineTypes/e2-micro'
|
|
287
|
+
)
|
|
288
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: empty_instance)
|
|
289
|
+
assert_nil cr.vm_ip_address
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
describe '#private_ip_address - no network interfaces' do
|
|
294
|
+
it 'returns nil' do
|
|
295
|
+
empty_instance = OpenStruct.new(
|
|
296
|
+
name: 'instance', network_interfaces: [],
|
|
297
|
+
creation_timestamp: Time.zone.now, zone: zone,
|
|
298
|
+
machine_type: 'machineTypes/e2-micro'
|
|
299
|
+
)
|
|
300
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: empty_instance)
|
|
301
|
+
assert_nil cr.private_ip_address
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
describe '#pretty_image_name - no disks' do
|
|
306
|
+
it 'returns nil' do
|
|
307
|
+
instance.disks = []
|
|
308
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: instance)
|
|
309
|
+
assert_nil cr.pretty_image_name
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
describe '#ip_addresses' do
|
|
314
|
+
it 'returns public and private IP' do
|
|
315
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: instance)
|
|
316
|
+
assert_equal ['1.2.3.4', '10.10.10.23'], cr.ip_addresses
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
describe '#serial_port_output' do
|
|
321
|
+
it 'delegates to client' do
|
|
322
|
+
client.stubs(:instance).with(zone, identity).returns(instance)
|
|
323
|
+
client.expects(:serial_port_output).with(zone, identity).returns(OpenStruct.new(contents: 'boot log'))
|
|
324
|
+
assert_equal 'boot log', subject.serial_port_output
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
it 'returns nil when client returns nil' do
|
|
328
|
+
client.stubs(:instance).with(zone, identity).returns(instance)
|
|
329
|
+
client.expects(:serial_port_output).with(zone, identity).returns(nil)
|
|
330
|
+
assert_nil subject.serial_port_output
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
describe '#volumes_attributes=' do
|
|
335
|
+
it 'is a no-op' do
|
|
336
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
|
|
337
|
+
cr.volumes_attributes = { '0' => { size_gb: 10 } }
|
|
338
|
+
assert cr.volumes.any?
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
describe '#reload - without identity' do
|
|
343
|
+
it 'returns nil' do
|
|
344
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
|
|
345
|
+
assert_nil cr.reload
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
describe '#create_volumes' do
|
|
350
|
+
it 'inserts disks and waits for READY' do
|
|
351
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: { volumes: [{ size_gb: '20' }] })
|
|
352
|
+
|
|
353
|
+
client.expects(:insert_disk).with(zone, cr.volumes.first.insert_attrs)
|
|
354
|
+
client.expects(:disk).with(zone, cr.volumes.first.device_name).returns(OpenStruct.new(status: 'READY'))
|
|
355
|
+
client.expects(:wait_for).yields.returns({ duration: 1 })
|
|
356
|
+
|
|
357
|
+
cr.create_volumes
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
describe '#destroy_volumes' do
|
|
362
|
+
it 'deletes each volume disk' do
|
|
363
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: { volumes: [{ size_gb: '20' }] })
|
|
364
|
+
client.expects(:delete_disk).with(zone, cr.volumes.first.device_name)
|
|
365
|
+
cr.destroy_volumes
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
describe '#create_instance' do
|
|
370
|
+
it 'calls insert_instance via ComputeAttributes' do
|
|
371
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: { name: 'test-vm', machine_type: 'e2-micro' })
|
|
372
|
+
client.expects(:insert_instance).with(zone, has_key(:name))
|
|
373
|
+
cr.create_instance
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
describe '#set_disk_auto_delete' do
|
|
378
|
+
it 'delegates to client' do
|
|
379
|
+
args = { name: 'my-vm' }
|
|
380
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: args)
|
|
381
|
+
client.expects(:set_disk_auto_delete).with(zone, 'my-vm')
|
|
382
|
+
cr.set_disk_auto_delete
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
describe '#wait_for' do
|
|
387
|
+
it 'delegates to client.wait_for' do
|
|
388
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
|
|
389
|
+
client.expects(:wait_for).yields.returns({ duration: 0 })
|
|
390
|
+
result = cr.wait_for { true }
|
|
391
|
+
assert_equal({ duration: 0 }, result)
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
describe '#public_ip_address' do
|
|
396
|
+
it 'is an alias for vm_ip_address' do
|
|
397
|
+
cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: instance)
|
|
398
|
+
assert_equal cr.vm_ip_address, cr.public_ip_address
|
|
399
|
+
end
|
|
211
400
|
end
|
|
212
401
|
end
|
|
213
402
|
end
|
|
@@ -131,7 +131,7 @@ module ForemanGoogle
|
|
|
131
131
|
|
|
132
132
|
result = subject.insert_instance('us-east1-b', args)
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
assert_equal 'insert', result.operation.operation_type
|
|
135
135
|
assert_includes result.operation.target_link, 'foreman-test-google'
|
|
136
136
|
end
|
|
137
137
|
|
|
@@ -156,14 +156,14 @@ module ForemanGoogle
|
|
|
156
156
|
stub_request(:post, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/instance_name/start')
|
|
157
157
|
.to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_start.json')))
|
|
158
158
|
result = subject.start('us-east1-b', 'instance_name')
|
|
159
|
-
|
|
159
|
+
assert_equal 'start', result.operation.operation_type
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
it '#stop' do
|
|
163
163
|
stub_request(:post, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/instance_name/stop')
|
|
164
164
|
.to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_stop.json')))
|
|
165
165
|
result = subject.stop('us-east1-b', 'instance_name')
|
|
166
|
-
|
|
166
|
+
assert_equal 'stop', result.operation.operation_type
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
it '#set_disk_auto_delete' do
|
|
@@ -174,7 +174,7 @@ module ForemanGoogle
|
|
|
174
174
|
.to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_set_disk_auto_delete.json')))
|
|
175
175
|
result = subject.set_disk_auto_delete('us-east1-b', 'instance_name')
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
assert_equal 'instance-1', result[0].device_name
|
|
178
178
|
assert result[0].auto_delete
|
|
179
179
|
end
|
|
180
180
|
end
|
|
@@ -186,14 +186,14 @@ module ForemanGoogle
|
|
|
186
186
|
|
|
187
187
|
result = subject.insert_disk('us-east1-b', { name: 'foreman-disk1', size_gb: 23 })
|
|
188
188
|
assert_includes result.operation.target_link, 'foreman-disk1'
|
|
189
|
-
|
|
189
|
+
assert_equal 'insert', result.operation.operation_type
|
|
190
190
|
end
|
|
191
191
|
|
|
192
192
|
it '#get' do
|
|
193
193
|
stub_request(:get, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/disks/foreman-disk1')
|
|
194
194
|
.to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'disks_get.json')))
|
|
195
195
|
result = subject.disk('us-east1-b', 'foreman-disk1')
|
|
196
|
-
|
|
196
|
+
assert_equal 'foreman-disk1', result.name
|
|
197
197
|
end
|
|
198
198
|
|
|
199
199
|
it '#delete' do
|
|
@@ -202,7 +202,59 @@ module ForemanGoogle
|
|
|
202
202
|
result = subject.delete_disk('us-east1-b', 'foreman-disk1')
|
|
203
203
|
|
|
204
204
|
assert_includes result.operation.target_link, 'foreman-disk1'
|
|
205
|
-
|
|
205
|
+
assert_equal 'delete', result.operation.operation_type
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
describe '#delete_instance' do
|
|
210
|
+
it 'deletes an instance' do
|
|
211
|
+
stub_request(:delete, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/instance_name')
|
|
212
|
+
.to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_stop.json')))
|
|
213
|
+
result = subject.delete_instance('us-east1-b', 'instance_name')
|
|
214
|
+
assert_equal 'stop', result.operation.operation_type
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
describe '#image' do
|
|
219
|
+
setup do
|
|
220
|
+
stub_request(:get, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/global/images')
|
|
221
|
+
.to_return(body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'images_coastal.json')))
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it 'finds image by numeric id' do
|
|
225
|
+
subject.stub(:all_projects, []) do
|
|
226
|
+
result = subject.image(1)
|
|
227
|
+
assert_equal 'coastal-image', result.name
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it 'returns nil when image not found' do
|
|
232
|
+
subject.stub(:all_projects, []) do
|
|
233
|
+
assert_nil subject.image(999)
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
describe '#serial_port_output' do
|
|
239
|
+
it 'returns serial port output' do
|
|
240
|
+
body = { contents: 'boot log output', next: 12_345, start: 0, selfLink: 'self-link' }.to_json
|
|
241
|
+
stub_request(:get, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/instance_name/serialPort')
|
|
242
|
+
.to_return(status: 200, body: body)
|
|
243
|
+
result = subject.serial_port_output('us-east1-b', 'instance_name')
|
|
244
|
+
assert_equal 'boot log output', result.contents
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
describe '#project_id' do
|
|
249
|
+
it 'returns the project_id from auth JSON' do
|
|
250
|
+
assert_equal 'coastal-haven-123456', subject.project_id
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
describe '#wait_for' do
|
|
255
|
+
it 'returns immediately when block yields true' do
|
|
256
|
+
result = subject.wait_for { true }
|
|
257
|
+
assert result[:duration] <= 1
|
|
206
258
|
end
|
|
207
259
|
end
|
|
208
260
|
end
|